"機械学習","信号解析","ディープラーニング"の勉強

読者です 読者をやめる 読者になる 読者になる

HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学などをテーマに扱っていきます

Chainerで勾配法の基礎の基礎を確認【ニューラルネット入門】

 

 

「勾配法」の画像検索結果

勾配法はニューラルネットワークの学習の基礎になります。基本的な問題を見て、勾配法を確認してみましょう。

勾配法

勾配法とは最小化問題や最大化問題などの最適化問題を解くための手法の1つです。例えばパラメータxに対して、目的関数y(x)があった場合に、xをどのような値にすれば、yが最小値を取るのかを探索することに使えます。

 

簡単な例

以下のように

 

y(x) = x^2 -2x +1

 

という関数があったとしましょう。このときxをどのような値にすればyを最小化できるのかというのが、最小化問題です。答えは簡単でy=(x-1)^2と変形できることに気づけば、x = 1y = 0が答えになります。

 

この問題に勾配法を用いる場合は以下のような考えで問題を解くことになります。

 

x = 3でとりあえず始めてみる。

 

x=3

y = 3^2-2*3+1=4

 

このときの微分値を求めましょう。

 

\displaystyle \frac{dy}{dx}=2x-2

 

であるので、

 

x =3

\displaystyle \frac{dy}{dx}=2*3-2=4

 

と求まります。このときの勾配は4であるということです。勾配があるということは、xを増やすか減らすかすれば、yの値も増えるか減るかするということです。現在の勾配は正の値であり、xを増やせばyも増えるという状況です。勾配の意味からすれば、xdxだけ増加させれば、ydy = 4dxだけ増加することになります。

 

すなわち、現在の値x=3から値を少し小さくすれば、yの値も小さくすることができるわけです。とりあえずどれくらい小さくすればいいかは分かりませんが、現在の値よりも少しだけ小さくしてみましょう。

 

x←x - δx

 

ここで、勾配dy/dxがちょうど使えます。勾配が正ならば、xを減らせばよく、勾配が負ならばxを増やせばいいわけですから、δxのところにそのままdy/dxを代入してしまえばいいのです。(今は最小化問題を考えているが、最大化問題ならば符号を+にすればいいだけ)

 

\displaystyle x←x-\frac{dy}{dx}

 

一応、どれくらい値を変化させるのかを調整するために学習係数εを準備して

 

\displaystyle x←x-ε\frac{dy}{dx}

 

としておけば、勾配法の完成です。

 

 

Chainerによる勾配法の確認

勾配法を確認してみましょう。

 

train(epoch, e_{rate})

 

