単純パーセプトロンの重み修正量を導出する

f:id:shogonir:20190909002343p:plain

目次

  1. はじめに
  2. 変数や関数の定義
  3. パーセプトロンの性能を計測する
  4. 最小値問題
  5. 勾配降下法
  6. 修正量の計算
  7. まとめ

はじめに

以前の記事で単純パーセプトロンの学習について、
下記のような計算を行うとご説明しました。

{} $$ w_j \leftarrow w_j - \alpha\sum_{i=1}^{4}\left(y_i^{\prime} - y_i\right) f^{\prime}(a_i) x_{ij} $$

blog.shogonir.jp

今回はこの計算式がどのように導けるのか解説したいと思います。
この記事はプログラミングではなく、どちらかというと数学の記事になります。

変数や関数の定義

まずはパーセプトロンの出力の計算に関する変数や関数です。
入力が {N} 次元だとして、入力 {x} から出力 {y} を計算します。
計算の際には重み {w} を使います。

 

f:id:shogonir:20190901142955p:plain

 

{} $$ y = f(a) $$

{} $$ x = \left[ x_1, x_2, \cdots, x_N \right] $$

{} $$ w = \left[ w_1, w_2, \cdots, w_N \right] $$

{} $$ a = \sum_{j=1}^{N}x_j w_j = x_1 w_1 + x_2 w_2 + \cdots + x_N w_N $$

