事前学習済みCNNモデルを使った画像分類入門(Keras+Python)

2025年5月27日火曜日

Google Colab Keras TensorFlow 画像分類 機械学習

X f B! P L
アイキャッチ画像 事前学習済みCNNモデルを使った画像分類入門(Keras+Python)

はじめに

こんにちは、SHOUです。

画像認識を始めたいけれど「どこから手をつければいいの?」という方も多いのではないでしょうか。

本記事では、画像認識タスクで高い精度を実現できる「事前学習済みモデル」と「CNN(畳み込みニューラルネットワーク)」の基礎を、初心者の方にもわかりやすく解説します。PythonとKerasを使った簡単な実装方法も紹介するので、実践しながら学びたい方にもおすすめです。

CNNとは何か?

CNN(Convolutional Neural Network)は、画像や映像といったデータを処理するために特化したディープラーニングのモデルです。

主に以下のような層で構成されます:

  • 畳み込み層:画像の特徴を抽出
  • プーリング層:特徴マップの縮小(計算コスト削減)
  • 全結合層:分類や回帰などの出力

事前学習(転移学習)とは?

事前学習とは、既に学習済みのモデルを再利用する手法です。これにより、以下のようなメリットがあります:

  • 少量のデータでも高い精度を実現
  • 学習時間の短縮
  • 計算資源の節約

代表的な事前学習済みモデルには以下のものがあります:

  • VGG16 / VGG19
  • ResNet50
  • InceptionV3
  • MobileNetV2

今回は、数字(0〜9)の分類タスクに適している軽量モデルのMobileNetV2を使います。

Kerasで事前学習済みモデルを使った画像分類

事前準備

Google Driveに接続する準備をします。

  1. from google.colab import drive
  2. drive.mount('/content/drive')

転移学習

  1. import tensorflow as tf
  2. from tensorflow import keras
  3. from tensorflow.keras.preprocessing.image import ImageDataGenerator
  4. # MobileNetV2は最低96x96の入力が必要 → 画像サイズを拡大
  5. IMG_SIZE = 96
  6. BATCH_SIZE = 32
  7. # 白黒反転 + 正規化 + 拡張
  8. datagen = ImageDataGenerator(
  9. rescale=1./255,
  10. preprocessing_function=lambda x: 1.0 - x, # 白地黒文字に対応
  11. rotation_range=20,
  12. width_shift_range=0.2,
  13. height_shift_range=0.2,
  14. shear_range=0.1,
  15. zoom_range=0.1,
  16. validation_split=0.2
  17. )
  18. train_generator = datagen.flow_from_directory(
  19. '/content/drive/MyDrive/Colab/digits',
  20. target_size=(IMG_SIZE, IMG_SIZE),
  21. color_mode='rgb', # MobileNetV2はRGBを期待
  22. batch_size=BATCH_SIZE,
  23. class_mode='sparse',
  24. subset='training'
  25. )
  26. val_generator = datagen.flow_from_directory(
  27. '/content/drive/MyDrive/Colab/digits',
  28. target_size=(IMG_SIZE, IMG_SIZE),
  29. color_mode='rgb',
  30. batch_size=BATCH_SIZE,
  31. class_mode='sparse',
  32. subset='validation'
  33. )
  34. # モデル構築(ベースモデル + 分類ヘッド)
  35. base_model = keras.applications.MobileNetV2(
  36. input_shape=(IMG_SIZE, IMG_SIZE, 3),
  37. include_top=False,
  38. weights='imagenet'
  39. )
  40. base_model.trainable = False # 転移学習の基本:特徴抽出器は凍結
  41. # 新しい分類ヘッドを追加
  42. model = keras.Sequential([
  43. base_model,
  44. keras.layers.GlobalAveragePooling2D(),
  45. keras.layers.Dense(128, activation='relu'),
  46. keras.layers.Dropout(0.3),
  47. keras.layers.Dense(10, activation='softmax')
  48. ])
  49. model.compile(optimizer='adam',
  50. loss='sparse_categorical_crossentropy',
  51. metrics=['accuracy'])
  52. # 学習
  53. history = model.fit(train_generator, epochs=20, validation_data=val_generator)

