Adam Optimizer
Adamはモメンタムと、直近の勾配の大きさに応じて調整されるパラメーターごとの学習率を組み合わせます。更新則、デフォルト設定、AdamW、AdamとSGDの比較を解説します。
Adamオプティマイザー(Adaptive Moment Estimationの略)は、ニューラルネットワークの学習に使う最適化アルゴリズムで、各パラメーターに適応的なステップサイズを個別に設定します。KingmaとBaによる論文Adam: 確率的最適化の手法で紹介され、過去の勾配とその二乗の移動平均を用いて確率的勾配降下法(SGD)を拡張しています。初期の学習が速く、デフォルト設定でも扱いやすいことから、Adamはディープラーニングで最も一般的な初期オプティマイザーになりました。AdamWはその派生版であり、Transformerや大規模言語モデルの学習に標準的に使われています。
Adamの仕組み#
学習では、各重みを勾配に沿って繰り返し更新し、損失関数を最小化します。通常のSGDでは、すべての勾配に同じ学習率を適用します。Adamはパラメーターごとに2つの値を追加で保持し、各ステップで現在の勾配tを使って更新しますg。
- 第1モーメント(モメンタム):
m = β1·m + (1 − β1)·g。勾配の指数減衰平均で、更新を一貫した方向に進めます。 - 第2モーメント:
v = β2·v + (1 − β2)·g²。勾配の二乗の減衰平均で、各パラメーターの勾配の典型的な大きさを追跡します。 - バイアス補正:
m̂ = m / (1 − β1^t)とv̂ = v / (1 − β2^t)。両方の平均値がゼロから始まることによる影響を補正します。 - 更新:
θ = θ − lr · m̂ / (√v̂ + ε)。
論文で推奨されたデフォルト値は、PyTorchのtorch.optim.Adamでも使われており、lr = 0.001、β1 = 0.9、β2 = 0.999、ε = 1e-8です。√v̂で割ることで、各ステップはパラメーターの典型的な勾配の大きさで正規化されます。そのため、勾配の大小にかかわらずステップサイズは学習率に近い値に保たれ、m̂内で正負の勾配が相殺されるノイズの多い方向では小さくなります。以下のコードでは、勾配の大きさが1,000倍異なる2つのパラメーターについて、SGDとAdamの最初のステップを比較します。
import torch
# Two parameters whose gradients differ in scale by 1,000x
scale = torch.tensor([1000.0, 1.0])
for name, optimizer_cls in [("SGD", torch.optim.SGD), ("Adam", torch.optim.Adam)]:
w = torch.zeros(2, requires_grad=True)
optimizer = optimizer_cls([w], lr=0.001)
loss = (scale * w).sum() # gradient is [1000, 1]
loss.backward()
optimizer.step()
print(f"{name} first step: {[round(v, 4) for v in w.tolist()]}")SGDでは、第1パラメーターは-1.0、第2パラメーターは-0.001だけ移動します。勾配に従うため、移動量には1,000倍の差があります。Adamでは、正規化されたステップが勾配の絶対値ではなく方向と一貫性に依存するため、両方とも学習率と同じ-0.001だけ移動します。
AdamとAdamWの比較#
一般的な実装のAdamでは、正則化の一種である重み減衰を、勾配に加えるL2ペナルティとして適用します。そのペナルティも他の項とともに√v̂で割られるため、勾配の大きな重みはほとんど正則化されません。LoshchilovとHutterによる重み減衰の分離では、適応的な更新とは分けて各ステップで重みを直接縮小することで、この問題を解決しています。論文の実験では、これによって得られたAdamWは画像分類の汎化性能をAdamより向上させており、torch.optim.AdamWとして利用できます。
AdamとSGDの比較#
モメンタム付きSGDは全体で1つの学習率を使い、パラメーターごとに1つのバッファーを保持します。一方、Adamはパラメーターごとに2つの値を保持し、32ビット精度ではパラメーターあたり8バイトになります。そのため、70億パラメーターのモデルでは、オプティマイザーの状態だけで56 GB必要です。Adamは一般に学習初期の進みが速く、学習率への感度も低いため、TransformerをSGDよりはるかに安定して学習できます。適切に調整したSGDは、畳み込み画像モデルで同等またはそれ以上の最終正解率に達することがよくあります。また、Wilsonらは、検証した画像分類タスクや言語タスクで、適応型手法はSGDより汎化性能が低いことが多いと報告しています。
Ultralytics YOLOの学習は、このトレードオフを反映しています。デフォルトのoptimizer="auto"は、クラス数に合わせて初期学習率を設定したAdamWを、最大10,000イテレーションの学習に選び、より長いスケジュールではSGDとMuonを組み合わせたMuSGDに切り替えます。オプティマイザーを明示的に設定する場合は、学習率も設定する必要があります。デフォルトのlr0=0.01はSGD向けで、一般的なAdamの学習率の10倍だからです。
from ultralytics import YOLO
# 事前学習済みYOLO26nモデルを読み込みます
model = YOLO("yolo26n.pt")
# AdamWとAdamに適した初期学習率で学習します
results = model.train(data="coco8.yaml", epochs=5, optimizer="AdamW", lr0=0.001)YOLO26がAdam系のオプティマイザーで学習する場合、momentum引数(デフォルト値0.937)でβ1を設定し、β2は0.999に固定されます。
Adamと関連オプティマイザーの比較#
- AdaGrad: 過去のすべての勾配の二乗和の平方根で各ステップを割ります。そのため、ステップサイズは縮小する一方となり、疎な特徴には適していますが、長時間の学習では速度が低下します。
- RMSProp: AdaGradの累積和を、勾配の二乗の指数減衰平均に置き換えます。Adamは基本的に、RMSPropにモメンタムとバイアス補正を加えたものです。
- Muon: 隠れ層の2次元重み行列向けのオプティマイザーです。ニュートン・シュルツ反復で各モメンタム更新を直交化し、パラメーターごとにAdamの半分となる1つの状態バッファーを保持します。










