はじめに
本記事では、CNN(Convolutional Neural Network) を用いた画像判定の実装に挑戦します。今回は、有名な MNIST データセットを使って手書き数字の分類モデルを作成します。
「CNN による画像判定入門」 で紹介した理論を実際にコードで動かしながら、畳み込み層やプーリング層がどのように働くのかを実感できる内容になっています。まだ入門編を読んでいない方は、ぜひ先にそちらをご覧ください。
使用するライブラリ
今回は Python と TensorFlow を使用して実装します。
pip install tensorflow matplotlib
- TensorFlow: 深層学習用ライブラリ
- Matplotlib: 画像表示用ライブラリ
MNIST データセットの準備
MNIST は、0~9 の手書き数字の画像が 70,000 枚 (60,000 の訓練データと 10,000 枚のテストデータ) 含まれるデータセットです。画像は 28x28 のグレースケールです。
import tensorflow as tf
from tensorflow.keras import datasets
import matplotlib.pyplot as plt
# データの読み込み
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
# データの正規化
train_images = train_images / 255.0
test_images = test_images / 255.0
# データの確認
plt.figure(figsize=(5, 5))
for I in range(9):
plt.subplot(3, 3, I+1)
plt.imshow(train_images[I], cmap="gray")
plt.title(f"Label: {train_labels[i]}")
plt.axis("off")
plt.show()
CNN モデルの構築
畳み込み層とプーリング層を組み合わせて特徴量を抽出し、全結合層で分類を行います。
from tensorflow.keras import models, layers
model = models.Sequential()
model.add(layers.Conv2D(
filters=32, kernel_size=(3, 3), strides=(1, 1),
padding="same", data_format="channels_last",
activation="relu", input_shape=(28, 28, 1),
))
model.add(layers.MaxPooling(pool_size=(2, 2)))
model.add(layers.Conv2D(
filters=64, kernel_size=(3, 3), activation="relu"
))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))
model.summary()
モデルの構造
- Conv2D: 畳み込み層 (カーネルサイズ 3x3)
- MaxPooling2D: 最大プーリング層
- Flatten: 2D データを 1D に変換
- Dense: 全結合層 (最終的に 10 クラスの出力)
モデルのコンパイルと学習
損失関数、最適化アルゴリズム、評価指標を設定して学習を進めます。
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"]
)
history = model.fit(
train_images[..., tf.newaxis], train_labels,
epochs=5,
validation_data=(test_images[..., tf.newaxis], test_labels)
)
モデルの評価
テストデータで精度を確認します。
test_loss, test_acc = model.evaluate(test_images[..., tf.newaxis], test_labels)
print(f"Test Accuracy: {test_acc: .2%}")
予測の結果と可視化
実際にモデルに画像を渡して予測してみましょう。
import dumpy as np
predictions = model.predict(test_images[..., tf.newaxis])
plt.figure(figsize=(10, 10))
for I in range(9):
plt.subplot(3, 3, I+1)
plt.imshow(test_images[I], cmap="gray")
pred_label = np.argmax(predictions[I])
true_label.= test_labels[I]
plt.title(f"Pred: {pred_label}, True: {true_label}",
color=("green" if pred_label == true_label else "red")
plt.axis("off")
plt.show()
)
おわりに
今回は CNN を使って MNIST の手書き数字を分類するモデルを作成しました。畳み込み層やプーリング層が特徴を抽出し、最終的に 0~9 の数字を判別できる仕組みを実際に動かして体感できたと思います。
今回の例ではシンプルな構造でしたが、層を増やしたり、正則化やデータ拡張を取り入れることでさらに精度を高めることができます。
次のステップとして、自分で画像分類データセットを用意して試してみるのも面白いでしょう!