目次[非表示]
はじめに
こんにちは、SHOUです。
画像認識を始めたいけれど「どこから手をつければいいの?」という方も多いのではないでしょうか。
本記事では、画像認識タスクで高い精度を実現できる「事前学習済みモデル」と「CNN(畳み込みニューラルネットワーク)」の基礎を、初心者の方にもわかりやすく解説します。PythonとKerasを使った簡単な実装方法も紹介するので、実践しながら学びたい方にもおすすめです。
CNNとは何か?
CNN(Convolutional Neural Network)は、画像や映像といったデータを処理するために特化したディープラーニングのモデルです。
主に以下のような層で構成されます:
- 畳み込み層:画像の特徴を抽出
- プーリング層:特徴マップの縮小(計算コスト削減)
- 全結合層:分類や回帰などの出力
事前学習(転移学習)とは?
事前学習とは、既に学習済みのモデルを再利用する手法です。これにより、以下のようなメリットがあります:
- 少量のデータでも高い精度を実現
- 学習時間の短縮
- 計算資源の節約
代表的な事前学習済みモデルには以下のものがあります:
- VGG16 / VGG19
- ResNet50
- InceptionV3
- MobileNetV2
今回は、数字(0〜9)の分類タスクに適している軽量モデルのMobileNetV2を使います。
Kerasで事前学習済みモデルを使った画像分類
事前準備
Google Driveに接続する準備をします。
from google.colab import drive
drive.mount('/content/drive')
転移学習
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# MobileNetV2は最低96x96の入力が必要 → 画像サイズを拡大
IMG_SIZE = 96
BATCH_SIZE = 32
# 白黒反転 + 正規化 + 拡張
datagen = ImageDataGenerator(
rescale=1./255,
preprocessing_function=lambda x: 1.0 - x, # 白地黒文字に対応
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.1,
zoom_range=0.1,
validation_split=0.2
)
train_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/Colab/digits',
target_size=(IMG_SIZE, IMG_SIZE),
color_mode='rgb', # MobileNetV2はRGBを期待
batch_size=BATCH_SIZE,
class_mode='sparse',
subset='training'
)
val_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/Colab/digits',
target_size=(IMG_SIZE, IMG_SIZE),
color_mode='rgb',
batch_size=BATCH_SIZE,
class_mode='sparse',
subset='validation'
)
# モデル構築(ベースモデル + 分類ヘッド)
base_model = keras.applications.MobileNetV2(
input_shape=(IMG_SIZE, IMG_SIZE, 3),
include_top=False,
weights='imagenet'
)
base_model.trainable = False # 転移学習の基本:特徴抽出器は凍結
# 新しい分類ヘッドを追加
model = keras.Sequential([
base_model,
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.3),
keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 学習
history = model.fit(train_generator, epochs=20, validation_data=val_generator)
学習結果
学習中のログ例:
- Found 80 images belonging to 10 classes.
- Found 20 images belonging to 10 classes.
- Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet_v2/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_96_no_top.h5
- 9406464/9406464 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step
- /usr/local/lib/python3.11/dist-packages/keras/src/trainers/data_adapters/py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.
- self._warn_if_super_not_called()
- Epoch 1/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 19s 6s/step - accuracy: 0.1120 - loss: 2.7394 - val_accuracy: 0.3000 - val_loss: 1.8545
- Epoch 2/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 444ms/step - accuracy: 0.3615 - loss: 1.9677 - val_accuracy: 0.5000 - val_loss: 1.5880
- Epoch 3/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 362ms/step - accuracy: 0.5229 - loss: 1.4203 - val_accuracy: 0.7000 - val_loss: 1.2281
- ・・・
- Epoch 15/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 354ms/step - accuracy: 0.8927 - loss: 0.3191 - val_accuracy: 0.9000 - val_loss: 0.3266
- Epoch 16/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 829ms/step - accuracy: 0.9510 - loss: 0.1885 - val_accuracy: 0.9000 - val_loss: 0.6225
- Epoch 17/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 436ms/step - accuracy: 0.8656 - loss: 0.3272 - val_accuracy: 0.9500 - val_loss: 0.3617
- Epoch 18/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 332ms/step - accuracy: 0.9617 - loss: 0.1494 - val_accuracy: 0.7500 - val_loss: 0.5225
- Epoch 19/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 399ms/step - accuracy: 0.9182 - loss: 0.1808 - val_accuracy: 0.9000 - val_loss: 0.4033
- Epoch 20/20
- 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 438ms/step - accuracy: 1.0000 - loss: 0.1406 - val_accuracy: 0.8500 - val_loss: 0.3530
画像の分類
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
import numpy as np
# 画像パス
img_path = '/content/drive/MyDrive/Colab/handwritten_digit.png'
# MobileNetV2用の入力に合わせてサイズとカラーを指定
img = image.load_img(img_path, target_size=(96, 96), color_mode='rgb')
# 配列に変換
img_array = image.img_to_array(img)
# 白黒反転(白地に黒文字 → 黒地に白文字)
img_array = 255.0 - img_array
# バッチ次元を追加 + 前処理
img_array = np.expand_dims(img_array, axis=0)
img_array = preprocess_input(img_array)
# 予測
prediction = model.predict(img_array)
predicted_label = np.argmax(prediction)
print('予測ラベル:', predicted_label)
実行結果は以下です:
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 1s/step 予測ラベル: 1
今回、実際の推論結果では「4」と書かれた画像が「1」と誤認識されていました。
実践でのポイント
- データ拡張:少ないデータでもモデルの汎化性能を高める
- Fine-tuning:モデルの一部層を再学習して精度向上を狙う
- GPU活用:Google Colabなどで学習を高速化
まとめ
事前学習済みのCNNモデルを活用すれば、初心者でも短時間で高精度な画像分類が可能になります。KerasのシンプルなAPIを使えば、実装も簡単です。
ぜひこの記事を参考に、画像分類タスクにチャレンジしてみてください!
参考リンク:
Keras Applications公式ドキュメント
0 件のコメント:
コメントを投稿