福くんと鈴木一真さんの画像分類問題をCNNで解く(訓練・テスト編)

これまではMNISTやIris等の既成のデータセットをもとにして問題を解いてきたが、 機械学習で一番苦労する部分は「データセットを作るところ」と噂でよく聞くので、 今回はデータセットを自分で作って分類問題を解いてみようと思う。

鈴木福くんと鈴木一真さんの画像をCNNに分類させてみることにした。下記にもあるように、福くんと鈴木一真さんは容姿が似ていることで有名なので、今回はこのお二方のサンプルを集めて分類させるところまでいきたい。
(参考:俳優・鈴木一真(44)と鈴木福くん(9)がソックリ過ぎる)

前記事で作成したデータセット(各カテゴリ50サンプルずつ)を使う。
ランダムに抽出した5サンプル↓はこんな感じ。 (上が福くん、下が鈴木一真さん)

f:id:yusuke_ujitoko:20170409204504p:plain f:id:yusuke_ujitoko:20170409204542p:plain

事前処理

事前処理としては標準化とテスト用サンプルの切り出しを行った。 各カテゴリごとに50サンプルあるが、 そのうち40サンプルずつを訓練に使い、残りの10サンプルでテストすることにした。

訓練に使ったモデル

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 128, 128, 32)      896       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 126, 126, 32)      9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 63, 63, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 63, 63, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 63, 63, 32)        9248      
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 61, 61, 32)        9248      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 30, 30, 32)        0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 30, 30, 32)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 28800)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 128)               3686528   
_________________________________________________________________
dropout_3 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 258       
=================================================================
Total params: 3,715,426.0
Trainable params: 3,715,426.0
Non-trainable params: 0.0
_________________________________________________________________

訓練結果(LossとAccuracy)

Loss

始めの方は順調に学習が進んでいるのがわかる。 また250エポック位から徐々に過学習の傾向が見られる。

f:id:yusuke_ujitoko:20170409203803p:plain

Accuracy

訓練データのAccuracyはほぼ1となっている。
一方、テストデータのAccuracyは一番良い時で0.85~0.9程度であり、過学習が進むと0.8程度に近づいていった。

f:id:yusuke_ujitoko:20170409203825p:plain

過学習を緩和するために、各層にL2正則化項を入れておいたが、効果は薄かったのかもしれない。
データセットがもう少し豊富であれば汎化性能をもっと上げられると考えられる。

福くんか鈴木一真さんか予測してみる

f:id:yusuke_ujitoko:20170409234417p:plain

福くんの画像は福くんと予測

f:id:yusuke_ujitoko:20170409234423p:plain

こちらの画像も正しく鈴木一真さんを予測

f:id:yusuke_ujitoko:20170409234429p:plain

コミカドは福くん

f:id:yusuke_ujitoko:20170409234435p:plain

太陽の男は鈴木一真さんのよう。

まとめ

データセットを作成するところを初めてやったらやはり大変。

  • ネット上の画像は重複が多い
  • 結局目視でゴミが混じってないか確認する必要がある。目が疲れる。

今回は各カテゴリ50個ずつしかサンプルを集められなかったが、サンプル増やせば汎化性能はよくなるはず。 あまりやりたくはないけど…

参考

ハリーポッターの組み分け帽子をCNNで実装してみた - Qiita
ちゅん顔の認識 - uphy’s tech blog

yusuke-ujitoko.hatenablog.com