誤差伝播法のアルゴリズムを表記方法からわかりやすく解説します。
ニューラルネットワークの計算の肝となる誤差伝播法。
わかりやすい解説を読めば理解した気になるのですが、実際に自分で実装しようと思うと理解していないことに気づく。
管理人と同じ人はいませんか?
特にExcelで実装しようとすると、完璧に理解していないと実装で躓きます。
ライブラリーを使ってワープできるPythonと違って、ゼロからスクラッチするExcelだと、自分の理解だけが頼りなのです。
このような時には、必要最小限に簡単なモデルで考えてみることが一番です。
すると、なんてことはない、普通に偏微分すれば解けるじゃないか!
何でそんなに難しく解説するんだ!
と思ってしまいました。
ほとんどの解説にはδを定義してどのこうの。。。
と書いてありますが、そんなこと気にせずに普通に偏微分すればよいことが分かりました。
難しく考える必要なんてありません。
メモを作りましたので、参考にしてみて下さい。
ニューラルネットワークの表記方法
単純パーセプトロンの表記方法
以前の記事で、
出荷量=人数×8+台数×2+10
の式は、ニューラルネットワークでは次のように描くことを紹介しました。
【初心者向け】ニューラルネットワークの仕組みをわかりやすく解説 より抜粋
これをもう少し一般化すると次のように描けます。
バイアスは入力層から来る信号には関係ないため、独立してノードに加えています。
また2つの入力に重みを掛けて合計した値をuという変数に入れています。
それ以外に難しい所はありませんね。
異なる層の表記方法
これは入力層と出力層しかない単純パーセプトロンですが、隠れ層(中間層)を加えて多層パーセプトロンに拡張させてみましょう。
次のようになります。
先ほど出力層のノードで、前の層から来た信号に重みを掛けて合計しましたが、同じことを隠れ層のノードでも行います。
こうなると、重みwやバイアスθや合計値uを層ごとに区別する必要がありますので、それぞれ右肩に層を表す記号H(Hidden, 隠れた)とO(Output, 出力)を付けます。
上図で描いたように、隠れ層Hのグループは青色、出力層Oのグループは赤色になります。
このように重みは、その後のノードに紐づいていると考えることが重要です。
また、バイアスθは入力信号に依存せず、毎回それぞれのノードに加えるものですので、今後はわざわざ図には描かないことにします。
活性化関数の表記方法
さて、ニューラルネットワークではそれぞれのノードにおいて、入力に重みを掛けて合計しているだけではありません。
合計した値を更に違う値に変換します。
この変換を行う関数のことを、活性化関数と呼んでいます。
なぜ変換するのかというと、こうすることでより複雑な問題が解けるようになるからです。
単に入力信号に重みを掛けて加えるだけでは、いくら隠れ層(中間層)を増やしたところで直線的な関係しかモデル化できません。
二次元グラフ上の点の集合を、直線で2つのグループに分けるようなことしかできないのです。
曲線でグループ分けしたいような場合には、非線形の活性化関数を入れないとできないのです。
従って、隠れ層と出力層にあるすべてのノードでは活性化関数による変換も行います。
図で表すと、次のようになります。
このように、それぞれのノードには2つの関数が入っていると考えます。
活性化関数はシグモイド関数やReLU関数などいろいろある中から、目的に応じて選びます。
今回は一番簡単な
f(u)=u
を活性化関数として話しを進めます。
簡単にいうと、何も変換せずにそのまま通す関数です。
恒等関数ともいいます。
表記方法のまとめ
さて、ここまでで入力層に2つのノード、隠れ層と出力層にそれぞれ1つずつのノードを持つモデルを表しましたが、誤差伝播法を理解するためには最低でも入力層:2つのノード、隠れ層:3つのノード、出力層:2つのノードを持つモデルで考える必要があります。
これを図で表すと、次のようになります。
紐づいているグループごとに色分けしてあります。
ここで新しいことは、それぞれの層に複数のノードがある時には、次のような規則によって文字を区別することです。
- ノード名をH1やO1のように、層名の右下に数字を付けて区別する
- uとzの右下にも数字を付けて区別する
- 重みwの右下には2つの数字を付けて区別する。数字の順序は次の規則に従う
重みwの右下に付ける数字の順番は、逆に定義する人もいます。
単なる決め事ですので、ここでは行き先を先に書く定義で進めます。
誤差伝播法のアルゴリズム
出力層は普通に偏微分
さて、本題に入ります。
誤差伝播法は損失関数の勾配を簡単に求めるための方法です。
なぜ勾配を求めるのかというと、損失関数の値が最小になる時の重みwやバイアスθを求めたいからです。
この重みwとバイアスθは初めに初期値をテキトーに決めますが、勾配を求めることで、プラスマイナスどちらの方向にどくれくらいwやθを動かせば良いかということが分かります。
これを勾配降下法といいました。
>> 【Excelでわかりやすく】勾配降下法で最小値が見つかる理由を視覚的に理解する
>> 【例題をExcelでわかりやすく】最急降下法で単回帰の最小二乗法を解いてみる
この勾配の計算は単純パーセプトロンでは簡単でした。
>> 【スーパーわかりやすく!】Excelで単純パーセプトロンの具体例を試してみる
ところが、多層パーセプトロンでは少し難しくなります。
それを簡単にする道しるべを与えてくれるのが誤差伝播法です。
誤差伝播法では、「まず最初に出力層の重みから計算しなさい」と教えています。
ですので、まず出力層の重みから求めてみましょう。
出力zO1とzO2の正解がt1とt2だとします。
正解とは教師データのことですので、teacherの頭文字を取ってtnとします。
すると、損失関数は次式のように誤差の平方和で表されます。
E={(zO1-t1)2+(zO2-t2)2}/2
ここで、zO1とzO2はそれぞれuO1とuO2と同じです。
なぜなら、今回の活性化関数はf(u)=uという、そのまま通す関数を仮定しているからです。
ですので、zO1とzO2はそれぞれ次式で表されます。
zO1=uO1=wO11zH1+ wO12zH2+ wO13zH3+θO1
zO2=uO2=wO21zH1+ wO22zH2+ wO23zH3+θO2
ここで、wO11の勾配を求めてみましょう。
つまり、∂E/∂ wO11を計算するということです。
一瞬ひるみますが、これはそれほど難しくはありません。
高校で習った合成関数の微分を使えばいいからです。
損失関数EはzO1の関数で、zO1はwO11の関数ですので、
∂E/∂ wO11 =∂E/∂ zO1 ・∂zO1/∂ wO11
です。
∂E/∂ zO1 = zO1-t1
∂zO1/∂ wO11 = zH1
ですので、
∂E/∂ wO11 = (zO1-t1) zH1
と簡単に計算できます。
出力層の重みはバイアスθも含めるとあと7個ありますが、すべて同じように計算できます。
隠れ層は入れ子が1つ増えるだけ。後は普通に偏微分
次に隠れ層の重みを計算します。
この計算は先ほどより少し難しくなります。
なぜでしょうか?
wH11の勾配、つまり∂E/∂ wH11 の計算をしてみましょう。
先ほどの式
zO1=uO1=wO11zH1+ wO12zH2+ wO13zH3+θO1
zO2=uO2=wO21zH1+ wO22zH2+ wO23zH3+θO2
にzH1が含まれていますが、この中にwH11が
zH1=uH1=wH11x1+ wH12x2 +θH1
のように入れ子で含まれているため、先ほどのように簡単には微分ができないのです。
しかし、ひるむ必要はありません。
ここでも合成関数の微分を使えばいいのです。
先ほど出力層の重みの微分では、次式のように分解しました。
∂E/∂ wO11 =∂E/∂ zO1 ・∂zO1/∂ wO11
これはEがzO1 の関数で、zO1 はwO11 の関数だからでした。
今度はEがzO1 の関数で、zO1 はzH1 の関数で、zH1 はwH11 の関数です。
つまり、一つ入れ子が増えただけです。
ですので、そのまま計算すればいいだけです。
∂E/∂ wH11 =∂E/∂ zH1 ・∂zH1/∂ wH11
=(∂E/∂ zO1 ・∂zO1/∂ zH1 +∂E/∂ zO2 ・∂zO2/∂ zH1)・∂zH1/∂ wH11
2行目で合成関数の微分を多変数に拡張した連鎖律を使っていますが、これはそんなに難しくありません。
こちらを参考にしてみて下さい。
>> 連鎖律(多変数関数の合成関数の微分)|高校数学の美しい物語
あとは各項の偏微分を計算すればいいだけです。
∂E/∂ zO1 は出力層で計算したのと同じです。
残りの項は次のようになります。
∂zO1/∂ zH1 = wO11
∂E/∂ zO2 = zO2-t2
∂zO2/∂ zH1 = wO21
∂zH1/∂ wH11 = x1
従って、
∂E/∂ wH11 = {(zO1-t1) wO11 + (zO2-t2) wO21} x1
です。
何も難しくありませんね。
他の隠れ層の重みも同じようにして計算できます。
出力と教師データの誤差を使ってすべての層の勾配が求められるから誤差伝播法
以上のようにすれば普通に勾配を求めることができるのですが、なぜこのやり方にわざわざ誤差伝播法という仰々しい名前が付いているのでしょうか?
それは、∂E/∂ zH1 が∂E/∂ zO1 を使って求めることができるからです。
Oは出力層でHは隠れ層ですが、OはHの次の層ともいうことができます。
つまり、O層はH+1層なのです。
これは何を意味しているかというと、H+1層の∂E/∂ zH+11 が分かれば、H層の∂E/∂ zH1 が偏微分なんてしなくても簡単に求まるということです。
∂E/∂ zH1 =∂E/∂ zO1 ・∂zO1/∂ zH1 +∂E/∂ zO2 ・∂zO2/∂ zH1
でしたね。
O層はH+1層なので、
∂E/∂ zH1 =∂E/∂ zH+11 ・∂zH+11/∂ zH1 +∂E/∂ zH+12 ・∂zH+12/∂ zH1
=∂E/∂ zH+11 ・wH+111+∂E/∂ zH+12 ・wH+121
です。
そして一番最後の層は出力層で、その∂E/∂ zH(Last)iは簡単に求まるので、その前の隠れ層の∂E/∂ zHiも遡ってすべて求めることができるのです。
その他の項の偏微分は簡単に求められることもポイントです。
なお、∂E/∂ zH(Last)iは(zH(Last)i-ti)ですので、出力と教師データの差、つまり誤差です。
この誤差を前の層に伝播させることによって連鎖的にすべての勾配が求められるので、誤差伝播法というのです。
次回は、誤差伝播法をExcelに実装して、ちょっとした画像処理を試してみたいと思います。