日本ディープラーニング協会 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/df745bc67a6ca3c24ce4)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その５）](https://qiita.com/awasirom/items/f8e9c0895f5d69fef3a2)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その６）](https://qiita.com/awasirom/items/0858abc1daddd7b33797)

---

セクションの構成は以下の通り。

Section1：勾配消失問題
Section2：学習率最適化手
Section3：過学習
Section4：畳み込みニューラルネットワークの概念
Section5：最新のCNN


#Section1：勾配消失問題

**勾配消失問題とは**

誤差逆伝播法で下位層に進むにつれ（出力層から入力層へ向けて）、勾配が緩やかになり、パラメータの更新が進まなくなること。

**原因**

シグモイド関数を使うと、微分値は最大でも0.25。逆伝播していくとこれが掛け合わされていくことになり、勾配消失の原因のひとつとなっていた。

**解決策**

- 活性化関数の選択
- 重みの初期値設定
- バッチ正規化

####活性化関数の選択

Sigmoid関数に変わって**ReLU関数**が用いられるようになった。
大きな値に対してもそのまま伝えるので勾配消失しにくい。

####重みの初期設定

**Xavier（ザビエル）の初期値設定**

＜計算方法＞
前のノード数の平方根で除算

＜組み合わせる活性化関数＞
・ReLU関数
・シグモイド（ロジスティック）関数
・双曲線正接関数

**Heの初期設定**

＜計算方法＞
前のノード数の平方根で除算し$\sqrt{2}$を掛ける。

＜組み合わせる活性化関数＞
・ReLU関数（これ専用に考えられた）

####バッチ正規化

- ミニバッチ単位で入力値を正規化
- 活性化関数の前後に適用。入力値に対してではなくネットワーク内に正規化する層を設ける。

＜数学的記述＞

```math
\begin{align}
\hat{x}_{ni} &= \frac{x_{ni}-\mu_{t}}{\sqrt{\sigma_{t}^2+\theta}}\\
\\
y_{ni} &= \gamma x_{ni}+\beta\\
\end{align}
```

$\gamma$ : スケーリングパラメータ
$\beta$  : シフトパラメータ

逆伝播ではこれらのパラメータを最適化する。

####演習問題

初期値、活性化関数、ノード数を色々と変えて学習させてみました。
sigmoid-gaussは学習が進みません。全くダメかと思ったらノード数784,784にしたら学習しだしました。
ReLU-XavierとReLU-Heはどちらも良い結果になりました。

![2_2_1_vanishing_gradient-Day2-23_演習.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/810e8b94-394e-f2a4-a77a-7ad511ffdb7b.png)


#Section2：学習率最適化手法

勾配降下法における学習率には、

- 大きすぎると発散してしまう。
- 小さすぎると時間が掛かる。局所的最適解から抜け出せない可能性が高くなる。

といった問題があった。それらを解決する手法が学習率最適化手法で、以下のようなものがある。

- モメンタム
- AdaGrad
- RMSProp
- Adam

####モメンタム

```math
\begin{align}
V_{t} &= \mu V_{t-1}-\epsilon \nabla E\\
w^{(t+1)} &= w^{(t)}+V_{t}\\
\\
慣性：\mu\\
\end{align}
```

$\epsilon \nabla E$を減じるだけでなく、前回の更新分の一定割合を加えてやる。

####AdaGrad

```math
\begin{align}
h_{0} &= \theta\\
h_{t} &= h_{t-1}+(\nabla E)^{2}\\
w^{(t+1)} &= w^{(t)}-\epsilon \frac{1}{\sqrt{h_{t}}+\theta} \nabla E \\
\end{align}
```

- 緩やかな斜面に対して最適値に近づける。
- 鞍点問題を引き起こすことがある。

####RMSProp

```math
\begin{align}
h_{t} &= \alpha h_{t-1}+(1-\alpha)(\nabla E)^{2}\\
w^{(t+1)} &= w^{(t)}-\epsilon \frac{1}{\sqrt{h_{t}}+\theta} \nabla E \\
\end{align}
```

- 局所最適解にはならず大域的最適解となる。
- ハイパーパラメータの調整があまり必要ではない。


####Adam

モメンタム、RMSPropの特徴、メリットをもっている。

Adamも問題があり現在でも新しい最適化手法が生まれているようです。
[[最新論文] 新しい最適化手法誕生! AdaBound & AMSBound](https://qiita.com/Phoeboooo/items/f610affdcaaae0a28f34)

#####演習問題

**2_4_optimizer**
＜SGD＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/c3eff72b-f9eb-78f1-a6bc-1334255c5858.png)

<Momentum>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/5a07e067-6812-413f-54cf-e2bcfba5f569.png)

＜MomentumをAdaGradに変更＞

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/0e4835ee-669d-4302-35c5-69e9297965d4.png)

