📋 このステップで学ぶこと
- 転移学習とは何か?なぜ効果的か?
- 事前学習済みモデル(VGG16, ResNet, MobileNet)
- 特徴抽出(Feature Extraction)
- ファインチューニング(Fine-tuning)
- Kerasでの実装方法
- 少量データでの画像分類実践
🎓 1. 転移学習とは?
1-1. 転移学習の定義
転移学習(Transfer Learning)は、ある問題で学習した知識を、別の問題に転用する技術です。
🚗 運転免許の例え
普通自動車の運転を覚えた人が、トラックの運転を学ぶとき:
ゼロから学習:
ハンドル操作、アクセル、ブレーキ…全部最初から
転移学習:
基本的な運転スキルは既に習得済み
→ トラック特有の部分だけ学べばOK!
CNNも同じ!「画像の特徴を見つける」スキルは転用できます。
1-2. なぜ転移学習が効果的?
✅ 転移学習のメリット
- 少ないデータで高精度:数百枚の画像でも実用的な精度
- 学習時間の短縮:何週間 → 数時間に
- 計算リソースの節約:高価なGPUが不要
- 高い汎化性能:ImageNetで学んだ知識が活きる
1-3. ImageNetとは?
【ImageNetデータセット】
・1400万枚以上の画像
・1000クラスの分類タスク
・VGG16, ResNet, MobileNetなどが学習済み
これらのモデルは「一般的な画像の特徴」を学習済み:
– 浅い層:エッジ、色、テクスチャ
– 中間層:目、耳、車輪などのパーツ
– 深い層:顔、車、建物などの物体
→ この知識は他のタスクにも活用できる!
🏛️ 2. 事前学習済みモデル
2-1. 代表的なモデル
| モデル |
パラメータ数 |
特徴 |
用途 |
| VGG16 |
1.38億 |
シンプルで理解しやすい |
学習用、特徴抽出 |
| ResNet50 |
2560万 |
残差接続で深い層が可能 |
高精度が必要な場合 |
| MobileNetV2 |
350万 |
軽量・高速 |
モバイル、エッジデバイス |
| EfficientNet |
可変 |
効率と精度のバランス |
最新の高性能モデル |
2-2. Kerasでのモデル読み込み
from tensorflow.keras.applications import VGG16, ResNet50, MobileNetV2
# VGG16を読み込み(ImageNetの重みを使用)
vgg16 = VGG16(
weights=’imagenet’, # ImageNetで学習済みの重み
include_top=False, # 分類層を含めない(★重要)
input_shape=(224, 224, 3)
)
# ResNet50を読み込み
resnet50 = ResNet50(
weights=’imagenet’,
include_top=False,
input_shape=(224, 224, 3)
)
# MobileNetV2を読み込み(軽量)
mobilenet = MobileNetV2(
weights=’imagenet’,
include_top=False,
input_shape=(224, 224, 3)
)
⚠️ include_top=False の意味
include_top=True:ImageNetの1000クラス分類層を含む
include_top=False:分類層を含めず、特徴抽出部分のみ
転移学習では通常Falseにして、自分のタスク用の分類層を追加します。
🔍 3. 特徴抽出(Feature Extraction)
3-1. 特徴抽出とは?
特徴抽出は、事前学習済みモデルの重みを固定したまま、新しい分類層だけを学習する方法です。
【特徴抽出の仕組み】
事前学習済みモデル(VGG16など)
┌─────────────────────────────────────┐
│ Conv層 → Conv層 → … → Conv層 │ ← 重みを固定(trainable=False)
│ (ImageNetで学習済み) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ GlobalAveragePooling │
│ Dense(256, relu) │ ← この部分だけ学習
│ Dense(num_classes, softmax) │
└─────────────────────────────────────┘
3-2. 実装コード
from tensorflow.keras.applications import VGG16
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
# 事前学習済みモデルを読み込み
base_model = VGG16(
weights=’imagenet’,
include_top=False,
input_shape=(224, 224, 3)
)
# ★ 重要:ベースモデルの重みを固定
base_model.trainable = False
# 新しいモデルを構築
model = Sequential([
base_model,
GlobalAveragePooling2D(),
Dense(256, activation=’relu’),
Dropout(0.5),
Dense(10, activation=’softmax’) # 10クラス分類の場合
])
model.compile(
optimizer=’adam’,
loss=’categorical_crossentropy’,
metrics=[‘accuracy’]
)
model.summary()
実行結果:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
vgg16 (Functional) (None, 7, 7, 512) 14,714,688
(Non-trainable)
global_average_pooling2d (None, 512) 0
dense (Dense) (None, 256) 131,328
dropout (Dropout) (None, 256) 0
dense_1 (Dense) (None, 10) 2,570
=================================================================
Total params: 14,848,586
Trainable params: 133,898 ← 学習するのはこれだけ!
Non-trainable params: 14,714,688
🔧 4. ファインチューニング(Fine-tuning)
4-1. ファインチューニングとは?
ファインチューニングは、特徴抽出の後、ベースモデルの一部の層も含めて学習する方法です。
📌 2段階のアプローチ
Step 1(特徴抽出):
ベースモデルを固定し、分類層のみ学習(数エポック)
Step 2(ファインチューニング):
ベースモデルの一部を解凍し、低い学習率で全体を学習
4-2. 実装コード
# Step 1: 特徴抽出(前のセクションと同じ)
base_model = VGG16(weights=’imagenet’, include_top=False, input_shape=(224, 224, 3))
base_model.trainable = False
model = Sequential([
base_model,
GlobalAveragePooling2D(),
Dense(256, activation=’relu’),
Dropout(0.5),
Dense(10, activation=’softmax’)
])
model.compile(optimizer=’adam’, loss=’categorical_crossentropy’, metrics=[‘accuracy’])
# 分類層を先に学習
model.fit(X_train, y_train, epochs=5, validation_data=(X_val, y_val))
# Step 2: ファインチューニング
# ベースモデルを解凍(最後の数層のみ)
base_model.trainable = True
# VGG16の最後の4層だけを学習可能に
for layer in base_model.layers[:-4]:
layer.trainable = False
# 低い学習率で再コンパイル(★重要)
from tensorflow.keras.optimizers import Adam
model.compile(
optimizer=Adam(learning_rate=1e-5), # 非常に低い学習率
loss=’categorical_crossentropy’,
metrics=[‘accuracy’]
)
# ファインチューニング
model.fit(X_train, y_train, epochs=10, validation_data=(X_val, y_val))
⚠️ ファインチューニングの注意点
- 学習率は非常に低く:1e-5程度(学習済み重みを壊さないため)
- 先に分類層を学習:いきなりファインチューニングは避ける
- 解凍する層は少なめに:最後の数層だけで十分な場合が多い
💻 5. 完成コード(CIFAR-10転移学習)
“””
CIFAR-10 転移学習(MobileNetV2使用)
Google Colabで実行可能
“””
import numpy as np
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
import tensorflow as tf
# ===== 1. データ準備 =====
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# CIFAR-10は32×32なので、224×224にリサイズ
X_train_resized = tf.image.resize(X_train, (96, 96)) # MobileNetは96以上
X_test_resized = tf.image.resize(X_test, (96, 96))
# 正規化(MobileNetV2用の前処理)
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
X_train_processed = preprocess_input(X_train_resized)
X_test_processed = preprocess_input(X_test_resized)
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
print(f”訓練データ: {X_train_processed.shape}”)
# ===== 2. ベースモデル(MobileNetV2) =====
base_model = MobileNetV2(
weights=’imagenet’,
include_top=False,
input_shape=(96, 96, 3)
)
base_model.trainable = False # 重みを固定
# ===== 3. モデル構築 =====
model = Sequential([
base_model,
GlobalAveragePooling2D(),
Dense(256, activation=’relu’),
Dropout(0.5),
Dense(10, activation=’softmax’)
])
model.compile(
optimizer=Adam(learning_rate=1e-3),
loss=’categorical_crossentropy’,
metrics=[‘accuracy’]
)
# ===== 4. Step 1: 特徴抽出 =====
print(“=== Step 1: 特徴抽出 ===”)
callbacks = [
EarlyStopping(patience=5, restore_best_weights=True),
ReduceLROnPlateau(factor=0.5, patience=3)
]
history1 = model.fit(
X_train_processed, y_train,
epochs=10,
batch_size=64,
validation_split=0.1,
callbacks=callbacks
)
# ===== 5. Step 2: ファインチューニング =====
print(“\n=== Step 2: ファインチューニング ===”)
base_model.trainable = True
# 最後の20層だけ学習可能に
for layer in base_model.layers[:-20]:
layer.trainable = False
model.compile(
optimizer=Adam(learning_rate=1e-5), # 低い学習率
loss=’categorical_crossentropy’,
metrics=[‘accuracy’]
)
history2 = model.fit(
X_train_processed, y_train,
epochs=10,
batch_size=64,
validation_split=0.1,
callbacks=callbacks
)
# ===== 6. 評価 =====
test_loss, test_acc = model.evaluate(X_test_processed, y_test)
print(f”\n🎯 テスト精度: {test_acc:.4f}”)
実行結果:
=== Step 1: 特徴抽出 ===
Epoch 1/10 - accuracy: 0.6523 - val_accuracy: 0.7812
...
Epoch 5/10 - accuracy: 0.8234 - val_accuracy: 0.8456
=== Step 2: ファインチューニング ===
Epoch 1/10 - accuracy: 0.8567 - val_accuracy: 0.8723
...
Epoch 8/10 - accuracy: 0.9012 - val_accuracy: 0.8934
🎯 テスト精度: 0.8856
→ ゼロから学習するより大幅に高精度!
📝 STEP 20 のまとめ
✅ このステップで学んだこと
- 転移学習:学習済みの知識を別のタスクに転用
- 事前学習済みモデル:VGG16, ResNet50, MobileNetV2など
- 特徴抽出:ベースモデルを固定し、分類層のみ学習
- ファインチューニング:ベースモデルの一部も含めて低い学習率で学習
- include_top=False:分類層を含めずに読み込む
- trainable=False:重みを固定して学習しない
💡 覚えておくべきコード
# 転移学習の基本パターン
from tensorflow.keras.applications import MobileNetV2
base_model = MobileNetV2(weights=’imagenet’, include_top=False, input_shape=(96, 96, 3))
base_model.trainable = False # 特徴抽出時
model = Sequential([
base_model,
GlobalAveragePooling2D(),
Dense(256, activation=’relu’),
Dense(num_classes, activation=’softmax’)
])
🚀 次のステップへ
CNNパートが完了しました!次のSTEP 21からはPart 5「RNN(リカレントニューラルネットワーク)」に入ります。
時系列データや自然言語処理の世界を探求しましょう!
📝 練習問題
問題1
やさしい
転移学習の利点
転移学習の利点として、正しくないものを選んでください。
- A. 少ないデータでも高精度が期待できる
- B. 学習時間が短縮できる
- C. どんなタスクでも必ず精度が上がる
- D. 計算リソースを節約できる
正解:C
転移学習は万能ではありません。元のタスク(ImageNet)と新しいタスクがかけ離れている場合、効果が薄いこともあります。
問題2
やさしい
include_topパラメータ
VGG16(include_top=False)で読み込んだ場合、何が含まれませんか?
- A. 最初の畳み込み層
- B. 最後の畳み込み層
- C. ImageNetの1000クラス分類層
- D. すべてのBatchNormalization層
正解:C
include_top=Falseは、ImageNet用の分類層(全結合層)を含めないという意味です。特徴抽出部分(畳み込み層)は含まれます。
問題3
ふつう
ファインチューニングの学習率
ファインチューニング時に学習率を低く設定する理由は?
- A. 学習を速くするため
- B. メモリ使用量を減らすため
- C. 学習済みの重みを壊さないため
- D. 過学習を増やすため
正解:C
ImageNetで学習した有用な重みを大きく変更してしまうと、せっかくの知識が失われます。低い学習率で少しずつ調整することで、既存の知識を活かしながら新しいタスクに適応します。
問題4
ふつう
特徴抽出とファインチューニング
特徴抽出とファインチューニングの違いについて、正しい説明を選んでください。
- A. 特徴抽出はベースモデルも学習する
- B. ファインチューニングはベースモデルを完全に固定する
- C. 特徴抽出はベースモデルを固定し、ファインチューニングは一部を解凍する
- D. 両者に違いはない
正解:C
特徴抽出ではbase_model.trainable=Falseで重みを固定し、ファインチューニングではtrainable=Trueにして(通常は一部の層だけ)学習可能にします。
問題5
むずかしい
適切なモデル選択
スマートフォンアプリで画像分類を行う場合、最も適切なモデルはどれですか?
- A. VGG16(1.38億パラメータ)
- B. ResNet152(6000万パラメータ)
- C. MobileNetV2(350万パラメータ)
- D. パラメータ数は関係ない
正解:C
スマートフォンはメモリや処理能力が限られています。MobileNetV2は「Mobile」の名の通り、モバイルデバイス向けに設計された軽量モデルで、精度と効率のバランスが良いです。
artnasekai
#artnasekai #学習メモ