ゼロから作るDeepLearning #11 - DNN！！ -

※以下の企画です

https://qiita.com/tatataichi/private/56936a028e625e62af8e

前回に続いてゼロつくを進めていきます。  
今回は第8章「ディープラーニング」の内容に入ります。  
要点をまとめつつ、ChatGPTなどの力も借りながら理解していきます。  
結構本書から離れてしまうかもですが、自分の理解のためにまとめています。

**※一応書籍的には最後の内容ですが、アドベントカレンダーの枠からははみ出ました。**

それでは頑張ります〜

# 8章 ディープラーニング
## ディープラーニングの登場
ディープラーニングは多層のニューラルネットワークを用いることで、従来の手法では難しいタスク（例えば、画像認識や自然言語処理）を高精度で解決する技術である。
本記事では以下の内容をまとめてみる。

- 多層ニューラルネットワークの特徴
- 勾配消失問題とその解決方法
- 学習効率を上げる手法

シンプルに中間層がめちゃくちゃ深くなるとDNNと言って良いのかな。ここらへんは定義がよくわからなかった。

## 勾配消失問題

ディープラーニングで発生する大きな問題の一つが **勾配消失問題** である。  
これは、活性化関数（特にシグモイド関数やtanh関数）を用いた場合に、勾配が小さくなりすぎてしまう現象を指す。

### 勾配消失の原因
1. 活性化関数の微分値が0に近づく
2. 多層ネットワークの連鎖的な微分により勾配が消える

### 解決方法
- **活性化関数の変更**: ReLU（Rectified Linear Unit）を使用
- **重みの初期化**: Heの初期化を用いる
- **Batch Normalization** を活用

#### ReLUの定義
ReLUは、入力が0を超える場合にそのまま出力し、0以下の場合は0を返す。  
計算がシンプルで勾配消失問題を軽減する。

```python
def relu(x):
    return np.maximum(0, x)
```

## 8.3 重みの初期化と活性化関数
適切な重みの初期化と活性化関数の選択は、学習の効率に大きな影響を与える。

### 重みの初期化方法
1. **標準初期化**: 勾配消失問題を引き起こしやすい
2. **Xavier初期化**: シグモイドやtanhに適している
3. **He初期化**: ReLUやその派生に適している

※chatGPT調べ

### 活性化関数の選択
- **ReLU**: 勾配消失を抑えるが、死んだノード問題に注意
- **Leaky ReLU**: ReLUの変種で負の値も微小に出力する
- **Swish**: 最近の研究で注目される活性化関数

```python:Leaky ReLUとSwish
def leaky_relu(x, alpha=0.01):
    return np.where(x > 0, x, alpha * x)

def swish(x):
    return x / (1 + np.exp(-x))
```

## 8.4 深いネットワークの効率的な学習
ディープラーニングでは、深いネットワークを効率よく学習させるために、以下の手法が活用される。

### Batch Normalization
以前の記事で述べた通り、各層の出力を正規化することで学習を安定させる。

### 残差ネットワーク（ResNet）
ResNetは、**スキップ接続** を導入することで、勾配消失問題を効果的に解決する。

#### スキップ接続の構造
```math
y = F(x) + x
```
ここで、$F(x)$ は通常のネットワークによる変換、$x$ はスキップ接続で直接渡される入力である。

```python:ResNet
from keras.layers import Input, Add, Dense
from keras.models import Model

input = Input(shape=(64,))
x = Dense(64, activation='relu')(input)
residual = Dense(64, activation='relu')(x)
out = Add()([residual, input])  # スキップ接続
model = Model(inputs=input, outputs=out)
model.summary()
```
```terminal:実行結果
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)              ┃ Output Shape           ┃        Param # ┃ Connected to           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ input_layer_1             │ (None, 64)             │              0 │ -                      │
│ (InputLayer)              │                        │                │                        │
├───────────────────────────┼────────────────────────┼────────────────┼────────────────────────┤
│ dense_3 (Dense)           │ (None, 64)             │          4,160 │ input_layer_1[0][0]    │
├───────────────────────────┼────────────────────────┼────────────────┼────────────────────────┤
│ dense_4 (Dense)           │ (None, 64)             │          4,160 │ dense_3[0][0]          │
├───────────────────────────┼────────────────────────┼────────────────┼────────────────────────┤
│ add (Add)                 │ (None, 64)             │              0 │ dense_4[0][0],         │
│                           │                        │                │ input_layer_1[0][0]    │
└───────────────────────────┴────────────────────────┴────────────────┴────────────────────────┘
 Total params: 8,320 (32.50 KB)
 Trainable params: 8,320 (32.50 KB)
 Non-trainable params: 0 (0.00 B)
 ```

## 8.5 ディープラーニングの適用例

ディープラーニングは以下の分野で活用されている。
僕が属しているweb広告業界だと、レコメンデーションや購買確率の計算などにも用いられている。

1. **画像認識**: CNN（畳み込みニューラルネットワーク）を使用
2. **自然言語処理**: RNN（リカレントニューラルネットワーク）やTransformer
3. **ゲームAI**: 深層強化学習（Deep Reinforcement Learning）

総集編的に、実際の学習テストを行ってみる。


```python:MNISTデータセットの分類
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.utils import to_categorical

# データの準備
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# モデルの構築
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, validation_split=0.1)
```
```python:テストデータの確認
import matplotlib.pyplot as plt
from keras.datasets import mnist

# MNISTデータのロード
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# テストデータの概要を表示
print(f"x_test shape: {x_test.shape}")  # (10000, 28, 28)
print(f"y_test shape: {y_test.shape}")  # (10000,)

# テストデータの最初の画像をプロット
plt.imshow(x_test[0], cmap="gray")
plt.title(f"Label: {y_test[0]}")
plt.show()
```
```terminal:テストデータ概要出力
x_test shape: (10000, 28, 28)
y_test shape: (10000,)

```
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/02e16217-8404-79e3-024e-e04486c86c76.png)

```python:実行テスト
# テストデータでモデルを評価する
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"Test Loss: {test_loss}")
print(f"Test Accuracy: {test_accuracy}")

# 学習済みモデルで予測を行う
predictions = model.predict(x_test[:5])  # テストデータから5つのサンプルを使用
print("Predicted labels:", np.argmax(predictions, axis=1))
print("True labels:", np.argmax(y_test[:5], axis=1))
```
```terminal:実行結果
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9665 - loss: 0.1055
Test Loss: 0.08812908083200455
Test Accuracy: 0.9725000262260437
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 59ms/step
Predicted labels: [7 2 1 0 4]
True labels: [7 2 1 0 4]
```

ふぅ。

## まとめ
なんとかこれで書籍の内容はざっくりさらえた。
後半は結構独自路線でまとめていっていたが、おおよそ内容としてはそれていなかったと思う。
いやあああ難しいね。これ本当にちゃんと自分で作って、自分で課題解決のために試行錯誤しないと覚えられない。
まずは基礎を頭で理解できたと思うので、今後は実践していこうと思う。

ここまでお付き合いいただきありがとうございました！