について、epochは更新回数、[tex:e_{rate}は学習係数です。

 

学習係数を変更して学習してみましたが、e_{rate}=0.01のよりもe_{rate}=0.1のほうが早くy=0に収束してくれています。さて、一般に学習係数が大きい方が学習が学習が早くなると言えるでしょうか。答えはNoです。

 

e_rate=1のときにはyの値が全く変化していません。それは以下のように、xの更新量が大きすぎて、x=3x=-1を行ったり来たりしているためです。進む方向があっていても、大きさが悪ければこのようなことが起こってしまいます。

f:id:s0sem0y:20170517004111p:plain

 

e_rate=1.1のときにはyの値はむしろ大きくなっています。こちらも更新量が大きすぎるのが原因です。しかももっとたちの悪い状況です。以下のように更新しすぎてむしろ本来の解から遠ざかっていくという最悪のケースに陥っています。

f:id:s0sem0y:20170517004417p:plain

 

上手に学習係数を決定できれば、最適解に素早く近づくことができますが、安全を考えれば少し小さめにしておくほうが無難でしょう。

f:id:s0sem0y:20170517004704p:plain

 

 

 

実用上の問題

実用上の問題はy(x) = x^2-2x + 1という関数が、y=1になるようにxを求めろなどが考えられます。普通は

 

1=x^2-2x+1

 

という方程式を解くところですが、勾配法を用いる場合は

 

y(x)≒1

 

となるように、目的関数を

 

\left( y(x)-1 \right)^2

 

などと設定して問題を解く事になります。

 

ちゃんと目的関数を設定すれば、y=1に収束させ、x=2に落ち着いているのが確認できるはずです(もっと学習回数を増やせば収束する)。

 

回帰の問題

回帰の問題は、まずパラメータw,bによって関数y=wx+bを作ります。この際に、xは調整できるパラメータではないことに注意してください。

 

色々な値になるxに対して、yxに対応して何らかの値を取る場合、上手くw,bを調整して、その関係を表したいという問題です。

 

例えばx_1=2y_1=5となって欲しいならば「5=w*2+b」が成り立つようなw,bがほしいのです。一方でx_2=1y_2=3という関係があるならば「5=w*2+b」が成り立っていなければいけません。更にたくさんx_iy_iのデータセットがある場合には、「y_i = wx_i +b」を更に考慮しなければならず、もはやピタリと式を成り立たせるw,bは見つからなくなります。

 

そこで、ぴったりでなくとも、とにかく妥当なw,bを得たいと考えるわけです。せめて色々なデータセット(いろいろなi)に対して

 

y_i-(wx_i+b)≒0

 

がなるべく成り立つようにしようと考えるのです。

その際の代表的な目的関数が、

 

y=f(w,b,x)=wx+b

 

と置いた時に

 

\displaystyle L(w,b) =\sum_{i} \frac{1}{2} \left( y_i - f(w,b,x_i) \right)^2=\frac{1}{2} \left( y_i - wx_i-b \right)^2

 

となります。この目的関数は「y_i-(wx_i+b)≒0」から外れれば、外れるほど大きな値になっていきます。従って、これを最小化するという問題設定にするのです(俗にいう最小二乗法です)。

 

 

ニューラルネットワークの学習とは

 上記の問題において、

 

\displaystyle L(w,b) =\sum_{i} \frac{1}{2} \left( y_i - f(w,b,x_i) \right)^2

 

f(w,b,x_i)をニューラルネットワークで表現してしまいましょう。そして、この最適化問題を解くことをニューラルネットワークの学習と言います。ニューラルネットワークは線形変換と活性化関数を組み合わせた複雑な合成関数になっています。その結果パラメータwがアホほどたくさんありますが、これを上手く調節してやるという面は全く同じです。

 

ニューラルネットワークがどのような合成関数になるかは以下の記事を参考にしてください。

s0sem0y.hatenablog.com

 

 また、ニューラルネットワークは複雑な関数ゆえ、様々な既存手法を代替できる可能性があります(それが再発見されたのが深層学習と言える)

s0sem0y.hatenablog.com

 

分類の問題の場合には、目的関数が変わります。それはy_iに相当する値が離散値になるため、最小二乗法のような単に距離を測る方法では妥当性がなくなるからです。通常は、ニューラルネットは分類パターンの確率を出力するものとして、交差エントロピーを目的関数にします。

 

しかし、目的関数が変わっても、学習という面においてパラメータを勾配法で調整することには変わりありません。

 

 

s0sem0y.hatenablog.com

 

最後に

本当はもっと色々なこと書こうと思ったんですけど、意外と基本的なことを書くのにChainerは向いていませんでしたのでやめました(笑)。これくらいのことならばnumpyで書いたほうが分かりやすいです。

多分、基本的な計算から自分で組み立てたい場合にはTensorFlowの方が向いているでしょう。numpyでやるような処理から、ニューラルネットワークの設計まで広範囲をカバーしているので、(静的なネットワークを使う限り)TensorFlowさえ使えるようになればある程度何でもできる感じがします。(たぶんchainerでもできますが、低レベルの基本的な処理に関するドキュメントは殆ど無い……。)

 

ニューラルネットワークの世界で複雑な処理や動的なネットワークを扱いたい場合はChainerの得意な分野であることは間違いないでしょう。ディープラーニングやりたいならChainerで良いと思います。ディープだけでなく、もっと基本的な処理も含めてやりたいならTensorFlowです。

 

 

s0sem0y.hatenablog.com

 

 

 

 

ニューラルネットワークに関しては

 

「突き詰めるとニューラルネットワークは、何らかの最適化問題の目的関数の一部」と考えても良さそうです。

 

そして学習を終えた後は、その何らかの目的を達成できる関数としてニューラルネットを取り出して使うことができます。通常のよく目にする問題では、ニューラルネットと目的関数が直結していますが、DQNに代表されるように、強化学習の一部で使われたり、あるいは適応制御や適応信号処理で使われるケースもあります。