Open3
野鳥の羽を識別してくれる何かを作りたい

今の自分
- 機会学習ド初心者
- Pythonド初心者
やりたいこと
- 拾ってきた鳥の羽を識別したい
- 機械学習の世界をちょっと知りたい
作戦
- Claudeに家庭教師をお願いする
ゴール
- この前拾ってきたフクロウの羽を識別できること

Claude先生に相談
🎯 基本的な学習ロードマップ
- Step 1: 機械学習の基礎理解
- 画像分類の概念 → CNNの仕組み → 転移学習 → 実装
- Step 2: 実践的な技術スタック
- フレームワーク: TensorFlow/Keras(初心者向け)
- ベースモデル: EfficientNet-B0(軽量で高性能)
- データ: まず5-10種類の野鳥から開始
- 環境: Google Colabで無料で始められます
所感
とりあえずプロトタイプ作りつつ調べつつ行ってみよー(おー)

ダミーデータを使用した簡単なデモ実装
アプローチ
- 初期化
- モデル作成
- ダミーデータ作成
- クイック訓練
- 予測テスト
- 結果可視化
- モデル情報表示
コード
# 野鳥羽識別システム - シンプル動作確認版
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras import layers, models
print(f"TensorFlow Version: {tf.__version__}")
print(f"GPU Available: {len(tf.config.list_physical_devices('GPU')) > 0}")
class SimpleBirdClassifier:
def __init__(self, num_classes=5):
self.num_classes = num_classes
self.species = ['スズメ', 'カラス', 'ハト', 'シジュウカラ', 'ヒヨドリ']
self.model = None
def create_model(self):
"""シンプルなEfficientNetベースモデル"""
print("モデル作成中...")
# EfficientNetB0をベースに使用
base_model = EfficientNetB0(
weights='imagenet',
include_top=False,
input_shape=(224, 224, 3)
)
# 転移学習のため、ベースモデルの重みは固定
base_model.trainable = False
# シンプルな分類ヘッドを追加
self.model = models.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dropout(0.2),
layers.Dense(128, activation='relu'),
layers.Dropout(0.1),
layers.Dense(self.num_classes, activation='softmax')
])
# コンパイル(シンプルなメトリクスのみ)
self.model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
print(f"✓ モデル作成完了")
print(f" パラメータ数: {self.model.count_params():,}")
print(f" 分類クラス数: {self.num_classes}")
return self.model
def create_dummy_data(self, train_samples=100, val_samples=30):
"""テスト用のダミーデータ作成"""
print("ダミーデータ作成中...")
# 訓練データ
X_train = np.random.random((train_samples, 224, 224, 3))
y_train = np.random.randint(0, self.num_classes, train_samples)
y_train = tf.keras.utils.to_categorical(y_train, self.num_classes)
# 検証データ
X_val = np.random.random((val_samples, 224, 224, 3))
y_val = np.random.randint(0, self.num_classes, val_samples)
y_val = tf.keras.utils.to_categorical(y_val, self.num_classes)
print(f"✓ ダミーデータ作成完了")
print(f" 訓練データ: {X_train.shape}")
print(f" 検証データ: {X_val.shape}")
return (X_train, y_train), (X_val, y_val)
def train_quick_test(self, train_data, val_data, epochs=3):
"""クイックテスト用の軽い訓練"""
X_train, y_train = train_data
X_val, y_val = val_data
print(f"クイック訓練開始({epochs}エポック)...")
# シンプルな訓練
history = self.model.fit(
X_train, y_train,
validation_data=(X_val, y_val),
epochs=epochs,
batch_size=32,
verbose=1
)
print("✓ 訓練完了")
return history
def test_prediction(self, test_data):
"""予測テスト"""
X_test, y_test = test_data
print("予測テスト中...")
# 予測実行
predictions = self.model.predict(X_test[:5], verbose=0)
print("✓ 予測結果(最初の5サンプル):")
for i, pred in enumerate(predictions):
predicted_class = np.argmax(pred)
confidence = np.max(pred)
actual_class = np.argmax(y_test[i])
print(f" サンプル{i+1}:")
print(f" 予測: {self.species[predicted_class]} (信頼度: {confidence:.3f})")
print(f" 実際: {self.species[actual_class]}")
print()
def plot_simple_results(self, history):
"""シンプルな結果可視化"""
plt.figure(figsize=(12, 4))
# 精度
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Train')
plt.plot(history.history['val_accuracy'], label='Validation')
plt.title('精度の推移')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True)
# 損失
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Train')
plt.plot(history.history['val_loss'], label='Validation')
plt.title('損失の推移')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
def run_complete_demo():
"""完全なデモ実行"""
print("=" * 50)
print("🐦 野鳥羽識別システム - デモ実行")
print("=" * 50)
# 1. 分類器初期化
classifier = SimpleBirdClassifier(num_classes=5)
# 2. モデル作成
model = classifier.create_model()
# 3. ダミーデータ作成
train_data, val_data = classifier.create_dummy_data()
# 4. クイック訓練
history = classifier.train_quick_test(train_data, val_data, epochs=3)
# 5. 予測テスト
classifier.test_prediction(val_data)
# 6. 結果可視化
classifier.plot_simple_results(history)
# 7. モデル情報表示
print("\n" + "=" * 30)
print("📊 モデル情報")
print("=" * 30)
model.summary()
return classifier, history
if __name__ == "__main__":
# デモ実行
classifier, history = run_complete_demo()
モデル作成
- 転移学習を使用
- 転移学習とは既存の学習済みモデルを利用し、出力層のみカスタマイズする手法
- 今回はEfficientNetB0というモデルを土台にする
- 最終層(出力層)だけを野鳥識別用にカスタマイズする
学んだこと
- Pythonの
__init__
メソッドはJavaのコンストラクタ的なものらしい - メソッドの第一引数に渡される
self
はこのオブジェクト自身のことらしい(this的な?) - ダミーデータを作成して使うと実際の羽画像がなくても動かせるのでお試しに良さげ
所感
- 転移学習とか出力層とかEfficientNetB0とかよく分かっていないので勉強したい
- モデルのコンパイルもよく分からん
- エポックもあまりピンときてない
- 静的型付け言語しか使ったことがないせいかすごくムズムズする
- Google Colabって諸々楽ちんだけどなんか使いにくさも感じる
- 知らないこと多すぎるので一つずつ調べていきましょー