深層モデルの最適化について (E資格対策)

今回は最適化について

目次
[学習と純粋な最適化の差異](#学習と純粋な最適化の差異)
[確率的勾配降下法-最適化の基本的なアルゴリズム](#確率的勾配降下法-最適化の基本的なアルゴリズム)
[適応的な学習率を持つ学習アルゴリズム](#適応的な学習率を持つ学習アルゴリズム)
[最適化戦略とメタアルゴリズム](#最適化戦略とメタアルゴリズム)





#学習と純粋な最適化の差異

DeepLearningで学習する際、与えられた学習データを学習させようとするとデータがメモリに載りません。
この学習方法を**バッチ学習**といいます。

そこで1つずつ逐次データを入れ学習させる手法があります。これを**オンライン学習**といいます。
これによってメモリに載り、突発的なデータ、季節性のイベントに対しても対応ができます。
ですが、学習が安定しないデメリットもあります。


2つs手法のいいところを取ったのが**ミニバッチ学習**です。
ミニバッチとはランダムにいくつかのグループに学習データを分け、並列に学習する方法。

それぞれの学習データのグループから損失の平均を計算し、それをもとに学習します。
グループごとに損失関数が若干異なるので局所解にハマりにくく、良い解にたどり着きやすくなります。
また並列計算ができるので計算を行うGPUとの相性が良いです。
バッチサイズはメモリ数、学習時間、データの傾向等を鑑みて決めます。




#確率的勾配降下法-最適化の基本的なアルゴリズム

以下の順番でwを求めます。

1.初期の点wを選び、損失関数E作成
2.訓練データをランダムサンプリング
3.サンプルをもとに勾配 $g=\frac{\partial E(\theta)}{\partial w}$を計算
4.$\theta = \theta-ng$
5. 2.~4.を繰り返す。

下図が学習のイメージ図です。
![sgd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/72640efc-9c55-0bf0-5c97-b1aa1b5d2a0c.png)

2.のおかげで右の局所解にたどり着くことなく、よいwにたどり着けます。


##Sharp minima, Flat minima



<img width="621" alt="flatminima.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/6366a983-25ae-918f-2b0a-c2efabb4ffc1.png">

Lossが同じでも、平坦(Flat)な解の方がテストデータに適合しやすくなります。
SGDはよりFlatな解に行く確率が高いそうです。





##モメンタム

過去の更新ベクトルを見て、勾配が大きい方向に更新幅を大きくする手法。


山頂を目指すとき、より傾斜が大きい方へ進んでいくイメージです。下にイメージ図を載せます。

<img width="621" alt="momentumds.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/80d33b32-1232-3918-d4f9-f1b85ada47e5.png">




##ネステロフのモメンタム
モメンタムでは勾配を急にしすぎて良い解を過ぎてしまうことも。
そこで更新後の重みを推定し、早く進まないよう補正する手法をネステロフのモメンタムと言います。


#適応的な学習率を持つ学習アルゴリズム
学習率（勾配の更新幅）を変えたらうまくいくんじゃね？と考えられ生み出された手法です。


##AdaGrad-各パラメータごとに異なる学習率を用いる
SGDでは学習率は固定ですが、各パラメータごとに異なる学習率を使う手法です。
学習率の補正にそれまでの勾配パラメータの二乗和(n)を使う


##RMSrop-AdaGradの改良
AdaGradでは学習率の減衰が過大気味になってしまいます。
そこで勾配の二乗の平均減衰を使って学習率が小さくなりすぎないようにした手法。


##Adam－AdaGradとMomentumの融合

AdaGradとMomentumといいとこどりです。


##AdaBound-AdamとSGDのいいとこどり
AdamはSGDより繁華性能の点で劣ったり不安定だったりします。

そこで開発されたのがAdaBoundという手法。
Adamの速さとSGDの繁華性能のいいとこどりの手法です。






##手法の比較

![koubaihou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/071482f8-2f1f-277d-2edf-e3880979c716.png)

SGDはガタガタに進み、Momentumは慣性を持ちながら進んでいる感じですね。
Adagradは終息が早く、Adamもゆるやかに解にたどり着いています。

引用：ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装


#最適化戦略とメタアルゴリズム

層やニューロン間でどのような処理をすればよいか学習がうまくいくのでしょうか。
「正規化」が答えの一つにあります。
ここからは正規化についてのお話。

![WS000022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/3aee8632-c59e-0187-35e7-9426796833a3.jpeg)


引用：http://mlexplained.com/2018/11/30/an-overview-of-normalization-methods-in-deep-learning/



##バッチ正規化(Batch Normalization)
各バッチ、各層ごとに平均と分散に対しての正規化を行う手法を言います。

NNの層ごとに入力されるデータの分布が異なると学習がうまくいきません（共変量シフト）。
そこでバッチ正規化を行い、共変量シフトを解消した結果、学習率を上げても学習できる（結果学習が早くなる）のがバッチ正規化のメリットです。
この正規化した後に$y_i=\gamma\hat{x_i}+\beta$でスケールシフトします（$\gamma=1,\beta=0$からスタートし、学習が進むにつれBackPropagationによって値が変化する)

```math

\hat{x_i}=\frac{x_i-\mu_B}{\sqrt{\sigma_B^2+\epsilon}} \\
y_i=\gamma\hat{x_i}+\beta \\

\mu_B=\frac{1}{N}\sum_{i=1}^{N}x_i \\
\sigma_B^2=\frac{1}{N}\sum_{i=1}^{N}(x_i-\mu_B)^2



```
$\epsilon$は0除算を防ぐための0.0000001ぐらいの小さい数字です。





##Layer正規化(Layer Normalization)
ここからは画像処理系で用いられる手法です。
バッチサイズが十分に確保できない場合の対策として、全チャンネルに跨って平均・分散をとり、正規化を行う手法です
バッチ正規化との比較は下図が参考になります。
![0ebdcae5ba2244cf8e9495f962005d07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/28ec9662-3265-9901-c291-c6f7f77d4721.jpeg)


引用：http://mlexplained.com/2018/11/30/an-overview-of-normalization-methods-in-deep-learning/



##Instance正規化(Instance Normalization)
各チャンネル独立に画像の縦横方向について正規化を行う手法。
バッチ正規化のバッチサイズが1の場合、Instance正規化と等価です。


##教師あり事前学習

バッチ正規化が登場したのでほぼ使わなくなった手法。Dropoutの層バージョン。

層1,層2,層3があるとします。
まず層1を学習させた後、層1の学習を止めた状態で層2と一緒に学習します。
その後層1，2の学習を止めたまま層3を追加し、ガキ収支、最後にすべての層を一度に学習させる手法です。

バッチ正規化によって使われていませんが、事前に簡単な問題を学習させ、その後本当にやりたい問題を学習すると性能が良くなるというテクニックは現在も使われています。




参考文献
https://dev.classmethod.jp/articles/online-batch-learning/
https://www.slideshare.net/KeigoNishida/layer-normalizationnips