アニメキャラ顔認識AI:アニガサキメンバー10人の顔認識に挑戦【Python,Keras,OpenCV,ラズパイ,ディープラーニング】

大変で激動な年だった2020年も、年末を迎えます。もう色んなことが密に起こりすぎて、何が何だか;

ただ厳しい状況の中でも、素敵な時間をくれたのは、やっぱりラブライブ!でした。1月のあのラブライブ!フェスから始まり、虹ヶ咲の2ndライブ、Aqoursのオンラインライブ、そして「ラブライブ!虹ヶ咲学園スクールアイドル同好会」のアニメ放送と今年も大きな動きがありました。

ラブライブ!虹ヶ咲学園スクールアイドル同好会

中でも今期に放送されている、虹ヶ咲のアニメ(アニガサキ)は出来がよすぎて、思わず泣いてしまう回が出てくるほどの神アニメで驚いています。特に1話とか11,12話あたりの主人公「高咲 侑」ちゃんと、ヒロインスクールアイドル「上原 歩夢」のエピソード「ゆうぽむ」回は尊死するしかなかったです。アニメ2期の制作も期待したいし、このご時世の中、生きる目的が将来に増えるのはありがたい!(ちょっと大げさかもw)

それはそうと、昨年の今頃ラブライブ!のゲーム「スクスタ」でディープラーニングによるキャラの顔認識なんてやってましたね。

Python 画像認識:機械学習AI(自作サンプル)でラブライブ虹ヶ咲キャラを顔認識【OpenCV,Keras,ディープラーニング,ラズパイ】 | 9が好きな人のブログ

この時は、スクスタのニジガクメンバー3人(歩夢、かすみ、せつ菜)を、9層CNN(KerasのCIFAR-10サンプル)で顔認識して、良好な結果が得られていました。ただ、3人という少人数で、しかも特徴のはっきり分かれているキャラだったので、まあ上手くいくのも当然かなと。

そこで、今回はアニメ版のニジガク(アニガサキ)メンバー10人に対して、ディープラーニングによる顔認識をやってみることにしました。

やってみた感想を先に言うと、結局AIはデータが命!

開発環境

■ハードウェア

・Raspberry Pi
※ラズパイ3Bを使いましたが、もちろん最新のラズパイ4で余裕で行けるはず。

ラズベリーパイ4 コンピューターモデルB 4GB Raspberry Pi 4 Computer Model B

■OS
・Raspbian GNU/Linux 9.13 (stretch)

■プログラミング言語、主なライブラリとバージョン
・Python 3.5.3
・OpenCV 2 4.4.0
・Numpy 1.18.3
・Keras 2.3.1
・Theano 1.0.4
・Matplotlib 3.0.3

※ラズパイのAI環境開発は以下の本が参考になります。

カラー図解 Raspberry Piではじめる機械学習 基礎からディープラーニングまで (ブルーバックス) Kindle版

プログラム解説

GitHub公開プログラム:https://github.com/kotetsu99/animeface_recognition

プログラムの使い方や、AIの仕様、ポイントの解説は以下に記してます。

プログラム使用法:https://nine-num-98.blogspot.com/2019/12/ai-lovelive-01.html
プログラム解説:https://nine-num-98.blogspot.com/2019/12/ai-lovelive-02.html

ただし、上記はPython2系の環境で開発・実行していますが、今回は主流のPython3系で試しています。本プログラムはPython3系でも、ちゃんと動いてくれてます。

そして今回の顔認識を行うキャラは、次の10人です。

・高咲 侑(Yu)
・上原 歩夢(Ayumu)
・中須 かすみ(Kasumi)
・桜坂 しずく(Shizuku)
・朝香 果林(Karin)
・宮下 愛(Ai)
・近江 彼方(Kanata)
・優木 せつ菜(Setsuna)
・エマ ヴェルデ(Emma)
・天王寺 璃奈(Rina)

先のキービジュアルに映っているキャラクター達ですが、彼女たちの画像を集めて顔画像を抽出し、顔画像をCNNで機械学習させます。そしてキービジュアル中のキャラの顔認識を実行し、認識結果を確認するところまで行きます。

画像集め

まずは画像集めです。1キャラあたり20枚程度集めることにします。地道ですがGoogleの画像検索にキャラ名をかけて探します。サイズを大にして、なるべく解像度の高い検索設定にし、なるべくキャラの特徴がはっきり出ている画像を選んでいきます。

↑は高咲 侑ちゃんです。9人の虹ヶ咲スクールアイドルを応援する主人公。彼女は黒髪ツインテールが特徴的なので、それがはっきり分かる画像を探していきます。

機械学習は、データ集めが地味で根気がいるものですがとても重要です。まあ、好きなアニメのキャラ画像を探すのは苦痛ではなく、むしろ2828しそうなこともありましたねw

