目次[非表示]
はじめに
こんにちは、SHOUです!
今回は、「各クラス10枚だけでAIモデルを学習させたら、どこまで認識できるのか?」という実験をしてみました。
データを集めるのが大変なとき、小規模なデータでもモデルを動かしたいときってありますよね。
実験の条件
- クラス数:10(0〜9の手書き数字)
- 1クラスあたりの画像数:10枚(合計100枚)
- モデル:Kerasによる多層パーセプトロン
- 学習環境:Google Colab + GPU
- データ拡張:あり(回転・ズーム・シフトなど)
学習の様子
データは合計100枚と非常に少ないため、ImageDataGenerator
を使って水増し(データ拡張)を行いました。
データ拡張
#Google Driveをマウント
from google.colab import drive
drive.mount('/content/drive')
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# データ拡張の設定
datagen = ImageDataGenerator(
rescale=1./255, # 正規化
preprocessing_function=lambda x: 1.0 - x, # 白黒反転
rotation_range=30, # 回転
width_shift_range=10, # 横移動
height_shift_range=10, # 縦移動
zoom_range=0.1, # ズーム
shear_range=0.1, # 傾き
validation_split=0.2 # 検証データ分割
)
train_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/Colab/digits',
target_size=(28, 28),
color_mode='grayscale',
batch_size=32,
class_mode='sparse',
subset='training',
shuffle=True
)
val_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/Colab/digits',
target_size=(28, 28),
color_mode='grayscale',
batch_size=32,
class_mode='sparse',
subset='validation'
)
学習
import tensorflow as tf
from tensorflow import keras
model = keras.models.Sequential([
keras.layers.Input(shape=(28, 28, 1)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.3),
keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 学習
history = model.fit(train_generator,epochs=30,validation_data=val_generator)
このようにして、少ない画像でもバリエーションを増やし、学習を進めました。
学習結果
Epoch 1/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 2s 273ms/step - accuracy: 0.0432 - loss: 2.9863 - val_accuracy: 0.1500 - val_loss: 2.4238
Epoch 2/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 190ms/step - accuracy: 0.0625 - loss: 2.7927 - val_accuracy: 0.0500 - val_loss: 2.3816
Epoch 3/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 149ms/step - accuracy: 0.0688 - loss: 2.5960 - val_accuracy: 0.1500 - val_loss: 2.3417
Epoch 4/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 156ms/step - accuracy: 0.1023 - loss: 2.4672 - val_accuracy: 0.1000 - val_loss: 2.3062
Epoch 5/30
・・・
Epoch 26/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 175ms/step - accuracy: 0.0646 - loss: 2.3042 - val_accuracy: 0.1000 - val_loss: 2.3020
Epoch 27/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 194ms/step - accuracy: 0.1177 - loss: 2.3022 - val_accuracy: 0.0500 - val_loss: 2.3025
Epoch 28/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 146ms/step - accuracy: 0.1203 - loss: 2.3023 - val_accuracy: 0.1000 - val_loss: 2.3026
Epoch 29/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 160ms/step - accuracy: 0.0932 - loss: 2.3028 - val_accuracy: 0.1000 - val_loss: 2.3026
Epoch 30/30
3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 153ms/step - accuracy: 0.0818 - loss: 2.3028 - val_accuracy: 0.1000 - val_loss: 2.3026
学習ログを見ると、「学習しているように見えて、実はほぼ何も学習していない」という状態となっています。
- accuracy: ~0.08 〜 0.15
- val_accuracy: 0.05 〜 0.15
- loss: ≈ 2.30
📝 まとめ:画像が少なすぎるとAIは学習できない
今回の検証から、1クラス8枚、全体で80枚という極端に少ないデータでは、AIモデルはほとんど学習できないことが明確になりました。 実際のログでは、精度や損失が改善せず、「学習しているように見えて何もしていない」状態が続いていました。
🔍 原因の本質
- 学習画像が極端に少ない(各クラス8枚)
- 検証データも各クラス2枚では評価できない
✅ 有効な対策
-
事前学習を有効にする
MNISTなどの大規模データセットでまず学習し、その後に自作データでファインチューニングする。 -
モデル構造をCNNに変更
画像の空間的特徴を活かすConv2D構造を使用。model = keras.models.Sequential([
keras.layers.Input(shape=(28, 28, 1)),
keras.layers.Conv2D(32, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
-
データ拡張をさらに強化(オプション)
水増しは補助的な手法だが、効果はある。datagen = ImageDataGenerator(
rescale=1./255,
preprocessing_function=lambda x: 1.0 - x,
rotation_range=40,
width_shift_range=0.3,
height_shift_range=0.3,
zoom_range=0.2,
shear_range=0.2,
validation_split=0.2
)
🎯 結論:データ量は正義。少なすぎるなら戦略が必要
画像分類AIを学習させるには、最低でも各クラス50〜100枚は必要です。
少量しか集められない場合は、事前学習+CNN+ファインチューニングを組み合わせて精度を引き出しましょう。
次回は、実際に「事前学習+CNN」の構成で再学習し、どこまで改善されるかを検証していきます!
0 件のコメント:
コメントを投稿