STEP 20:転移学習(Transfer Learning)

🎓 STEP 20: 転移学習(Transfer Learning)

巨人の肩に乗る!学習済みモデルを活用して高精度を実現

📋 このステップで学ぶこと

  • 転移学習とは何か?なぜ効果的か?
  • 事前学習済みモデル(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」の名の通り、モバイルデバイス向けに設計された軽量モデルで、精度と効率のバランスが良いです。

📝

学習メモ

ディープラーニング基礎 - Step 20

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE