日陰のテクノロジ

卒業研究の備忘録と世間一般にタブーとされている技術について

制服JKの画像から学校名を推定できるCNNを作った

はじめに

女子高生を見て、どこの学校の制服なのか気になったことがないだろうか。

もちろんヤバい意味ではなく、見覚えはあるがどこの学校だったかど忘れした、というような知的好奇心から純粋に気になるシチュエーションのことだ。

最近ふと、CNN (Convolutional Neural Network)を使えば、制服の画像から学校名を推定できるのではないかと思ったので、機械学習への理解を深めるために制服JKの画像から学校名を推定できる装置を作ってみた。あくまで機械学習への理解を深めるためにだ。

エビデンス

画像分類で定番のCNNをKerasを用いて構築して学習を行った。

学習用データ集め

主にTwitterから女子高生の画像を収集した。何度か自分が何をやっているのかわからなくなったが、なんとか続行して3校の女子高生の画像を数枚集めた。 f:id:yoidea:20171119183040p:plain:h200

前処理

プリクラや集合写真が混在するデータをそのまま学習するのには無理があると判断したため、前処理を人力で行うことにした。

女子高生の画像から最も特徴が現れると思われる部分を切り出す。以下のイラスト(実際の画像を使うと問題があるため)を参考にして欲しい。

f:id:yoidea:20171119171552p:plain:h200

基本的には正面からの立ち姿が好ましい。首下からスカートの終端までを切り取る。

f:id:yoidea:20171119171558p:plain:h200

このような作業をひたすら行った。単純作業ではあったが不思議と疲れなかった。

最終的に3校各20枚、合計60のデータセットが完成した。

f:id:yoidea:20171119184449p:plain:h200

学習

Kerasを用いて、4層の畳み込み層と全結合層を持つ定番のネットワークを構築した。学習データが少ないので、ドロップアウトを極端に大きくしてみた。

詳しくはGithubを参照して頂きたい。

github.com

結果

テスト画像を用意

学習データとは別に女子高生の画像を用意した。TwitterGoogle画像検索を駆使して再度画像を集めた。

f:id:yoidea:20171119190823p:plain:h200

前処理

前処理を行う必要がある。将来的には自動化したいが試作品なので手動で行う。

3校各4枚、合計12枚のテストデータが完成した。

f:id:yoidea:20171119180021p:plain:h200

分類

プログラムを起動して、前処理を行った画像のパスを入力すると、学校名が推定された。

思いの外良い精度で驚いた。

>> test/uniformA1.jpg
○○○高校
 99% #############################

○○北高校
  0% 

○○南高校
  0% 
>> test/uniformB1.jpg
○○○高校
 39% ###########

○○北高校
 59% #################

○○南高校
  1%
>> test/uniformC1.jpg
○○○高校
  0% 

○○北高校
  0% 

○○南高校
100% ##############################

使用方法

手元でも動かしてみたいという方は是非プログラムをダウンロードしてみて欲しい。(くれぐれも悪用しないように

依存関係

  • Python 3.0 以上
  • Keras 2.0 以上 (Tensorflow backend)
  • Pillow
  • numpy
  • tqdm
  • h5py

ダウンロード

gitでリポジトリをクローンする。もしくはDownload ZIPからダウンロードしても問題ない。

git clone https://github.com/yoidea/JK_uniform_classifier.git
cd JK_uniform_classifier/

データ集め

まず、制服の女子高生の画像を収集する。(くれぐれも違法行為を行わないように

データセット用のディレクトリを作成して、その中に1校につき1ディレクトリを作成して、上記のように前処理をした画像を格納する。

ls images/
南高校     北高校     西高校     東高校
ls images/北高校/
01.jpg     02.jpg     ...     99.jpg

学習

引数を与えてtrain.pyを実行して学習を開始する。

例えば、データセット用のディレクトリがimages/で、バッチサイズが10枚、エポック数が3000回の場合は以下のように指定する。

python train.py --input images/ --batch 10 --epoch 3000

推定

学習が完了すると、train.pyと同じディレクトリにmodel.jsonnames.jsonweights.hdf5が生成される。それを確認してclassify.pyを実行する。

python classify.py
Using TensorFlow backend.
Enter the file name (*.jpg)
>> 

そうすると、プロンプトが出現するので、判定したい画像のパスを入力する。

>> test/uniform.jpg
南高校
 10% ###

北高校
 60% ##################

西高校
 20% ######

東高校
 10% ###

その制服が各学校のものである確率が出力される。

今後の課題

判定できる学校数を増やす

3校だからたった20枚の画像で良い精度がでているのではないか、と思われるかもしれない。全くその通りだと思う。

制服は特性上、似ているものが存在し、学校数が増えれば増えるほど正確な判定が困難になる。

そこで、画像と位置情報を組み合わせることで解決したいと考えている。具体的には、撮影した画像の位置情報から半径20km県内の学校のみを対象にする、もしくは画像と一緒に位置情報もネットワークに入力する、などを考えている。

ご協力のお願い

このプログラムは機械学習を噛じったばかりの素人が作成している。そのため、野蛮なコードかもしれない。

問題点や違和感等、何かあれば是非IssueやPullRequestを投げて欲しい。(本音はGithubに友達がいないので会話してみたいだけ)