深層学習 Day 2 - Section 3 過学習 のまとめ

この記事は個人的なお勉強用のメモです。

# このお勉強の位置

深層学習 Day 2

Section 1 勾配消失問題
Section 2 学習率最適化手法
**Section 3 過学習**　←　これ
Section 4 畳み込みニューラルネットワークの概念
Section 5 最新のCNN

# 講義

## 過学習とは

テスト誤差と訓練誤差とで学習曲線が乖離すること。

原因
・パラメータの数が多い
・パラメータの値が不適切
・ノードが多い

言い換えると、ネットワークの自由度が高いのが過学習の原因。

## 正則化

正則化とは、ネットワークの自由度を制約すること。（ルールを設けること）
制約すると、過学習を防げる。

- L1正則化
- L2正則化
- ドロップアウト

データを水増しすると同じ傾向のデータになるため、過学習しやすい。
CNN 畳み込みとか。ドロップアウトがよく使われる。

## Weight decay（荷重減衰）

重みが大きい値をとると、過学習が発生することがある。
重みが大きいということは、そのデータを重要視するということ。
重みの抑制が重要。

## L1,L2正則化

```math
E_n(w)+\frac{1}{p}\lambda ||x||_p\\
```

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

```math
||x||_p=(|x_1|^p+...+|x_n|^p)^{\frac{1}{p}}
```

p=1：L1正則化（絶対値の和）
p=2：L2正則化（二乗和）

L1,L2正則化の適用方法
1. ある層上の複数の重みに対してpノルムを計算する。
2. 他の層に対しても同様の計算をする。
3. すべての層のpノルムを足し算する。
4. 3.で求めたpノルムに係数をかけて、誤差関数に加える。


## ドロップアウト

ランダムにノードを削除。
しきい値を超えないノードは不活性化。
これにより学習を抑制（過学習の防止）。

メリット
・データ量を変えずに、異なるモデルを学習させていると解釈できる。

## 例題チャレンジ

### L2正則化でパラメータの更新を行うプログラム

```python
def ridge(param, grad, rate):
  grad += rate * param
```

param、が正解。

np.sqrt(np.sum(param**2))が正解かと思ったが、それは誤り。
pパラムを加えるのは誤差関数に対して。
その誤差関数を微分することによって、誤差関数の勾配を最小にするため、
pパラムを微分する必要がある。

つまり、誤差関数に||param||^2の勾配を加えるので
重みを更新するプログラムとしては||param||^2を微分した値が正解。
（係数の2は正則化の係数に吸収される）

### L1正則化でパラメータの更新を行うプログラム

```python
def lasso(param, grad, rate):
  x = sign(param)
  grad += rate * x
```

sign(param)、が正解。(-1, 0, 1 といった符号が返る）

L2と同じように考える。
|param|の勾配を加える、とのことなので
|param|を微分した値が正解。


### データ集合の拡張（水増し）

```python
def random_crop(image, crop_size):
  h, w = image.shape
  crop_h, crop_w = crop_size
  top = np.random.randint(0, h - crop_h)
  left = np.random.randint(0, w - crop_w)
  bottom = top + crop_h
  right = left + crop_w
  image = image[top:bottom, left:right, :]
  return image
```

外部仕様
imageの形式は (縦幅, 横幅, チャンネル）
出力される画像の縦幅と横幅を指定する。

# 実装演習

### L2,L1正則化

#### 正則化なし

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/d43b4936-15a9-c301-6d0a-45b5184dc48e.png)

訓練データに対する正解率(Accuracy)が1になっている。
つまり、過学習の状態。

#### L2正則化（weight_decay_lambda=0.1）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/e5e6ad0b-c9a9-8808-672d-f186ad5ccb00.png)

正則化なしに比べて過学習は抑制できている。
しかし、テストデータに対する正解率は低いまま。
これだけでは過学習を抑制してもメリットは感じられない。

#### L1正則化（weight_decay_lambda=0.1）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/667a6e0b-5421-003f-d18e-705b2c8c706a.png)

こちらも過学習を抑制できている。
線がジグザグになっているのは、パラメータがゼロになることによって
学習率の低下が目に見えて現れたということだろうか。

#### L2正則化（weight_decay_lambda=0.2）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/cd300c40-6203-fc9b-bc13-18a072c68220.png)

weight_decay_lambdaを0.1から0.2にしたところ、
学習データとテストデータの両方で、正解率が学習中に低下してしまった。
これは制約が強すぎたということか。

適切なパラメータに調整するのは難しい。
試行錯誤が必要。

### ドロップアウト（dropout_ratio=0.15）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/f5c30651-e47e-eae5-c580-4fa0db652677.png)

まるで学習できていない。
dropout_ratio=0.9の場合、最初から最後までまるで学習しない。
dropout_ratio=0.2の場合、0.1とほぼ同じ。
dropout_ratio=0.01の場合、0.15のときよりはましだが、この場合も途中から正解率が落ちていく。

dropout_ratioだけの変更で正解率を上げるのは難しい。

### ドロップアウト（use_drop=False）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/00a325d4-ce2d-faf7-acef-f047ab3186db.png)

そもそもドロップアウト無しの状態で過学習が発生していない。
実装演習としては過学習が発生している状態にしてから
ドロップアウト有りを試すのがよかったかもしれない。

### ドロップアウト＋L1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810819/521fe867-5526-568a-3e0c-f22f2e286106.png)


過学習を抑制しつつ、テストデータに対する正解率を高くできた。

実務では仮説を立てつつ実行してみるのが重要。
仮説と実際の結果を比較して考察する。

# 確認テスト

### リッジ回帰の特徴

- ハイパーパラメータを大きくすると、すべての重みが限りなく0に近づく。  
ハイパーパラメータが大きいということは制約を強くするということ。  
制約が強くなるというのは重みが0に近づくこと。
- リッジ回帰は元々線形回帰であり、ハイパーパラメータを0にしても線形回帰のまま。
- バイアス項は正則化されない。
- 隠れ層ではなく誤差関数に対して正則化項を加える。

右上に楕円がある、あのグラフがリッジ回帰。
(0,0)を中心とした円を描く。
重みは、この円の上(円の中も？)だけで値をとれる。
これを制約と言っている。

### L1正則化を表すグラフ

(0,0)を中心とした四角の方のグラフが、L1正則化。

L1：スパース推定
　　重みがちょっとした値でも存在すると、シグモイド関数とかの計算リソースがかかるが、
　　重みがゼロなら計算リソースはゼロ。
L2：縮小推定
　　計算リソースは減らないが精度は高い。

# 修了テスト～練習問題～

終了テストに過学習に関する問題なし。

代わりに、赤本 6.4 節で勉強。
過学習を抑制するとテストデータでの訓練精度が下がる（ことがある）が、
下がることを問題視するのではなく、学習データとテストデータとで
学習精度の隔たりが小さくなることが重要。