Rabbit Challenge レポート(深層学習 DAY2)

#1. 勾配消失問題

## 勾配消失問題とは

誤差逆伝播法が下位層に進んでいくにつれて、勾配がどんどん緩やかになっていく。

そのため勾配降下法による更新では下位層パラメータは殆ど変わらず、訓練は最適値に収束しなくなる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/78159f6a-369c-3aa3-cb77-fb080513d5b2.png)


## 勾配消失の解決方

### 活性化関数の選択

- ReLU関数を利用

### 重みの初期値設定

- Xavier
  - 初期値を設定する際の活性化関数
    - ReLU関数
    - シグモイド関数
    - 双曲線正接関数
  - 初期値の設定方法
    - 重みの要素を、前の層のノード数平方根で除算した値

```
self.params['W1'] = np.random.randn(input_size, hidden_size) / nq.sqrt(input_layer_size)
self.params['W2'] = np.random.randn(hidden_size, output_size) / nq.sqrt(hidden_layer_size)
```

- He
  - 初期値を設定する際の活性化関数
    - ReLU関数
  - 初期値の設定方法
    - 重みの要素を、前の層のノード数の平方根で除算した値に対し、√2を掛け合わせた値

```
self.params['W1'] = np.random.randn(input_size, hidden_size) / nq.sqrt(input_layer_size)*np.sqrt(2)
self.params['W2'] = np.random.randn(hidden_size, output_size) / nq.sqrt(hidden_layer_size)*np.sqrt(2)
```

### バッチ正規化

ミニバッチ単位で、入力値のデータの方よりを抑制する手法

活性化関数に値を渡す前後に、バッチ正規化の処理を孕んだ層を加える

$ \mu_1 = \frac{1}{N_t}\sum_{i=1}^{N_t} x_{ni}$

$ \sigma_t^2 = \frac{1}{N_t} \sum_{i=1}^{Nt}(x_{ni}-\mu t)^2$

$\hat{x_{ni}} = \frac{x_{ni}- \mu _t}{\sqrt {\sigma _t^2 + \theta }}$

$y_{ni} = \gamma x_{ni} + \beta $

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/1c4fa586-f712-d961-fdc5-5314b51dda72.png)


## 演習

### シグモイド関数を利用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/5aafb1ac-759c-87e8-37fa-04852d4d839b.png)

勾配消失が起きていることが分かる

### ReLU関数を利用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/66b0cbd8-6163-96f7-2ff2-e74b200589c3.png)


シグモイド関数を利用した際と比較すると、かなり良い結果が出ていることがわかる

### シグモイド関数、Xavierを利用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/1d7f1899-9e97-69ab-b28b-9dd19559fba7.png)


単純にシグモイド関数を利用した際と比較すると勾配消失が起こっていないようにみえる

### ReLU関数、Heを利用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/4b07e7c5-bf58-f3c5-d599-b18d642852e1.png)


単純にReLUを利用した際と比較すると、テスト試行回数が少ない時点でかなり制度が出ているようにみえる

# 2. 学習率最適化手法

## モメンタム

誤差をパラメータで微分したものと、学習率の積を減算した後、現在の重みに前回の重みを減算した値と慣性の積を加算する

$ V_t = \mu V_{t-1} - \epsilon \nabla E $

```
self.v[key] = self.momentum* self.v[key] -self.learning_rate* grad[key]
```

$w^{(t+1)} = w^(t) + V_t$

```
params[key] += self.v[key]
```

慣性: $\mu$

メリット

- 局所的最適解にはならず、大域的最適解となる
- 谷間についてから最も低い位置にいくまでの時間が早い

## AdaGrad

誤差をパラメータで微分したものと再定義した学習率の積を減算する

$ h_0 = \theta $

```
self.h[key] = np.zeros_like(val)
```

$h_t = h_{t-1} + (\nabla E)^2$

```
self.h[key] += grad[key] * grad[key]
```

$w^{(t+1)} = w^{(t)} -\epsilon \frac{1}{\sqrt {h_1} + \theta }$

```
params[key] -= self.learning_rate* grad[key] / (np.sqrt(self.h[key]) + 1e-7)
```

メリット

- 勾配の緩やかな斜面に対して、最適地に近づける

課題

- 学習率が徐々に小さくなるので、鞍点問題を引き起こす事があった

## RMSProp

誤差をパラメータで微分したものと再定義した学習率の積を減算する

$ h_t = \alpha h_{t-1} + (1- \alpha )(\nabla E)$

```
self.h[key] *= self.decay_rateself.h[key] += (1 -self.decay_rate) * grad[key] * grad[key]
```

$w^{(t+1)} = w^{(t)} -\epsilon \frac{1}{\sqrt {h_1} + \theta } \nabla E$

