勾配降下法と最適化手法
細長い谷・ローゼンブロック関数・鞍点などの等高線の上で、SGD・モーメンタム・AdaGrad・RMSProp・Adam が最小値へ進む道筋を並べて比べます。学習率やノイズを変えて、振動や発散も確かめられます。
関数
f(x, y) = 0.1x² + 2y²
x 方向はゆるやか、y 方向は急な谷です。学習率を上げると、SGD は急な y 方向で行ったり来たり振動し、ゆるやかな x 方向はなかなか進みません。
開始点(地図を押しても選べます)
歩数
勾配のノイズ(ミニバッチのばらつき)
開始点 (-5.50, 2.00)。× は最小値。明るいほど高く、暗いほど低い
縦は 10 の何乗かで、1 目盛り下がるごとに最小値との差が 1/10 になります。≈0 は差が 0.001 以下です。途中で線が切れたものは発散しました。
方法と学習率
| 方法 | 学習率 η | 今の f | 最小値まで(f の差 < 0.001) |
|---|---|---|---|
| 8.046e-25 | 43 歩 | ||
| 1.857e-13 | 58 歩 | ||
| — | — | ||
| — | — | ||
| 0.005251 | 70 歩 | ||
| 1.849e-13 | 51 歩 |
- SGD
- θ ← θ − η∇f
- 勾配の逆向きに、学習率の分だけ進みます。一番素直ですが、細長い谷では振動し、平らなところでは止まりそうになります。
- モーメンタム
- v ← βv + ∇f, θ ← θ − ηv(β = 0.9)
- それまでの進み方を「勢い」としてため、坂を転がるボールのように進みます。谷の振動が打ち消し合い、谷底の方向には加速します。
- ネステロフ
- v ← βv + ∇f(θ − ηβv), θ ← θ − ηv
- 勢いで進んだ先の勾配を見て向きを決めるので、行き過ぎにいち早く気づいてブレーキをかけます。
- AdaGrad
- s ← s + (∇f)², θ ← θ − η∇f / √s
- これまでの勾配の 2 乗の合計で割り、急な方向は小さく、ゆるやかな方向は大きく進みます。合計は増える一方なので、だんだん進まなくなります。
- RMSProp
- s ← ρs + (1 − ρ)(∇f)², θ ← θ − η∇f / √s(ρ = 0.9)
- AdaGrad の合計を、最近の勾配ほど重く見る移動平均に変えて、学習が止まらないようにしたものです。
- Adam
- m ← β₁m + (1 − β₁)∇f, v ← β₂v + (1 − β₂)(∇f)², θ ← θ − η m̂ / √v̂
- モーメンタムの勢いと RMSProp の割り算を組み合わせたもので、深層学習で最もよく使われます。最初の数歩は平均が 0 に寄るので補正します。
使い方
- 関数を選ぶと、等高線の地図の上で、選んだ方法が開始点(白い四角)から最小値(×)へ進む様子を再生します。地図を押すと、その点から始め直します。
- 下の表で方法の表示を切り替え、学習率を変えられます。初期値は、それぞれの方法の良さと弱点が見えやすい値にしています。
- 右のグラフは、最小値との差が歩数とともにどう減るかを対数目盛で表します。スライダーで好きな歩数に移れます(← → キーでも動きます)。
- 「勾配のノイズ」を入れると、ミニバッチで勾配を見積もったときのようなばらつきが加わります。
勾配降下法
機械学習の「学習」は、誤差を表す関数(損失関数)が小さくなるようにパラメータを少しずつ動かすことです。今いる点で一番急に下る向きは勾配の逆向きなので、そちらへ学習率の分だけ進むことを繰り返します。これが勾配降下法です。ニューラルネットワークではパラメータが何百万〜何千億もあり、このアプリの 2 変数の地図はその縮小版にあたります。
学習率が小さすぎるとなかなか進まず、大きすぎると谷を飛び越えて振動したり発散したりします。谷の向きによって急さが違うと、1 つの学習率ではどちらかの向きに合いません。そこで、それまでの進み方を勢いとして使う方法(モーメンタム・ネステロフ)や、向きごとに学習率を自動で調整する方法(AdaGrad・RMSProp・Adam)が考えられてきました。
注意
学習率の良し悪しは関数によって変わるので、方法どうしの速さの比べ方は学習率の選び方しだいです。実際の深層学習では、勾配はデータの一部(ミニバッチ)から見積もるのでノイズを含み、ノイズがかえって浅いくぼみや鞍点から抜け出す助けになることもあります。