C×Labo

主にプログラミング関係について書いていきます。

確率的勾配降下法(SGD)

_________________________________________________________________________________________
【目次】

_________________________________________________________________________________________

勾配とは?

 ベクトルです!!!!
数式は省きますが∇Eは勾配だと思ってください。

勾配降下法とは?

勾配降下法とは現在の重みwを負の勾配方向に少し動かし、これを何度も繰り返す方法。
現在の重みをw^{(t)}、動かした後の重みをw^{(t+1)}とすると、

w^{(t+1)}=w^{(t)}-ε∇E

εとは、学習係数と呼ばれ、
wの更新量の大きさえお定める定数である。
この式を繰り返せば極小値に到達できる。

しかしε(学習係数)は小さすぎると学習にかかる時間が大きくなり、
大きすぎると場合によってはwが増大してしまうこともあるため、
このε(学習係数)の決定はかなり重要な問題の一つになっている。

確率的勾配降下法SGD

先ほど説明した勾配を使ったwの更新をバッチ学習と呼ぶ。
これに対し、データの一部だけを使ってパラメータを更新する方法があり、
これを確率的勾配降下法と呼ぶ。
これのメリットは訓練データの冗長性がある場合、学習が速く実行されることである。
他にもメリットは多くある。

ミニバッチ

重みの更新を少数のデータの集合をひとまとめにし、その集合単位で重みを更新する。
このひとまとめにした集合をミニバッチという。
このミニバッチは10~100前後にすることが多いそうだ。
あまり大きくするのも良くない。
クラス数が10~100程度で、かつ各クラスの出現頻度が等しい場合は、
分類すべきクラス数と同サイズのミニバッチを作ると良いらしい。

テストデータ

前回の記事にも少し登場したテストデータ。
これは訓練データで学習したものをテストするためのデータという
説明であった。訓練データでのaccuracy(精度)が高くても汎用性がないので
あまり意味がない。
テストデータでaccuracyが高くなればそれは汎用性があり、使えるということである。
訓練データでの誤差とテストデータでの誤差が乖離した状態を過学習という。
いかに過学習することなく、テスト誤差を小さくできるかが鍵である。

過学習の緩和

過学習はネットワークの自由度が高ければ高いほど起きる可能性が大きくなる。
しかし、だからといって自由度を減らすことは基本的にはあまり望ましくない。
そこで正則化という方法があり、2つ紹介する。(数式を使わずに説明します)

  • 重みの制約

重み減衰:誤差関数に近江の二乗和(二乗ノルム)を加算し、最小化すること。
正則化の強さを制御するパラメータがあり、その値は0.01~0.00001の範囲から選ぶ。
これにより、学習時に小さい重みが選好されることになる。

重み上限:重みの上限を制約する方法。
各ユニットの入力側結合の重みの二乗和の上限を制約する。
この方法と次に出るドロップアウトを組み合わせると高い効果が得られるそう。

多層ネットワークのユニットを確率的に選別して学習させる方法。
中間層の各層と入力層のユニットを決まった割合(0~1.0)で選出し、
それらを無効化する。
よく使われている方法である。

学習時の小技

学習時に実行すると性能が向上し、学習速く進められる方法がいくつかあり、その方法を紹介する。

  • データの正規化

データに偏りがある場合、偏りをなくす処理を行う。
データの標準化とも言う(?)らしい。
数式はよくわからないので、コードで書くと以下のような感じにする(python)

data -= np.min(np.abs(data))
data /= np.max(np.abs(data))

統計学を勉強していないので、詳しいことは分からないが、
こう書くと偏りがなく、正規化できるらしい。(違っていたらごめんなさい)
近いうちに統計学も勉強します・・

  • データ拡張

手持ちのデータになんらかの加工を施して、水増しする方法。
画像データの場合、画像を平行移動したり、左右に鏡像反転したり、
色を若干変えたりしたデータを追加する。
画像以外の時系列の数値的なデータは水増しはできるのだろうか?
加工のしようが無い気がしたのでできないと思ったが、
できるのであれば教えて欲しい・・・

  • 複数ネットの平均

複数の異なるニューラルネットを組み合わせると精度向上につながる。
パラメータの異なった複数の訓練データや、「データ拡張」で書いた加工をしたデータを用いて、
複数の出力を出し、その平均を出す。
この平均のことをモデル平均と呼ぶ。
ドロップアウトは単一のネットワークを使って、実質的に複数のネットワークのモデル平均を
実行する効果があると考えられている。

  • 学習係数の決め方

学習係数は自動で決定させる方法もあるが、現在は手動で試行錯誤的に決定するのが
良いと言われている。
ここではその方法を紹介する。

  1. 学習の初期ほど大きな学習係数を与え、進捗とともに小さくしていく。
  2. ネットワークのすべての層に同じ学習係数を用いるのではなく、層ごとに異なる値を使う。その際、各層の重みの更新速度がなるべく揃うように設定するのが良いと言われている。

学習係数を自動で決定(変化)させる方法では、AdaGradが最もよく使われているらしい。
(多分現在ではAdamのほうが人気)