(第5回)微分(勾配算出)
誤差が算出し、それを小さくすることで良い結果が得られます。重みをどの方向に変化させれば良いか?微分を 使って勾配を算出することで、決定します。計算が遅いため実用的ではありませんが、勾配をどのように算出するか 理解する必要があるため、調べていきます。
<数値微分>
製品を作るときのサイクルタイムを短くする場合、現状が60秒/個を一気に10秒短縮するのは難しいですが、
製品の工程を分解して、それぞれを少しずつ短縮して目標に近づけることで、目標を達成します。
同じように、機械学習でも誤差を微分して少しづつ誤差を低減していきます。まず微分の式は
のように、関数f(x)の変化をx-hによって作り、hを0に近づける事で微分を行います。
しかし、Pythonで計算する場合、$1.0e^{-50}$などという数値をhに使うと不具合が生じてしまうため、
対策が必要です。
Pythonで計算すると$h=1.0e^{-50}$+前方差分の方は0になってしまい、計算ができていません。しかし$h=1.0e^{-4}$程度にして、中心差分$f(x+h)$と$f(x-h)$の差分
にすると計算ができています。
計算結果としては、$x^{2}+x$の微分は$2x+1$ですので、numerical_diff2に$f(x)=x^{2}+x$と$x=1$を入力すると3が出力されています。
次に、$0.01x^{2}+0.1x$と$x^{2}$の2つの式のグラフを描いて、それぞれを微分してみます。x=5,10がそれぞれ、微分した傾きになっていることが
分かります。
この傾きを使って、誤差を小さくすれば良いという事になります。
<偏微分>
いままでは1つの変数の微分ですが、変数が複数になった場合も計算する必要があります。複数の変数の微分を偏微分といいますが、 この傾きも算出する必要があります。
$x_0^2$と$x_1^2$をそれぞれ微分すると、$2x_{0}$、$2x_{1}$になり、x0=5、x1=10の場合は、x0の傾きが10、x1の傾きが20という答えが得られます。
Pythonで計算する場合も、x0、x1それぞれ微分をすることで、同じ答えが得られます。
Pythonを実行すると、偏微分の計算ができます。x0:-5.0~5.0、x1:10.0~10.0のグラフを描いて、x0=5、x=10の 部分がx0の傾きが10、x1の傾きが20になっていることがわかります。(Pythonのグラフウィンドウではグラフが回転できます)
<勾配>
偏微分のグラフをみると、ある方向に進むことで、中央に近づくことがわかりますが、実際に方向を数値化するために Pythonで計算します。
偏微分で出力した図の傾きを考えると上の図のようになると思います。この傾きの方向に進めれば、誤差を小さくできそうです。
<勾配法>
いよいよ誤差の傾きを小さくするために、パラメーターを変更して目標にむかって変更させます。勾配の方向へ進める方法を
勾配法といい、1回の更新量を学習率と呼びます。
実際にPythonで計算すると次の通りになります。学習率が0.1の場合は、(0,0)に向かって進むのですが、学習率が10(大きすぎ)や、
$1e^{-10}$(小さすぎ)など適切でない学習率の場合は、目標に進まないことがわかります。
適切な学習率で計算すると、外側の点から、中央(0,0)の方向に値が更新されていくことが下の図で分かります。
微分をすることで、傾きを求め、その傾きの方向に値を更新することで、目標の数値に近づくことがわかりました。
-------------