機械学習するためには、大量の教師データが必要です。これから始める方に参考になればと思い、人間の顔の教師データを作ってて感じたこと、反省点などを書き留めます。
大量画像処理は、記事「openCVで複数画像ファイルから顔検出をして切り出し保存」にあるコードを使っています。
openCVの基本に関しては記事「【入門者向け解説】openCV顔検出の仕組と実践(detectMultiScale)」を参照ください。
実行環境は下記のとおりです。
感想
画像の大量教師データを作成するのは、とにかく面倒
データサイエンティストと呼ばれる花形っぽい仕事の裏に「マエショリスト」と呼ばれる人がいると聞きました。その一端ではありますが、苦労を感じることができた気がします。とにかく手作業での時間がかかり地味です・・・
経験から得たTips
##1. プログラム実行、目視確認をできるだけ効率化する
プログラム実行、目視確認の流れをできるだけ効率化するために以下のことを実行しています。全体的には、下図のやり方で実施しています。
###1.1. 最初にサンプル実行して、detectMultiScaleのパラメータと画像の相性を理解しておく
ただ、闇雲に実行するのではなく計画を立てましょう。そのための情報をサンプル実行で取得します。筆者は、こんな感じでまとめていました。学習済モデルとしては"alt"が誤検知が少なく最も活用しました。
###1.2. 最初は誤検知率が低いパラメータから実行
まずは、誤検知率が低いパラメータでプログラム実行で顔検出をして、検出結果から目視で誤検知顔画像捨てる作業を少なくします。
###1.3. 検出した画像はフォルダ移動して分けておく
実際に正しい顔検出をしたらその画像は再度使う必要がないので別フォルダに置いておきます(図の「加工元画像(検知済)」フォルダ)。
###1.4. 検知率が高いパラメータで再実行
再度、顔検出を検知率が高いパラメータで実行します。元画像が十分にあるならば、このプロセス不要です。筆者は元画像が少なかったので、なんとか増やしたいと思い、この一連の作業を繰り返しました。
##2. openCVの顔検出率は60%から70%くらい
元画像や検出方法によりますが、だいたいopenCVの顔検出率は60%から70%くらいです。
筆者の場合、Bing Image Search APIを使って検出元画像を集めました(「PythonからBing Image Search API v5を呼び出して画像収集」参照)。
下記のその結果です。
人 | 検出率 | 検索エンジン画像収集数 | openCV顔検出画像数 | 備考 |
---|---|---|---|---|
柏木由紀 | 66% | 871 | 578 | パラメータを変えてかなり頑張ってこの程度 |
新垣結衣 | 74% | 822 | 604 | 女優さんは、歌っている画像が少なくて検出率が高い? |
松浦亜弥 | 60% | 778 | 463 | パラメータを変えなくて実行するとこの程度 |
モーニング娘。 | 160% | 726 | 1645 | 1枚からたくさんの顔画像を取得できるので100%超え |
「【入門者向け解説】openCV顔検出の仕組と実践(detectMultiScale)」記事で書いたとおり、openCVは傾きに弱いので、横向き画像だと検出してくれません。Heroku + OpenCVで簡易顔検出APIに書かれているような角度を考慮した機能を実装していれば、かなり検出率があがったでしょうが、そこまでしませんでした。
##3. openCVののパラメータと検知率
openCVのdetectMultiScaleメソッドパラメータでは、scaleFactor, minNeighbors, minSize を変えて実行します。パラメータの実装は記事「openCVの顔検出でパラメータを指定して手っ取り早く検出精度を高める」を参照ください。
scaleFactor=1.2, minNeighbors=2, minSize=[50,50]が誤検知率が低くて優秀でした。
##4. 顔検出をあきらめて画像水増しをする
OpenCVにこだわらず、教師データを増やすこともできます。その「こんな方法があるのか」と途中で気づいたのが画像加工による水増しです。「画像の水増し方法をTensorFlowのコードから学ぶ」の記事に方法が紹介されています。教師データ不足に悩まされたので、早めに気づければやれていたのに・・・