SGDの先へ — Adam・二次法・制約付き最適化
モーメンタムは何を溜めているのか、Adamの4行は各行で何をしているのか、AdamWは何を直したのか、理論上もっと速いはずの二次法がなぜLLMで使われないのか。勾配クリッピングまで含めて、比喩→式→動く図→コード→現場の順で前提知識なしに解きほぐします。
Adam: A Method for Stochastic Optimization
一次資料 — この記事の根拠
この解説の公開 2026-08-22
Adam: A Method for Stochastic OptimizationarXiv:1412.6980論文ページ·PDFDecoupled Weight Decay RegularizationarXiv:1711.05101論文ページ·PDF
On the difficulty of training Recurrent Neural NetworksarXiv:1211.5063論文ページ·PDF
Optimizing Neural Networks with Kronecker-factored Approximate CurvaturearXiv:1503.05671論文ページ·PDF
Shampoo: Preconditioned Stochastic Tensor OptimizationarXiv:1802.09568論文ページ·PDF
Adafactor: Adaptive Learning Rates with Sublinear Memory CostarXiv:1804.04235論文ページ·PDF
ZeRO: Memory Optimizations Toward Training Trillion Parameter ModelsarXiv:1910.02054論文ページ·PDF
比喩: 細長い谷を、足元の傾きだけで下りる
霧の中で足元の傾きだけを頼りに谷底を目指す—AIのための微分で使ったこの比喩を、もう一歩進めます。
舞台は両側の壁が急で、谷筋の方向はほとんど平らな細長い峡谷です。「いま一番急に下っている向き」へ律儀に歩くと、その向きは谷筋ではなく壁を横切る方向になります。一歩進めば反対側の斜面に着き、そこでもまた一番急なのは壁を横切る方向。左右に跳ね返るばかりで、出口である谷筋へはごくわずかしか進みません。
これは損失面で日常的に起きていることです。方向によって曲がり具合(曲率)が100倍違えば、歩幅は最も急な方向に合わせるしかなく、平らな方向は100分の1の速さでしか進めません。SGDが遅いのは勾配が間違っているからではなく、「一番急な向き」が「行きたい向き」と一致しないからです。打ち手は4つ—溜める(モーメンタム)、方向ごとに歩幅を変える(Adam)、曲がり具合そのものを測る(二次法)、動ける範囲に柵を作る(制約付き最適化)。
おさらい: SGDが実際にやっていること
言い換えると、いまのパラメータ から、手元のデータで測った「悪くなる向き」 の逆へ、学習率 の分だけ動く。それだけです。 は今回引いたミニバッチ(数十〜数百件のデータの束)を指します。つまり、足元の傾きを数百件のデータで測り、その反対向きへ決まった歩幅で1歩踏み出す—これを延々と繰り返しているだけ、ということです。
ここに問題が2つ同居しています。1つは冒頭の方向の問題。もう1つはノイズの問題で、 は全データの勾配ではなく数百件からの推定値なので、同じ場所に立っていても引いたデータ次第で指す向きが揺れます。この2つは、同じ道具で同時に緩和できます。
モーメンタム: 一歩ごとに消さず、速度として溜める
SGDには過去の記憶がありません。そこに「速度」を持ち込みます。
読み下すと、速度 は「前の速度を 倍に減衰させたもの」+「今回の勾配」であり、パラメータはその速度の分だけ動く。(ベータ)は0〜1の減衰率で、慣例的に0.9が使われます。つまり、毎回まっさらな一歩を測り直すのではなく、前回の勢いを9割だけ引き継いで、そこに今回測った傾きを足している、ということです。
の意味は という計算で掴めます。おおよそ直近10ステップ分の勾配を足している、という感覚です。この足し算が2つの問題を同時に潰します。
- 方向: 壁を横切る成分は左右の壁で符号が反転するので打ち消し合う。谷筋方向の成分は毎回同じ符号なので積み上がる。ジグザグが消え、進みたい方向だけが伸びる。
- ノイズ: ミニバッチごとのランダムな揺れも、平均を取れば薄まる。10ステップ分ならおよそ 倍ノイズに強くなります。
SGDが「毎回止まって足元を測り直す歩行者」なら、モーメンタムは「斜面を転がる重い球」です。
副作用は行き過ぎ(オーバーシュート)です。谷底に着いても速度が残っているので通り過ぎる。 を上げるほど加速する代わりに止まりにくくなる—この綱引きが以降の工夫すべての背景にあります。
方向ごとに歩幅を変える: AdaGrad から RMSProp へ
モーメンタムは「向き」を直しましたが、歩幅は全パラメータ共通のままです。ならばパラメータごとに別の歩幅を持たせればよい。材料にはその方向の勾配が過去どれくらい大きかったかを使います。大きな勾配がよく来る方向は歩幅を縮め、めったに来ない方向は伸ばす—これがAdaGradの発想です。ただしAdaGradは過去の2乗和をすべて足し込むので、進むほど分母が膨らみ歩幅がゼロへ死んでいく。「すべて」を「最近だけ」に替えたのがRMSPropです。
言い換えると、各パラメータについて「最近の勾配の2乗の平均」 を持ち、その平方根で学習率を割る。 は要素ごとの2乗、(イプシロン)はゼロ割りを防ぐ小さな数( 程度)です。 は「その方向の勾配の典型的な大きさ」なので、それで割るのは勾配の大きさを1前後に揃えてから進むことを意味します。つまり、いつも大声で騒ぐ方向は音量を絞り、めったに喋らない方向は音量を上げて、どの方向も同じ大きさに聞こえるようにしてから歩く、ということです。
これで材料が2つ揃いました。モーメンタムはどっちへ進むか、RMSPropはどれだけ進むか。見ている統計量が違うので、干渉せずに同居できます。
コメント
コメントにはログインが必要です