勾配降下法（入力値が複数の場合の更新式）

#前回の続き…
前回の記事では、入力値としては $x$ 一つだけのもので説明しましたが、まぁ、入力値は 2つ以上のことがほとんどですよね。例えばよくある Iris データセットなんかだと、花弁の長さ、花弁の幅、がくの長さ、がくの幅の 4つを入力として、あやめ（Iris）の種類を出力とします。そんなわけで、じゃあ、複数の入力があった場合の更新式ってどうなるの？っていうのを確認の意味も込めてちょっと見ていこうと思います。

前回記事はこちら
『[勾配降下法を、いま一つ腹落ちしていない過去の自分にくどくどと説明してみる](https://qiita.com/celaeno42/items/19531a4cb5b2857a9482)』

あ、今回はくどくないです。

#問題設定
とはいえ、いきなり 4つの入力というのもアレなので、ひとまず 2つの入力とした場合で見ていきましょう。今回入力としては $x$, $y$ 出力としては $z$ で扱うことにします。というわけで、求める直線の式を

$\qquad z = ax + by + c$

とします。

#誤差関数を立てる
ではこの式を元に誤差関数を考えてみましょう。とはいえ、前回やったのとほとんど同じです。


```math
\begin{align}
E &= \frac{1}{2}\sum_{i=1}^n(z_i - \hat{z_i})^2 \\
\\
  &= \frac{1}{2}\sum_{i=1}^n(z_i - (ax_i + by_i + c))^2
\end{align}
```


前回、$ax + b$ とおいていたところを $ax + by + c$ としているだけですね。
今回も二乗和誤差としています。

これを変形して、

```math
\begin{align}
E &= \frac{1}{2}\sum(z_i - (ax_i + by_i + c))^2 \\
\\
  &= \frac{1}{2}\sum(z_i - A)^2 \\
\\
  &= \frac{1}{2}\sum(z_i^2 - 2z_iA + A^2) \\
\\
  &= \frac{1}{2}\sum(z_i^2 - 2z_i(ax_i + by_i + c) + (ax_i + by_i + c)^2) \\
\\
  &= \frac{1}{2}\sum(z_i^2 - 2ax_iz_i - 2by_iz_i - 2cz_i + a^2x_i^2 + b^2y_i^2 + c^2 + 2abx_iy_i + 2acx_i + 2bcy_i)
\end{align}
```
  
それぞれのパラメータで偏微分すると、

```math
\begin{align}
\frac{\partial E}{\partial a} &= \frac{1}{2}\sum(0 - 2x_iz_i - 0 - 0 + 2ax_i^2 + 0 + 0 + 2bx_iy_i + 2cx_i + 0) \\
\\
          &= \frac{1}{2}\sum(2ax_i^2 + 2bx_iy_i + 2cx_i - 2x_iz_i) \\
\\
          &= \sum(ax_i^2 + bx_iy_i + cx_i - x_iz_i) \\
\\
          &= \sum(((ax_i + by_i + c) - z_i) * x_i) \\
\\
\\
\frac{\partial E}{\partial b} &= \frac{1}{2}\sum(0 - 0 - 2y_iz_i - 0 + 0 + 2by_i^2 + 0 + 2ax_iy_i + 0 + 2cy_i) \\
\\
          &= \frac{1}{2}\sum(2by_i^2 + 2ax_iy_i + 2cy_i - 2y_iz_i) \\
\\
          &= \sum(by_i^2 + ax_iy_i + cy_i - y_iz_i) \\
\\
          &= \sum(((ax_i + by_i + c) - z_i) * y_i) \\
\\
\\
\frac{\partial E}{\partial c} &= \frac{1}{2}\sum(0 - 0 - 0 - 2z_i + 0 + 0 + 2c + 0 + 2ax_i + 2by_i) \\
\\
          &= \frac{1}{2}\sum(2ax_i + 2by_i + 2c - 2z_i) \\
\\
          &= \sum(((ax_i + by_i + c) - z_i) * 1)
\end{align}
```

となります。

#比べてみると

$y = ax + b$ の場合が

$\qquad \frac{\partial E}{\partial a} = \sum(((ax_i + b) - y_i) * x_i)$
         
$\qquad \frac{\partial E}{\partial b} = \sum((ax_i + b) - y_i)$

だったので、比べるとどちらも

$\qquad \frac{\partial E}{\partial n} = \sum(式 - 正解値) * そのパラメータにかかる入力値$

という形式になっていることがわかると思います。

#問題設定２
では、こんな関数だった場合はどうでしょうか。

$\qquad z = ax^2 + by + c$

今回は曲線ですね。

#誤差関数を立てる
ではこの式を元に誤差関数を考えてみましょう。

```math
\begin{align}
E &= \frac{1}{2}\sum(z_i - \hat{z_i})^2 \\
\\
  &= \frac{1}{2}\sum(z_i - (ax_i^2 + by_i + c))^2 \\
\end{align}
```

前回同様変形してみます。

```math
\begin{align}
E &= \frac{1}{2}\sum(z_i - (ax_i^2 + by_i + c))^2 \\
\\
  &= \frac{1}{2}\sum(z_i - A)^2 \\
\\
  &= \frac{1}{2}\sum(z_i^2 - 2z_iA + A^2) \\
\\
  &= \frac{1}{2}\sum(z_i^2 - 2z_i(ax_i^2 + by_i + c) + (ax_i^2 + by_i + c)^2) \\
\\
  &= \frac{1}{2}\sum(z_i^2 - 2ax_i^2z_i - 2by_iz_i - 2cz_i + a^2x_i^4 + b^2y_i^2 + c^2 + 2abx_i^2y_i + 2acx_i^2 + 2bcy_i)
\end{align}
```

それぞれを偏微分すると、

```math
\begin{align}
\frac{\partial E}{\partial a} &= \frac{1}{2}\sum(0 - 2x_i^2z_i - 0 - 0 + 2ax_i^4 + 0 + 0 + 2bx_i^2y_i + 2cx_i^2 + 0) \\
\\
          &= \frac{1}{2}\sum(2ax_i^4 + 2bx_i^2y_i + 2cx_i^2 - 2x_i^2z_i) \\
\\
          &= \sum(ax_i^4 + bx_i^2y_i + cx_i^2 - x_i^2z_i) \\
\\
          &= \sum(((ax_i^2 + by_i + c) - z_i) * x_i^2) \\
\\
\\
\frac{\partial E}{\partial b} &= \frac{1}{2}\sum(0 - 0 - 2y_iz_i - 0 + 0 + 2by_i^2 + 0 + 2ax_i^2y_i + 0 + 2cy_i) \\
\\
          &= \frac{1}{2}\sum(2by_i^2 + 2ax_i^2y_i + 2cy_i - 2y_iz_i) \\
\\
          &= \sum(by_i^2 + ax_i^2y_i + cy_i - y_iz_i) \\
\\
          &= \sum(((ax_i^2 + by_i + c) - z_i) * y_i) \\
\\
\\
\frac{\partial E}{\partial c} &= \frac{1}{2}\sum(0 - 0 - 0 - 2z_i + 0 + 0 + 2c + 0 + 2ax_i^2 + 2by_i) \\
\\
          &= \frac{1}{2}\sum(2ax_i^2 + 2by_i + 2c - 2z_i) \\
\\
          &= \sum(((ax_i^2 + by_i + c) - z_i) * 1)
\end{align}
```

#比べてみると
では、いままで扱った３パターンの式についての誤差関数の勾配計算の式を比べてみましょう。
３パターンの式は以下のようなものでした。

$\qquad y = ax + b$
$\qquad z = ax + by + c$
$\qquad z = ax^2 + by + c$

それぞれの誤差関数をパラメータ $a$, $b$, $c$ で偏微分した結果はこのようになりました。

```math
\begin{align}
\frac{\partial E}{\partial a} = \sum(((ax_i + b) - y_i) * x_i) \\
\\
\frac{\partial E}{\partial a} = \sum(((ax_i + by_i + c) - z_i) * x_i) \\
\\
\frac{\partial E}{\partial a} = \sum(((ax_i^2 + by_i + c) - z_i) * x_i^2) \\
\\
\\
\frac{\partial E}{\partial b} = \sum(((ax_i + by_i + c) - z_i) * y_i) \\
\\
\frac{\partial E}{\partial b} = \sum(((ax_i^2 + by_i + c) - z_i) * y_i) \\
\\
\\
\frac{\partial E}{\partial b} = \sum(((ax_i + b) - y_i) * 1) \\
\\
\frac{\partial E}{\partial c} = \sum(((ax_i + by_i + c) - z_i) * 1) \\
\\
\frac{\partial E}{\partial c} = \sum(((ax_i^2 + by_i + c) - z_i) * 1) \\
\end{align}
```

今回も前回前々回同様、

$\qquad \frac{\partial E}{\partial n} = \sum(式 - 正解値) * そのパラメータにかかる入力値$

となっていることがわかりますね。

#まとめ
というわけで、求めたい式が

$\qquad y = ax + b$

であっても

$\qquad z = ax + by + c$

であっても、はたまた

$\qquad z = ax^2 + by + c$

であっても勾配を求める式は

$\qquad \frac{\partial E}{\partial n} = \sum(式 - 正解値) * そのパラメータにかかる入力値$

となっていて違いはありませんでした。

さらに言うと、「式」の部分は

$\qquad \hat y_i = ax_i + b$
$\qquad \hat z_i = ax_i + by_i + c$
$\qquad \hat z_i = ax_i^2 + by_i + c$

と表すことができることから「推測値」、「予測値」とも言い換えられるので、

$\qquad \frac{\partial E}{\partial n} = \sum(推測値 - 正解値) * そのパラメータにかかる入力値$

とすれば、「どのような式か」を気にする必要がなくなりますね。

#機械学習風に書き換えてみましょう
さて、それでは、前回同様に機械学習風の記号に置き換えてみましょう。
$a$, $b$, $c$ をそれぞれ、$w_1$, $w_2$, $w_0$、$x$, $y$ を $x_1$, $y_1$, $z$ を $y$ とすると、

```math
\begin{align}
\frac{\partial E}{\partial w_1} &= \sum_{i=1}^n(((w_0 + w_1x_{1i} + w_2x_{2i}) - y_i) * x_{1i}) = \sum((\hat y_i - y_i) * x_{1i}) \\
\\
\frac{\partial E}{\partial w_2} &= \sum_{i=1}^n(((w_0 + w_1x_{1i} + w_2x_{2i}) - y_i) * x_{2i}) = \sum((\hat y_i - y_i) * x_{2i}) \\
\\
\frac{\partial E}{\partial w_0} &= \sum_{i=1}^n(((w_0 + w_1x_{1i} + w_2x_{2i}) - y_i) * 1) = \sum((\hat y_i - y_i) * 1) 
\end{align}
```

と表すことができますね。
そして結局のところ、それぞれのパラメータの更新式は、

```math
\begin{align}
w_1 := w_1 - \eta (\frac{\partial E}{\partial w_1}) \\
\\
w_2 := w_2 - \eta (\frac{\partial E}{\partial w_2}) \\
\\
w_0 := w_0 - \eta (\frac{\partial E}{\partial w_0})
\end{align}
```

のようにまとめることができます。（$\eta$ は学習率）

途中の計算は面倒ですが、結果的にはこのスッキリした簡単な式でパラメータを更新していけます。すごいですね。
なお、$w_0$ はバイアスです。$w_1$, $w_2$ ではそれぞれの入力値を掛けているので、表記をあわせるために $1$ を掛けています。ニューラルネットワークの本などではよく バイアスの入力として $1$ になっているものがあると思いますが、それと同じです。

さて、今回３パターンの式について、誤差関数の勾配を求める式を見ていきましたが、結局どれも同じ構造の計算式になるというのが面白いですね。今回求めたのはいわゆるパーセプトロンのパラメータ更新式ですが、ニューラルネットワークであってもパラメータ更新の発想は同様で、誤差関数を微分しながら手前（？）の層に戻っていく（誤差逆伝播）ので、やっぱりこのあたり（勾配降下法）がイメージできているとよさそうですね。

***
####--Excel VBA でニューラルネットワークをフルスクラッチしてみる--
以前書いていたExcel VBAでニューラルネットワークをフルスクラッチしてみる的な記事は以下のブログに移動しました。
[無限不可能性ドライブ](https://celaeno42.hatenablog.com/)
***