あどりぶろぐ=adli"B"log

表情認識を研究する海なし県民のブログ

CNNを用いた表情認識技術とそれを用いた映像コンテンツ推薦アルゴリズムの開発

f:id:shubarie:20171015175014p:plain 

 

研究内容紹介

僕は高専に6年間通っています。

 

…6年間とか小学生かよ!とツッコまれるかもしれませんが、中学を卒業した瞬間から工学のことが学べて、大学生が卒業するころには3年間の一貫した研究を修了しているというアドバンテージが高専生(専攻科生)にはある!…と思っています。

 

僕はその一貫した研究の2年目です。

 

研究テーマは「CNNを用いた表情認識技術とそれを用いた映像コンテンツ推薦アルゴリズムの開発」です。

 

このテーマは与えられたものではなく自ら考えだしたテーマなので、研究の意義があるのかという部分がいささか不安ではありますが、簡単に説明すると、動画を見ている被験者の表情をディープラーニングを使って認識して、その表情データを利用して被験者が好みそうな動画を推薦するアルゴリズムを開発する研究です。

 

簡単に説明するって言ったけどちょっと日本語的にややこしくなってしまった(;'∀')

 

先述したように高専(専攻科)では3年間の一貫した研究が行えますが、僕の場合は、

 

1年目は表情認識モデルの開発と検証

2年目は表情認識率の向上(教師データの拡張、転移学習等)・被験者の表情認識

3年目は推薦アルゴリズムの開発と検証

 

というスケジュールで研究を行っており、週に1回指導教員への報告会とミーティングがあるという状況です。

 

成果物とその解説

 

まずは今までの成果物(スクリプト群)を公開します。

(今日段階での成果を残しておきたいからbranchで分けてみたんだけどこういう使い方で良いだろうか…笑)

 

github.com


 

training_model.py⇒realtime_recognition.pyの順に実行すればとりあえずは動くと思います。

 

ただ、Githubの仕様上(?)dataの一部は省かれてしまったので、後述する方法でdataを別途用意してください。

 

ここで、それぞれのモジュールについても簡単に説明しておきます。

 

training_model.py

実行すると学習モデルを構築して、データセットから学習を行うスクリプト。学習したなかで最もAccuracyが高かった時の重みデータと、学習のログを吐き出す。モデルは下図のような構成になっている。

DatasetクラスとModelクラスが格納されており、モデル構築や学習にはKerasを使っている。

f:id:shubarie:20180209143344p:plain

学習モデル

realtime_recognition.py

OpenCV3でハードウェアカメラにアクセスして、ループで画像をプレビューしながらそこにフレームごとの表情認識結果をオーバーレイするスクリプト。直感的に認識精度を感じられるように作った。主にModelクラスのpredictメソッドを動かしている。

f:id:shubarie:20180209151936g:plain

リアルタイム表情認識の様子

このデモではPC画面で流している動画の登場人物をWebカメラで撮影して表情認識しています。

evaluation.py

新しい入力をラベルとセットで与えてテストする(=認識率を計算する)。複数の入力を与えて全体の認識率を計算することができるため、モデルの有用性がわかる。

主にModelクラスのevaluateメソッドを動かしている。

 

f:id:shubarie:20180208151434p:plain

リアルタイム表情認識とテスト それぞれのフロー

 

ちなみに、先日実験的にお笑い芸人のコントを視聴する自分の顔をrealtime_recognition.pyで保存し、evaluation.pyで表情認識率を計算したら、84.55%だった。

 

なお、学習に用いているデータは、以下のような特徴のもので、convert_fer2013.pyで画像として書き出した後に、基準(複数の顔が写っている、横を向いている等)に則っていくつかの画像を省いた上でその9割を学習モデルにぶち込んでいます。残りの1割はテスト用です。

 

fer-2013データセット

Challenges in Representation Learning: Facial Expression Recognition Challenge | Kaggle

表情の発現した画像データのピクセル値をcsv形式でまとめたデータセット。元画像はGoogle画像検索からスクレイピングしたもので、それぞれの画像に(0=Angry, 1=Disgust, 2=Fear, 3=Happy, 4=Sad, 5=Surprise, 6=Neutral)でラベル付けされている(っぽい)。枚数は36000枚弱で、すべてグレースケールかつ48x48の大きさにリサイズされている。

 

convertor_fer2013.py

 データセットをpandasで読み込んでnumpyでreshape、その後PIL(Python Image Library)で画像として書き出すスクリプト。書き出す際にラベルごとにディレクトリを分ける
 

課題点と今後の展望  

・顔領域認識の精度の低さ

映像コンテンツを視聴する人の顔が認識できれば良いので正面顔を認識できれば良いのですが、OpenCV3標準の顔領域認識では顔周りの装備品(メガネやマスク)、光の当たり方によって認識できない場合が多く難航しています。

 

・コンフュージョンマトリクスの表示

何をどれだけ誤認識したか知るために、evaluation.pyでコンフュージョンマトリクスが生成されるようにしたい。

 

・多様な動画を視聴して表情認識を行う

推薦アルゴリズムを開発するための知見の入手が目的です。

 

・撮影した顔画像群を効率的に分類するGUIアプリを作成する

現在は大量の顔画像を撮影⇒手作業でラベル付け(フォルダ分け)⇒テストという手順でテストを行っているのでこれを効率化するためのGUIアプリを作ろうかと考えています。

 

来夏の学会発表があるからちょっと焦ってる←

 

 

 

つづきます⇒