{f} は活性化関数で、 {f^{'}} は活性化関数の微分です。
活性化関数には、標準シグモイド関数などがよく使われますが、
微分さえできればどんな関数でも使用することができます。

このパーセプトロンを学習させるために、学習データを準備します。
学習データは入力と、その入力に対する正しい出力のセットのことです。
今回は入力と出力を {M} 個ずつ準備するとします。

{} $$ \hat{x} = \left[ \begin{array}{cccc} \hat{x}_{11} & \hat{x}_{12} & \cdots & \hat{x}_{1N} \\ \hat{x}_{21} & \hat{x}_{22} & \cdots & \hat{x}_{2N} \\ \vdots & \vdots & \ddots & \vdots \\ \hat{x}_{M1} & \hat{x}_{M2} & \cdots & \hat{x}_{MN} \\ \end{array} \right] $$

{} $$ \hat{y} = \left[ \begin{array}{c} \hat{y}_{1} \\ \hat{y}_{2} \\ \vdots \\ \hat{y}_{M} \\ \end{array} \right] $$

この学習データをもとにパーセプトロンは学習することができます。
学習で重みを更新する際に用いるのが冒頭の数式になります。

{} $$ w_j \leftarrow w_j - \alpha\sum_{i=1}^{M}\left(\hat{y_i} - y_i\right) f^{\prime}(a_i) \hat{x}_{ij} $$

{} $$ y_i = f(a_i) $$

{} $$ a_i = \sum_{j=1}^{N} x_{ij} w_j $$

{\alpha} は学習率と呼ばれ、重みの修正をどの程度するのかという変数です。

パーセプトロンの能力を計測する

パーセプトロンの能力は、そのパーセプトロンと学習データを用いて計測します。
まず、入力データをパーセプトロンに入力して、その出力を実測値と呼ぶことにします。
学習データの中でも出力データ ( {\hat{y}} ) を正解データと呼ぶことにします。

このパーセプトロンがもし優秀なのであれば、実測値と正解データは近い値になるはずです。
逆にパーセプトロンが劣等だと、実測値と正解データは大きく異なる値になるはずです。
つまり、パーセプトロンの優劣は実測値と正解データの差分で計測できそうです。

また、学習データは {M} 個あるので、差分を全ての学習データについて計算し、
これをうまく均(なら)す必要があります。

ということで、誤差 {J} は次の様に計算するのがいいとされています。

{} $$ J = \sum_{i=1}^{M} \left( \hat{y}_{i} - y_i \right) ^{2} $$

誤差は、「実測値と正解データの差分を二乗して、全ての学習データ分を足したもの」です。
二乗しないと、差分を足す時に正負で打ち消す可能性もあるのでこうなっています。

さて、ここまででパーセプトロンの優劣を誤差 {J} で計測できることがわかりました。
この誤差が小さくなるように重みを修正すればパーセプトロンが優秀になるはずです。

最小値問題

高校数学でも最小値問題は解いたことがあると思います。
{y=f(x)} が最小になるような {x} と、その時の {y} を求めよ」ってやつです。

高校数学では、関数の増加減少の傾向を分析して、最小値をとる値を求めます。
この関数の増加減少の傾向を分析するのに微分を使いました。
大抵の問題は微分した関数が 0 になるところで最小値をとったりしました。

パーセプトロンで誤差を最小にする際は、上記の高校数学の解き方と違う方針でいきます。
誤差の関数が複雑すぎて、同じ方法だと現実的な時間で解けなくなるためです。

ここで、学習法の1つである勾配降下法を紹介します。

勾配降下法

勾配降下法は、ある関数の最小値問題を解くための1つの方法です。
特徴として、複雑な関数に対しても高速に計算できます。

勾配降下法の方針は、関数の傾きを求めて、それを変数から引いていくというものです。
イメージ的には関数の滑り台を滑るようなイメージです。

{y = f(x) = x^{2}} を例にして説明したいと思います。
学習率は {\alpha = 0.25} 初期値 {x = 2} とします。

 

f:id:shogonir:20190909004508p:plain

 

また、関数の微分を求めておきます。 {y^{\prime}=f^{\prime}(x)=2x} となります。
現在の {x} の傾きを求め、学習率をかけて、これを引くことで {x} を更新します。
{x \leftarrow x - \alpha f^{\prime}(x) = 2 - 0.25 * 2 * 2 = 2 - 1 = 1} となり {x} が1になります。
この更新をもう一回おこなうとどうなるでしょうか。
{x \leftarrow x - \alpha f^{\prime}(x) = 2 - 0.25 * 2 * 1 = 1 - 0.5 = 0.5} となり {x} が0.5になります。
このように更新を繰り返すことで {x} が0に近づいていきます。

ということで、勾配降下法で最小値問題が解ける例を紹介しました。
次に局所解と言われる、特定の範囲での最小値に落ち着いてしまう例を紹介します。

{y=f(x) = x^{4} - 2x^{3} - 9x^{2} , \alpha = 0.05, x = -1} の時を考えます。

 

f:id:shogonir:20190909004536p:plain

 

関数の微分を求めておきます。 {y^{\prime} = f^{\prime}(x)=4x^{3} - 6x^{2} - 18x} となります。
最初の重み更新は次の様になります。
{x \leftarrow x - \alpha f^{'}(x) = -1 - 0.05 8 = -1 - 0.4 = -1.4} となります。
この重み更新を繰り返すことで、 {x} が-1.5 に落ち着き、
このときの {y}{y  = - \frac{135}{16} = -8.4375} となります。 ですが、この関数の本当の最小値は {x=3} の時の {y=-54} です。

これが、勾配降下法で局所解に落ち着いた例でした。
しかし、学習率がもう少し大きければ最適化に落ち着く可能性もあります。
また、もちろん初期値がよければ最適解に落ち着く可能性もあります。

 

f:id:shogonir:20190909004554p:plain

 

このような特徴が勾配降下法にあることは理解しておいた方がいいでしょう。

勾配降下法まとめ

  • 関数の最小値に近い値を高速に求めることができます
  • 局所解と呼ばれる、特定の領域での最小値に落ち着く可能性があります
  • 学習後の値は、学習率や初期値や試行回数に大きく左右されます

修正量の計算

重みの修正量は勾配降下法をそのまま用います。
勾配降下法に用いる関数は、先述の誤差 {J} を使います。
ただし微分に使う変数は {w} です。

{} $$ w_j \leftarrow w_j - \alpha \frac{\partial J}{\partial w_j} $$

ここから先は {\frac{\partial J}{\partial w_j}} を計算していきます。

{\frac{\partial}{\partial w_j} J}

{} $$ \frac{\partial J}{\partial w_j} = \frac{\partial}{\partial w_j} J $$

{} $$ = \frac{\partial}{\partial w_j} \sum_{i=1}^{M} \left( \hat{y}_{i} - y_i \right) ^{2} $$

{} $$ = \frac{\partial}{\partial w_j} \sum_{i=1}^{M} \left( \hat{y}_{i}^{2} - 2 \hat{y}_{i} y_i + y_{i}^{2} \right) $$

{} $$ = \sum_{i=1}^{M} \left( \frac{\partial \hat{y}_{i}^{2}}{\partial w_j} - 2 \frac{\partial \hat{y}_{i} y_i}{\partial w_j} + \frac{\partial y_{i}^{2}}{\partial w_j} \right) $$

変数 {\hat{y}} は定数({w_j} とは関係ない)ため {\frac{\partial}{\partial w_{j}} \hat{y}_{i}^{2} = 0 , \frac{\partial}{\partial w_{j}} \hat{y}_{i} y_{i} = \hat{y} \frac{\partial}{\partial w_{j}} y_{i}} となります。
よって

{} $$ \frac{\partial J}{\partial w_j} = \sum_{i=1}^{M} \left( \frac{\partial y_{i}^{2}}{\partial w_j} - 2 \hat{y}_{i} \frac{\partial y_i}{\partial w_j} \right) $$

となります。ここからは {\frac{\partial}{\partial w_j} y_{i}^{2}}{\frac{\partial}{\partial w_j} y_i} を求めていきます。
その前に合成関数の微分について説明しなくてはなりません。

合成関数の微分

高校の教科書に載っている合成関数の微分について説明します。
合成関数とは、変数が二つの関数にかけられる {y=f(g(x))} のような状況のことです。
これを微分した {\frac{dy}{dx}} を求める際には、次のような計算をおこなう必要があります。

{u=g(x)} とおくと、次の様になります。

{} $$ \frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx} = \frac{du}{dx} \frac{dy}{du} = g^{\prime}(x) \cdot f^{\prime}(g(x)) $$

さて、修正量の計算の続きに戻ります。

{\frac{\partial}{\partial w_j} y_i}

合成関数の微分を使えば、次の様に進めることができます。

{} $$ \frac{\partial}{\partial w_j} y_i = \frac{\partial a_i}{\partial w_j} \frac{\partial y_i}{\partial a_i} $$

ここで {\frac{\partial}{\partial w_{j}} a_{i}} を求めます。

{} $$ \frac{\partial}{\partial w_{j}} a_{i} = \frac{\partial}{\partial w_{j}} \sum_{j=1}^{N} x_{ij} w_j = \frac{\partial}{\partial w_{j}} \left( x_{i1} w_1 + x_{i2} w_2 + \cdots + x_{ij} w_j + \cdots + x_{iN} w_N \right) = x_{ij} $$

なので、

{} $$ \frac{\partial}{\partial w_j} y_i = \frac{\partial a_i}{\partial w_j} \frac{\partial y_i}{\partial a_i} $$

{} $$ = x_{ij} \frac{\partial y_i}{\partial a_i} = x_{ij} f^{\prime}(a_i) $$

次に {\frac{\partial}{\partial w_j} y_{i}^{2}} についても合成関数の微分を用いて計算します。

{\frac{\partial}{\partial w_j} y_{i}^{2}}

{} $$ \frac{\partial}{\partial w_{j}} y_{i}^{2} = \frac{\partial y_{i}^{2}}{\partial y_{i}} \frac{\partial y_{i}}{\partial w_{j}} $$

{} $$ = 2 y_i \frac{\partial y_i}{\partial w_j} $$

{} $$ = 2 y_i x_{ij} f^{\prime}(a_i) $$

ついに {\frac{\partial}{\partial w_j} y_{i}^{2}}{\frac{\partial}{\partial w_j} y_i} がわかったので、 {\frac{\partial}{\partial w_{j}} J} の計算に戻ります。

{\frac{\partial}{\partial w_j} J} の続き

{} $$ \frac{\partial J}{\partial w_j} = \sum_{i=1}^{M} \left( \frac{\partial y_{i}^{2}}{\partial w_j} - 2 \hat{y}_{i} \frac{\partial y_i}{\partial w_j} \right) $$

{} $$ = \sum_{i=1}^{M} \left( 2 x_{ij} f^{\prime}(a_{i}) y_{i} - 2 \hat{y}_{i} x_{ij} f^{a_{i}} \right) $$

{} $$ = 2 \sum_{i=1}^{M} \left( x_{ij} f^{\prime}(a_{i}) \left( y_{i} - \hat{y}_{i} \right) \right) $$

よって、重みの修正は次の式でおこなうことができます。

{} $$ w_j \leftarrow w_j - \alpha \frac{\partial J}{\partial w_j} $$

{} $$ w_j \leftarrow w_j - 2 \alpha \sum_{i=1}^{M} \left( x_{ij} f^{\prime}(a_{i}) \left( y_{i} - \hat{y}_{i} \right) \right) $$

ということで、ようやく冒頭の数式を導出することができました。
係数の2は学習率の部分で吸収できるため、消えている記事などもあるようです。

まとめ

今回は勾配降下法を用いたパーセプトロンの重み修正の数式を導出しました。
思ったよりボリュームが大きい記事になってしまいました。

始まりは、「なんで修正する数式に {x_{ij}} が出てくるんだろう?」という疑問がスタートでした。
しかし数式の導出を丁寧に解説している記事になかなか行き当たらず、
自分で計算したみたところ、結構楽しかったので記事にしてみました。

勾配微分法の弱点や、数式の気持ちなどを改めて知ることができました。
この記事が、同じことが気になった方のために役立てば幸いです。