```
params[key] -= self.learning_rate* grad[key] / (np.sqrt(self.h[key]) + 1e-7)
```

メリット

- 局所的最適解にはならず、大域的最適解となる
- ハイパーパラメータの調整が必要な場合が少ない

## Adam

これらの特徴をもつ最適化アルゴリズム

- モメンタムの過去の勾配の指数関数的減衰平均
- RMSPropの過去の勾配の二乗の指数関数的減衰平均

メリット

上記特徴を持つことがメリット

## 演習

### SGD

学習率0.01

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/b1060bff-5588-3f76-6bf5-e54099823422.png)


学習率0.05

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/358b2df2-7c76-a836-52bb-ad015385d2e2.png)


学習率を5倍にしてみたが、トレインデータの正答率は上がったものの、テストデータへの影響はないことがわかった

### Momentum

momentim = 0.9（一般的な値)

学習率0.01

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/687d8aee-df31-cbad-4a57-215358ca90d2.png)


学習率0.1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/f9b052d4-4447-b590-896b-c26e8fcbba98.png)


学習率を10倍に上げることで大きく変化が見られた。更に調整を行えばよりよい結果が得られるかもしれない

### AdaGrad

学習率0.0.1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/9698abf9-0264-3410-ee0f-c1c1730eb870.png)


### RSMProp

学習率0.01

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/3c65efb3-f841-70a2-fdfc-66a8f1212bdf.png)


他の結果と大きく差が出ていることがわかる。特徴であるハイパーパラメータのチューニングが不要ということがその理由だろうか。

# 3.過学習

## 正則化とは

ネットワークの自由度（層数、ノード数、パラメータの値)を制約すること

⇒　過学習を抑制できる

## Weight decay (荷重減衰)

過学習の原因

- 重みが大きい値をとる事で、過学習が発生することがある

過学習の解決策

- 誤差に対して正則化項を加算することで重みを抑制する

## L1,L2正則化

$ E_n(w) + \frac{1}{p}\lambda || x || _p$ 誤差関数にpノルムを加える

```
np.sum(np.abs(network.params['W' + str(idx)]))
```

$||x||_p =  (| x_1|^p + ... + |x_n|^p)^{\frac{1}{p}}$ pノルムの計算

```
weight_decay+= weight_decay_lambda*np.sum(np.abs(network.params['W' + str(idx)]))loss = network.loss(x_batch, d_batch) + weight_decay
```

p=1: L1正則化

p=2: L2正則化

## ドロップアウト

ランダムにノードを削除して学習させること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/2c013963-4950-40d4-0ef9-f0a16f9abe4e.png)


メリット

データ量を変化させずに、異なるモデルを学習させていると解釈できる

## 演習

### L2正則化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/7401102c-11bf-21ad-04bb-2cc6668bc62f.png)


### L1正則化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/ac8d8d82-ead8-8f44-a14e-a9c45fc5e5ce.png)


#### [try] weigth_decay_lambdaの値を変更して正則化の強さを確認しよう

```
weight_decay_lambda = 0.50
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/a257a80f-b9cb-3362-a345-34b75d171a57.png)

```
weight_decay_lambda = 0.01
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/4259432c-f043-eddd-06d6-daa51d41eb65.png)


大きすぎると勾配消失し、小さすぎると勾配爆発しているように読み取れる

### Dropout

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/af39a709-e7dc-a3a3-9b72-1e5b853e8a7b.png)


過学習が抑制されており、良い精度が出ていることがわかる。

#### [try] dropout_ratioの値を変更してみよう

```
dropout_ratio = 0.20
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/d0deb4f2-33c7-4299-04ee-2a484b95ea09.png)


精度の上昇が緩やかになり、最終的には過学習が起こってしまっている

[try] optimizerとdropout_ratioの値を変更してみよう

```
dropout_ratio = 0.20

optimizer = optimizer.Adam()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/eaa6e68d-a9a0-22d9-bf00-0e94aa867623.png)


先ほどと比較すると良い結果になっているが、やはり過学習が起こってしまっている。

dropout_ratioが高すぎるとこういう結果に近づくと思われる

### Dropout + L1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/1239cf7c-1e1f-4e13-c3a2-212a56f18839.png)


L1のみの時と比べて精度がわずかに上昇していることがわかる

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

CNNの構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/69b20ff9-4281-985f-7ad1-39dbf7ae8869.png)


畳み込み層の全体像

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/8c2e0921-f7f2-8b49-7e37-85c08df8da32.png)

## 畳み込み層

畳み込み層では、画像の場合、縦、横、チャンネルの3次元データをそのまま学習し、次に伝える事が出来る

⇒　3次元の空間情報も学習できるような層が畳み込み層である

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/b66ae067-5689-90ac-ca1f-dc1d37ebb516.png)