学習結果

学習中のログ例:

  1. Found 80 images belonging to 10 classes.
  2. Found 20 images belonging to 10 classes.
  3. 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
  4. 9406464/9406464 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step
  5. /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.
  6. self._warn_if_super_not_called()
  7. Epoch 1/20
  8. 3/3 ━━━━━━━━━━━━━━━━━━━━ 19s 6s/step - accuracy: 0.1120 - loss: 2.7394 - val_accuracy: 0.3000 - val_loss: 1.8545
  9. Epoch 2/20
  10. 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 444ms/step - accuracy: 0.3615 - loss: 1.9677 - val_accuracy: 0.5000 - val_loss: 1.5880
  11. Epoch 3/20
  12. 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 362ms/step - accuracy: 0.5229 - loss: 1.4203 - val_accuracy: 0.7000 - val_loss: 1.2281
  13. ・・・
  14. Epoch 15/20
  15. 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 354ms/step - accuracy: 0.8927 - loss: 0.3191 - val_accuracy: 0.9000 - val_loss: 0.3266
  16. Epoch 16/20
  17. 3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 829ms/step - accuracy: 0.9510 - loss: 0.1885 - val_accuracy: 0.9000 - val_loss: 0.6225
  18. Epoch 17/20
  19. 3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 436ms/step - accuracy: 0.8656 - loss: 0.3272 - val_accuracy: 0.9500 - val_loss: 0.3617
  20. Epoch 18/20
  21. 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 332ms/step - accuracy: 0.9617 - loss: 0.1494 - val_accuracy: 0.7500 - val_loss: 0.5225
  22. Epoch 19/20
  23. 3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 399ms/step - accuracy: 0.9182 - loss: 0.1808 - val_accuracy: 0.9000 - val_loss: 0.4033
  24. Epoch 20/20
  25. 3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 438ms/step - accuracy: 1.0000 - loss: 0.1406 - val_accuracy: 0.8500 - val_loss: 0.3530

画像の分類

  1. from tensorflow.keras.preprocessing import image
  2. from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
  3. import numpy as np
  4. # 画像パス
  5. img_path = '/content/drive/MyDrive/Colab/handwritten_digit.png'
  6. # MobileNetV2用の入力に合わせてサイズとカラーを指定
  7. img = image.load_img(img_path, target_size=(96, 96), color_mode='rgb')
  8. # 配列に変換
  9. img_array = image.img_to_array(img)
  10. # 白黒反転(白地に黒文字 → 黒地に白文字)
  11. img_array = 255.0 - img_array
  12. # バッチ次元を追加 + 前処理
  13. img_array = np.expand_dims(img_array, axis=0)
  14. img_array = preprocess_input(img_array)
  15. # 予測
  16. prediction = model.predict(img_array)
  17. predicted_label = np.argmax(prediction)
  18. print('予測ラベル:', predicted_label)

実行結果は以下です:

1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 1s/step
予測ラベル: 1

今回、実際の推論結果では「4」と書かれた画像が「1」と誤認識されていました。

実践でのポイント

  • データ拡張:少ないデータでもモデルの汎化性能を高める
  • Fine-tuning:モデルの一部層を再学習して精度向上を狙う
  • GPU活用:Google Colabなどで学習を高速化

まとめ

事前学習済みのCNNモデルを活用すれば、初心者でも短時間で高精度な画像分類が可能になります。KerasのシンプルなAPIを使えば、実装も簡単です。

ぜひこの記事を参考に、画像分類タスクにチャレンジしてみてください!


参考リンク:
Keras Applications公式ドキュメント

このブログを検索

自己紹介

機械学習を学習中。虫も飼ってます。

お問い合わせ

名前

メール *

メッセージ *

プライバシーポリシー

QooQ