STEP 27:ガイド付きプロジェクト(犬猫画像分類)

🐱🐶 STEP 27: ガイド付きプロジェクト

犬と猫の画像分類 – 転移学習とデータ拡張で高精度を目指す!

📋 プロジェクト概要

  • 目標:犬と猫の画像を95%以上の精度で分類
  • 使用技術:CNN、転移学習(MobileNetV2)、データ拡張
  • データセット:Cats vs Dogs(Kaggle)
  • 所要時間:約90分
  • 環境:Google Colab(GPU推奨)

🎯 プロジェクト紹介

🏆 チャレンジ

犬と猫の画像を自動で分類するディープラーニングモデルを構築します。
このプロジェクトでは、これまで学んだ全ての技術を総動員します!

  • ✅ CNN(畳み込みニューラルネットワーク)
  • ✅ 転移学習(MobileNetV2)
  • ✅ データ拡張
  • ✅ コールバック(Early Stopping、ReduceLROnPlateau)
  • ✅ モデル評価と可視化

プロジェクトの流れ

📌 5つのステップ
  1. 環境準備:データセットのダウンロードと前処理
  2. ベースラインモデル:シンプルなCNNで基準を作る
  3. データ拡張:訓練データを増強
  4. 転移学習:MobileNetV2で高精度を実現
  5. 評価と改善:結果の分析と改善

📦 STEP 1: 環境準備

1-1. Google Colabの設定

# GPUを有効化(ランタイム → ランタイムのタイプを変更 → GPU) # GPUの確認 import tensorflow as tf print(f”TensorFlow version: {tf.__version__}”) print(f”GPU available: {tf.config.list_physical_devices(‘GPU’)}”)

1-2. データセットのダウンロード

import tensorflow as tf from tensorflow.keras.utils import get_file import os import zipfile # Cats vs Dogsデータセット(Microsoft提供のサブセット) URL = “https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip” path = get_file(“cats_and_dogs_filtered.zip”, origin=URL, extract=True) PATH = os.path.join(os.path.dirname(path), “cats_and_dogs_filtered”) # ディレクトリ構造の確認 train_dir = os.path.join(PATH, “train”) validation_dir = os.path.join(PATH, “validation”) train_cats = os.path.join(train_dir, “cats”) train_dogs = os.path.join(train_dir, “dogs”) val_cats = os.path.join(validation_dir, “cats”) val_dogs = os.path.join(validation_dir, “dogs”) print(f”訓練用 猫: {len(os.listdir(train_cats))}枚”) print(f”訓練用 犬: {len(os.listdir(train_dogs))}枚”) print(f”検証用 猫: {len(os.listdir(val_cats))}枚”) print(f”検証用 犬: {len(os.listdir(val_dogs))}枚”)
実行結果:
訓練用 猫: 1000枚
訓練用 犬: 1000枚
検証用 猫: 500枚
検証用 犬: 500枚

合計: 訓練2000枚、検証1000枚

1-3. データの読み込み

from tensorflow.keras.preprocessing.image import ImageDataGenerator IMG_SIZE = 150 BATCH_SIZE = 32 # データ読み込み(正規化のみ) train_datagen = ImageDataGenerator(rescale=1./255) val_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_dir, target_size=(IMG_SIZE, IMG_SIZE), batch_size=BATCH_SIZE, class_mode=’binary’ ) validation_generator = val_datagen.flow_from_directory( validation_dir, target_size=(IMG_SIZE, IMG_SIZE), batch_size=BATCH_SIZE, class_mode=’binary’ ) print(f”クラス: {train_generator.class_indices}”)

🏗️ STEP 2: ベースラインモデル

2-1. シンプルなCNN

from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout # ベースラインモデル baseline_model = Sequential([ Conv2D(32, (3, 3), activation=’relu’, input_shape=(IMG_SIZE, IMG_SIZE, 3)), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activation=’relu’), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation=’relu’), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation=’relu’), MaxPooling2D((2, 2)), Flatten(), Dense(512, activation=’relu’), Dropout(0.5), Dense(1, activation=’sigmoid’) ]) baseline_model.compile( optimizer=’adam’, loss=’binary_crossentropy’, metrics=[‘accuracy’] ) baseline_model.summary()

2-2. ベースラインの学習

from tensorflow.keras.callbacks import EarlyStopping early_stop = EarlyStopping(monitor=’val_loss’, patience=5, restore_best_weights=True) # 学習 baseline_history = baseline_model.fit( train_generator, epochs=30, validation_data=validation_generator, callbacks=[early_stop] ) # 結果 val_loss, val_acc = baseline_model.evaluate(validation_generator) print(f”\n📊 ベースライン検証精度: {val_acc:.4f}”)
実行結果:
Epoch 1/30 - accuracy: 0.5525 - val_accuracy: 0.6420
...
Epoch 15/30 - accuracy: 0.8950 - val_accuracy: 0.7240

📊 ベースライン検証精度: 0.7240

→ 訓練は90%近いが、検証は72%...過学習している!
⚠️ 問題点

訓練精度と検証精度の差が大きい → 過学習

対策:データ拡張、転移学習を導入しよう!

🔄 STEP 3: データ拡張

3-1. データ拡張の設定

# データ拡張付きのImageDataGenerator train_datagen_aug = ImageDataGenerator( rescale=1./255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode=’nearest’ ) # 検証データは拡張しない val_datagen = ImageDataGenerator(rescale=1./255) train_generator_aug = train_datagen_aug.flow_from_directory( train_dir, target_size=(IMG_SIZE, IMG_SIZE), batch_size=BATCH_SIZE, class_mode=’binary’ )

3-2. 拡張データでの再学習