この部分に関する実装の問題。
以下のMomentumのプログラムをAdaGradに書き換える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/921f805d-55a3-3ede-2233-b20b15259b68.png)

私の解答
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/4bdab35f-9820-ee02-7887-dbfcd51d59f2.png)

正解
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/91fcf93f-205c-b96b-4f7e-2e08068757f1.png)

np.full_like()というのもあった。

実行結果（learning_rate=0.1）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/440d2465-178e-49a6-7fd8-b71abb4ead1f.png)


#Section3：過学習

####過学習

訓練誤差は小さくなるがテスト誤差が大きいままの状態。

＜原因＞
ネットワークの自由度（層数、ノード数、パラメータの値）が高すぎる。その結果、訓練データに過度に適合しすぎてしまう。

####正則化

- Ｌ１正則化、Ｌ２正則化
- ドロップアウト

**Ｌ１正則化、Ｌ２正則化**

重みが大きい値を取ると過学習が発生することがある。正則化は重みを抑制する方法。

```math
E_{n}(W)+\frac{1}{p}\lambda || x ||_{p}\\
||x||_{p} = (|x_{1}|^{p}+...+|x_{n}|^{p})^{\frac{1}{p}}
```

$p = 1$ : Ｌ１正則化
$p = 2$ : Ｌ２正則化

Ｌ３以降もある。

**ドロップアウト**

ノードが多いことも過学習の原因。ドロップアウトはランダムにノードを削除して学習させる方法。

異なるモデルを学習させていると解釈できる。

####演習問題

2_5_overfitingの実行結果

＜正則化なし＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/5c0b2318-6796-11f1-f98b-73e816fa17a4.png)

学習データの正解率がほぼ100％で張り付いて過学習が起きているのがわかる。

＜Ｌ２正則化＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e06f2768-e135-2718-b1c3-1e8e6ecd68d6.png)

学習データの正解率が引き下げられて過学習が抑制されている。

＜Ｌ１正則化＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/d18d5d8f-ed20-30ea-069e-0abba9377ce0.png)

形は複雑だが、やはり学習データの正解率が引き下げられている。

以下はＬ１、Ｌ２正則化においてハイパーパラメータを変えてみた結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/d7a8e4d7-6ae2-73d8-2d3f-7e73f12eb358.png)

＜ドロップアウト＞
以下は、Drop out ratioとOptimizerの組み合わせ。
上のOptimizerほどDorop outの効果が早く出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e88baaaf-78ac-a15a-5c8a-053ce926585a.png)

＜ドロップアウト＋Ｌ１正則化＞
dropout_ratio = 0.08
weight_decay_lambda=0.004
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/45a06e73-146f-c047-c46b-8af179017974.png)
ほどよく効いている感じがします。

#Section4：畳み込みニューラルネットワークの概念

全結合層だけでは一次元のデータとして扱うので画像の処理に弱い（少しずれた同じ画像が全く異なるデータになってしまうため）。

これを解決するために、畳み込み層やプーリング層を組み合わせた処理を、全結合層の前に加えたものが畳み込みニューラルネットワーク（ＣＮＮ）。

####畳み込み層

縦×横×チャネルの3次元を学習できる。

下図のようにフィルタを掛け合わせバイアスを加える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/13c930cf-e3a8-a6bd-facf-ab02915aaaf6.png)

**パディング**

フィルタを掛けるだけだとデータサイズが小さくなってしまう。周りにダミーのデータを埋め込んで大きくしてからフィルタを掛けることにより、元のサイズを保つことができる。これをパディングと呼ぶ。埋める値は決まっていないが出来るだけ元の画像に影響を与えないものが良い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/ef9901ec-b4d3-eaf0-8c50-3e857229863c.png)


**ストライド**

フィルタをずらして全体に掛けていくのだが、ずらす歩幅をストライドという。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/5dfd284c-472a-08a6-e111-4231819e3d93.png)


**チャネル**

縦×横のデータの枚数。普通はグレーなら１、カラーならRGBの３チャネル。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/b307f6de-c918-fb32-ed00-a064b8916586.png)

####プーリング層

対象領域をひとつの値に落とし込むのはフィルタリングと同じ。領域内の最大値をとるものが、**MAXプーリング**、平均値をとるものが**Averageプーリング**。
#####演習問題

＜im2colの動作確認＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/44714e6a-2a21-f6b9-6c01-95d54e1db309.png)

＜im2colについて＞
多次元配列を２次元配列に変換する。
メリット：行列にすることによって色々なライブラリが使える。

＜col2imgで画像に変換＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/68e9a227-1fa4-b264-41bd-5e6caa864f4f.png)

実際には戻すことはない。
また元の画像（img2colの入力値）には戻らない。

＜Simple Convolution Networkの実行結果＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/56a6655c-6d55-1134-2682-99113140d29c.png)


#Section5：最新のCNN

####AlexNet

画像認識コンテストLSVRC-2012で２位に大差をつけて優勝しディープラーニングが注目されるきっかけとなった。

