今回は、顔画像から年齢を推定する回帰問題をやってみたいと思います。
こんにちは cedroです。
先回、3つの変数(専有面積、駅徒歩、築年数)から家賃を推定する回帰問題をやってみました。
言い換えれば数字から数字を回帰分析させたわけですが、そうすると今度は画像から数字を回帰分析させてみたくなって来る。
ということで今回は、顔画像から年齢を推定する回帰問題をやってみたいと思います。
まずは、Webで顔画像と年齢が載っているデータベースを探してみると、IMDB-WIKIデータセットというのを見つけました。
これは、IMDbに460,723枚、Wikipediaに62,328枚、の顔画像と人物に関するメタデータがあります。
ちなみに、画像から年齢推定を行うコンペの優勝チームも事前学習のデータセットとして、これを利用したらしいのです。素晴らしい!
しかし、これを使おうとすると、Pythonを使えないと無理なんですねー。でも、私、まだPython触ったことないので。。。。
もっと手軽に、データを収集できるサイトはないものかと探してみると、
その名は、日本最大級のタレント情報網「タレントデータバンク」!
データ数は男性10,445人、女性14,055人、合計24,500人とまずまず充実しています。
特筆すべきは、豊富な検索条件が用意されているので、目的に合った画像データを効率的に収集すること。
まず、男性か女性かグループか、どんなジャンルの人かの検索条件を設定ができます。
これに加えて、年齢、血液型、出身地、身長、体重、スリーサイズなどまでも検索条件が設定が出来ます。そして、複数の条件を重ねて検索することも可能。これは色々活用ができそうですね。
データの収集・加工をする
収集する画像データは、11歳から70歳までの女性を1歳刻みで60種類に分け、各20人分集めることにしますので、60×20=1,200個。
さすがに、このデータ量になるとSnipping toolでいちいち画像保存するのは辛いので、Webで色々探した結果、Chromeブラウザの拡張機能「Image Downloder」を入れました。
これによって、Webページに表示されている画像データを一括してダウンロードすることができ、とても便利です。
拡張機能をインストールすると、Chromeブラウザの右上に起動ボタン①が表示されるようになります。
ダウンロードした画像の保存先は②の設定ボタンで設定します。
「詳細設定」の中に、ダウンロード先の設定があります。設定変更したい場合は、変更ボタンで押して変更できます。
それではデータ収集を開始します。
「タレントデータバンク」で検索をかけ、検索結果が表示されたら、「赤丸」ボタンを押してImage Downloderを起動します。
「Select all」を選択し、「 Dawnload 」ボタンを押します。
*どの画像をダウンロードするか個別に選択も出来ますが、とりあえず全部ダウンロードして、後でいらないものを削除する方が早いです。
「YES」ボタンを押すと、一括ダウンロードがあっと言うまに完了します。こんな感じでデータを収集して行きます。
なお、今回は、データ量がいつもと比べてかなり多いので、ダウンロードした画像の顔部分だけ切り抜くプロセスは省き、そのまま使うことにします。手抜きですねー(笑)。
画像データのダウンロードが完了したら、XnCovert でリサイズを掛けます。まず、XnCovertを起動し、リサイズを掛けたい画像をドラッグ&ドロップします。
動作設定画面です。オリジナルサイズの200×200ピクセルから64×64ピクセルにリサイズする設定です。
出力設定画面です。リサイズした画像の保存先を設定します。私は、11歳のデータは、フォルダー名「11」に保存することにします。
形式は、「JPG-JPEG/JFIF」を選択します。そして、保存するファイル名は「##」開始インデックス「1」としました。
これで「変換」ボタンを押せば、フォルダー名「11」に、01.jpg~20.jpgの画像データが格納されます。
こんな感じで、フォルダー「11」~「70」まで作成を完了したら、学習・評価ファイルを作成します。
但し、まともにやると、1201行のCSVファイルをゼロから作ることになって大変です。
なので、SONY Neural Network Consoleが持っている、画像カテゴリ毎にフォルダ分けされた画像を元に画像分類用データセットを作成する機能を使います。
C:直下に、SNNC70のフォルダーを作成し、その中にSourceフォルダーとOutputフォルダーを作りまり、Sourceフォルダーの方に、作成した「11」~「70」の画像フォルダーを格納します。
そうしたら、Neural Network Consoleを起動し、DATASET画面で、「Create Dataset」ボタンを押します。
ここの設定で注意すべきは、Shuffle the order of the dataのチェックを外し、Output Fileは学習ファイルの方だけ100%にしておくことです。
*この2つをやっておかないと、データ順がバラバラになったり、変なところで分割されてしまい、後の処理が面倒ですので。
左側がNeural Network ConsoleがSNNC70のOutputフォルダーの中に作成してくれた、age_train.csvファイルです。
このage_train.csvをOutputフォルダーから抜き出して、左側のように修正します。
今回は、yがラベルではなく変数なので、y → y__0 に変更します(yと0の間は、ダブルアンダースコアであることに注意)。
y__0:dataは11歳〜70歳なので、y__0:dataの最大値が1になるように、11を引いて59で割った数字に加工します。なので、12歳のフォルダーの値は、(12ー11)/ 59=0.01694153です。
後は、このファイルを学習ファイルと評価ファイルに分割すればOKです。私は、学習ファイル960個(80%)、評価ファイル240個(20%)に分割しました。
出来た学習ファイルと評価ファイルは、SNNC70のOutputフォルダーに入れて、DATASET画面のOpen datasetで読み込み登録しておきます。
ニューラルネットワークの作成・学習
今回流用するプロジェクトは、binary_connect_mnist_LeNet.sdcproj です。
EDIT画面で、修正を掛けます。Input は、1,28,28 → 3,64,64(白黒28×28 → カラー64×64)。
下から4段目の BinaryConnectAffine_2 は、10 → 1(10分類から変数)。
下から1段目と2段目は、Softmax → Sigmoid 、CatgericalCrossEntorpy → SquaredError (分類から回帰)
Batch Size:60、MaxEpoch:200で学習した結果です。所用時間2時間30分。
さすがに、データが1200個で、そこそこの構成のニューラルネットワークだと、結構時間がかかります。
学習状況は、学習誤差は下がっていますが、評価誤差がなかなか下がりません。あまり学習は上手く進んでいないようですね。
評価してみます
評価結果です。y__0:dataが実際のデータ、y’が推定したデータです。No.62を見ると、実際が0.2542372881、推定が0.2639310956で、推定が実際より約4%高くなっているようです。
評価画面を右クリックして、評価結果をCSVファイルにセーブします。このままでは分かり難いので、加工します。
データを59倍し11を足して年齢データに戻し、差異が分かる項目を追加します。
さて、どういう画像データの時、大きく外しているのか具体的な例を見てみましょう。
この2人は実際は12才ですが、推定はそれより30才以上も上に外しています。
人間では、ちょっと間違えようのないレベルですが、全体的に低年齢層の推定精度が悪いです。
この2人、実際は左側が67才、右側が68才ですが、推定はそれより30才以上も下に外しています。
右側は、ちょっとニューラルネットワークには高度な問題だったかもしれません(笑)。
実際年齢と推定年齢を散布図にして全体像を見てみます。
なんかあまり上手く推定ができていないようですね(笑)。
今回は「画像の顔部分だけ切り抜くプロセス」をサボって入れていないので、その分精度は悪くなったかもしれません。
それにしても、画像データから数値を回帰させるという問題は、ディープラーニングらしくていいですねー。
では、また。