ニューラルネットワークの計算を図で描く

デープラーニングで話題のニューラルネットワークですが、中でなにやら大量の計算してる事は分かりますし、難しい理論はいっぱいありますが、中で何やってるのかイマイチわからないですよね。ニューラルネットワークの計算は一体どんな計算なのかを図にして描いてみます
図にしてみると、ニューラルネットワークの計算とは多次元のデータをアフィン変換（回転→拡大縮小反転→回転→平行移動）して第1象限（すべての要素が正の値）に投影する。という計算の繰り返しであることが分かります
#深層ニューラルネットワークの概念図
典型的なMLP(multilayer perceptron)を例にニューラルネットの構成を図に示します。中間層が1段だけ書いていますが、これが数十から百段を超えるものを深層ニューラルネットワークと呼びます。例えば画像に写っているものが猫、犬、飛行機を答えるネットワークとすると、入力は画像の画素の値、出力は猫、犬、飛行機を示すフラグとなります。
<div align="center">
<img width="80%" alt="NNの概念.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/78aa9601-b29f-d6ab-3b6b-d094a19246fc.png">
</div>
##入力層
入力層では、例えば画像を入力とすると、画素値を並べたベクトルが入力$x$となり、最初の中間層（第0層）の変数$h_0$になります。
##中間層
中間層で行われる計算

