はじめに|ファインチューニングで高精度な画像分類を目指す
画像認識や機械学習の分野では、限られたデータセットで高精度な分類を実現するために「転移学習」や「ファインチューニング」といった手法が非常に効果的です。 本記事では、KerasとGoogle Colabを用いて、事前学習済みモデルをファインチューニングする方法をステップバイステップで解説します。
手書き数字認識のような小規模な画像分類タスクでも、ファインチューニングを活用すれば短時間かつ高精度なモデル構築が可能です。
転移学習とファインチューニングの違いとは?|画像分類モデルの再利用戦略
転移学習(Transfer Learning)は、すでに学習済みのモデルを他のタスクに応用するための技術です。
- 過去に大規模データセットで学習された重みを活用
- 新しい問題に適応するために、モデルの一部または全部を再利用
- 全層を再学習するとは限らない
ファインチューニング(Fine-tuning)は、転移学習の一手法であり、以下のような特徴があります。
- 学習済みモデルの一部の層の重みを「再調整」
- 一部の層は「凍結(学習させない)」し、一部は「再学習」させる
- より高度で微細な調整が可能
要点:ファインチューニングでは、事前学習済みモデルの知識を活かしつつ、新しいデータに合わせた調整を行います。
Kerasでの学習準備|Google Driveのマウントとベースモデルの構築
Google Driveのマウント
学習用画像データはGoogle Drive上に保存しておくと便利です。以下のコードでColabからDriveにアクセスできるようになります。
from google.colab import drive
drive.mount('/content/drive')
MNISTを使って事前学習モデルを構築
まずは、KerasのMNISTデータセットを使って、畳み込みニューラルネットワーク(CNN)のベースモデルを作成・学習します。
import tensorflow as tf
from tensorflow import keras
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0
# モデル構築
base_model = keras.Sequential([
keras.layers.Input(shape=(28, 28, 1)),
keras.layers.Conv2D(32, 3, activation='relu'), # layer 0
keras.layers.MaxPooling2D(), # layer 1
keras.layers.Flatten(), # layer 2
keras.layers.Dense(128, activation='relu'), # layer 3
keras.layers.Dropout(0.2), # layer 4
keras.layers.Dense(10, activation='softmax') # layer 5
])
base_model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 事前学習
base_model.fit(x_train, y_train, epochs=5)
# モデル保存
base_model.save('my_mnist_model.keras')
Kerasでファインチューニングを実装する|層の凍結と再学習
保存したベースモデルを読み込み、一部の層を「凍結」して再学習を行うことでファインチューニングを実現します。
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# モデル読み込み
model = load_model('my_mnist_model.keras')
# 一部の層を凍結(例:畳み込み層)
for layer in model.layers[:-2]:
layer.trainable = False
# 再コンパイル(凍結後は必要)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
ポイント: `model.layers[:-2]` により、出力層以外を凍結しています。
最後の2層を除いた層すべてを選ぶスライスです。今回なら layer0 ~ layer3 が対象になります。
つまり「畳み込み層」「プーリング層」「Flatten」「中間のDense」などの層の重みが訓練中に更新されなくなります。
# trainable 状態の確認
for i, layer in enumerate(model.layers):
print(f"{i:2d}: {layer.name:30s} trainable = {layer.trainable}")
画像データはImageDataGeneratorで読み込み、白黒反転などの前処理を追加しています。
# データ準備(白黒反転など)
datagen = ImageDataGenerator(
rescale=1./255,
preprocessing_function=lambda x: 1.0 - x
)
train_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/Colab/digits',
target_size=(28, 28),
color_mode='grayscale',
batch_size=32,
class_mode='sparse'
)
# ファインチューニング(凍結していない層だけ訓練される)
model.fit(train_generator, epochs=5)
転移学習・ファインチューニングの目的:
- すでに学習した「汎用的な特徴抽出器(Conv層など)」はそのまま使いたい
- 新しいデータセットに合わせて、分類部分(出力層やその直前)だけを再学習したい
→ だから「特徴抽出部分は凍結し、出力層だけ trainable にする」。
ファインチューニングの学習ログ|層のtrainable設定と結果
モデルの各層の学習可能(trainable)状態を確認した結果です。
0: conv2d_1 trainable = False 1: max_pooling2d_1 trainable = False 2: flatten_1 trainable = False 3: dense_2 trainable = False 4: dropout_1 trainable = True 5: dense_3 trainable = True
このように、出力層付近のみが学習対象となっており、その他の層は再学習されていないことがわかります。 これにより、元のモデルの特徴抽出能力を活かしつつ、効率的な学習が可能になります。
ファインチューニング後のモデルによる画像予測|手書き数字の分類
ファインチューニング後のモデルに任意の画像を入力し、分類結果を確認します。
from tensorflow.keras.preprocessing import image
import numpy as np
img_path = '/content/drive/MyDrive/Colab/handwritten_digit.png'
img = image.load_img(img_path, target_size=(28, 28), color_mode='grayscale')
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0) / 255.0
img_array = 1.0 - img_array # ←★ 追加:白黒反転
prediction = model.predict(img_array)
print('予測ラベル:', np.argmax(prediction))
実行結果は以下です:
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 82ms/step 予測ラベル: 4
このように、少量の学習でも「4」と書かれた画像を正しく分類できました。ファインチューニングの有効性が示されています。
少ない学習で効率的にモデルを構築することができた。
まとめ|転移学習とファインチューニングで効率よく画像分類
- 転移学習は、既存の学習済みモデルを活用できるため、少ないデータでも高い精度を出せる
- ファインチューニングにより、新しいデータに最適化されたモデル構築が可能
- 層の凍結を活用することで、学習時間と計算リソースを削減しながら高精度な分類を実現
この記事を参考に、あなたのプロジェクトでもファインチューニングを取り入れて、よりスマートな画像分類モデルを構築してみてください!
0 件のコメント:
コメントを投稿