＜特徴＞
５層の畳み込み層、プーリング層、３層の全結合層
ドロップアウト採用

説明は沢山載っているが、例えばこちら。
[https://news.mynavi.jp/article/architecture-371/](https://news.mynavi.jp/article/architecture-371/)


#確認テスト

#####Q1. 連鎖律の原理を使い、dz/dx を求めよ。


```math
z = t^{2}\\
t = x +y\\
```

#####A1.　以下の通り。

```math
\begin{align}
\frac{dz}{dx} &= \frac{dz}{dt}\frac{dt}{dx}\\
&=(2t)･(1)\\
&=2t\\
&=2(x+y)
\end{align}
```

#####Q2. シグモイド関数を微分した時、入力値が0の時に最大値をとる。その値として正しいものを選択肢から選べ。

(1) 0.15
(2) 0.25
(3) 0.35
(4) 0.45

#####A2. (2)

```math
\begin{align}
\sigma &= \frac{1}{1+e^{-u}}\\
\frac{d\sigma}{du} &= (1+e^{-u})^{-2}e^{-u}\\
&= \sigma(1-\sigma)
\end{align}
```
であったので、$u=0$または$\sigma=0.5$を代入して、$0.25$が解となる。
なお、入力値が0の時に微分値が最大になることは、２回微分が0となる点を求めればよい。

```math
\begin{align}
\frac{d^{2}\sigma}{du^{2}} &= \sigma'-2\sigma\sigma'\\
&= \sigma'(1-2\sigma)\\
&= \sigma(1-\sigma)(1-2\sigma)\\
\end{align}
```
より、

```math
\begin{align}
\sigma(1-\sigma)(1-2\sigma) &= 0\\
\sigma &= 0, \frac{1}{2}, 1
\end{align}
```
となり、そのときの$u$は、

```math
u = -\infty, 0, \infty
```

$-\infty$、$\infty$は、傾きが０に収束しているところで、$u=0$が傾き最大になるところである。

#####Q3. 重みの初期値に0 を設定すると、どのような問題が発生するか。簡潔に説明よ。

#####A3. 全てのノードに同じ値が伝わるので、ノードが複数ある意味がなく、学習が進まない。

これは初期値０に限った話ではなく、全て同じ値が設定されると同じ問題が発生する。また、大き過ぎても問題があり、一般的に-1.0～1.0の小さい値が良いとされている。

#####Q4. 一般的に考えられるバッチ正規化の効果を２点挙げよ。

#####A4. 以下のような効果がある。

- 勾配損失や発散を抑えられる。
- 大きな学習係数が収束速度が上がる。
- L2正則化の必要性が下がる。
- ドロップアウトの必要性が下がる。
- 初期値にそれほど依存しなくなる。

以下を参照しました。
[https://deepage.net/deep_learning/2016/10/26/batch_normalization.html](https://deepage.net/deep_learning/2016/10/26/batch_normalization.html)

先生の解答では、勾配損失の抑制と計算速度向上を挙げられていました。

#####Q5. モメンタム・AdaGrad・RMSProp の特徴をそれぞれ簡潔に説明せよ。

#####A5. 以下の通り
- モメンタム：同じ方向に加速されるので谷間についてから収束までが早い。
- AdaGrad：誤差が大きいパラメータは大きく、誤差が小さいパラメータは小さく更新する。しかし学習率が単調に減少するので、ある程度以上小さくなると学習が進まない。
- RMSProp：勾配の2乗の指数移動平均を取る（最近のものを優先する）。AdaGradの学習が進まなくなる問題を改善。

講義では、AdaGradは傾きが小さくなっても収束しやすい、RMSPropはハイパーパラメータの調整が少なくて済む、とも言っていました。

#####Q6. 
![確認テスト_問題06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/2635c307-49e6-e82f-3cfe-a20e09af5f17.png)

#####A6. 
(a) -> 正解。ハイパーパラメータが大きければ大きいほど、重みの値が誤差に与える影響が大きくなるので、誤差を小さくするためには重みが０に近づけなければならなくなる。
(b) -> 正則化項がないことと同じなので、元のモデルそのままである。
(c) -> バイアスは正則化項には含まれない。
(d) -> 正則化項は誤差に加える。

#####Q7. 下図について、L1 正則化を表しているグラフはどちらか答えよ。

![確認テスト_問題07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e167f668-bb6e-e875-7b8c-23ecae666c0e.png)

#####A7. 右

Ｌ１正則化はパラメータが０になりやすく計算コストの節約になる。精度はＬ２正則化の方良い。

#####Q8. サイズ6 × 6 の入力画像を、サイズ 2 × 2 のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なおストライドとパディングは1 とする。

#####A8. 7 × 7

各辺、パディング分（両側なので２）増え、フィルタのサイズ－１（２－１＝１）だけ減るので、６＋２－１＝７となる。