# 同じモデル構造で新規作成 aug_model = Sequential([ Conv2D(32, (3, 3), activation=’relu’, input_shape=(IMG_SIZE, IMG_SIZE, 3)), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activation=’relu’), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation=’relu’), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation=’relu’), MaxPooling2D((2, 2)), Flatten(), Dense(512, activation=’relu’), Dropout(0.5), Dense(1, activation=’sigmoid’) ]) aug_model.compile(optimizer=’adam’, loss=’binary_crossentropy’, metrics=[‘accuracy’]) # 学習 aug_history = aug_model.fit( train_generator_aug, epochs=50, validation_data=validation_generator, callbacks=[early_stop] ) val_loss, val_acc = aug_model.evaluate(validation_generator) print(f”\n📊 データ拡張後の検証精度: {val_acc:.4f}”)
実行結果:
📊 データ拡張後の検証精度: 0.7980

→ 72% → 80%に改善!でもまだ物足りない...

🎓 STEP 4: 転移学習

4-1. MobileNetV2の読み込み

from tensorflow.keras.applications import MobileNetV2 from tensorflow.keras.layers import GlobalAveragePooling2D # 事前学習済みモデル base_model = MobileNetV2( weights=’imagenet’, include_top=False, input_shape=(IMG_SIZE, IMG_SIZE, 3) ) # 重みを固定 base_model.trainable = False # 転移学習モデル transfer_model = Sequential([ base_model, GlobalAveragePooling2D(), Dense(256, activation=’relu’), Dropout(0.5), Dense(1, activation=’sigmoid’) ]) transfer_model.compile( optimizer=’adam’, loss=’binary_crossentropy’, metrics=[‘accuracy’] ) transfer_model.summary()

4-2. 特徴抽出(Phase 1)

# Phase 1: 分類層のみ学習 from tensorflow.keras.callbacks import ReduceLROnPlateau callbacks = [ EarlyStopping(monitor=’val_loss’, patience=5, restore_best_weights=True), ReduceLROnPlateau(monitor=’val_loss’, factor=0.5, patience=3) ] transfer_history = transfer_model.fit( train_generator_aug, epochs=20, validation_data=validation_generator, callbacks=callbacks ) val_loss, val_acc = transfer_model.evaluate(validation_generator) print(f”\n📊 転移学習(Phase 1)検証精度: {val_acc:.4f}”)
実行結果:
📊 転移学習(Phase 1)検証精度: 0.9520

→ 一気に95%超え!転移学習の威力!

4-3. ファインチューニング(Phase 2)

# Phase 2: ベースモデルの一部を解凍してファインチューニング base_model.trainable = True # 最後の50層だけ学習可能に for layer in base_model.layers[:-50]: layer.trainable = False # 低い学習率で再コンパイル from tensorflow.keras.optimizers import Adam transfer_model.compile( optimizer=Adam(learning_rate=1e-5), loss=’binary_crossentropy’, metrics=[‘accuracy’] ) # ファインチューニング finetune_history = transfer_model.fit( train_generator_aug, epochs=10, validation_data=validation_generator, callbacks=callbacks ) val_loss, val_acc = transfer_model.evaluate(validation_generator) print(f”\n📊 転移学習(Phase 2)検証精度: {val_acc:.4f}”)
実行結果:
📊 転移学習(Phase 2)検証精度: 0.9680

🎉 96.8%達成!目標の95%を大幅に超えました!

📊 STEP 5: 評価と可視化

5-1. 学習曲線の比較

import matplotlib.pyplot as plt def plot_comparison(histories, labels): “””複数の学習曲線を比較””” fig, axes = plt.subplots(1, 2, figsize=(14, 5)) for history, label in zip(histories, labels): axes[0].plot(history.history[‘val_loss’], label=label) axes[1].plot(history.history[‘val_accuracy’], label=label) axes[0].set_title(‘検証損失の比較’) axes[0].set_xlabel(‘エポック’) axes[0].legend() axes[1].set_title(‘検証精度の比較’) axes[1].set_xlabel(‘エポック’) axes[1].legend() plt.tight_layout() plt.show() # 比較プロット plot_comparison( [baseline_history, aug_history, transfer_history], [‘ベースライン’, ‘データ拡張’, ‘転移学習’] )

5-2. 結果のまとめ

モデル 検証精度 改善率
ベースラインCNN 72.4%
+データ拡張 79.8% +7.4%
+転移学習(Phase 1) 95.2% +15.4%
+ファインチューニング 96.8% +1.6%

📝 プロジェクトまとめ

✅ 達成したこと
  • 犬と猫の画像を96.8%の精度で分類
  • ベースラインから24.4%の精度向上
  • CNN、データ拡張、転移学習の実践的な活用
  • 過学習への対処法の理解
💡 学んだポイント
  • ベースライン重要:まずシンプルなモデルで基準を作る
  • データ拡張の効果:少ないデータでも多様性を増やせる
  • 転移学習の威力:事前学習済みモデルで大幅に精度向上
  • 段階的なアプローチ:特徴抽出→ファインチューニング
🚀 次のステップへ

ガイド付きプロジェクトを完了しました!

次のSTEP 28では、独立プロジェクトとして自分でテーマを選んで取り組みます。
このプロジェクトで学んだテクニックを応用してみましょう!

✅ プロジェクトチェックリスト

  • Google ColabでGPUを有効化した
  • データセットをダウンロードして構造を確認した
  • ベースラインCNNモデルを構築・学習した
  • データ拡張を適用して再学習した
  • MobileNetV2による転移学習を実装した
  • ファインチューニングで精度を向上させた
  • 学習曲線を可視化して比較した
  • 目標精度(95%以上)を達成した
📝

学習メモ

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

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