0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【用語】Pathological Curvature、Momentum、Nesterov Accelerated Gradient

Last updated at Posted at 2024-05-03

E資格用語の備忘録
シラバス2024 3.深層学習 (2)深層モデルのための最適化 i.基本的なアルゴリズム モメンタム

Pathological Curvature

関数の形状が渓谷のようになっており、勾配降下法などの最適化アルゴリズムに影響を与える問題。
この形状で勾配降下法は、一方向に進むスピードが速く、他の方向に進むスピードが遅い場合、オーバーシュート(一度の更新が大きすぎること)を引き起こし、振動が発生し、最小値に到達するのが遅くなる。
解決策として、モメンタムやNesterov Accelerated Gradientなどの手法が提案されている。

import numpy as np
# 最適化手法 : SGD : 確率的勾配降下法
class SGD:
    # 学習率を0.01で初期化
    def __init__(self, lr=0.01):
        self.lr = lr
    # パラメータと勾配を受け取り、パラメータの更新
    def update(self, params, grads):
        # パラメータの各キーを順に取得、.keys()は辞書のすべてのキーを返すメソッド
        for key in params.keys():
            # 各パラメータを各勾配で更新
            params[key] -= self.lr * grads[key]

Momentum

最適化アルゴリズムの一つで、パラメータの更新に前回の更新方向を考慮に入れた手法。
通常の勾配降下法(SGD)に比べ最適化の過程での振動が抑制され、よりスムーズな収束が可能になる。

import numpy as np


# 最適化手法 : モーメンタム
class Momentum:
    # 学習率を0.01、モーメンタム項を0.9で初期化
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        self.v = None  # ベロシティ用のインスタンス変数の初期化

    # パラメータの更新、パラメータと勾配を受け取る
    def update(self, params, grads):
        # 初回ベロシティが無い状態
        if self.v is None:
            # 空の辞書を代入
            self.v = {}
            # 各パラメータのキーと値を順に取得、.items()は辞書のすべてのキーと値のペアを返すメソッド
            for key, val in params.items():
                # valと同じ形状のゼロ配列を生成
                self.v[key] = np.zeros_like(val)
        # パラメータの各キーを順に取得、.keys()は辞書のすべてのキーを返すメソッド
        for key in params.keys():
            # ベロシティを各勾配で更新
            self.v[key] = self.momentum * self.v[key] - self.lr * grads[key]
            # 各パラメータを各勾配で更新
            params[key] += self.v[key]

Nesterov Accelerated Gradient

ネステロフのモーメンタムやNAGとも言う。
最適化アルゴリズムの一つで、モメンタムを改良したもので、モメンタムが次の位置を予測し、その予測位置での勾配を計算する。
モメンタムSGDが引き起こすオーバーシュ
ートを抑制し、最適化の速度を向上させる。
実装においては理論上の更新式に等価な式を使用する。

import numpy as np


# 最適化手法 : ネステロフのモーメンタム : NAG
class Nesterov:
    # 学習率を0.01、モーメンタム項を0.9で初期化
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        self.v = None  # ベロシティ用のインスタンス変数の初期化

    # パラメータの更新、パラメータと勾配を受け取る
    def update(self, params, grads):
        # 初回ベロシティが無い状態
        if self.v is None:
            # 空の辞書を代入
            self.v = {}
            # 各パラメータのキーと値を順に取得、.items()は辞書のすべてのキーと値のペアを返すメソッド
            for key, val in params.items():
                # valと同じ形状のゼロ配列を生成
                self.v[key] = np.zeros_like(val)
        # パラメータの各キーを順に取得、.keys()は辞書のすべてのキーを返すメソッド
        for key in params.keys():
            # 各パラメータを各勾配で更新
            params[key] += self.momentum * self.momentum * self.v[key]
            params[key] -= (1 + self.momentum) * self.lr * grads[key]
            # params[key] = params[key] + self.momentum * self.momentum * self.v[key] - (1 + self.momentum) * self.lr * grads[key]

            # 次回のベロシティを各勾配で更新
            self.v[key] *= self.momentum
            self.v[key] -= self.lr * grads[key]
            # self.v[key] = self.momentum * self.v[key] - self.lr * grads[key]
        # ネステロフのモーメンタムでは、「先読み」を行い、現在のベロシティ方向に少し「先読み」した位置での勾配を計算し、その情報を用いてパラメータを更新する。
        # 上記の実装では、次回のベロシティを今回の最後に更新する。初回の更新については、ネステロフのモーメンタムも通常のモーメンタムも同じ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?