誤差逆伝搬法その1

前回ニュートン法と勾配法の話をしました。
今回はそれと教師データを元にどうやって、関数のパラーメーターを調整していくのか、やりながら見てみましょう。ニューラルネットは出てこないですが、ニューラルネットも同じことやります。

y=ax

まず、ある教師データがあります。ある入力をした時にこういう出力であるべきっていうデータですね。そして、今回はそのある入力値xに対して出力値yが比例っぽい(y=axの形)ということが分かっている前提でやってみましょう。

Untitled_Artwork-9

教師データは上の図の赤のてんてんです。x軸が入力値でその時の出力が赤い点の値になるのが理想です。赤い点はバラけているので本当はy=axにピッタリ合うわけじゃないのですが、これにすごく近い無難なy=axとなるaを探してみます(グラフが単純なので、見ればa=1ぐらいかなって思えますね)。ただ、どの数値がどうなったら”いいa”だと言えるでしょうか。前回の話を思い出すと、理想的な答えである教師データに近ければいいわけです。具体的には教師データのxを入れた時の結果が教師データのyとどのぐらい近いのか。そのズレは「誤差」って呼ぶんでしたね。ここで、教師データがN個あって、あるi番目のデータをyi xiとするならば。その誤差は

y_{k}-ax_{k}

となると思います。
これがすべての教師データで小さければ小さいほどいいわけですから、これを全部足した値が小さければいいということになります。これを式で表すと

E_{(a)} = {\displaystyle \sum_{k=1}^{N}} |y_{k}-ax_{k}|

こんな感じ。絶対値にするのはプラス側にズレてもマイナス側にずれてもズレとして足すためです。もし、教師データyとあるaで計算したaxが全部の教師データで同じなら誤差は0ってことになりますから目指すaはこれを0にするか、0にならなくても他に比べて小さくなるようなaを探すことです。ある関数の小さな値を探す、、、これどっかでやりましたね

ここでやっと勾配法の登場

ある関数の逆関数はわからないけど、とにかく小さくなる値がどの辺かを調べたい。
ここで優秀な皆さんは前回やった勾配法を思い出すわけです。E(a)が小さくなるaを探す。そのために

  1. 適当なaを決める
  2. 関数の微分とそのaを使って計算した微分値からどっちにaを動かしたほうが値が小さくなるかを見る
  3. その勾配に合わせてaをちょっと動かす。2へ戻る

を繰り返すわけです。今回の小さくしたい関数は誤差値であるE(a)ですが、これはラッキーな事に微分可能です。微分してみましょう。これが元々の関数ですね。

E_{(a)} = {\displaystyle \sum_{k=1}^{N}} |y_{k}-ax_{k}|

絶対値が邪魔なので二乗しちゃいます。

E_{(a)} = {\displaystyle \sum_{k=1}^{N}} (y_{k}-ax_{k})^{2}

2乗しても大小関係は変わらないですよね。でも、2乗するとマイナスがなくなるので絶対値でなくてもよくなるわけです。これをaについて微分しますと

\frac{\partial E_{(a)}}{\partial a} = -2{\displaystyle \sum_{k=1}^{N}} (y_{k}-ax_{k})x_{k}

こうなります。ちなみに他にも変数があるくせにaだけで微分するのを偏微分と言います。知らない人はググってください。簡単に説明すると、他にも変数はあるけどとりあえずaだけで微分してaを増やすと結果が増えるのか減るのかが分かるのがaについての偏微分です。さて、これでE(a)の微分が求められました。これでやることはわかりますね。
例えば適当にa=100とか入れたら E(100)=なんとか ってかんじで結果が分かりますね。で、微分値である E'(100)が例えば-50だとします。これはつまり「E(a)において、a=100の場所ってのはaを1増やすと結果が50減っちゃう傾きがある」ってことです。これはもうaを増やすしか無いです。勾配法でいくと、せっかくだから傾きの値を使って傾きが大きければaをより沢山、すくなければより少なく動かそう。で、ちょっとずつ動かしていけばオーバーしないだろう。っていうやり方で行きます。だから、適当に決めたaは

a_{next} = a_{old} - \varepsilon \frac{\partial E_{(a_{old})}}{\partial a}

を元に今のaの値(a old)から次のaの値(a next)を計算します。ε(イプシロン)は何か適当な小さな値って意味です。数学や物理の世界でよく出てきます。これはつまり「aの値を今の傾きを元に小さくなる方へ動かす!ただし、怖いから小さいεをかけてちょっとずつ動かす」ってことです(前回やったビビリ係数です)。

ちょっと長い話になったのでまとめますと

 

  1. 教師データとの誤差を表す関数を作る
  2. 1.の関数が小さい場所を探したいので1.の関数を微分する
  3. 適当なパラメーターを決めてその時の微分値を計算する
  4. 3の結果(勾配)を元にパラメーターをちょっとだけ動かして3をもう一度やる。

これで繰り返しながら誤差が小さくなる場所を探すわけです。
ちなみにaがある値の時の微分値を計算するのに全部の教師データを使いますね(シグマのところで)こうやってパラメーターをちょっと動かすときに全部のデータを使うの一括更新学習法って言います。逆にちょっとずつ使うようなのを随時更新学習法って言います。

ここまでは単純にある教師データに近い関数のパラメーターをどうやって探すか実際に式を使ってやってみました。
次回はこれをニューラルネットワークでやってニューラルネットワークを学習させてみましょう。