[Review] ニューラルネットワークと深層学習 CH.3 ~ニューラルネットワークの学習の改善~

① 勉強テーマ
ニューラルネットワークが深層学習へと進化していく過程
② 勉強の背景
自習の一環として、これまで深層学習のことを勉強をしてきたが、それがどういった問題から生じてきた手法であったのかの原点に立ち返ることが必要であると感じたので
③ 勉強の方法
こちらのリンクに掲載をしていただいている著者の素晴らしいリソースを拝借いたします
http://nnadl-ja.github.io/nnadl_site_ja/chap2.html
④ 期待される成果
深層学習の生まれたきっかけをつかみ、根本的な問題解決の新しい方法を見つけること

[CH.1](https://qiita.com/Rowing0914/items/5df3b7c08fc70d3047ff)はこちらです。
[CH.2](https://qiita.com/Rowing0914/items/fb55082a4fd636a816a1#4-%E9%80%86%E4%BC%9D%E6%92%AD%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%A8%E3%81%AA%E3%82%8B4%E3%81%A4%E3%81%AE%E5%BC%8F)はこちらです。

## 構成
1. クロスエントロピーコスト関数
2. クロスエントロピーコスト関数の導入
3. クロスエントロピーを使ったMNISTの分類
4. クロスエントロピーは何を意味するのか？それはどこから来たのか？
5. 過適合と正規化
6. 正規化
7. なぜ正規化で過適合が軽減されるのか？
8. その他の正規化手法
9. 重みの初期化
10. 手書き文字認識再訪：コード
11. ニューラルネットワークのハイパーパラメーターをどう選ぶのか？
12. その他の手法
13. 確率的勾配降下方のバリエーション
14. 人口ニューロンのその他のモデル
15. ニューラルネットワークに関するお話について

## 1. クロスエントロピーコスト関数
この章で説明するテクニックは以下の通りです。

- クロスエントロピー
- 正規化
    - L1/L2
    - ドロップアウト
    - 人口的な学習データの伸張
- 重みの初期化の優良なやり方
- 良いハイパーパラメーターの見つけ方

### クロスエントロピーコスト関数
一般的な二次コスト関数であると、変数ごとに偏微分をしなくてはならす、それぞれの係数より導きだされる学習スピードが遅いという問題がある。
それを克服するために、まずは殺すエントロピーコスト関数を定義して、それを最適化して行く。

### クロスエントロピー関数の導入
クロスエントロピー関数

```math
C = - \frac{1}{n} \sum_x [y \log a + (1-y)\log(1-a)]
```
where y: target, a: output of the neuron

### クロスエントロピー関数の二つの性質
1. 常に正の値を吐き出す：両方の$log$の引数が０から１までの範囲なので、その値は常に負であるが、前にマイナスがついているため、総じると常に正となる。
2. 出力$a$がターゲット関数$y$に近くなればなるほど、クロスエントロピーは０に近づく。

ここでクロスエントロピーを実際のニューロンの出力を想定して、偏微分を行い、各係数ごとにどれほど学習に寄与しているのかを確認してみる。

```math
a = \sigma(z) = \sigma(\sum_j Wx_j + b)\\
W : weight\\
b : bias\\
x : input\\
a : output\\
\frac{\partial C}{\partial w_j} = \frac{\partial C}{\partial \sigma(z)} \frac{\partial \sigma(z)}{\partial z} \frac{\partial z}{\partial w_j}\\
= - \frac{1}{n} \sum \biggl( \frac{y}{\sigma(z)} + \frac{1 - y}{1 - \sigma(z)} \biggl) \frac{\partial \sigma(z)}{\partial z} \frac{\partial z}{\partial w_j}\\
= - \frac{1}{n} \sum \biggl( \frac{y}{\sigma(z)} + \frac{1 - y}{1 - \sigma(z)} \biggl) \sigma'(z) \frac{\partial z}{\partial w_j}\\
= - \frac{1}{n} \sum \biggl( \frac{y}{\sigma(z)} + \frac{1 - y}{1 - \sigma(z)} \biggl) \sigma'(z) x_j\\
= \frac{1}{n} \sum \frac{\sigma'(z)x_j}{\sigma(z)(1 - \sigma(z))}(\sigma(z) - y)\\
= \frac{1}{n} \sum \frac{\sigma'(z)x_j}{\sigma'(z)}(\sigma(z) - y)\\
= \frac{1}{n} \sum x_j(\sigma(z) - y)\\

\frac{\partial C}{\partial b} = \frac{\partial C}{\partial \sigma(z)} \frac{\partial \sigma(z)}{\partial z} \frac{\partial z}{\partial b}\\
= - \frac{1}{n} \sum \biggl( \frac{y}{\sigma(z)} + \frac{1 - y}{1 - \sigma(z)} \biggl) \frac{\partial \sigma(z)}{\partial z} \frac{\partial z}{\partial b}\\
= - \frac{1}{n} \sum \biggl( \frac{y}{\sigma(z)} + \frac{1 - y}{1 - \sigma(z)} \biggl) \sigma'(z) \frac{\partial z}{\partial b}\\
= - \frac{1}{n} \sum \biggl( \frac{y}{\sigma(z)} + \frac{1 - y}{1 - \sigma(z)} \biggl) \sigma'(z) 1\\
= \frac{1}{n} \sum \frac{\sigma'(z)1}{\sigma(z)(1 - \sigma(z))}(\sigma(z) - y)\\
= \frac{1}{n} \sum \frac{\sigma'(z)1}{\sigma'(z)}(\sigma(z) - y)\\
= \frac{1}{n} \sum 1(\sigma(z) - y)\\
```

## 3. クロスエントロピーを使ったMNISTの分類
省略可能箇所でした。

## 4. クロスエントロピーは何を意味するのか？それはどこから来たのか？
クロスエントロピーのいい点などはこれまで見て来ましたが、一体どうやってこれを導出したのでしょうか？
ネットでは基本的にクロスエントロピーがある前提でそれの微分の説明をしている人は多くいますが、これを反対に積分をしていって、クロスエントロピーの導出を説明している人はあまり見かけませんので、ここではそれを行います。

```math
\frac{\partial C}{\partial w_j} = x_j(a - y)\\
\frac{\partial C}{\partial b} = (a - y)\\
```
は先ほど導出したクロスエントロピーの各パラメータごとの変動の仕方ですね。
さて、では、今回は学習を早くしたい！こういった形の関数があればいいなといった期待から入ります。
そこで、この関数を生み出してくれるような親となる関数を、これまでの微分の作業とは逆に積分を使用して導き出して見ます。

```math
\frac{\partial C}{\partial b} = \frac{\partial C}{\partial a} \frac{\partial a}{\partial b}\\
where \space a = \sigma(z)\\
\frac{\partial C}{\partial b} = \frac{\partial C}{\partial a} \frac{\partial a}{\partial b}\\
\frac{\partial C}{\partial b} = \frac{\partial C}{\partial a} \sigma'(z) \Longleftrightarrow (a - y) = \frac{\partial C}{\partial a} \sigma'(z)\\
Hence\\
\frac{\partial C}{\partial a} = \frac{(a - y)}{\sigma'(z)} = \frac{(a - y)}{a(1 - a)}
```
上記により、コストに対しての活性化後のニューロンの出力の変化の仕方を求めることができました。
ここから、もう一個上の階層に戻るべく、積分により、親の関数(クロスエントロピー関数)を求めて見ましょう。忘れている方は積分の公式を参照してください。https://mathtrain.jp/integral_matome

```math
\int \frac{\partial C}{\partial a} = C = \int \frac{(a - y)}{\sigma'(z)} = \int \frac{(a - y)}{a(1 - a)}\\
= (a - y) \log (a(1 - a)) = (a - y)\log(a) + (a - y)\log(1 - a) + constant\\
= a \log(a) -y\log(a) + a \log(1 - a) - y \log(1 - a) + constant\\
= 1 - y\log(a) + a \log(1 - a) - y \log(1 - a) + constant\\
where \space a \log a = 1 = (1 - a) \log (1 - a)\\
= (1 - a) \log (1 - a) - y\log(a) + a \log(1 - a) - y \log(1 - a) + constant\\
= \log (1 - a) - a \log (1 - a) + a \log(1 - a) - y \log(1 - a) - y\log(a) + constant\\
= \log (1 - a) - y \log(1 - a) - y\log(a) + constant\\
= (1 - y) \log(1 - a) - y\log(a) + constant\\
C = - [y\log(a) + (1 - y) \log(1 - a)] + constant\\
```

ここから学習データ全体の輪と平均を取ると。

```math
C = - \frac{1}{n} \sum_x [y \log a + (1-y)\log(1-a)] + constant
```

## 5. 過適合と正規化
過適合：過学習と言うことが一般的。学習に際してのパラメータが多く、トレーニングデータにおいての表現能力は高いが、テストデータや未知のデータへの汎化能力が乏しくなってしまう現象を指す。
正規化：常軌を防ぐために、意図的に学習に負荷をかけて、トレーニングデータへの適合する度合いを薄めて行くテクニック。

## 6. 正規化