学習率の調整アルゴリズムについて、いろいろ試した結果AdaGradが一番使いやすいという結論に至ったのでまとめ。
前提
線形モデルの学習に限った話。(特に、コンピュータ将棋の評価関数、進行度、実現確率とかでの経験に基づく話。)
非線形モデル(というかNN)の場合は挙動がそれほど素直じゃないので、指数移動平均を使うアルゴリズム(AdamとかRMSPropとか)の方が合っていると思う。
AdaGradとは
オンライン学習で学習率を自動調整する手法の一つ。
g:勾配、w:特徴の重みの配列に対して、
g2[i] += g * g;
w[i] -= eta * g / sqrt(g2[i]);
こんなような感じで更新する。g2:配列(最初は0)、eta:定数。
実装するときのポイント
その1
g2にg * gを足すのは先にやる必要がある。
正しく実装すると、初回の学習率がeta * g / sqrt(g * g) == etaになっていて、2回目以降はちょっとずつ小さくなっていくという、とても分かりやすい挙動になる。
その2
ゼロ除算を避けるため、abs(g)が小さい場合はスキップした方がいい。
(分母に小さい値を足す実装もあるが、勾配がゼロであるにも関わらず初回の学習率分動かしてしまうのはあまりいい挙動ではないと思う。)
どこが良いの?
AdaGradの類似品としてはAdaDelta、Adam、RMSPropとか。
そこら辺と比べて、以下のようなところが気に入っている。
- ハイパーパラメータが1つだけ
- シンプルで挙動が分かりやすい
- 学習率は必ず単調減少するので、勾配が極端に変動するものとかでもあまり変な挙動にならない
AdaGradの振る舞いメモ
etaの値を決めるときの参考としていろいろ計算した結果のメモ。
学習率
勾配がほぼ一定な場合で考えると、ある要素のn回目の学習率はeta / sqrt(n)くらいになる。
初回はeta。1万回目ならeta * 0.01。1億回目ならeta * 0.0001。
学習率の総和
同じく勾配が一定だった場合、1万回目までの学習率の総和はeta * 199くらい。
勾配の大きさが一定で符号が「60%が正、40%が負」の場合の1万回の総和の期待値はeta * 40くらい。
勾配の大きさが一定で符号が「55%が正、45%が負」の場合の1万回の総和の期待値はeta * 20くらい。
※ 50%/50%だと当然期待値は0で、そこから100%/0%のeta * 199まで線形に変化する。
学習率の目安
Adamの場合は、論文でおすすめされている学習率が0.001なので、オープンソースのライブラリ(Kerasとか)を読んでも既定値は大体この値になっている。
AdaGradはAdamに比べて急激に学習率が下がるので、これより10倍かそれ以上くらい大きめの値が良さそう。手元にあるKerasのソースを見てみたらAdaGradの既定値は0.01だった。