### バイアス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/b2a05bcd-86c2-ec0e-7c43-c5f37439bdd3.png)

### パティング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/f5d947e7-19fa-470d-0261-bbcba4ffa388.png)


入力画像や出力画像の大きさを合わせたり、大きくしたりなどの操作が可能

外周に0などの要素を加えた後に、フィルターの計算を行う

### ストライド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/55e79e54-dc22-d6bc-2994-facbcdfd8a39.png)


フィルターが移動する幅。2だった場合はその数字分動かして計算を行う

### チャンネル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/a53be426-b84d-e37d-32de-7e9c10dabf82.png)


奥行きをチャンネルとして、そのチャンネル数分フィルターを用意して計算を行う

## プーリング層

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/61b6d146-34d7-9648-b604-4fa3d32be51d.png)

## 演習

### im2col

画像データを二次元データへ変換

```
========== input_data ===========
 [[[[51. 68.  4. 71.]
   [79. 51. 77. 10.]
   [20. 81. 27. 38.]
   [64. 27. 20. 37.]]]


 [[[80. 95. 22. 91.]
   [16. 21. 72. 57.]
   [41. 96. 57. 77.]
   [20.  6. 53. 19.]]]]
==============================
============= col ==============
 [[51. 68.  4. 79. 51. 77. 20. 81. 27.]
 [68.  4. 71. 51. 77. 10. 81. 27. 38.]
 [79. 51. 77. 20. 81. 27. 64. 27. 20.]
 [51. 77. 10. 81. 27. 38. 27. 20. 37.]
 [80. 95. 22. 16. 21. 72. 41. 96. 57.]
 [95. 22. 91. 21. 72. 57. 96. 57. 77.]
 [16. 21. 72. 41. 96. 57. 20.  6. 53.]
 [21. 72. 57. 96. 57. 77.  6. 53. 19.]]
==============================

```

### col2im

変換された二次元データを画像へ変換

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/41452f93-0066-0951-1c85-dae27e71d675.png)


この方法では同じものに戻らない事が分かった

### CNN

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/ffb9199e-7bf6-224e-80b2-45abf34802f6.png)

最終的に0.95と、悪くない精度がでた。

CNNは今まで実行してきた処理よりも体感できるほど時間がかかることが分かった

# 5.最新のCNN

## AlexNet

5層の畳み込み層およびプーリング層など、それに続く3層の全結合層から構成される

サイズ4096の全結合層の出力にドロップアウトを使用している

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/163092aa-2872-cfae-590c-89d1f51e286e.png)

他にどういうものがあるのか調査

## VGG

AlexNetをより深くしたもので、畳み込み層や全結合層を16or19層重ねたもの

小さいフィルター何度も畳み込む方法が特徴的

## ResNet

勾配消失や発散を防ぐことができるスキップ構造を利用して152層を実現。

# 確認テスト

## 確認テスト1-1

Q.連鎖率の原理を使い、dx/dzを求めよ

$ z=t^2$

$t=x +y$

A.

$ \frac{\partial z}{\partial x} = \frac{\partial z}{\partial t} \frac{\partial t}{\partial x} = 2t *1 = 2(x+y)$

## 確認テスト1-2

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

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

A. (2)

## 確認テスト1-3

Q. 重みの初期値に0を設定するとどのような問題が発生するか

A. すべての重みが同じになり、チューニングが正しく行えない

## 確認テスト1-4
Q. 一般的に考えられるバッチ正規化の効果を2点挙げよ

A. 勾配消失が起こりづらい、計算が高速。

## 確認テスト2-1

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

A.
モメンタム: 大局的局所解を見つける

AdaGrad: 勾配が緩やかでも最適解が見つけられる

RMSProp: 大局的局所解を見つけやすい、ハイパーパラメータの調整が必要ない場合が多い

## 確認テスト3-1

Q．機械学習で使われる線形モデルの正則化は、モデルの重みを制限することで可能となる。

前述の線形モデルの正則化手法の中にリッジ回帰という手法があり、その特徴として正しいものを選択しなさい

(a)ハイパーパラメータを大きな値に設定すると、すべての重みが限りなく0に近づく

(b)ハイパーパラメータを0に設定すると、非線形回帰となる

(c)バイアス項についても、正則化される

(d)リッジ回帰の場合、隠れ層に対して正則化項を加える

A.　(a)

## 確認テスト3-2

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960917/342f957e-4123-bb10-8c7f-cc5b451c3f21.png)


A. 右図

補足: 左図RidgeはL2正規化, 右図LassoはL1正規化

## 確認テスト4-1

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

A. 7×7

$OH = \frac{6 + 2*1 - 2)}{1} + 1 = 7$

$ OW = \frac{6 + 2*1-2)}{1} + 1 = 7$