ただ今回は1キャラ20枚程度なので(それでも10キャラ分合計で200枚!)、手作業でも何とかやりきれましたが、これが1人100枚で合計1000枚とかになるとさすがに厳しいかも;

Googleで探した画像は、以下のディレクトリにキャラごとに分けて保存します。

dataset/01-org/Yu
dataset/01-org/Ayumu
dataset/01-org/Kasumi
dataset/01-org/Shizuku
dataset/01-org/Karin
dataset/01-org/Ai
dataset/01-org/Kanata
dataset/01-org/Setsuna
dataset/01-org/Emma
dataset/01-org/Rina

顔画像抽出

保存した顔画像に対して、01-face_detection.py(顔検出プログラム)を実行し、キャラの顔画像を抽出します。事前に、以下のディレクトリを作っておきます。

dataset/02-face/Yu
dataset/02-face/Ayumu
dataset/02-face/Kasumi
dataset/02-face/Shizuku
dataset/02-face/Karin
dataset/02-face/Ai
dataset/02-face/Kanata
dataset/02-face/Setsuna
dataset/02-face/Emma
dataset/02-face/Rina

このうえで、以下のコマンドを実行します。

$ python3 01-face_detection.py

すると、事前につくったdataset/02-face配下のキャラディレクトリに、01-org配下の画像から検出された顔画像が保存されます。

dataset/02-face/Yu
にはこんな感じで保存されました。なかなか良好な結果です。それにしても、改めて侑ちゃんは可愛いかったりイケメンだったりとか最強スペックだな~歩夢も素敵な幼馴染彼氏(?)を持ってるもんだ^^

顔抽出にはOpenCVというライブラリを使用し、アニメ顔を認識させるためのカスケード分類器として以下をお借りしています。

OpenCVによるアニメ顔検出ならlbpcascade_animeface.xml - デー

他のキャラも大体いい感触でしたが、一部反応できなかった顔画像もあり、1人当たり17枚に揃えました。

顔画像をディープラーニング

顔画像1キャラ17枚、合計170枚に対して、02-cnn_face_train.py: 顔学習プログラムを使って、CNNによるディープラーニングを行います。

以下のコマンドを実行すれば学習が始まり、完了後に学習済みモデル「anigasaki.h5」を生成します。

nohup python3 02-cnn_face_train.py model/anigasaki.h5 &

進捗状況は、nohup.outファイルに出力されるので、以下のコマンドで確認できます。

$ tail -f nohup.out

今回はエポック数100で実行しましたが、所要時間など最終的に以下の結果になりました。

39/40 [============================>.] - ETA: 2s - loss: 0.0360 - accuracy      : 0.9936
40/40 [==============================] - 121s 3s/step - loss: 0.0352 - acc      uracy: 0.9937 - val_loss: 0.0067 - val_accuracy: 0.8000
Using Theano backend.
process_time =  201.97490223646165 [min]

3時間20分程度かかりました。val_accracy(未知の評価用データに対する認識精度)が0.8程度と、そこそこですが

・loss(学習用データに対する損失関数)
・val_loss(未知の評価用データに対する損失関数)

の推移を1~100エポックまでみてみると、以下のようなグラフになっています。

lossは収束していますが、val_lossはかなり波打って収束の気配がないですね。未知の画像に対する、画像の認識精度は不安定なのが読み取れます。モデルの汎化をすすめるには、もっと多くの画像が必要なのかなと。

顔認識実行

生成したモデルの精度に不安はありますが、アニガサキのキービジュアル絵に対して、これで画像認識をやってみます。

dataset/03-test/

のディレクトリ下に、キービジュアル画像を保存して以下を実行します。

$ python3 03-cnn_face_recognition.py model/anigasaki.h5

顔認識結果は以下のフォルダに保存されます。

dataset/04-rec

キービジュアル絵に映っている顔画像はモデルの訓練データに含めていないため、AIにとっては未知の顔画像になります。
結果はこうでした;

[各キャラの顔認識結果詳細]

  
dataset/03-test/01-test.jpg
[('Yu', 0.8082491), ('Shizuku', 0.19175075), ('Kasumi', 1.06866516e-07)]
=======================================
[('Kasumi', 0.99725085), ('Ai', 0.0027312934), ('Rina', 1.7875065e-05)]
=======================================
[('Emma', 1.0), ('Shizuku', 2.8103397e-09), ('Kanata', 2.9043026e-10)]
=======================================
[('Setsuna', 0.99999994), ('Karin', 3.0121473e-08), ('Yu', 2.307216e-09)]
=======================================
[('Karin', 1.0), ('Setsuna', 7.516162e-11), ('Ai', 2.6331824e-11)]
=======================================
[('Yu', 0.5438412), ('Shizuku', 0.45151082), ('Kasumi', 0.0034408337)] ▼誤認▼
=======================================
[('Ayumu', 0.99208134), ('Kanata', 0.007917836), ('Rina', 7.6736694e-07)]
=======================================
[('Ayumu', 0.7899039), ('Kanata', 0.20556568), ('Emma', 0.0045077815)] ▼誤認▼
=======================================

