📦 1. CIFAR-10データセット
1-1. CIFAR-10とは?
CIFAR-10は、10クラスのカラー画像を含む有名なベンチマークデータセットです。
MNISTの次のステップとして、画像認識の練習に最適です。
| 項目 |
MNIST |
CIFAR-10 |
| 画像サイズ |
28×28 |
32×32 |
| カラー |
グレースケール(1ch) |
カラー(3ch: RGB) |
| クラス数 |
10(数字) |
10(物体) |
| 訓練データ |
60,000枚 |
50,000枚 |
| テストデータ |
10,000枚 |
10,000枚 |
| 難易度 |
★☆☆ 簡単 |
★★★ 難しい |
1-2. CIFAR-10の10クラス
【CIFAR-10の10クラス】
0: 飛行機(airplane) 5: 犬(dog)
1: 自動車(automobile) 6: カエル(frog)
2: 鳥(bird) 7: 馬(horse)
3: 猫(cat) 8: 船(ship)
4: 鹿(deer) 9: トラック(truck)
→ 動物と乗り物が混在しており、MNISTより難しい
1-3. データの読み込み
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
# データ読み込み
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print(f”訓練データ: {X_train.shape}”) # (50000, 32, 32, 3)
print(f”テストデータ: {X_test.shape}”) # (10000, 32, 32, 3)
print(f”ラベル: {y_train.shape}”) # (50000, 1)
# 正規化(0-255 → 0-1)
X_train = X_train.astype(‘float32’) / 255.0
X_test = X_test.astype(‘float32’) / 255.0
# ラベルをOne-Hot形式に
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
🏛️ 2. 典型的なCNNアーキテクチャ
2-1. CNNの基本構造
以下の図は横スクロールできます。
【典型的なCNNの構造】
入力画像
↓
┌─────────────────────────────────────────────────┐
│ 特徴抽出部(Feature Extraction) │
│ │
│ ┌──────────────────────────────────┐ │
│ │ Conv Block 1 │ │
│ │ Conv2D → BatchNorm → ReLU → Pool │ │
│ └──────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────┐ │
│ │ Conv Block 2 │ │
│ │ Conv2D → BatchNorm → ReLU → Pool │ │
│ └──────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────┐ │
│ │ Conv Block 3 │ │
│ │ Conv2D → BatchNorm → ReLU → Pool │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ 分類部(Classifier) │
│ │
│ Flatten または GlobalAveragePooling │
│ ↓ │
│ Dense → Dropout → Dense(softmax) │
└─────────────────────────────────────────────────┘
↓
出力(クラス確率)
2-2. 設計のポイント
✅ CNNアーキテクチャ設計のポイント
- フィルター数は徐々に増やす:32 → 64 → 128のように
- 画像サイズは徐々に小さく:Poolingで縮小
- BatchNormalizationを使う:学習の安定化
- Dropoutで過学習防止:特に全結合層で
- 最後はsoftmax:多クラス分類の場合
💻 3. CIFAR-10モデルの構築
3-1. シンプルなCNNモデル
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
from tensorflow.keras.layers import Dropout, BatchNormalization
# シンプルなCNNモデル
model = Sequential([
# === Conv Block 1 ===
Conv2D(32, (3, 3), padding=’same’, activation=’relu’, input_shape=(32, 32, 3)),
BatchNormalization(),
Conv2D(32, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
MaxPooling2D(pool_size=(2, 2)),
Dropout(0.25),
# === Conv Block 2 ===
Conv2D(64, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
Conv2D(64, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
MaxPooling2D(pool_size=(2, 2)),
Dropout(0.25),
# === Conv Block 3 ===
Conv2D(128, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
Conv2D(128, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
MaxPooling2D(pool_size=(2, 2)),
Dropout(0.25),
# === 分類部 ===
Flatten(),
Dense(512, activation=’relu’),
BatchNormalization(),
Dropout(0.5),
Dense(10, activation=’softmax’)
])
model.summary()
モデル構造:
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 32, 32, 32) 896
batch_normalization (None, 32, 32, 32) 128
conv2d_1 (Conv2D) (None, 32, 32, 32) 9248
batch_normalization_1 (None, 32, 32, 32) 128
max_pooling2d (None, 16, 16, 32) 0
dropout (None, 16, 16, 32) 0
...
dense_1 (Dense) (None, 10) 5130
=================================================================
Total params: 1,250,698
3-2. コンパイルと学習
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
# コンパイル
model.compile(
optimizer=’adam’,
loss=’categorical_crossentropy’,
metrics=[‘accuracy’]
)
# コールバック
callbacks = [
EarlyStopping(monitor=’val_loss’, patience=10, restore_best_weights=True),
ReduceLROnPlateau(monitor=’val_loss’, factor=0.5, patience=5, min_lr=1e-6)
]
# 学習
history = model.fit(
X_train, y_train,
epochs=50,
batch_size=64,
validation_split=0.1,
callbacks=callbacks
)
学習経過:
Epoch 1/50
703/703 - accuracy: 0.4523 - val_accuracy: 0.5812
Epoch 10/50
703/703 - accuracy: 0.7856 - val_accuracy: 0.7623
Epoch 20/50
703/703 - accuracy: 0.8534 - val_accuracy: 0.8012
...
Epoch 35/50
Epoch 35: ReduceLROnPlateau reducing learning rate to 0.0005
...
Epoch 45/50
703/703 - accuracy: 0.9123 - val_accuracy: 0.8456
※ CIFAR-10は難しいので、80%台で良好な結果
3-3. 評価
# テストデータで評価
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f”\nテスト精度: {test_acc:.4f}”)
# 予測
import numpy as np
predictions = model.predict(X_test[:10])
predicted_classes = np.argmax(predictions, axis=1)
actual_classes = np.argmax(y_test[:10], axis=1)
class_names = [‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’,
‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’]
print(“\n予測結果:”)
for i in range(10):
print(f” 実際: {class_names[actual_classes[i]]}, 予測: {class_names[predicted_classes[i]]}”)
評価結果:
テスト精度: 0.8234
予測結果:
実際: cat, 予測: cat ✓
実際: ship, 予測: ship ✓
実際: ship, 予測: airplane ✗
実際: airplane, 予測: airplane ✓
実際: frog, 予測: frog ✓
...
📊 4. 学習曲線の可視化
import matplotlib.pyplot as plt
# 学習曲線のプロット
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 精度
axes[0].plot(history.history[‘accuracy’], label=’Train’)
axes[0].plot(history.history[‘val_accuracy’], label=’Validation’)
axes[0].set_title(‘Model Accuracy’)
axes[0].set_xlabel(‘Epoch’)
axes[0].set_ylabel(‘Accuracy’)
axes[0].legend()
# 損失
axes[1].plot(history.history[‘loss’], label=’Train’)
axes[1].plot(history.history[‘val_loss’], label=’Validation’)
axes[1].set_title(‘Model Loss’)
axes[1].set_xlabel(‘Epoch’)
axes[1].set_ylabel(‘Loss’)
axes[1].legend()
plt.tight_layout()
plt.show()
📌 学習曲線の見方
- 両方下がっている:学習が順調 ✓
- 訓練のみ下がる:過学習の兆候 → Dropoutを増やす
- 両方停滞:学習率が低い可能性 → 学習率を調整
- 激しく振動:学習率が高すぎる → 学習率を下げる
📝 5. 完成コード(Google Colab対応)
“””
CIFAR-10画像分類 – 完成コード
Google Colabで実行可能
“””
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
from tensorflow.keras.layers import Dropout, BatchNormalization
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
# ===== 1. データ準備 =====
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X_train = X_train.astype(‘float32’) / 255.0
X_test = X_test.astype(‘float32′) / 255.0
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
print(f”訓練データ: {X_train.shape}”)
print(f”テストデータ: {X_test.shape}”)
# ===== 2. モデル構築 =====
model = Sequential([
# Block 1
Conv2D(32, (3, 3), padding=’same’, activation=’relu’, input_shape=(32, 32, 3)),
BatchNormalization(),
Conv2D(32, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
MaxPooling2D((2, 2)),
Dropout(0.25),
# Block 2
Conv2D(64, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
Conv2D(64, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
MaxPooling2D((2, 2)),
Dropout(0.25),
# Block 3
Conv2D(128, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
Conv2D(128, (3, 3), padding=’same’, activation=’relu’),
BatchNormalization(),
MaxPooling2D((2, 2)),
Dropout(0.25),
# Classifier
Flatten(),
Dense(512, activation=’relu’),
BatchNormalization(),
Dropout(0.5),
Dense(10, activation=’softmax’)
])
model.compile(optimizer=’adam’, loss=’categorical_crossentropy’, metrics=[‘accuracy’])
# ===== 3. コールバック =====
callbacks = [
EarlyStopping(monitor=’val_loss’, patience=10, restore_best_weights=True),
ReduceLROnPlateau(monitor=’val_loss’, factor=0.5, patience=5),
ModelCheckpoint(‘best_cifar10_model.keras’, monitor=’val_accuracy’, save_best_only=True)
]
# ===== 4. 学習 =====
history = model.fit(
X_train, y_train,
epochs=50,
batch_size=64,
validation_split=0.1,
callbacks=callbacks
)
# ===== 5. 評価 =====
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f”\n🎯 テスト精度: {test_acc:.4f}”)
print(f”🎯 テスト損失: {test_loss:.4f}”)
📝 STEP 18 のまとめ
✅ このステップで学んだこと
- CIFAR-10:32×32のカラー画像、10クラス分類
- CNNの典型構造:Conv→BN→ReLU→Poolのブロック
- フィルター数:32→64→128と徐々に増やす
- BatchNormalization:学習の安定化に効果的
- Dropout:過学習防止(特に全結合層で重要)
- コールバック:EarlyStopping + ReduceLROnPlateauの組み合わせ
💡 CIFAR-10の目安精度
70%台:基本的なCNN
80%台:BatchNorm + Dropoutを適切に使用
85%以上:データ拡張を使用
90%以上:転移学習を使用
🚀 次のステップへ
CNNアーキテクチャを構築できたので、次のSTEP 19ではデータ拡張(Data Augmentation)を学びます。
限られたデータから多様な訓練データを生成し、精度を向上させましょう!