LoginSignup
4
2

More than 3 years have passed since last update.

[Neural Network Console Challenge]NNCを使って人の感情で画像を分類してみた

Last updated at Posted at 2020-03-31

はじめに

Sonyとレッジが企画するAI開発コンテスト「Neural Network Console Challenge」に参加しました!
私は『NNCで画像を学習し人の感情によって分類』に挑戦し、PIXTAの写真素材をポジティブな感情の画像とネガティブな感情の画像に分類し、約80%の精度を出すことができました。

[追記]
https://support.dl.sony.com/public-projects/2020/04/01/nnc-challenge_faceemotionclassification/
プロジェクトを公開しました。
Neural Network Console をご利用の方は上記ページ中の「Copy the project to Neural Network Console Cloud」からプロジェクトをコピーできます。

動機

今回このコンテストに参加した動機は、

  • NNC愛用家であること
  • 1万枚のデータセットがあること
  • GPU利用枠10,000円分を付与されること

です。
今まで無料のNNC(windows版)を使っていたので私のGPUなしPCでは画像を使った学習はしたくてもできませんでした...
なので、3つ目のGPU利用枠10,000円分はかなり大きな決め手となりました。
今回初めてGPUを使って、圧倒的計算能力に感動したのでGPUとCPUの比較も最後に載せています。

アノテーション

このコンテストはテーマが自由な分、アノテーションも自分でしないといけない...

手順4 新たな画像カテゴリ分類を考え、ダウンロードしたデータにアノテーション(タグ付け)する

正直、1万枚の画像のアノテーションは気が滅入る...
せめてもの作業効率化のために、簡単な画像仕分けプログラムを書いて暇なときにぼちぼちやりました。

分類する感情のカテゴリ

そもそも感情って何種類あるんだ?どこまで細分化するんだ?
という疑問が湧き、調べてみるとこんな本がありました。

『感情表現辞典』 中村 明

この本は人間の感情を喜,怒,哀,怖,恥,好,厭,昂,安,驚の10種類に分類し、それぞれに合った表現の言葉を収録しています。
これなら人間の感情を網羅できているみたいですが、細かすぎるかも...(喜と好の区別とか)

さらに調べてみるとこんな論文が見つかりました。

多次元感情ベクトルを考慮した名言検索手法の提案

この論文では『感情表現辞典』をもとに感情の次元圧縮をしています。
その結果、

  • 喜,好,昂,安
  • 哀,怖,恥,厭

の4種類に分類。
これをもとに1万枚のデータセットを仕分けしてみました。
しかし、数百枚仕分けして気づいたことが...
このデータセット、怒と驚がほとんどない!
といことで、

  • ネガティブ(哀,怖,恥,厭,怒)
  • ポジティブ(喜,好,昂,安,驚)

の2つのカテゴリに分類しました。
また、このデータセットには風景の画像もあり、感情が読み取れないので風景は別にしました。

その結果、下のようになりました。

  • ネガティブ 5704枚
  • ポジティブ 4121枚
  • 風景 175枚

ネガティブの画像例

pixta_21936140_S.jpgpixta_26390829_S.jpg

ポジティブの画像例

pixta_22374690_S.jpgpixta_26390326_S.jpg

風景の画像例

pixta_16544720_S.jpgpixta_21790230_S.jpg
学習用データ提供:PIXTA

学習

学習にはもちろんNNCを用いました。

データの整形

このデータセットの画像はサイズが様々でリサイズする必要があります。
そこで、NNCのデータセット作成機能を使ってデータの整形を行いました。
整形後の画像サイズは顔の表情をある程度読み取れるくらいのサイズとして256x256にしました。

Shaping Mode : Padding
Output Color Ch : 3(RGB)
Output Width : 256
Output Height : 256
Training ratio : 90%
Validation ratio : 10%
image.png

まずはそのまま

学習モデル
image.png

学習曲線
image.png

混同行列
image.png

精度71%!
でも、ポジティブの分類精度が悪いなぁ...
風景はデータ数が少ないので仕方ない気がします。

顔に注目したい!

写真から感情を読み取るには顔の表情が重要ということで、顔検出データセットで事前学習することにしました。
顔検出データセットには

kaggle : Face Detection in Images

を用いました。
このデータセットには409枚の複数人が写っている画像があり、顔領域のバウンディングボックスもあります。

学習には下のようなモデルを用い、感情分類にも用いれるように入力は同じ形にしました。
この学習モデルは感情分類にも用いる前半部分(Share_Unit)と顔検出用の後半部分(Face_Unit)に分かれます。
image.png

再学習

再学習では事前学習の学習済みモデルのShare_Unitの重みを初期値として用いました。
また、Face_Unitに代わって感情分類のためのEmotion_Unitを作り、下のようなモデルで学習しました。

学習モデル
image.png

学習曲線
image.png

混同行列
image.png

精度79.4%!!!
なんと、ポジティブの精度が50.23%から69.35%に上がりました!!!
おそらく、顔に注目したことにより笑顔をきちんと認識できるようになったのではないでしょうか。

分類結果

正しく分類された画像例

ネガティブ

pixta_21936140_S.jpgpixta_26390829_S.jpg

ポジティブ

pixta_22374690_S.jpgpixta_26390326_S.jpg

風景

pixta_16544720_S.jpgpixta_21790230_S.jpg
学習用データ提供:PIXTA

誤って分類された画像例

ネガティブがポジティブに分類された例

pixta_22857001_S.jpgpixta_35235896_S.jpg

ポジティブがネガティブに分類された例

pixta_24785471_S.jpgpixta_25108831_S.jpg

風景がネガティブに分類された例

pixta_31213454_S.jpgpixta_21790213_S.jpg
学習用データ提供:PIXTA

GPUとCPUの比較

再学習の時に用いた学習モデルでGPUとCPUの比較を行いました。
ちなみに、
GPUはTesla V100
エポック数は200
バッチサイズは64
です。

GPU
image.png

CPU(学習が全然終わらなくて10エポックが終了したところで止めました)
image.png

結果、
GPUは53分
CPUは14日15時間

その差は約400倍と圧倒的な差でした(笑)

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2