ちょっと残念な結果でした…

・しずくを侑に、彼方を歩夢に誤認
   -しずく認識結果:侑54.4%、しずく45.2%
   -彼方認識結果:歩夢78.9%、彼方20.6%
・愛さん、璃奈は顔そのものが認識できていない
・他のメンバーは認識OK

まず1点目ですが、これは単に学習不足だろうなと。しずくと侑は同じ黒髪ということもあり、顔の角度によっては見間違えるのかなと。彼方と歩夢も、やはり髪の色が暖色系で近いことから間違えたのかもしれません。あと歩夢はこの彼方のように、片目を閉じた顔画像が訓練データに入っていたので、それが反応してしまったのかも?

最後方にいる、愛さんと璃奈はそもそもOpenCVの顔認識から見逃されていますが、これは03-cnn_face_recognition.pyのOpenCVのパラメータ設定により改善できる可能性があります。

# OpenCV検出サイズ定義
cv_width, cv_height = 64, 64
# OpenCV検出閾値
minN = 15

検出する画像サイズを小さくすれば、遠くに映っている小さな顔画像にも反応できる反面、顔でない画像も誤検出してしまうことが多くなります。またOpenCVの検出閾値も検出精度にかかわりますが、下げるほど見落としが少なくなるが低精度、上げるほど高精度だが見落としが多くなるトレードオフの特性があります。詳細は以下で解説しています。
https://nine-num-98.blogspot.com/2019/12/ai-lovelive-02.html

他のメンバー、侑・歩夢・かすみ・せつ菜・果林・エマについては認識OKでした。10人中6人正解ということで、まあ60点といったところでしょうか。

気を取り直して、みんな正面向きで顔の近さ(大きさ)も揃っている、分かりやすい画像で試してみます。

↓拡大




[各キャラの顔認識結果詳細]

dataset/03-test/02-test.jpg
[('Karin', 1.0), ('Setsuna', 3.8613382e-10), ('Shizuku', 2.2942694e-10)]
=======================================
[('Emma', 0.9999807), ('Shizuku', 1.7750148e-05), ('Kasumi', 1.1136434e-06)]
=======================================
[('Ai', 0.9999971), ('Kasumi', 2.482074e-06), ('Rina', 2.1312452e-07)]
=======================================
[('Kasumi', 0.9999993), ('Yu', 7.2226504e-07), ('Ai', 4.1193565e-10)]
=======================================
[('Ayumu', 0.9999992), ('Kanata', 5.7506827e-07), ('Emma', 2.1883237e-07)]
=======================================
[('Shizuku', 0.9991715), ('Yu', 0.00082328724), ('Kasumi', 2.7237486e-06)]
=======================================
[('Setsuna', 0.78039896), ('Karin', 0.21936733), ('Yu', 0.00018758755)]
=======================================
[('Kanata', 0.9999994), ('Emma', 4.7596794e-07), ('Rina', 7.274937e-08)]
=======================================
[('Yu', 1.0), ('Karin', 2.7718627e-08), ('Shizuku', 2.7849905e-11)]
=======================================
[('Rina', 0.72277325), ('Shizuku', 0.123437904), ('Ai', 0.1121369)]
=======================================

こちらは、全員正解でした。

しずくや彼方など、何人かは学習データに入っている既知の顔画像だったので、今度は誤認せずに済みました。りなちゃんボードをつけた璃奈にも、OpenCVは反応してくれまました。

果林・せつ菜・璃奈については、学習データにない画像であるにも関わらず、正解でした。璃奈はともかく、果林・せつ菜はAIにとって割と特徴がつかみやすい顔なのかも?

いずれにしても、少なくとも学習データに入っている顔画像については、ほぼ100%の認識精度が出ます。様々な顔のパターンを学習させるほど、対応できる画像が多くなり、誤認が減っていくはずです。

やはり、AI(ディープラーニング)はデータが命ですね。大量のデータを用意できれば望ましいですが、日常生活で見かける様々な物の画像を事前学習させたモデルを流用して、データ集めやAI学習の手間と時間をある程度スキップするテクニックも知られています。転移学習Fine-tuningと呼ばれるものですね。アニメ画像などにも通用するかどうかは分かりませんが、機会があれば試してみたいなと思います。

以上、参考になれば幸いです。来年2021年はみんな、今の大変な状況から抜け出せるといいですね。アニガサキも来年に2期来るかな!?楽しみです。

スポンサーリンク