あれ?誤差がない・・勾配消失問題
みなさんこんにちは。
今何かと話題のディープラーニング。この記事を読んでくれている方はいろんなところでディープラーニングの話とか聞くと思います。
この技術により機械は人間の「眼」の機能を獲得して識別能力が格段に上がり
様々な分野での実用化が進み始めています。
ディープラーニングはニューラルネットワークを応用した手法です。
ニューラルネットワークは人間の脳の神経回路を模式的に表現したもので
多層パーセプトロンが基本形となっていました。これは単純パーセプトロンに
隠れ層を追加したものであり、隠れ層の追加によって
非線形分離ができ複雑な表現ができるようになりました。
ディープラーニングというのはニューラルネットワークの隠れ層を多層にして
ニューラルネットワークを「深く」したものなのです。
ここでこんな疑問な湧いてきます。
「隠れ層を増やすアイデアは誰でもすぐに思いつきそうだけどな・・」
昔からこのアイデア自体はあったのですが実現できなかったのです。
ニューラルネットワークでは予測値と実際の値との
誤差を出力層から入力層へ向かって伝播させて重みの値を調整していました。(このこと
を逆誤差伝播法と呼びましたね)アイデアのように隠れ層を増やした場合、
誤差が正確に伝播されなくなっていたのです。
このことを勾配消失問題と言います。
この勾配消失問題が原因で隠れ層を増やしたところで学習が進まないので
ニューラルネットワークよりも別の方法(SVMとか)の方がよく用いられていたのです。
ではなぜ誤差が正しく伝播されなくなってしまったのでしょうか?
実はこの隠れ層に使っていた活性化関数「シグモイド関数」にあります。
誤差を伝播していく過程でこのシグモイドの微分の値を使うのですが、
ここに問題がありました。
このシグモイド関数の微分の値は最大で0.25までしか取ることができません。
結果的にこのシグモイドの微分を使っていくと誤差が次第に
小さくなっていきます。そのためせっかく求められた誤差が伝播していく
過程で小さくなっていくので、最終的には
「あれ誤差がほとんどないじゃん!俺たち完璧なんだ!!」
とニューラルネットワークが勘違いを起こして学習が進まなくなってしまい
ダメダメだったのです。
そこで!!「それなら使う活性化関数を工夫すればいいじゃん!」となって
研究の結果生まれたのがtanh関数だったのです。
明らかにシグモイドよりも微分の値は大きそうですね!!
tanh関数の場合微分の最大値は1になりました。結果的に隠れ層にシグモイド関数を使うよりもtanhを使った方がより誤差が伝播しやすくなります。
けどいうて最大値が1なのであり常に1が出るわけではないので誤差はやはり消失してしまいます。そこで生まれたのがReLU関数で現在でも使われている関数の1つです。
この関数を微分すると0以下は微分の値が0、0より大きくなると常に微分の値が1で
より安定して誤差が伝播することができるようになりました!!
ReLU関数の導関数はこんな感じです。
他のやつと比べてカクッとしていますね。
3つの関数の導関数を比較して見ましょう。
よくよくランプ関数に注目するとが0以下の場合には微分の値は0になっています。
つまり0以下の値では誤差が伝達されることはないということになります。
学習がうまくいかなくなる場合があるので注意が必要になります。
参考文献
あと読者になってくださった方。ありがとうございます!
もっと頑張ろうと思います。これからもよろしくおねがいします!!!