Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Python DeepLearningに再挑戦 18 学習に関するテクニック AdaGrad

概要

Python DeepLearningに再挑戦 18 学習に関するテクニック AdaGrad

参考書籍

AdaGrad

ηの値を初めは大きく、学習が進むに連れて小さく学習するというように、学習係数ηの方を更新して最適化を図るという手法。

数式だと以下の通り。

h <- h + ∂L/∂W ⊙ ∂L/∂W

# ⊙は、行列の要素ごとの掛け算

W <- W - η *(1/√h)* ∂L/∂W
  • Wは更新する重みパラメータ、∂L/∂Wは、Wに関する損失関数の勾配、ηは学習係数を表す。
  • hは、勾配の値を2乗和して、更新していく。
  • パラメータ更新の時に、1/√hを乗算することで、学習のスケールを調整する。
  • 意味するところは、よく動いた、大きく変化したパラメータの学習係数は次第に小さくなっていく。
  • また、そのパラメータの学習係数をパラメータの要素ごとに行うことができる。
  • AdaGradの問題点は、学習を進めるほど、更新の度合いは小さくなり、更新量が0になって更新されなくなる時がくる点。
  • それを改善したのが、RMSPropという方法らしい。(これは後で出てくるのかな。)

pythonの実装コードは以下の通り。

class AdaGrad:
    def __init__(self, lr=0.01):# インスタンス変数の初期化
        self.lr = lr
        self.h = None
        
    def update(self, params, grads):
        if self.h is None:# hがなければ、辞書型を代入する。
            self.h = {}
            for key, val in params.items():# itemsで、keyとvalueをゲットする。
                self.h[key] = np.zeros_like(val) # それぞれkeyに対応した値を代入する。
                
        for key in params.keys():
            self.h[key] += grads[key] * grads[key]#h <- h + ∂L/∂W ⊙ ∂L/∂W に対応するところ
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)#  W <- W - η *(1/√h)* ∂L/∂W に対応するところ。
            # 最後の1e-7は、self.h[key]の中に0があった場合に、0で除算してしまうことを防ぐためのもの。
            # ディープラーニングのフレームワークではこの小さな値もパラメータとして設定できるようになっている。

Adam

  • 理論が複雑だが、ベースとなるのは、Momentum + AdaGrad。
  • 複雑なので、それはまた今度にしよう。

重要そうなコメントが、参考書籍の本文にあったので、引用しておこう。

Adam は 3 つのハイパーパラメータを設定します。ひとつは、これまでの学習 係数(論文では α として登場)。後の 2 つは、一次モーメント用の係数 β1 と 二次モーメント用の係数 β2 です。論文によると、標準の設定値は、β1 は 0.9、 β2 は 0.999 であり、その設定値であれば、多くの場合うまくいくようです。

更新手法の比較

  • 今の所の主流は、SGDとAdamぽい.