```math
a^{(k)}=b^{(k)}+W^{(k)}h^{(k-1)} \hspace{10mm} (1)\\
h^{(k)}=f(a^{(k)}) \hspace{10mm} (2)
```
　中間層の第k層では2段階の処理を行います。
　まず前の第k-1層の出力をエッジ上の係数$w_{i,j}$とかけ算して次のk層に送ります、k層で他のノードからの値とノード毎の定数$b$と足し合わされることにより、k層の入力$a$を計算します。式(1)に示すようにこの計算はアフィン変換です。
　次に非線形活性化関数$f$により$h^{(k)}$を計算します（式(2)）。活性化関数としては次の図に示すReLU(Rectified Linear Unit)がよく使われています。ReLUは正の値はそのまま、負の値はゼロに変換する処理です。
<div align="center">
<img width="30%" alt="ReLU.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/296d2f0b-f37e-e942-1aea-0a74b9aae5b1.png">
</div>
この中間層を複数段接続して複雑な関数を表現します。
##出力層
出力層は、最終層の出力をそのまま出力します。
##出力の評価
ニューラルネットワークを設計する目的は入力$x$を入れてネットワークが計算した出力$\hat{y}$が、人が認識した結果$y$と同じになることです。例えば入力画像$x$に写っているものが猫か犬か飛行機かを判断するネットワークを作る場合、出力層$\hat{y}=(\hat{y}_c,\hat{y}_d,\hat{y}_p)$は3個のノードを持ちそれぞれの値は、画像が猫、犬、飛行機である確率に対応します。猫の画像を入力したときは$\hat{y}_c$の値が大きくなりそれ以外の値が小さくなるように、中間のエッジの係数$W$のそれぞれの値を多数の猫、犬、飛行機画像を用いて調整します。
#中間層の計算の意味
式(1)で示されるアフィン変換を図で示します。アフィン変換は[アフィン変換を回転と拡大縮小に分解する](https://qiita.com/osadataku/items/cb778b49799e718c68b8)に書いたように、回転→拡大縮小→回転→平行移動に分解できます。図で示すために２ノードの簡単なネットワークの中間層で説明します。
##ノード数２の中間層
次の図はノード数2の中間層の1層を示します
<div align="center">
<img width="60%" alt="2ノード.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/fd7f5d22-e033-ba16-d645-70cda4ef6498.png">
</div>
最初の図では省略していたバイアス項$b^{(k)}$を実現するために定数1のノードを表示しています。
##1サンプルの入力
###中間層：線形（アフィン）変換パート
このネットワークに1つのデータを入力するとネットワークを順伝播してk-1層では

```math
h^{(k-1)}=(h^{(k-1)}_1,h^{(k-1)}_2)
```
の値（2次元の点（ベクトル））になっていたとします。この値を$W^{(k)}$と$b^{(k)}$をパラメータとする（1）式ででアフィン変換して

```math
a^{(k)}=(a^{(k)}_1,a^{(k)}_2)
```
となります。この変換を2次元の座標系でプロットすると次の図になります。活性化関数$f$を通す前です。
<div align="center">
<img width="50%" alt="hk-1からak.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/cbedc86b-42d0-e4a0-bf94-3319880b6ef1.png">
</div>
アフィン変換は回転、拡大縮小、平行移動に分解できるので、$w^{(k)}=U_r\Gamma V_r$と分解できるとすると、この変換は次の図のように分解できます。
<div align="center">
<img width="80%" alt="hk-1からak分解.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/b5690132-29ee-a6a9-c136-bfde0c50f1d9.png">
</div>
###中間層：活性化関数パート
続いて$a^{(k)}$に活性化関数として、ここではReLUにより変換します。ReLUは前の図でも示すように、正の値はそのまま、負の値はゼロに変換する処理です。今の例では$a^{(k)}$は第一象限にあり、要素はすべて正の値なので点の位置は変化しません。次の図に示すように、$a^{(k)}$に負の値の要素があると第一象限の境界（座標軸）に投影した位置に変換されます。$a^{(k)'}$は$h_1$要素が負の値なので$h_2$軸上に、$a^{(k)''}$はすべての要素の負値なので原点に変換されます。
<div align="center">
<img width="50%" alt="hk-1からakReLU.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/9298ba68-f3a6-9ae0-16c9-470f3f36833b.png">
</div>
###出力層と評価関数（LOSS）
中間層で計算をしていった結果最後の第l層の出力がネットワークの出力$\hat{y}$になったとします。その入力でネットワークに出力してほしかった正解が$y$だとすると、その関係は次の図に示すようになり、二乗誤差を損失関数とすると、2点間の距離が損失となります。
<div align="center">
<img width="40%" alt="出力層.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/bde3d0ad-870a-df80-0715-70b918a6f9d6.png">
</div>
中間層の重み$W, b$（つまり回転量、拡大量、平行移動量）を変更すると、出力$\hat{y}$の位置が変わります。なるべくこの距離$J$が小さくなるように中間層の重み$W, b$を調節します。
##ミニバッチの入力
###中間層（第k層）への入力
同じノード数2のネットワークに複数の入力データと正解のペアからなるミニバッチを入力した時の第k-1層の状態を次の図に示します。青点1個が1個のデータに対応し、入力から第k-1層まで計算した結果の値をプロットしたものです。第k-1層のReLUの出力なので、点はすべて第1象限か座標軸上にあります。
<div align="center">
<img width="30%" alt="MBhk-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/d0cd3f45-462d-7d72-af4a-6a69f25f9d12.png">
</div>
###中間層での計算
この$h^{(k-1)}$のそれぞれのデータ（状態）を$W^{(k)}, b^{(k)}$でアフィン変換し活性化関数（ReLU）で変換したのが次の図です。

1. アフィン変換１：回転　例では原点を中心に左へ約30deg回転しています
1. アフィン変換２：拡大縮小　$h_1$（横）方向に約20%縮小、$h_2$（縦）方向に約50%拡大。ここで、元の座標軸は垂直でなくなります
1. アフィン変換３：回転　原点を中心に右へ約20deg回転
1. アフィン変換４：平行移動　左下へ平行移動
1. 活性化関数（ReLU）：負の要素の値をゼロにするので、第一象限以外の点は第一象限へ投影されます
![MBaffin1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/11d61b26-78bb-1630-2069-e0dfdb321111.png)
![MBaffin2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/aace7327-d4dc-e1af-1c7a-a39473c89ea7.png)

####中間層の入出力データ
第k層の入出力データの分布を取り出すと次の図になります。このような変換を重ねることによってデータが望ましい分布になるようにパラメータ$W,b$を調整します。例えば、猫画像と犬画像を区別する課題において、図のオレンジの点が猫の画像、青い点が犬の画像だとすると、各層での変換を重ねて最終的に（次の節で説明する）出力層で区別しやすい分布のパターンになるようにパラメータを調整します。
<div align="center">
<img width="70%" alt="MBio.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/e794064c-8ce4-2851-4069-de3523501358.png">
</div>
アファイン変換は回転と拡大縮小ぐらいしか形を変えないので点の間の関係はそれほど変わりません。活性化関数（ReLU）の作用によって分布の形は大きく変わっています。このページでは図の中に収めるためにそれほど大きくマイナス側の値を作れていないので、あまり実感できないかもしれません。実際の計算では大きな負の値でもゼロに変えられてしまうので大きく位置が動くことになります。
###出力層
前節で出た猫画像と犬画像を区別する課題において、学習画像のミニバッチを入力した時の理想的な出力を次の図に示します。オレンジの点と青い点が線形分離可能な配置に（1本の線で切り分けられるように）変換されることが目標です
<div align="center">
<img width="40%" alt="MBout.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535482/629d701d-8e08-b6ea-797b-39421d600e84.png">
</div>
#まとめ
　ニューラルネットの計算を図形的に描いてみるといった説明を見たことがなかったので、作ってみました。このように図にしてみることで考えやすくなるネットワークの挙動もあるのではないでしょうか？　バッチ正則化などの理解には役立ちそうです。
　この図を描いてみて思うのは、ReLUの乱暴さ（強力さ）です。2次元での説明なので第1象限は全空間の1/4ですが、3次元では1/8、N次元では$1/2^N$の空間にReLUによってデータを押し込むことになってしまいます。
　間違いなどありましたらご指摘ください。特にアフィン変換を特異値分解を通して回転と拡大縮小（負の倍率は反転を示す）に分解できるという資料は無かったのであまり自信がありません。
　類似の説明を見つけました[1]
#参考文献
[1] ITエンジニアのための機械学習と線形代数入門. Software Design, 2019.1月号:18-57