ファインチューニングによる画像分類の実験

2025年5月31日土曜日

Google Colab Keras TensorFlow 画像分類 転移学習

ファインチューニングによる画像分類の実験 アイキャッチ画像

はじめに

転移学習の一種であるファインチューニングを行ってみました。限られたデータでも、事前学習済みモデルを活かすことで、精度よく画像分類が行えます。

転移学習とファインチューニングの違い

転移学習:

  • すでに学習済みのモデルの知識(重み)を活かして、新しいデータに対応させる手法全般
  • 学習済みモデルの重みを活用
  • 必ずしも全層を再学習するとは限らない

ファインチューニング:

  • 転移学習の一部で、学習済みモデルの一部または全部の層の重みを微調整(再学習)すること
  • 通常、学習済みのモデル(例:VGG16, ResNet等)を読み込み
  • 一部の層を凍結(trainable = False)、一部は再学習する

ポイント: 学習済みの重みを活かして一部層を再調整する。

学習の準備

Google Driveのマウント

学習用のデータを読み込むために、Google Driveをマウントします。

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

ベースモデルの作成(MNISTで事前学習)

まずはKerasのMNISTデータセットで、シンプルなベースモデルを作成・学習します。

  1. import tensorflow as tf
  2. from tensorflow import keras
  3. (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
  4. x_train = x_train / 255.0
  5. x_test = x_test / 255.0
  6. # モデル構築
  7. base_model = keras.Sequential([
  8. keras.layers.Input(shape=(28, 28, 1)),
  9. keras.layers.Conv2D(32, 3, activation='relu'), # layer 0
  10. keras.layers.MaxPooling2D(), # layer 1
  11. keras.layers.Flatten(), # layer 2
  12. keras.layers.Dense(128, activation='relu'), # layer 3
  13. keras.layers.Dropout(0.2), # layer 4
  14. keras.layers.Dense(10, activation='softmax') # layer 5
  15. ])
  16. base_model.compile(optimizer='adam',
  17. loss='sparse_categorical_crossentropy',
  18. metrics=['accuracy'])
  19. # 事前学習
  20. base_model.fit(x_train, y_train, epochs=5)
  21. # モデル保存
  22. base_model.save('my_mnist_model.keras')

ファインチューニング

  1. from tensorflow.keras.models import load_model
  2. from tensorflow.keras.preprocessing.image import ImageDataGenerator
  3. # モデル読み込み
  4. model = load_model('my_mnist_model.keras')
  5. # 一部の層を凍結(例:畳み込み層)
  6. for layer in model.layers[:-2]:
  7. layer.trainable = False
  8. # 再コンパイル(凍結後は必要)
  9. model.compile(optimizer='adam',
  10. loss='sparse_categorical_crossentropy',
  11. metrics=['accuracy'])
  12. # trainable 状態の確認
  13. for i, layer in enumerate(model.layers):
  14. print(f"{i:2d}: {layer.name:30s} trainable = {layer.trainable}")
  15. # データ準備(白黒反転など)
  16. datagen = ImageDataGenerator(
  17. rescale=1./255,
  18. preprocessing_function=lambda x: 1.0 - x
  19. )
  20. train_generator = datagen.flow_from_directory(
  21. '/content/drive/MyDrive/Colab/digits',
  22. target_size=(28, 28),
  23. color_mode='grayscale',
  24. batch_size=32,
  25. class_mode='sparse'
  26. )
  27. # ファインチューニング(凍結していない層だけ訓練される)
  28. model.fit(train_generator, epochs=5)

ポイント:

  1. for layer in model.layers[:-2]:
  2. layer.trainable = False

最後の2層を除いた層すべてを選ぶスライスです。今回なら layer0 ~ layer3 が対象になります。

つまり「畳み込み層」「プーリング層」「Flatten」「中間のDense」などの層の重みが訓練中に更新されなくなります。

転移学習・ファインチューニングの目的:

  • すでに学習した「汎用的な特徴抽出器(Conv層など)」はそのまま使いたい
  • 新しいデータセットに合わせて、分類部分(出力層やその直前)だけを再学習したい

→ だから「特徴抽出部分は凍結し、出力層だけ trainable にする」。

実行時ログ(抜粋)

  1. 0: conv2d_1 trainable = False
  2. 1: max_pooling2d_1 trainable = False
  3. 2: flatten_1 trainable = False
  4. 3: dense_2 trainable = False
  5. 4: dropout_1 trainable = True
  6. 5: dense_3 trainable = True

予測

  1. from tensorflow.keras.preprocessing import image
  2. import numpy as np
  3. img_path = '/content/drive/MyDrive/Colab/handwritten_digit.png'
  4. img = image.load_img(img_path, target_size=(28, 28), color_mode='grayscale')
  5. img_array = image.img_to_array(img)
  6. img_array = np.expand_dims(img_array, axis=0) / 255.0
  7. img_array = 1.0 - img_array # ←★ 追加:白黒反転
  8. prediction = model.predict(img_array)
  9. print('予測ラベル:', np.argmax(prediction))

実行結果は以下です:

  1. 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 82ms/step
  2. 予測ラベル: 4

予測の結果、「4」と書かれた画像が「4」と認識されました。

少ない学習で効率的にモデルを構築することができた。

まとめ

  • 転移学習は既存モデルを再利用できる強力な手法です
  • ファインチューニングにより新しいデータにも対応可能です
  • 層を凍結することで、汎用的な特徴を活かしながら効率的に学習できます

自己紹介

はじめまして、機械学習を独学中のSHOU TAKEと申します。本ブログでは、Python・Keras・Google Colabを活用した画像分類やニューラルネットワークの実験記事を中心に発信しています。初学者の方にも分かりやすく、学んだことをそのまま実験形式でまとめるスタイルです。これまで取り組んだテーマには、学習率やOptimizerの比較、Batch Sizeの検証、事前学習の活用などがあります。ご質問やご感想は、お問い合わせフォームからお気軽にどうぞ。

プライバシーポリシー

QooQ