一般化線形モデルの訓練

一般化線形モデルの訓練についてまとめてみました。
ちゃんと確認が取れているわけではなく、間違っている部分があるかもしれませんがご了承ください。

誤差の削減

損失関数によりモデルの当てはまりの良さの計算が行える。 モデルの訓練では損失の計算、パラメータの更新、損失の計算を繰り返しにより誤差が少なくなるようにします。 モデルの訓練を進める中で損失が変化しなくなったり、パラメータの更新が非常にゆっくりになります、この状態をモデルの収束と呼びます。 モデルの訓練では収束する前までに最良のモデルを見つけることが目的となります。

モデルの訓練の流れ

  1. 教師データから訓練に使うサンプルデータを取り出す
     - フルバッチ: 全ての教師データを使う
     - 確率的勾配降下法(SGD): 1つのサンプルデータを使う
     - ミニバッチ: 複数のサンプルデータを使う
  2. 取り出したサンプルデータを使って損失、勾配を計算する
  3. 勾配を元と学習率を元に現在のパラメータを更新する
  4. 更新後のパラメータで教師データ、テストデータの損失を計算する

サンプルデータの取り出し

パラメータを更新するためには訓練データからデータを取り出して損失を計算する必要があるのですが、データの取り出しかたにはいくつか種類があります。 フルバッチでは全ての訓練データを使います。確率的勾配降下法では訓練データからランダムに一つのデータを取り出します。ミニバッチでは適当な数件のデータを取り出して使用します、件数を増やした方が学習の精度は上がるはずですがその分計算コストがかかるはずなので動かしながらちょうど良いサイズを決めるなどなのでしょうか。

確率的勾配効果法では損失を以下のように求めます。dは訓練データの値とします。
f:id:steavevaivai:20180616095058p:plain
ここでは絶対値を2乗していますが、損失は大きさの単位なので負の数にならないために絶対値を使った方が内容的に正しいのかと思います。

フルバッチでは全ての訓練データを使用するので以下のように表せられます。
f:id:steavevaivai:20180616095129p:plain

ミニバッチでは数件のデータを取り出して一件ごとは確率的勾配降下法と同様に損失を計算するのですが、その後平均をとるようにしています。
f:id:steavevaivai:20180616095142p:plain

勾配の計算

パラメータの更新では損失が小さくなる方向にパラメータを変えていくのですが、そのためにはパラメータと損失の勾配
f:id:steavevaivai:20180616095247p:plain を求める必要があります。

パラメータwと損失Eを以下のグラフで表した時、求めたい勾配はこのようになります。 f:id:steavevaivai:20180616095306p:plain

確率的勾配降下法について、パラメータが1つのシンプルなモデルで勾配を求めてみたいと思います。
f:id:steavevaivai:20180616095318p:plain

w, bの初期値が1でサンプルデータとしてx=3, y=11のデータががあったとします。

求める勾配を以下のようにして、hを小さい数0.001としたら
f:id:steavevaivai:20180616095331p:plain
のようになりE(w+0.001)とE(w-0.001)をそれぞれ求める

E(w+0.001) = 1/2 || y - (w+0.001) * x + b || ^2    
  = 1/2 || 11 - (1+0.001) * 3 + 1|| ^2    
  = 40.4730045    

同様に

E(w-0.001) = 1/2 || y - (w-0.001) * x + b|| ^2    
= 1/2 || 11 - (1-0.001) * 3 + 1|| ^2    
= 40.5270045    

となる。よって

∂E/∂w ≡ (40.4730045 - 40.5270045) / 0.002 = -27    

と勾配は求められる。

勾配の計算を一般化について、例えばパラメータが一つのモデルであれば f:id:steavevaivai:20180616095346p:plain
ここで||d - wx - b ||をuと置いたら E=1/2 ||u||^2となるので
f:id:steavevaivai:20180616095357p:plain
と表すことができる。よって求めたい∂E/∂wは
f:id:steavevaivai:20180616095411p:plainとなる
ここで u = ||d - wx - b ||としているがd - wx - b > 0の時は∂u/∂w = -x
d - wx - b < 0の時は∂u/∂w = xと考えることができるので
f:id:steavevaivai:20180616104610p:plain
と簡単に表すことができる これを使えば先ほどの勾配計算は以下のようになる

∂E/∂w = - (d - y(x;w)x = - (11 - 1*3 -1) * 1
      = - (11 - 1*3 - 1) * 1 = -7

パラメータの更新

勾配を求めたら次のパラメータの更新を行う。現在のパラメータから先ほど求めた勾配に学習率を掛けたものを引いたものが新しいパラメータとなる。
y=wx+bのモデルについて現在のパラメータwが1で勾配が -7, 学習率εが0.01とした場合、アタ新しいパラメータは以下のように求められる。
w_new = w - ε ∂E/∂w = 1 - 0.01 * (-7) = 1.07
この時の学習率が学習の進み方に影響を与え、小さすぎるとゆっくりにしか進まず時間がかかり、大きいと一気に学習が進むが最良のモデルを見つける前に収束するなどします。

学習率の決め方

学習率の決め方については手動で試行錯誤に選んだものを固定で使用するなどありますが、学習の回数に応じて学習率を小さくする(ε = ε0 - αt)方法などもあります。 他の有名な方法としてAdaGradがあり、これは複数のパラメータがあった場合に、パラメータ毎の学習の進み方により学習率を変動させるイメージでパラメータ毎の勾配∂E/∂w_tをg_tとして以下の式で表せられる。
f:id:steavevaivai:20180616095450p:plain
これはパラメータ毎の勾配の各学習毎の合計を使って学習率を変動させている。

モメンタム

モデルの収束性能を向上させる方法としてはモメンタムがある。大きい学習率で学数を進めるとパラメータがジグザグに進むがモメンタムを利用して以下のように更新すると通常の学習に比べて大きくジグザグすることは少なくなる。
f:id:steavevaivai:20180616095502p:plain