CNNを使って父親と子供を写真で判別するAIモデルを作ろう!
CNNを使って父親と子供を写真で判別するAIモデルを作ろう!
AIやCNN(畳み込みニューラルネットワーク)という言葉を聞いたことがあっても、実際に「自分で作るなんて無理…」と思っていませんか?そんなことはありません!今回は、初心者でも簡単にできるCNNを使ったAIモデルの作り方を、ステップバイステップで紹介します。しかも、今回は「父親と子供を写真から判別するAI」というテーマで進めていきます。
ステップ 1: 準備は大事!Google Colabを使って手軽にAI開発を始めよう
まずは、AIを作るための環境を整えます。Google Colabというブラウザ上で動くPython環境を使えば、初学者でも簡単に高性能なAIを作ることができます。GPUを無料で使えるので、難しい設定は一切不要です!
1.1 Google Colabを開こう
Googleアカウントにサインインして、Google Colabにアクセスします。
「新しいノートブック」を作成して、AIの冒険に出発です!
1.2 必要なツールをインストール
AIを動かすためのツール「TensorFlow」と「Keras」をインストールします。Colabのセルに以下のコードを貼り付けて実行してください。
!pip install tensorflow keras
ステップ 2: データを集めよう!父親と子供の写真をGoogle Driveにアップロード
次に、AIに「これが父親」「これが子供」と教えるための写真データを準備します。Google Driveに写真をアップロードし、AIがそれを学習するようにします。
2.1 フォルダ構成を準備
Google Drive内に以下のようなフォルダ構成を作りましょう。これで、AIが自動的にどれが父親の写真で、どれが子供の写真かを理解してくれます。
MyDrive/
└── AI Discrimination/
├── father/ # 父親の写真をこのフォルダに
└── child/ # 子供の写真をこのフォルダに
2.2 Google DriveとColabを連携させよう
次に、Google ColabからGoogle Driveにアクセスできるようにします。以下のコードを実行して、Driveをマウントしましょう。
from google.colab import drive
drive.mount('/content/drive')
これで写真データが準備完了です!
ステップ 3: いよいよAIモデルを作成!魔法のようなCNNモデル
ここからがワクワクの本番!CNNを使って、AIが父親と子供を判別できるようにプログラムを作成します。今回はデータ拡張という技術を使って、写真のバリエーションを増やし、AIがさらに賢くなるように工夫します。
データ拡張を使った理由
データの準備の段階で、父親の写真が7枚、子供の写真が11枚という状況でした。父親の写真が少ないため、AIがバランスよく学習できない可能性があったので、データ拡張を使ってデータを増やしました。これにより、少ないデータでもAIがうまく学習できるようになります。
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# データ拡張を使ってデータセットを準備
train_datagen = 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'
)
# Google Drive内の写真を読み込み
train_generator = train_datagen.flow_from_directory(
'/content/drive/MyDrive/AI Discrimination/', # データセットが保存されているGoogle Driveのパス
target_size=(150, 150),
batch_size=20,
class_mode='binary' # 2クラス(父親と子供)を判別する
)
# CNNモデルの作成
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid') # 父親と子供を分類する
])
# CNNモデルの作成の解説
# 1. **モデルを作る**
# 最初に、モデルを作るための箱(`Sequential`)を用意する。ここにレイヤー(データを処理する層)を順番に積み重ねていく。
# 2. **画像を読み込んで特徴を捉える**
# 次に、画像を処理して特徴を捉えるための「畳み込み層(Conv2D)」を使っている。これが、画像の特徴(例えば、目や口の形)を見つけてくれる。
# - 3×3のフィルタを使って、画像の小さい部分を見ていくよ。
# - 最初は、画像サイズが「150×150ピクセル」で、色の情報が3つ(赤・緑・青)ある。
# 3. **画像を小さくして計算を楽にする**
# 「プーリング層(MaxPooling2D)」というのを使って、画像を小さくしながら重要な部分だけを残す。これをすることで、コンピュータが画像を処理するのが楽になるんだ。
# 4. **画像の中の特徴をさらに細かく見る**
# 畳み込みとプーリングを何回か繰り返して、より深く、細かい特徴を探していく。
# 5. **画像を1本の長いデータに変える**
# 「Flatten」という処理を使って、2Dの画像を1本の長いデータに変える。これで、画像が数字の列になるんだ。
# 6. **最後に分類する**
# - 「Dense層」という層で、たくさんの数字を使って、どの特徴が「父親らしい」か「子供らしい」かを判断する。
# - 最後に、出力が1つの「sigmoid層」を使って、結果を0か1にする。例えば、0なら「父親」、1なら「子供」って感じ。
# 結論
#このモデルは、画像を見て、父親か子供かを判断するための「脳」を作っているんだ!
# モデルをコンパイル
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# クラスのバランスを調整して学習
class_weight = {0: 1.5, 1: 1.0} # 父親のデータが少ないため重みをつける
history = model.fit(train_generator, steps_per_epoch=100, epochs=10, class_weight=class_weight)
# モデルをGoogle Driveに保存
model.save('/content/drive/MyDrive/father_child_classifier.h5')
ステップ 4: 学習結果を確認しよう!損失値と精度の意味を知る
訓練が終わったら、モデルがどの程度正しく学習できたかを確認します。損失値と精度を確認することで、モデルの性能を評価できます。
損失値とは?
損失値(Loss)は、モデルがどれだけ間違っているかを示す指標です。値が低いほどモデルは正確に予測できていることを意味します。損失値が高いと、予測に多くの誤差があることを示します。
精度とは?
精度(Accuracy)は、モデルが正しく予測できた割合を示します。値が高いほど正確なモデルです。精度が90%以上であれば、かなり良いモデルといえます。
損失値と精度を表示するコード
print("損失値の履歴:", history.history['loss'])
print("精度の履歴:", history.history['accuracy'])
実際の結果では、最初は損失値が高く、精度も低い状態でしたが、訓練が進むにつれて損失値が下がり、精度が90%以上に達しました。最終的には一部のエポックで**100%**の精度を達成することができました!
ステップ 5: 精度をさらに向上させるための調整!
今回、精度が81.8%に達しましたが、より高い精度(90%以上)を目指して次のような調整を行いました。
1. エポック数を増やす
最初は10エポックで訓練を行っていましたが、モデルが十分に収束していないと感じたため、エポック数を20〜30に増やしました。エポック数を増やすことで、モデルがより多くのデータを学習し、精度が向上する可能性があります。
history = model.fit(train_generator, steps_per_epoch=100, epochs=30, class_weight=class_weight)
2. 学習率の調整
学習率が大きすぎると、モデルが急激に損失値を下げてしまい、安定した学習ができません。そのため、学習率を小さく(0.001から0.0001に)調整しました。これにより、モデルがより安定して学習できるようになり、精度が向上しました。
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])
3. **バッチサイズの調整
**
バッチサイズは1回の学習に使うデータの量を決定します。バッチサイズを適切に調整することで、学習の安定性が向上します。今回は、バッチサイズを20から16や32に調整して、より効率的な学習を目指しました。
train_generator = train_datagen.flow_from_directory(
'/content/drive/MyDrive/AI Discrimination/',
target_size=(150, 150),
batch_size=16, # バッチサイズを16に変更
class_mode='binary'
)
ステップ 6: 新しい写真でAIをテスト!驚きの判別力を体験しよう
学習が終わったモデルを使って、新しい写真でテストしてみましょう。父親と子供の写真をモデルに与え、正しく判別できるか確認します。
from tensorflow.keras.preprocessing import image
import numpy as np
# 判別したい写真を読み込む
img_path = '/content/drive/MyDrive/AI Discrimination/test_image.jpg'
img = image.load_img(img_path, target_size=(150, 150))
img_array = image.img_to_array(img) / 255.0
img_array = np.expand_dims(img_array, axis=0)
# モデルを使って予測
model = tf.keras.models.load_model('/content/drive/MyDrive/father_child_classifier.h5')
prediction = model.predict(img_array)
# 結果を表示
if prediction[0][0] > 0.5:
print("これは父親です!")
else:
print("これは子供です!")
AIが正確に「これは父親」「これは子供」と判別してくれるでしょう!
まとめ:AIは初学者でも手軽に作れる!ワクワクするプロジェクトを楽しもう
今回のプロジェクトを通じて、初学者でもCNNを使って父親と子供を写真から判別するAIモデルを作ることができることをお伝えしました。AIは、何も特別な技術者だけのものではありません。ちょっとした努力と工夫で、あなたも自分だけのAIモデルを作ることができるのです。