コスプレイヤーの画像から元ネタ(キャラ)を当てる

やりたかったこと

コスプレイヤーの画像から、その元ネタを当てる、というものを作りたかった。
タイトルの通り。

機械学習で何か作りたいけどアイデアがない、といったことを彼女に相談してみたところ、コスプレイヤーである彼女が「こういうのはどう?」と提案してくれた。

しかし学習のために画像を集めているときに大変気持ち悪がられてしまうという予想外の事態になってしまったので、このへんで終了して別のものを作ろうと思う。

コンセプトはなかなか面白いし役にたつ可能性もあるので誰かに意思を継いでもらえれば嬉しい。

モデル

畳み込み(24 x 3 x 3)

畳み込み(42 x 3 x 3)

ドロップアウト: 50%

maxプーリング(2 x 2)

(Flattenしておく)

全結合: 出力500

ドロップアウト: 20%

全結合: 出力200

全結合: 出力は分類するクラスの数

中間層の活性化関数はすべてReLU。

model.summary() の結果

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d (Conv2D)              (None, 128, 128, 24)      672
_________________________________________________________________
activation (Activation)      (None, 128, 128, 24)      0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 126, 126, 42)      9114
_________________________________________________________________
dropout (Dropout)            (None, 126, 126, 42)      0
_________________________________________________________________
activation_1 (Activation)    (None, 126, 126, 42)      0
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 63, 63, 42)        0
_________________________________________________________________
flatten (Flatten)            (None, 166698)            0
_________________________________________________________________
dense (Dense)                (None, 500)               83349500
_________________________________________________________________
dropout_1 (Dropout)          (None, 500)               0
_________________________________________________________________
dense_1 (Dense)              (None, 200)               100200
_________________________________________________________________
dense_2 (Dense)              (None, 6)                 1206
=================================================================
Total params: 83,460,692
Trainable params: 83,460,692
Non-trainable params: 0
_________________________________________________________________

用意したクラス

の6クラスを用意してみた。

画像のラベル付けは(作りが悪くなければ)フォルダにぶち込むだけで済むのでテキストの分類に比べると楽だなー等と思いつつ、インターネットで適当に各120枚くらい集めた。

各100ちょっとでは学習データとしてあまりにも心もとないので、 コントラストや明度などをいじった水増しデータも用意して2000枚くらいに増やしてみたが、過学習を起こしまくって逆に精度が下がってしまった(ので学習に使ったデータはオリジナルのみ)

精度は?

テストデータはもちろん分けたうえで

586/586 [==============================] - 8s 13ms/step - loss: 11.1606 - acc: 0.1928
Epoch 2/10
586/586 [==============================] - 2s 3ms/step - loss: 2.0719 - acc: 0.4761
Epoch 3/10
586/586 [==============================] - 2s 3ms/step - loss: 0.5985 - acc: 0.8225
Epoch 4/10
586/586 [==============================] - 2s 3ms/step - loss: 0.2646 - acc: 0.9403
Epoch 5/10
586/586 [==============================] - 2s 3ms/step - loss: 0.0915 - acc: 0.9812
Epoch 6/10
586/586 [==============================] - 2s 3ms/step - loss: 0.0432 - acc: 0.9966
Epoch 7/10
586/586 [==============================] - 2s 3ms/step - loss: 0.0106 - acc: 0.9966
Epoch 8/10
586/586 [==============================] - 2s 3ms/step - loss: 0.0065 - acc: 1.0000
Epoch 9/10
586/586 [==============================] - 2s 3ms/step - loss: 0.0019 - acc: 1.0000
Epoch 10/10
586/586 [==============================] - 2s 3ms/step - loss: 9.6496e-04 - acc: 1.0000
91/91 [==============================] - 0s 2ms/step
0.8021977949928452

最後の 0.8021977949928452 がテストデータを使った検証(model.evaluate)の結果。

8エポック目からaccuracyが1に達してしまい、明らかに過学習を起こしてしまっているが、学習に使ったのがたった100枚程度の画像だということを加味すれば正解率80%は悪くはない。

データをもう少し綺麗にする、丁寧に水増しする、新しいデータを調達する等すればもっと上がるだろうと思う。

おまけ

Webで動かしてみたかったのでDjangoウェブアプリケーションにして組み込んでみたがいろいろと大変で学びがあった

h5ファイルがでかい

学習はあらかじめ開発環境で済ませておいてh5ファイルとして保存しておく。

そのh5ファイルが学習したパラメータを持っているだけにとにかくでかい(今回は1GB少し)。

これをメモリにロードすることになるので、学習させる必要はなくてもある程度のスペックが求められる。

Linodeの8GBでどうにか動いたが$40/month。つらい。

Djangoアプリに組み込む場合の定石 is 何

Djangoの知見がなくどうしたらいいかよくわからなかったが、もしRailsならinitializersでモデルを読み込むだろうと考えてapps.pyで読み込んだ。合ってるんだろうか。。。

しばらく公開しておく

2018/10/19までは動かしておくので興味があれば。

nginxまともに設定してないのでいろいろとエラーが見えるかも

http://xxx.xxx.xxx.xxx/classifier/

注: 2018/10/20にインスタンスごと抹消予定

2018/10/27 追記
消しました