myaun’s blog

FaceNetによる顔画像の特徴量抽出 - アイドル画像による検証 -

1. はじめに

本記事では、アイドルブログの画像から検出された顔画像からFaceNetによる特徴量を抽出しました。 そして、得られた特徴量の表現力や挙動を確認しました。

この検証は、ブログやSNSなどのメディアで、気になるメンバ以外の投稿に気になるメンバが出現したときに検出したいと思うことがあり、そのための1歩目の実験です。

ラベル付けをする根性が無いので、自動ラベル付け or 1枚だけ(プロフィール画像など)から学習するOne-shot learning (or Few-shot learning)により、これが実現できればいいなと思っています。 今回は、FaceNetのような大規模顔画像データセットで学習済みのモデルから得られる特徴量で、どの程度表現可能か検証してみました。

参考

本記事は以下の記事を参考をしたり、影響を受けたりしてます。
特にすぎゃーんさんの記事すごい。ラベル付けすごいし、3年以上前にやってることもすごい。

2. FaceNetによる顔画像の特徴量抽出

2-1. ブログ画像を収集

欅坂46、日向坂46のブログをスクレイピングし、画像を取得しました。

  • 対象メンバ数: 38名
  • 総取得画像数: 47740枚

使用したコード: keyakizaka46-mining/retrieve_Blog_images.ipynb at master · haradai1262/keyakizaka46-mining · GitHub

2-2. ブログ画像から顔検出、保存

物体検出のSOTAとして有名であるYOLOv3を使いました。 実装は以下のコードを参考にしました。

タスクが顔検出なので、YOLOv3の重みとして、顔検出データ・セットWIDER FACE: A Face Detection Benchmarkで学習済みのものを使用しています。 今回は、パッと見た感じ検出された顔画像のサイズが小さいものは誤検出が多かったので、サイズが小さいものを取り除きました。 最終的に、検出された顔画像は29825枚でした。

検出結果例は以下の通りです。

入力画像 f:id:myaun:20190313194405j:plain

検出された顔画像

f:id:myaun:20190313194652p:plainf:id:myaun:20190313194625p:plainf:id:myaun:20190313194642p:plain

使用したコード: keyakizaka46-mining/script/risa_inf/face_detection at master · haradai1262/keyakizaka46-mining · GitHub

2-3. Facenetにより顔画像から特徴量抽出

FaceNetは2015年にGoogleの研究者により発表された手法です。 FaceNetでは、画像間の距離をTriplet Lossを用いた距離学習により、サンプルと同じものとの距離を近く、異なるものとの距離を遠くにマッピングされるように学習されます。 これにより、顔認識やクラスタリングのための高い表現力を持つ顔画像のベクトル表現を取得することを実現しました。

以下のコードで、公開されている最新の学習済みモデルは、Inception ResNet v1をCasia-WebFaceやVGGFace2で学習したものらしい。今回の実験では、こちらの学習済みモデルを使用して特徴量を抽出しました。

使用したコード: keyakizaka46-mining-gpu/extract_facenet_features_from_blog_faceimages.ipynb at master · haradai1262/keyakizaka46-mining-gpu · GitHub

2-4. 得られた顔画像特徴量の検証

A. 類似顔画像検索

得られた特徴量を用いた類似画像検索を行いました。検索は、Pythonの近似最近傍探索ライブラリAnnoyを使いました。 他の特徴量と比較したかったので、物体認識のデータセットであるImageNetで学習されたVGG16の中間層(fc2)の出力値でも同じことを比較しました。

実行結果の一部は以下の通りです。 結果がわかりやすそうなものを選びましたが*1、他の結果を見てもFaceNetは特徴的な顔のメンバはある程度表現できているように感じました。

  • 各行の一番左がクエリ画像で、右から順に距離が小さい画像です。
  • 上段がFaceNetによる検索、下段がVGG16による検索です。
  • ◎が付いてるものは、クエリ画像と人物が一致しているものです(私の目視チェック)

f:id:myaun:20190313213856p:plain

f:id:myaun:20190313213813p:plain

f:id:myaun:20190313213836p:plain

f:id:myaun:20190313213750p:plain

f:id:myaun:20190313213021p:plain

B. t-SNEによる2次元可視化

得られた特徴量をt-SNEにより2次元空間へ射影しました。 ここからは、対象とする画像が多すぎると苦しい(マシン的にも確認の難しさ的にも)ので、以下の1メンバのブログから取得された顔画像のみを対象にしました。

結果は以下の通りです。
顔がちゃんと写っている画像であれば、ある程度同じメンバが近くに集まっているように見える(気がする)

f:id:myaun:20190313212013p:plain

C. クラスタリング

得られた特徴量を用いてクラスタリングをしました。 クラスタリング手法はGMMを採用し、クラスタ数は20としました。

結果は以下の通りです。
各行の画像が同じクラスタの画像であり、最も左から順にクラスタ中心に距離が近い画像です。

f:id:myaun:20190309015628p:plain f:id:myaun:20190309015656p:plain

全体としては、同じメンバの画像が同じクラスタになっていたり、同じ渡邉理佐の画像であっても雰囲気や撮影時期が近いものが同じクラスタになっているように見える。 例えば、Cluster 8やCluster 17は、渡邉理佐以外の同じメンバが集まっている。 とはいえ、精度としては微妙な気がするし、そもそも顔検出自体もイケてない気がする。

使用したコード: keyakizaka46-mining-gpu/check_blog_faceimages.ipynb at master · haradai1262/keyakizaka46-mining-gpu · GitHub

3. 終わりに

  • 類似画像検索やクラスタリングでも一部メンバ毎に分割されていたので、ある程度の表現力はありそう
  • 顔検出自体の精度が気になるので、以下の記事などを参考に顔の角度補正や前処理、後処理を追加して改善したい
  • One-shot Learningを夢見てるけど、コンピュータビジョン系あんまりなので、できそうか無理そうかも勉強しなきゃ分からん
  • 適合性フィードバックと距離学習みたいな方法もやってみたいとおもった
  • 次はMusic Videoを使って実験してみたい

*1:私がFaceNetがうまくいっていそうなものを意図的に選んでるかもしれませんが...