ラビットチャレンジ - 深層学習 Day2 Section2 学習率最適化手法


0.概要

本記事は日本ディープラーニング協会認定の講座プログラムである「ラビット・チャレンジ」が提供している科目の1つである深層学習のレポートである。
記事タイトルに記載のとおり、Day2 Section2 学習率最適化手法について以下にまとめる。

1.学習率の決め方

  • 初期は大きく設定し、学習が進むにつれて徐々に学習率を小さくする。
  • パラメータごとに学習率を可変させる。
  • 学習率最適化手法を使用する。

1.1.モメンタム

誤差をパラメータで微分した値と学習率の積を減算(ここまでは勾配降下法と同じ)し、現在の重みに前回の重みを減算した値と慣性の積$\mu$を加算する。

V_{t}=\mu V_{t-1}-\epsilon\nabla E
w^{t+1}=w^{t}+V_{t}

局所最適解に陥らない、谷間から最適解までたどり着くのが早い(移動平均によって振動が抑えられているため)。
勾配の向きが正しい方向を向いているか保証した発展型のアルゴリズムとしてネステロフの加速勾配法(NAG)がある。

1.2.AdaGrad

誤差をパラメータで微分したものと再定義$\epsilon\frac{1}{\sqrt{h_{t}}+\theta}\nabla E$した学習率の積を減算する。
学習率が徐々に小さくなっていく。

$\theta$:0にはならない微小な値。

h_{0}=\theta
h_{t}=h_{t-1}+(\nabla E)^2
w^{t+1}=w^{t}-\epsilon\frac{1}{\sqrt{h_{t}}+\theta}\nabla E

暗転問題を引き起こすことがある。

1.3.RMSprop

AdaGradの問題を改良したもの。

$\alpha$:勾配を何倍して取り込むか。

h_{t}=\alpha h_{t-1}+(1-\alpha)(\nabla E)^2
w^{t+1}=w^{t}-\epsilon\frac{1}{\sqrt{h_{t}}+\theta}\nabla E

AdaGradと比較して局所最適解にならず大域的最適解になる、ハイパーパラメータの調整が少なくて済みやすいという利点がある。

1.4.Adam

モメンタムとRMSpropをいわば組み合わせた最適解アルゴリズム。
つまり移動平均による振動の抑制と学習率の調整をしている。

2.確認テスト

2.1.確認テスト1

モメンタム、AdaGrad、RMSpropの特徴をそれぞれ簡潔に説明せよ。

回答:

  • モメンタム:勾配の移動平均を出して振動を抑える(過去の勾配たちを考慮することで急な変化を抑える)。
  • AdaGrad:次元ごとに学習率を変化させるようにしたもの。
  • RMSprop:AdaGradの改良版であり、一度学習率が0に近づくとほとんど変化しなくなるAdaGradの問題を改良したもの。

Day1 Section4 勾配降下法の際に調査。
https://qiita.com/Helvetica822/items/7da1a6ed88448534739d

3.Jupter演習

3.1.SGD

学習率を変えて変化を見る。
勾配消失を起こしてたようなので活性化関数もシグモイド関数からReLU関数に変更。

学習率:0.01

学習率:0.1

前SectionでReLU関数が良い結果となったが、それも学習率が適切だったからであり、学習率が良くなければ結局最適化がうまくされず意味がない。
学習率0.01の時は局所最適解に陥っていたのではと考えられる。

3.2.モメンタム

慣性項を変えて変化を見る。
こっちも比較のため活性化関数はReLU関数に変更。
学習率はいずれも0.01。

慣性:0.5

慣性:0.9

SGDではなくモメンタムを使っていてもやはり慣性項を適切に設定していなければ意味がない。
SGDでは学習率0.01で学習が進まなかったが慣性0.9のモメンタムでは学習できている。

3.3.モメンタムをAdaGradに書き換える。

モメンタム

grad = network.gradient(x_batch, d_batch)
if i == 0:
    h = {}
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):

    if i == 0:
        h[key] = np.zeros_like(network.params[key])
    h[key] = momentum * h[key] - learning_rate * grad[key]
    network.params[key] += h[key]

回答:

theta = 1e-4

grad = network.gradient(x_batch, d_batch)
if i == 0:
    h = {}
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):

    if i == 0:
    # h_0
        h[key] = np.full_like(network.params[key], theta)
    else:
        # h_t
        h[key] = np.square(grad[key])
    network.params[key] -= learning_rate * grad[key] / np.sqrt(h[key])

3.4.RMSprop

decay_rate(学習率の減衰。数式の$alpha$)を0.5等に変えてみてもあまり大きな変化は見られなかったため、活性化関数を変えてみた。
decay_rateは0.99。
学習率はいずれも0.01。

シグモイド関数

ReLU関数

どちらも早い段階から正解率が上がっているが、ReLU関数の方がさらに早い。

3.5.Adam

とりあえずパラメータはそのままで実行してみた。

シグモイド関数

ReLU関数

シグモイド関数だとむしろ若干RMSpropの方が良さげ?なくらい。

3.6.SGD(学習率・重みの初期化・バッチ正規化)

学習率を0.1、重みをXavierで初期化、バッチ正規化を有効とした場合のSGDの結果。

RMSpropやAdamと遜色ない結果となった。
言い換えるとここまでしないとRMSpropやAdamと同じくらいの結果とはならないと言えそう。

X.ラビットチャレンジとは

ラビットチャレンジとは、日本ディープラーニング協会認定の講座プログラムの1つ。
E資格を受験するためにはこのラビットチャレンジ等、いずれかの講座プログラムを修了しなければならない。

ラビットチャレンジの特徴は「現場で潰しが効くディープラーニング講座」の通学講座録画ビデオを編集した教材を使用した自習スタイルであるという点。
サポートは他の講座より少なく、受け身ではなく自主的に学んでいく姿勢でなければ進められないが、その分、他の講座に比べると安価であり、手が出しやすい。
ある程度知識がある人、自力で頑張るぞというガッツのある人向けではないかと感じる。