勾配法はニューラルネットワークの学習の基礎になります。基本的な問題を見て、勾配法を確認してみましょう。
勾配法
勾配法とは最小化問題や最大化問題などの最適化問題を解くための手法の1つです。例えばパラメータに対して、目的関数
があった場合に、
をどのような値にすれば、
が最小値を取るのかを探索することに使えます。
簡単な例
以下のように
という関数があったとしましょう。このときをどのような値にすれば
を最小化できるのかというのが、最小化問題です。答えは簡単で
と変形できることに気づけば、
で
が答えになります。
この問題に勾配法を用いる場合は以下のような考えで問題を解くことになります。
でとりあえず始めてみる。
このときの微分値を求めましょう。
であるので、
と求まります。このときの勾配はであるということです。勾配があるということは、
を増やすか減らすかすれば、
の値も増えるか減るかするということです。現在の勾配は正の値であり、
を増やせば
も増えるという状況です。勾配の意味からすれば、
を
だけ増加させれば、
は
だけ増加することになります。
すなわち、現在の値から値を少し小さくすれば、
の値も小さくすることができるわけです。とりあえずどれくらい小さくすればいいかは分かりませんが、現在の値よりも少しだけ小さくしてみましょう。
ここで、勾配がちょうど使えます。勾配が正ならば、
を減らせばよく、勾配が負ならば
を増やせばいいわけですから、
のところにそのまま
を代入してしまえばいいのです。(今は最小化問題を考えているが、最大化問題ならば符号を+にすればいいだけ)
一応、どれくらい値を変化させるのかを調整するために学習係数を準備して
としておけば、勾配法の完成です。
Chainerによる勾配法の確認
勾配法を確認してみましょう。
について、は更新回数、[tex:e_{rate}は学習係数です。
学習係数を変更して学習してみましたが、のよりも
のほうが早く
に収束してくれています。さて、一般に学習係数が大きい方が学習が学習が早くなると言えるでしょうか。答えはNoです。
のときには
の値が全く変化していません。それは以下のように、
の更新量が大きすぎて、
と
を行ったり来たりしているためです。進む方向があっていても、大きさが悪ければこのようなことが起こってしまいます。
のときには
の値はむしろ大きくなっています。こちらも更新量が大きすぎるのが原因です。しかももっとたちの悪い状況です。以下のように更新しすぎてむしろ本来の解から遠ざかっていくという最悪のケースに陥っています。
上手に学習係数を決定できれば、最適解に素早く近づくことができますが、安全を考えれば少し小さめにしておくほうが無難でしょう。
実用上の問題
実用上の問題はという関数が、
になるように
を求めろなどが考えられます。普通は
という方程式を解くところですが、勾配法を用いる場合は
となるように、目的関数を
などと設定して問題を解く事になります。
ちゃんと目的関数を設定すれば、に収束させ、
に落ち着いているのが確認できるはずです(もっと学習回数を増やせば収束する)。
回帰の問題
回帰の問題は、まずパラメータによって関数
を作ります。この際に、
は調整できるパラメータではないことに注意してください。
色々な値になるに対して、
が
に対応して何らかの値を取る場合、上手く
を調整して、その関係を表したいという問題です。
例えばで
となって欲しいならば「
」が成り立つような
がほしいのです。一方で
で
という関係があるならば「
」が成り立っていなければいけません。更にたくさん
と
のデータセットがある場合には、「
」を更に考慮しなければならず、もはやピタリと式を成り立たせる
は見つからなくなります。
そこで、ぴったりでなくとも、とにかく妥当なを得たいと考えるわけです。せめて色々なデータセット(いろいろな
)に対して
がなるべく成り立つようにしようと考えるのです。
その際の代表的な目的関数が、
と置いた時に
となります。この目的関数は「」から外れれば、外れるほど大きな値になっていきます。従って、これを最小化するという問題設定にするのです(俗にいう最小二乗法です)。
ニューラルネットワークの学習とは
上記の問題において、
のをニューラルネットワークで表現してしまいましょう。そして、この最適化問題を解くことをニューラルネットワークの学習と言います。ニューラルネットワークは線形変換と活性化関数を組み合わせた複雑な合成関数になっています。その結果パラメータ
がアホほどたくさんありますが、これを上手く調節してやるという面は全く同じです。
ニューラルネットワークがどのような合成関数になるかは以下の記事を参考にしてください。
また、ニューラルネットワークは複雑な関数ゆえ、様々な既存手法を代替できる可能性があります(それが再発見されたのが深層学習と言える)。
分類の問題の場合には、目的関数が変わります。それはに相当する値が離散値になるため、最小二乗法のような単に距離を測る方法では妥当性がなくなるからです。通常は、ニューラルネットは分類パターンの確率を出力するものとして、交差エントロピーを目的関数にします。
しかし、目的関数が変わっても、学習という面においてパラメータを勾配法で調整することには変わりありません。
最後に
本当はもっと色々なこと書こうと思ったんですけど、意外と基本的なことを書くのにChainerは向いていませんでしたのでやめました(笑)。これくらいのことならばnumpyで書いたほうが分かりやすいです。
多分、基本的な計算から自分で組み立てたい場合にはTensorFlowの方が向いているでしょう。numpyでやるような処理から、ニューラルネットワークの設計まで広範囲をカバーしているので、(静的なネットワークを使う限り)TensorFlowさえ使えるようになればある程度何でもできる感じがします。(たぶんchainerでもできますが、低レベルの基本的な処理に関するドキュメントは殆ど無い……。)
ニューラルネットワークの世界で複雑な処理や動的なネットワークを扱いたい場合はChainerの得意な分野であることは間違いないでしょう。ディープラーニングやりたいならChainerで良いと思います。ディープだけでなく、もっと基本的な処理も含めてやりたいならTensorFlowです。
ニューラルネットワークに関しては
「突き詰めるとニューラルネットワークは、何らかの最適化問題の目的関数の一部」と考えても良さそうです。
そして学習を終えた後は、その何らかの目的を達成できる関数としてニューラルネットを取り出して使うことができます。通常のよく目にする問題では、ニューラルネットと目的関数が直結していますが、DQNに代表されるように、強化学習の一部で使われたり、あるいは適応制御や適応信号処理で使われるケースもあります。