日向坂46の顔識別をしてみた KerasでResnet50によるfine tuning

開発環境

CPU: Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz

RAM: 24GB

GPU: NVIDIA GeForce GTX 1060 6GB

TensorFlow 1.13.1

Keras 2.2.4

 

はじめに

以前TensorFlowで作成した識別器では精度もまあまあぐらいだったためもうちょっと良くしたいなと思っていたのでやってみました.

 

以前の記事

tsu-tech.hatenablog.com

 

Deep Learningでうまくいってる事例で思い浮かんだのが jirou_deep だったので調べてみたところ,どうやらfine tuning(ファインチューニング)というものを使用していることを知りました.

Large Scale Jirou Classification - ディープラーニングによるラーメン二郎全店舗識別

 

fine tuning(ファインチューニング)

既存のモデルの一部を再利用し,新しいモデルを構築する手法です.VGG16,VGG19,ResNet50などすでに訓練済みの代表的なモデルを利用するのがよくあるパターンみたいです.注意点として学習に使用されていた画像と実際に自分が学習させて識別したい画像がかけ離れているとうまくいかないことがあります.(知らずに1回やってしまいました)

tech.wonderpla.net

 

モデル選定

fine tuningをやってみるまでは決まり,どのモデルを使うか探してみたところKerasで利用できる keras-vggface というモデルがあったのでこれを使ってKerasで実装することにしました.

github.com

 

caffe(オープンソースディープラーニングライブラリ)からKeras用にモデルをコンバートしたものみたいです.顔認識用に学習されたVGG16,Resnet50,Senet50のモデルを利用することができます.このうちResnet50のモデルを利用してfine tuningを行うことにしました.

 

fine tuningでは元のモデルの重みを自分が用いるデータセットに合わせて再学習させることができます.Resnet50では以下のようなモデル構造になっています.

https://i.stack.imgur.com/XTo6Q.png

 

 CNNの入力層に近い層では画像のおおまかな特徴を学習して深くなるほど特徴的な部分を学習するらしいのでfine tuningでは最後の方の層だけは重みを学習してそこまでの層は元のモデルの重みを使うのがよくあるパターンみたいです.

例に習い最後の色のブロック部分([3x3 conv, 512, /2]~[3x3 conv, 512])の重みだけ学習するようにしました.

全結合層ではFlatten()の代わりにGlobalAveragePooling2D()を利用しています.Flatten()と同じように出力を平滑化するのですがパラメータ数を減らすことができるので過学習を防ぎやすくなるそうです.

 

ソースコード

 

以前と同様でTFRecordから画像を読み込んでいます.モデルは学習用とテスト用を2つ作成し1エポックごとにlossとaccuracyを計算します.TensorBoardに学習時の画像を出力してみたところ,KerasでTFRecordから読み込む場合だと1ステップごとの学習画像が同じ処理になっていたみたいなので学習画像の水増し処理はランダムクロップとランダムフリップだけにしておきました.

学習,テストに用いた画像は前回と同じものを利用しました.(学習:約14000枚,テスト:約3600枚)

 

参考にしたブログなど

taka5hi.hatenablog.com

qiita.com

qiita.com

 

学習曲線 (train test)

accuracy

f:id:tsu_tech:20190511005808p:plain

 

loss

f:id:tsu_tech:20190511005930p:plain

 

testの最も良い地点での accuracy:98.1%,loss:0.1527 でした.

以前作成したモデルよりもaccuracyが向上して良さそうな感じです.

 

検証

何種類かの画像でテストしてみました.

間違っている場合には手動で✕つけてます.

 

・109

https://collabo-cafe.com/events/collabo/hinatazaka46-shibuya109-2019/

f:id:tsu_tech:20190511171648j:plain

 

f:id:tsu_tech:20190511171806j:plain

正答率:13/18 未検出:2

やたら佐々木久美に識別されてるのはなぜか分からない...明るめの画像がそういう識別をされているのかな?

 

・HINABINGO!

https://abematimes.com/posts/6043370

f:id:tsu_tech:20190511172711j:plain

f:id:tsu_tech:20190511172726j:plain

正答率:18/20 未検出:0

 

ひらがなけやき1期生

https://ticket-trade.emtg.jp/artists/keyakizaka46/budokan2018/top

f:id:tsu_tech:20190511172914j:plain

f:id:tsu_tech:20190511172931j:plain

正答率:11/11 未検出:0

 

・ブログ画像 (5/2)

https://www.hinatazaka46.com/s/official/diary/detail/28896?ima=0000&cd=member

f:id:tsu_tech:20190511173118j:plain

f:id:tsu_tech:20190511173130j:plain

正答率:5/5 未検出:0

 

 ・Mステ

https://twitter.com/hinatazaka46/status/1119189265039052800

f:id:tsu_tech:20190511180348j:plain

f:id:tsu_tech:20190511180402j:plain

正答率:16/19 未検出:0

これは前回と同じ画像での検証ですが正答率13/19だったのが16/19になってます.

 

・うたコン

https://twitter.com/hinatazaka46/status/1115562448176599040

f:id:tsu_tech:20190511180618j:plain

f:id:tsu_tech:20190511180629j:plain

正答率:16/19 未検出:0

Mステの画像と同様金村美玖と富田鈴花が間違ってる...

 

検証用のソースコード

 

まとめ

・KerasでResnet50によるfine tuningをして顔認識をしてみた

・以前TensorFlowで1から学習したモデルよりも精度を高くすることができた