パーセプトロンを誤差伝播、バックプロパゲーションで学習させている時に、学習が終わらなくなった時のトラブルシューティングです。

症状としては、

誤差がある0ではない値に収束して学習が進まない、出力層の出力を確認すると出力がすべて0になっているか、-1になっている状態です。

こんな時に考えるバグは

最初に逆伝搬させている勾配が、損失関数(誤差関数)の微分ではなく損失関数自体になっている

 

かなり初歩的なミスですが、僕はたまにやってました。

ちゃんとライブラリを使って実装している人はこういうミスはないのかもしれませんが、やってしまうと一見うまく学習できているはずなのに何度やっても0位外のところに誤差が行ってしまいます。

やってしまった人はここで、あってなると思うと思うんですけど、せっかくなのでもう少し詳しく書くと。

バックプロパゲーションを簡単にすると、

「誤差を計算してもう少し出力を増やしたいところは結合を大きく調整、減らしたいところは結合を小さく調整、誤差が小さいところは調整量増やして、誤差が大きところはいっぱい変える」

というものになります。

で、損失関数(誤差関数)は2乗誤差やクロスエントロピーとかを使うと思います。

これらの誤差関数の出力って正の値なんですよね。だからそのまま勾配として逆電波させると重みの更新は現行の重みから逆伝播してきた誤差と学習率を引き続けることになるので、永久に値が下がってしまうんですよね。

損失を逆伝搬させたバイアス
結合が下がる下がる
損失をちょくで伝播
バイアスも下がる

誤差は一旦0に近づきますが、どんどん離れてある値で収束します。

損失をちょくで学習させた
変なところで収束してしまう誤差(損失)

そうなってくると、出力もどんどん下がってきて、出力関数にシグモイドやReluを使っているとは0。tanhを使っている人は-1になっちゃいます。

で、どうして出力関数の微分(勾配)を逆伝搬させるかは、普通にバックプロパゲーションの原理だし、にわかの僕が説明することじゃないので割愛しますが、ちゃんと微分の方を逆伝播させてください。

微分なら下げたいときはちゃんと負の値を取りますから、結合強度はいい感じに調整されます。

勾配を伝播させた時の誤差
勾配を伝播させた時の誤差
勾配を逆伝播させた時の結合強度
結合強度は下がる時もあれば上がる時もある
勾配を伝播させた時のバイアス
勾配を伝播させればある値でバイアスも落ち着く

かなり初歩的な話ですが、アルゴリズムについてちゃんと考える時間がない人がネットワークをいじるとミスるのでは?需要ないかな・・・。

それでは。