スプーキーズのちょっとTech。

SPOOKIES社内のより技工的な、専門的なブログページです。

Are you Spookies?? 機械学習で顔の画像認識をしよう

最近、アニメを見まくっているIoT開発部の西村です。
こんにちは。
感動シーンでナミダしている僕の横で、犬がうるせーなって顔してるのがたまらないです。
どうぞよろしくお願い致します。

課題・モチベーション

ということで 人の顔を機械学習で覚えさせ、メンバーが来たかもよ君にバージョンアップだ!

Spookiesメンバーの顔画像認識パターンモデルを作ってみる

顔画像の収集

毎日顔を合わせて一緒に仕事してますが、いざメンバーの顔写真が必要となっても、あまり持っていないもんです。 携帯で何枚か撮ったかもしれませんが、そんなに数は無いですよね。

合宿等の写真を拾い集める

会社の共有フォルダーに、合宿の写真が入ってました。

  • 沖縄合宿
  • 和歌山合宿
  • 淡路島合宿

こちらを使いましょう。

DLしてフォルダを開くと、こんな写真がいっぱいあります。

f:id:spookies-nishimura:20171014200226p:plain

顔画像のみ抽出

さて、ここから顔画像を取得しましょう。
一つのフォルダの中に全ての画像をぶち込んで、OpenCVを使って画像を切り出しましょう。

OpenCVには、画像から顔を抽出するCascade Classifier=分類器と呼ばれるものが公開されてるので、それを使って顔だけを切り出します。

さらにデータが少ないので、反転・コントラスト調整を行い、画像の水増しを行います。

寺師君の結果
f:id:spookies-nishimura:20171014200300p:plain

ではこれらのデータを使って、モデルを作ります。

モデルの作成

機械学習ライブラリといえば、TensorFlow
但し、素人にはなかなか扱いづらい為、日本語ドキュメントが完備されているラッパーライブラリの Keras を使いました。

from keras.models import Sequential
from keras.layers import Dense, Activation

# 画像データ読込(txtファイルは画像パスとラベルを設定した一覧)
(X_train, y_train)= train_input.read_data('./face_detect/train.txt') # X_train: 学習データ, y_train: 学習ラベル
(X_test, y_test)= train_input.read_data('./face_detect/test.txt') # X_test: テストデータ, y_test: テストラベル

### モデル定義 ###
# Sequentialはただ層を積み上げるだけの単純なモデル
model = Sequential()

model.add(Conv2D(32, (3, 3), padding='same', input_shape=X_train.shape[1:])) # 2次元畳み込み層
model.add(Activation('relu'))   # 活性化関数(レイヤをつなぐもの)
model.add(Conv2D(32, (3, 3)))
model.add(BatchNormalization()) # 誤差・分類性能向上の層
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))   # レイヤ縮小を行い、扱いやすくする層
model.add(Dropout(0.25))    # 過学習の防止

model.add(Flatten())    # 入力を平滑化
model.add(Dense(512)) # 全結合(クラス分類)
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(nb_classes)) 
model.add(Activation('softmax')) # 活性化関数

# compile
model.compile(loss='categorical_crossentropy',  # 損失関数
              optimizer='adam', # 最適化関数
              metrics=['accuracy']) # 評価指標のリスト

### 学習させる ###
model.fit(X_train, Y_train,
          batch_size=batch_size,
          nb_epoch=nb_epoch,
          validation_data=(X_test, Y_test),
          shuffle=True,
          callbacks=[csv_logger, cp_cb, stopping])

...

これでモデル作成です。(MacBookPro で 2時間くらいかかりました)

実験

では、早速できたモデルを使って画像認識してみました。

f:id:spookies-nishimura:20171014203702p:plain:w300 (パジャマですみません)

oops!!!! takanoになってる!

京都オフィスでも何名か試してもらいましたが、だいたい takano になってしまいました orz

原因

今回、精度が出なかった原因としては

  • 元画像の質が悪すぎる
  • 学習データ量が圧倒的に少ない

ですかね。

まとめ

残念ながら現在は takano が来たかもよ君になってしまいましたが、新しい事をするのは凄く楽しいですね。
引き続き精度を向上を図り、ラズパイにも組み込みたいと考えております。 f:id:spookies-nishimura:20171014200226p:plain

イエェェェイ!

f:id:spookies-nishimura:20171014193126j:plain:w100

labs.spookies.co.jp