日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その３）

[ラビットチャレンジ](http://ai999.careers/rabbit/)のＥ資格講座、いよいよディープラーニングに入ります。
[![card.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/8e9be486-3440-a3d1-db0c-2b7866601b10.png)
](http://ai999.careers/rabbit/)

[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その１）](https://qiita.com/awasirom/items/6cce5ca6d9c446edb2a4)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その２）](https://qiita.com/awasirom/items/8a4e91d0cd024dff6df3)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その４）](https://qiita.com/awasirom/items/2c97f3186ffbe2466dd8)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その５）](https://qiita.com/awasirom/items/f8e9c0895f5d69fef3a2)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その６）](https://qiita.com/awasirom/items/0858abc1daddd7b33797)

---

ディープラーニングは更にＤａｙ１～Ｄａｙ４にわかれていて、Ｄａｙ１は以下の５つのセクションからなります。セクションの構成は以下の通り。

Section1：入力層～中間層
Section2：活性化関数
Section3：出力層
Section4：勾配降下法
Section5：誤差逆伝播法

#Section1：入力層～中間層

最初の中間層への総入力$u$は、

```math
u = W\boldsymbol{x}+b\\
```

$W$：重みのベクトル
$\boldsymbol{x}$：入力値のベクトル
$b$：バイアス

**順伝播の実装演習**

[http://espj.web.fc2.com/1_1_forward_propagation-Day1-DN06.html](http://espj.web.fc2.com/1_1_forward_propagation-Day1-DN06.html)
[http://espj.web.fc2.com/1_1_forward_propagation-Day1-DN08.html](http://espj.web.fc2.com/1_1_forward_propagation-Day1-DN08.html)


#Section2：活性化関数

- 次の層への出力の大きさを決める非線形の関数
- 入力値によって次の層へのON/OFFや強弱を定める

####中間層用

- **ステップ関数**　
    - パーセプトロンで使われた。ディープラーニングでは使われない。
    - ON/OFFのみ。強弱が伝えられない。 

```math
f\left( x\right) =\begin{cases}1 & (x \geqq 0) \\\\ 0 & (x \leq 0)\end{cases}
```

- **シグモイド（ロジスティック）関数**
    - 強弱が伝えられるようになった。
    - 予想ニューラルネットワーク普及のきっかけとなった。
    - 勾配消失問題があった。

```math
f(u) = \frac{1}{1+e^{-u}}\\
```


- **ReLU関数**
    - 勾配消失問題を回避しスパース化に貢献
    - 現在、最も使われている

```math
f\left( x\right) =\begin{cases}x & (x \geqq 0) \\\\ 0 & (x \leq 0)\end{cases}
```

出力層用活性化関数は次セクションで。

#Section3：出力層

####出⼒層の役割

中間層までは人が理解できない数値だが出力値には意味がある。
例えば、犬、猫、ネズミの分類問題ならこんな感じ。

正解値：犬･･･1 　　猫･･･0　　　 ネズミ･･･0
予測値：犬･･･0.82　猫･･･0.07　　ネズミ･･･0.11　←　犬の確率が82%

####誤差関数

以下は二乗誤差（分類では交差エントロピーを使う）。

```math
E_{n}(W)=\dfrac {1}{2}\sum ^{J}_{j=1}\left( y_{j}-d_{j}\right) ^{2}=\dfrac {1}{2}\left\| y-d\right\| ^{2}\\
```
####出力層の活性化関数

中間層では信号の強弱を調整したが、出力層では信号の大きさ（比率）は変えない。
分類問題なら確率に変換（各値：0~1、総和：1）

- **ソフトマックス関数**

```math
f(i,u) = \frac{e^{u_{i}}}{\sum_{k=1}^{K}e^{u_{k}}}\\
```

- **恒等関数**

```math
f(u) = u\\
```

- **シグモイド（ロジスティック）関数**  

```math
f(u)=\frac{1}{1+e^{-u}}\\
```

|                  |        回帰        |      二値分類      |     クラス分類     |
|:-----------------|:------------------:|:------------------:|:------------------:|
|  **活性化関数**   |      恒等関数      |   シグモイド関数   | ソフトマックス関数 |
|   **誤差関数**   |      二乗誤差      |  交差エントロピー  |  交差エントロピー  |



#Section4：勾配降下法

- **勾配降下法**

```math
W^{t+1} = W^{t} - \varepsilon \nabla E\\
\\
\varepsilon ：学習率　　\nabla E = \frac{\partial{E}}{\partial{W}}
```

これを重みとバイアスに対して何度も繰り返す。繰り返しの１回をエポックと呼ぶ。

![Section4-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/4a44bcbf-6209-988a-deb0-734366f97d68.png)

#####学習率の問題
学習率が大きすぎると収束しない（発散する）。
学習率が小さすぎると収束まで時間が掛かりすぎたり、局所的極小解から抜け出せなかったりする。

学習率の問題を改善する各種アルゴリズムには以下のようなものがある。

- Momentum
- AdaGrad
- Adadelta
- Adam

**確率的勾配降下法（ＳＧＤ）**

ランダムに選択したサンプルで誤差を計算する。

メリット
- 計算コスト削減
- 局所極小解から抜け出しやすい
- オンライン学習ができる

- **ミニバッチ勾配降下法**

ランダムに分割したデータの集合（ミニバッチ$D_{t}$）に属するサンプル対して誤差を計算し平均を取る。

＜メリット＞
確率的勾配降下法のメリットを損なわず、計算コストを削減できる。

#Section5：誤差逆伝播法

誤差勾配の計算は、数値計算（微小に値をずらしていって近似的に計算する方法）も可能だが、計算コストが高い。
誤差逆伝播法では、出力層側から前の層に向かってパラメータの微分値を解析的に計算する。

実装上のテクニックとして、出力層の活性化関数と誤差関数の組み合わせ（Sigmoidと交差エントロピー、など）で複合導関数を用意しておくとよい。

####演習問題
確率的勾配降下法で、活性化関数がReLUとSigmoid、入力値が０～１と－５～５のそれぞれの場合について試す演習。

- ReLU ０～１
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/da95b107-4b39-5108-bfe8-2398f69fca8c.png)

- Sigmoid ０～１
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e0ec7637-a8e9-3292-4d8b-a37d9abba35b.png)

上の２つからReLUの方がSigmoidより誤差が小さいことがわかる。

- ReLU －５～５  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/a548f2d9-f0c9-7c67-929f-33253433bbae.png)

途中から数値がNaNになって計算できていない。

- Sigmoid －５～５  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/a808740c-32ef-e487-5bb3-26ca3f162a4c.png)

Overflowが発生し誤差も減っていない。

#確認問題

以下は、ビデオの途中に出てくる確認テスト。

**Q1. ディープラーニングは、結局何をやろうとしているか2⾏以内で述べよ。また、次の中のどの値の最適化が最終⽬的か。全て選べ。**

①⼊⼒値[X]　②出⼒値[Y]　③重み[W]　④バイアス[b]　⑤総⼊⼒[u]　⑥中間層⼊⼒[ z]　⑦学習率[ρ]

**A1.　誤差を最小化するパラメータを発見すること。③、④**

前者はちょっと漠然とした問題で、考えられる幅が広いので、とりあえず先生の解答を書いておきました。学習の計算が行う直接的な目的を解答としたようです。最終的な目的は未知の入力データに対して十分正確な出力を行うモデルを構築することで、そのためにはモデルの選択、ハイパーパラメータの選択など、人がやることも含めて、とらえ方しだいで色んな解答が考えられると思います。

---

**Q2.　次のネットワークを紙にかけ。**

⼊⼒層︓２ノード１層
中間層︓３ノード２層
出⼒層︓１ノード１層

**A2.　下図の通り。**

![確認テスト-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/5f466924-014a-2a12-f74f-4f002d8d0964.png)
---
**Q3. この図式に動物分類の実例を⼊れてみよう。**
![確認テスト-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/a67daf72-506b-949a-7cd5-06c35cce8313.png)

**A3. 下図の通り。**

![確認テスト-03 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/283ef855-8098-60da-2e04-3c491500489b.png)

動物分類の実例は割愛していますが、上図のように７種の入力値がありました。重み、バイアスの値については記述なし。

---

**Q4. 以下の数式をPythonで書け**

```math
\begin{align}
u &= w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+w_{4}x_{4}+b\\
&=W\boldsymbol{x}+b
\end{align}
```

**A4. 自分の結果は以下の通り**

![確認テスト-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/274abff6-0893-a411-405f-b8bfb15ecb7c.png)


先生の解答は、$u1 = np.dot(x, W1) + b1$　

私は行列を仮定して転置しましたが、正解は入力$x$、重み$W1$はベクトルを仮定しているようで転置していませんでした。

---

**Q.5 1-1のファイルから中間層の出⼒を定義しているソースを抜き出せ**

ファイルは載せられませんが、順伝播のソースが与えられていて、そこから該当の箇所を抜き出す問題です。

**A5. 自分の結果は以下の通り**

![確認テスト-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/8a7efd63-2f9c-cb71-403d-5d37b9ea0ae8.png)

コメントにそのままあるので間違いようがないですが、総入力に活性化関数を掛けた部分になります。
なお、ここでは活性化関数にRelu関数を用いています。$functions.py$に色々な関数の実装があります。このコースは、サンプルソースが豊富で、素のPython、Numpyでの実装はとても参考になります。可視化の例も多いです。

---

**Q6. 線形と⾮線形の違いを図にかいて簡易に説明せよ。**

**A6. 平面で言えば、線形は直線、非線形はその他。３次元で言えば、線形は平面、非線形はその他。下図はその例。**

![確認テスト-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/d8b3ca47-2e21-c47c-5b6e-6f36a349dc25.png)

---

**Q7. 配布されたソースコードより該当する箇所を抜き出せ。**

全結合NN - 単層・複数ノード

![確認テスト-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/722b19ce-3ef5-600d-a73a-5eb7859b82fc.png)

**A7. 下図の通り。今回はSigmoid関数になっています。**

![確認テスト-07 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/532ab120-56cd-bff1-07e1-9d9e20f9dce5.png)

---

**Q8-1. なぜ、引き算でなく⼆乗するか述べよ**
**Q8-2. 下式の1/2はどういう意味を持つか述べよ**

```math
E_{n}(W)=\dfrac {1}{2}\sum ^{J}_{j=1}\left( y_{j}-d_{j}\right) ^{2}=\dfrac {1}{2}\left\| y-d\right\| ^{2}\\
```

**A8-1. 正負が打ち消しあわないように。絶対値の和でもいいが微分出来るよう二乗和とした。**
**A8-2. 微分したときに係数が１となるよう調整するため。本質的な意味はない。**

---

**Q9. ①~③の数式に該当するソースコードを⽰し、⼀⾏づつ処理の説明をせよ。**

![確認テスト-09 問題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e774c2cb-0f80-6bd8-37b1-a3b4fde356e9.png)

**A9. 下図の通り。**

![確認テスト-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/ef8ff819-47e3-5aaa-dd2a-f84053d5f9e3.png)

②、③はそれぞれ、$e^{x} → np.exp(x)$、$\sum{x} → np.sum(x)$とNumpyの関数で置き換えたもの。
値は全て$e^{x}$からなっているので正の数であり、②は③の一部なので0<①<1となり確率としてとらえることができる。
オーバーフロー対策は大きい値の影響が大き過ぎるのを防ぐため、全ての値が0以下になるように調整している。
またif文の中は行列対応で必要な転置を行っている。

**Q10. ①~②の数式に該当するソースコードを⽰し、⼀⾏づつ処理の説明をせよ。**

![確認テスト-10 問題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/7b394fb9-23ec-44ec-8205-becdd7d19235.png)

**A10. 下図の通り**

![確認テスト-10 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/a2595149-8aec-3640-f04c-18e591300104.png)

入力がベクトルで入ってきたときは１ＸＮの行列に直しています。
$\sum → np.sum()、\log → np.log()$
$np.log(y[np.arange(batch\_size), d]$は、y[行の指定、列の指定]なので、この場合は正解ラベルのインデックス値の列の全部の行についてlogをとっていることになる。1e-7を加えているのは分子が０にならないようにするための実装上の工夫。
Kerasとかを使うとき、教師データがOne-hotベクトルになるかどうかで使う関数が違ってきたりするので要注意とのことでした。

**Q11. 該当するソースコードを探してみよう。**

![確認テスト-11 問題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/875ce8e2-99f2-f290-a06e-43f03fc2b021.png)

**A11. 下図の通り。**

![確認テスト-11 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/81fff532-f107-57d3-0943-b0dae4c53be6.png)

$backward()$関数で勾配を計算して、学習率$learning$を掛けたものを引いています。

**Q12. オンライン学習とは何か2⾏でまとめよ**

**A12. 既にあるモデルの上で、データを取得しながら追加学習をしていくこと。これに対して、事前にまとまったデータで学習しておくことはバッチ学習とよぶ。**

先生は、Facebookなどで新しいユーザが入ってきたら、そのユーザについて学習する、という例を挙げていました。

**Q13. この数式の意味を図に書いて説明せよ（ミニバッチ勾配降下法について説明せよとのことらしい）。**

![確認テスト-13 問題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/57a915af-3bdb-c9a3-3ff0-6a18f8e5455d.png)

**A13. 下図の通り**
![確認テスト-13 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e6ac74c8-a094-5e9a-5dbe-b33604731760.png)

**Q14. 誤差逆伝播法では不要な再帰的処理を避ける事が出来る。既に⾏った計算結果を保持しているソースコードを抽出せよ。**

**A14. 下図の通り。**

![確認テスト-14 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/cd871320-2b5f-90ea-49eb-6b43a46602e5.png)

出力層で行った計算結果$delta2$を中間層の$delta1$の計算に使っています。

**Q15. 2つの空欄に該当するソースコードを探せ**

![確認テスト-15 問題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/4aae2d02-2704-27cf-ee17-90d7525421a4.png)

**A15. それぞれ以下の箇所になる。**
![確認テスト-15 解答.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/79b581bd-275f-7ccf-276c-83749f0f6b4a.png)

活性化関数は恒等写像なので、$\frac{\partial{y}}{\partial{u}} = 1$。したがって、2番目の式は最初の式と同じ$delta2$

$\frac{\partial{u}}{\partial{w_{ji}^{(2)}}} = z1$なので、２番目の式は$z1$と$delta2$の内積になる。