【入門向け】ニューラルネットワークの仕組みを緩く図解

この記事は、自身のブログ、[Data Science Struggle](http://marubon-ds.blogspot.jp)を翻訳したものになる。  

#概略
ニューラルネットワークのアルゴリズムを大まかに追っていく。 
数式を使って追ってはいくが、あまり厳密にしっかりとは進めない。緩く、イメージを掴めるように進めていく。
#ニューラルネットワークとは何か？
ニューラルネットワークとは受け付けた入力を最低一つ以上の隠れ層と出力層を通り出力に至らせるアルゴリズム。
図にすると以下のようになる。 

![nn_1 (1).png](https://qiita-image-store.s3.amazonaws.com/0/122985/a16d45c1-7fb2-8074-770e-947227d0e841.png)

#どのように動作するのか？
ニューラルネットワークの動きを理解するために以下の図のようなシンプルなモデルを考える。  

![nn_2.png](https://qiita-image-store.s3.amazonaws.com/0/122985/2e5c2b91-7525-df19-d682-035e6aa449b4.png)

このモデルの構造だと 
Input: [1, 3] :$X=\left(\begin{matrix} x_{1}& x_{2}& x_{3}\end{matrix}\right)$
Weight: [3, 1] :$W=\left(\begin{matrix} w_{1}& w_{2}& w_{3}\end{matrix}\right)^{T}$

$l_{2}$レイヤーにフォーカスする。  

![nn_3.png](https://qiita-image-store.s3.amazonaws.com/0/122985/74093d34-55ef-1653-9218-06d78df6ecf5.png)

```math
\begin{align*} & d=XW\\ 
& =\left( \begin{matrix}x_{1}& x_{2}& x_{3}\end{matrix}\right) \left( \begin{matrix} w_{1}\\ w_{2}\\ w_{3}\end{matrix} \right) \end{align*}
```

入力$d$は関数$f\left( x\right)$を通って出力される。 
ニューラルネットワークの訓練の目的はパラメーター$W$を更新していき、十分な精度の出るところまで持っていくことになる。 
関数$f\left( x\right)$を選択することによって回帰や分類を使い分けることができる。 
この関数は活性化関数という。 

#計算を追っていく
よりしっかり理解するために下記のモデルの計算を追っていく。  

![nn_4 (1).png](https://qiita-image-store.s3.amazonaws.com/0/122985/90acb215-d032-164c-afdd-262082ee174e.png)

パラメーター（重み）は図の矢印で表せる。訓練によってデータを読み込ませることでこのパラメーターを更新していく。 
行列表現を使うことで計算は簡単に表すことができる。 


```math
\begin{align*} & X=\left( \begin{matrix} x_{1}& x_{2}&x_{3}\end{matrix} \right) \\ & W_{1}=\left( \begin{matrix} w_{11}& w_{12}\\
 w_{21}& w_{22}\\
 w_{31}& w_{32}\end{matrix} \right) \\
 & w_{2}=\left( \begin{matrix} w_{1}^{\ast}\\
 w_{2}^{\ast}\end{matrix} \right) \end{align*}
```

上記のモデルの条件下で、出力までの計算を追っていく。  

$l_{1}$~$l_{2}$  

```math
\begin{align*} & XW_{1}\\ & =\left( \begin{matrix} x_{1}&x_{2}&x_{3}\end{matrix} \right) \left( \begin{matrix} w_{11}&w_{12}\\ w_{21}&w_{22}\\ w_{31}&w_{32}\end{matrix} \right) \\ & =(x_{1}w_{11}+x_{2}w_{21}+x_{3}w_{31}&x_{1}w_{12}+x_{2}w_{22}+x_{3}w_{23})\end{align*}
```

$\begin{align*} & A=x_{1}w_{11}+x_{2}w_{21}+x_{3}w_{31}\\
 & B=x_{1}w_{12}+x_{2}w_{22}+x_{3}w_{32}\end{align*}$  

plot_1のAとBは上記の式となる。  

![nn_5.png](https://qiita-image-store.s3.amazonaws.com/0/122985/81e84196-39c0-d2bc-0bce-42c27321dd84.png)


$l_{2}$~$l_{3}$
レイヤー$l_{2}$の出力は$\begin{align*} & (f_{1}\left( x_{1}w_{11}+x_{2}w_{21}+x_{3}w_{31}\right)&f_{2}\left( x_{1}w_{12}+x_{2}w_{22}+x_{3}w_{32})\right) \end{align*}$となる。  
この値を$D$とおく。$l_{3}$の入力は$DW_{2}$と表せる。  

![nn_6.png](https://qiita-image-store.s3.amazonaws.com/0/122985/122609e9-fb3e-a9ef-5bda-7fd60b196f60.png)


$DW_{2}$を$C$とおく。 

```math
\begin{align*} & C=DW_{2}\\ & =(f_{1}\left( x_{1}w_{11}+x_{2}w_{21}+x_{3}w_{21}\right) & f_{2}\left( x_{1}w_{12}+x_{2}w_{22}+x_{3}w_{32}\right) )\left( \begin{matrix} w_{11}^{\ast }\\ w_{21}^{\ast }\end{matrix} \right) \end{align*}
```

故に、レイヤー$l_{3}$の入力は下記のようになる。  
$\begin{align*} & C=\left( f_{1}\left( x_{1}w_{11}+x_{2}w_{21}+x_{3}w_{31}\right) \right) w_{11}^{\ast }+\left( f_{2}\left( x_{2}w_{12}+x_{2}w_{22}+x_{3}w_{32}\right) \right) w_{21}^{\ast }\end{align*}$  

![nn_7.png](https://qiita-image-store.s3.amazonaws.com/0/122985/5cd1b27d-3d1a-cbf6-328c-3c58f4e0b70d.png)

レイヤー$l_{3}$の出力の値は入力値に活性化関数$f_{3}\left( x\right)$を当てたものである。  

$\begin{align*} & f_{3}\left( \left( f_{1}\left( x_{1}w_{11}+x_{2}w_{21}+x_{3}w_{31}\right) \right) w_{11}^{\ast }+\left( f_{2}\left( x_{2}w_{12}+x_{2}w_{22}+x_{3}w_{32}\right) \right) w_{21}^{\ast } \right)\end{align*}$

#パラメーターの更新
モデルのパラメーターは以下のようにして更新していく。  

* 損失関数を定め、それを局所的に最適化するパラメーターに行きつくように更新する

例  
$f\left( x\right) =\dfrac {1} {3}x^{3}-x$  

![nn_8.png](https://qiita-image-store.s3.amazonaws.com/0/122985/a6ea9653-1099-f349-4d22-d5cf6800d200.png)

この場合、極小値が学習によって局所最適解として求められる。つまり、この場合は$x=1$がおおよそ求めるパラメーターとなる。  
しかし、実際にニューラルネットワークを組む場合は多くのパラメータをもち、最適化する式も関数がネストした複雑なものになり、最適化は容易ではない。  
パラメーターを得るための方法は、最初にパラメーターに適当な初期値を与え、データを読み込ませて訓練させることでパラメーターを更新していくというものになる。  
この例では  

* $x$: the parameter
* $f\left( x\right)$: loss function

訓練の目的は局所的に$f\left( x\right)$を最小化するパラメーターを求めることになる。  

手順  

1. パラメーターに初期値を与える。今回は$x$に0を与える。
2. パラメーターを更新する

#パラメーターの更新方法
$x$を$+$もしくは$-$方向に動かす。  
$\rightarrow \begin{cases} w^{t+1}=W^{t}-\varepsilon \nabla E\\ \nabla E=\dfrac {\partial E} {\partial w}\end{cases}$