深層学習

Nesterov加速

モメンタムで先に進んだ位置の勾配を使い、行き過ぎを早めに補正する最適化手法。

  • B|標準
  • 深層学習

数式の記号で止まったら 記号の読み方 (∂・⊙・転置・上付き添字を、読み方から)

ひとことで言うと

Nesterov加速は、モメンタムの移動量で少し先へ進んだ位置を仮に作り、その位置で勾配を評価して更新する方法です。現在位置の勾配だけで進む通常のモメンタムより、進み過ぎへの補正が早く入ります。

坂道を下る車が、いまいる場所だけでなく、惰性で進んだ先の路面を見てハンドルを切るイメージです。先の傾きを使うので、曲がり始めの判断が遅れません。

なぜ必要か

@@ Nesterov加速では、まず勢いによる予測位置を作り、その予測位置の勾配を次の更新に使います。したがって、モメンタムを捨てずに、先回りした勾配で行き過ぎを抑えます。これは学習率やモメンタム係数を別の最適化手法へ置き換える話ではなく、勾配をどこで評価するかの違いです。

手法勾配を取る場所補正のタイミング
通常のモメンタム現在位置勢いを加えた後
Nesterov加速勢いで進んだ先更新前

Nesterov加速では、まず勢いによる予測位置を作り、その予測位置の勾配を次の更新に使います。したがって、モメンタムを捨てずに、先回りした勾配で行き過ぎを抑えます。これは学習率やモメンタム係数を別の最適化手法へ置き換える話ではなく、勾配をどこで評価するかの違いです。

仕組み

θt\theta_t を時刻 tt のパラメータ、vt\mathbf{v}_t を蓄積する速度、η\eta を学習率、μ\mu をモメンタム係数、LL を損失とします。先読み位置 θ~t\widetilde{\theta}_t を作り、そこで勾配を取ります。

θ~t=θt+μvt,gt=∇L(θ~t)\widetilde{\theta}_t = \theta_t + \mu\mathbf{v}_t, \qquad \mathbf{g}_t = \nabla L(\widetilde{\theta}_t)

速度とパラメータを次のように更新します。

vt+1=μvt−ηgt,θt+1=θt+vt+1\mathbf{v}_{t+1}=\mu\mathbf{v}_t-\eta\mathbf{g}_t, \qquad \theta_{t+1}=\theta_t+\mathbf{v}_{t+1}

gt\mathbf{g}_t は先読み位置での損失勾配です。実装では、現在のパラメータを直接書き換えず、一時的な先読み値を作って勾配計算後に元の更新を行います。PyTorchのSGDでは momentum が0でないときに nesterov=True を指定する形で、この方式を選べます。係数の定義や初回ステップの扱いは実装の更新則を確認してください。

試験でどう問われるか

問われ方正解に寄る条件引っかけ
通常のモメンタムとの差勾配を現在位置ではなく、勢いで進んだ先で評価する勢いを使わず毎回先読みするだけとする
更新式の穴埋めθ~t=θt+μvt\widetilde{\theta}_t=\theta_t+\mu\mathbf{v}_t を先に作るθt−μvt\theta_t-\mu\mathbf{v}_t と符号を逆にする
実装設定の確認momentum を有効にして nesterov=True とするNesterovだけを単独で有効化できるとする

実装で確かめる

1変数の二次関数で、先読み位置の勾配を使う更新をそのまま実装します。θ\theta はパラメータ、L(θ)=θ2/2L(\theta)=\theta^2/2 なので勾配は θ\theta です。

import numpy as np

theta, velocity = 4.0, 0.0
eta, mu = 0.1, 0.9
for _ in range(20):
    lookahead = theta + mu * velocity
    grad = lookahead
    velocity = mu * velocity - eta * grad
    theta += velocity
print(theta)

このコードを実行すると 0.4904749238276017 と表示されます。grad = theta に変えると、先読みをしない通常のモメンタムとの違いを同じ条件で比較できます。

取り違えやすいもの

用語勾配を評価する位置見分けるポイント
通常のモメンタム現在の θt\theta_t現在の勾配に過去の速度を組み合わせる
Nesterov加速先読みした θ~t\widetilde{\theta}_t勢いを加えた仮の位置で勾配を取る
SGD現在の θt\theta_t速度の蓄積を使わず、勾配だけで更新する
Adam系実装ごとの評価位置一次・二次モーメントを使う別系統の更新則

想起チェック

Nesterov加速で、通常のモメンタムと最も違う計算箇所はどこか

勾配を現在位置ではなく、モメンタムによる移動を加えた先読み位置で評価する点です。

先読み位置を表す式は何か

θ~t=θt+μvt\widetilde{\theta}_t=\theta_t+\mu\mathbf{v}_t です。θt\theta_t はパラメータ、vt\mathbf{v}_t は速度、μ\mu はモメンタム係数です。

PyTorchでNesterovを有効にする前提は何か

SGDの momentum を有効にしたうえで、nesterov=True を指定します。

出典