見出し画像

ゼロからつくるDeepLearning学習中~その4

6章 学習に関するテクニックを学習中です。

学習 = 損失関数の値を最小にするパラメータを探す最適化なので、どのような最適化手法があるか、初期値をどのように設定すれば良いかを学習しました。

最適化手法を切り替えやすいようにクラスで実装するのがミソ。

各種最適化手法の比較

SGD (確率的勾配降下法)

勾配の小さなパラメータはなかなか動かないため、パラメータによって勾配のばらつきがあると非効率になってしまう。

下記は x 軸方向に横長な楕円放物面の更新経路。中央部分に最適解があるが、y 軸方向に行ったり来たりしながら x 軸方向にはゆっくりと進んでいる。

Momentum

速度にあたる変数を導入することで探索方向に加速度の概念を持ち込む。常に同じ方向に勾配があると探索が加速していく。速度が大きすぎて最適解を通り越してしまうと逆向きの加速度が生じるので探索方向が戻っていく。

なかなか興味深い。勾配の小さい x 軸方向にもちゃんと進んでいく。

AdaGrad

勾配の大きなパラメータの学習係数を減衰させていくことで学習係数を適切に維持しようとする方法。SGD や Momentum に比べるとジグザグな動きがなく効率的に最適化されていく感じ。

Adam

AdaGrad と Momentum を合わせたような手法。Momentum の勾配方向の動きを AdaGrad のような手法で抑制する。勾配方向に大きく効率的に動かしつつ、行き過ぎてしまう動きを抑制している感じ。

どの手法が良いかは条件によって変わるけれど、100 ニューロンの 5層ネットワーク (活性化関数 = ReLU) で MNIST を学習させた例では、AdaGrad が一番成績が良かった。

隠れ層のアクティベーション分布

重み初期値の標準偏差を変化させて隠れ層のアクティベーション (活性化関数の出力) を比較する。100ニューロンの 5層ネットワークに 1,000個のガウス分布データを入力している。

標準偏差=1、活性化関数 = Sigmoid

0, 1 付近に偏ってしまうと、Sigmoid 関数の勾配が 0 に近いところの出力ばかりになり、勾配消失になってしまう。

標準偏差=0.01、活性化関数 = Sigmoid

勾配消失は無いが、中央値付近に偏ってしまうとニューロンを複数持つ意味が薄れる。

標準偏差 = Xavier の初期値、活性化関数 = Sigmoid

Xavier の初期値を使うと広がりを持った分布が得られた。

標準偏差 = Xavier の初期値、活性化関数 = tanh

活性化関数が Sigmoid、tanh の場合は Xavier の初期値を使うのが良い。

標準偏差 = He の初期値、活性化関数 = ReLU

活性化関数を ReLU とした場合は、He の初期値を使うと良い。

MNIST での重み初期値比較 (活性化関数 = ReLU)

標準偏差 0.01 ではほとんど学習が進んでいない。また、Xavier より He の初期値の方が成績が良い。

Twitter (https://twitter.com/alt_area) でも、時々学習状況をつぶやきますのでよろしくお願いします。
ブログ (https://jade.alt-area.jp/) にも Python 情報等を記事にしています。


Note やるからには、サポートがいただけるような役立つ記事を書きたいものです。サポートは資料購入に宛てます。