※以下の企画です
前回に続いてゼロつくを進めていきます。
今回は第8章「ディープラーニング」の内容に入ります。
要点をまとめつつ、ChatGPTなどの力も借りながら理解していきます。
結構本書から離れてしまうかもですが、自分の理解のためにまとめています。
※一応書籍的には最後の内容ですが、アドベントカレンダーの枠からははみ出ました。
それでは頑張ります〜
8章 ディープラーニング
ディープラーニングの登場
ディープラーニングは多層のニューラルネットワークを用いることで、従来の手法では難しいタスク(例えば、画像認識や自然言語処理)を高精度で解決する技術である。
本記事では以下の内容をまとめてみる。
- 多層ニューラルネットワークの特徴
- 勾配消失問題とその解決方法
- 学習効率を上げる手法
シンプルに中間層がめちゃくちゃ深くなるとDNNと言って良いのかな。ここらへんは定義がよくわからなかった。
勾配消失問題
ディープラーニングで発生する大きな問題の一つが 勾配消失問題 である。
これは、活性化関数(特にシグモイド関数やtanh関数)を用いた場合に、勾配が小さくなりすぎてしまう現象を指す。
勾配消失の原因
- 活性化関数の微分値が0に近づく
- 多層ネットワークの連鎖的な微分により勾配が消える
解決方法
- 活性化関数の変更: ReLU(Rectified Linear Unit)を使用
- 重みの初期化: Heの初期化を用いる
- Batch Normalization を活用
ReLUの定義
ReLUは、入力が0を超える場合にそのまま出力し、0以下の場合は0を返す。
計算がシンプルで勾配消失問題を軽減する。
def relu(x):
return np.maximum(0, x)
8.3 重みの初期化と活性化関数
適切な重みの初期化と活性化関数の選択は、学習の効率に大きな影響を与える。
重みの初期化方法
- 標準初期化: 勾配消失問題を引き起こしやすい
- Xavier初期化: シグモイドやtanhに適している
- He初期化: ReLUやその派生に適している
※chatGPT調べ
活性化関数の選択
- ReLU: 勾配消失を抑えるが、死んだノード問題に注意
- Leaky ReLU: 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は、スキップ接続 を導入することで、勾配消失問題を効果的に解決する。
スキップ接続の構造
y = F(x) + x
ここで、$F(x)$ は通常のネットワークによる変換、$x$ はスキップ接続で直接渡される入力である。
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()
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広告業界だと、レコメンデーションや購買確率の計算などにも用いられている。
- 画像認識: CNN(畳み込みニューラルネットワーク)を使用
- 自然言語処理: RNN(リカレントニューラルネットワーク)やTransformer
- ゲームAI: 深層強化学習(Deep Reinforcement Learning)
総集編的に、実際の学習テストを行ってみる。
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)
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()
x_test shape: (10000, 28, 28)
y_test shape: (10000,)
# テストデータでモデルを評価する
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))
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]
ふぅ。
まとめ
なんとかこれで書籍の内容はざっくりさらえた。
後半は結構独自路線でまとめていっていたが、おおよそ内容としてはそれていなかったと思う。
いやあああ難しいね。これ本当にちゃんと自分で作って、自分で課題解決のために試行錯誤しないと覚えられない。
まずは基礎を頭で理解できたと思うので、今後は実践していこうと思う。
ここまでお付き合いいただきありがとうございました!