
ゆうき( @BASEBALLY15 )です^^
前回は,畳み込みニューラルネットワークによって顔の画像を学習しましたね.
そうですね^^
第2章 後半では,学習させた結果を使って,自分の顔と他人の顔を判定します.
はたして,AIは自分の顔と他人の顔を判別することが出来るのでしょうか・・・?

目次
第1章から第3章までの構成要素

今回は,第2章の『face_predict.py』を作ります.
前回に,畳み込みニューラルネットワークによって,自分の顔と他人の顔を学習させました.
そこで,この章では,学習させたものとは違う画像をAIが判定できるのかを検証していきます.

それでは,コードを見ていきましょう^^
AIは顔を判定できるのか!?
ファイル名:face_predict.py
ライブラリ
#画像を編集するために使う
import cv2
#画像を表示するために使う
import matplotlib.pyplot as plt
#画像を編集するために使う
from PIL import Image
import numpy as np
#コマンドプロンプトから文字を読み取るために使う
import sys
import keras
#ニューラルネットワークのモデルを定義するためのライブラリ
from keras.models import Sequential
#畳み込みの処理やプーリングの処理をするためのライブラリ
from keras.layers import Conv2D, MaxPooling2D
#Activationは活性化関数,Dropoutはドロップアウト処理,
#Flattenはデータを1次元に変換,Denseは全結合
from keras.layers import Activation, Dropout, Flatten, Dense
#ファイルをロードするためのライブラリ
from keras.models import load_model
コード
まずは,クラスの作り,画像サイズを決めておきます.
クラスの作り,画像サイズを決めよう!
#クラスを作成
face_classes = ["my_face", "other_face", "other_face2"]
#表示形式を変えておく
face_name = ["本人です!", "あなたではないです!", "あなたではないです!"]
#クラスの数(=3)
num_face_classes = len(face_classes)
#画像のサイズを指定
image_size = 50
実行した時に,日本語で表示させたいので,『face_name』というクラスを作ります.
次に,画像を判定するために,畳み込みニューラルネットワークのモデルを作ります.
畳み込みニューラルネットワークのモデルを作る!
#ニューラルネットワークのモデルを作成する
def neural_model():
#------------------------------------------------
model = Sequential()
model.add(Conv2D(32,
kernel_size=(3,3),
padding="same",
input_shape=(image_size, image_size, 3)))
#マイナスの値を除去
model.add(Activation("relu"))
#------------------------------------------------
model.add(Conv2D(32,
kernel_size=(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
#過学習の抑制(ランダムでニューロンを無効化)
#偏ったニューロンに依存しないため
model.add(Dropout(rate=0.25))#25%無効化
#------------------------------------------------
model.add(Conv2D(64,
kernel_size=(3,3),
padding="same"))
model.add(Activation("relu"))
#------------------------------------------------
model.add(Conv2D(64,
kernel_size=(3,3)))
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(Dropout(0.5))
model.add(Dense(num_face_classes))
model.add(Activation("softmax"))
#------------------------------------------------
#オプティマイザーを作成
opt = keras.optimizers.RMSprop(learning_rate=0.0001,
decay=1e-6)
#コンパイル
model.compile(loss="categorical_crossentropy",
optimizer=opt,
metrics=["accuracy"])
#モデルのロード()
model = load_model("./face_cnn.h5")
return model
畳み込みニューラルネットワークのモデルを作ったら,
次に,メインとなる関数を作ります.
メインとなる関数を作ろう!
今回,判定する画像は,顔から体までは映っているため,
そのまま使うと,自分の顔画像を他人の顔だと判定したり,
他人の顔画像を自分だと判定することがあったので,

第1章で使った,カスケードファイルによって,
顔のみをニューラルネットワークに読み込むと,
上手く判定することが出来ました.

それでは,そのコードをご紹介します.
main_predict()という関数を作ります.
def main_predict():
#---------------------------------------------------------------------------
#読み込む画像のファイル名
image_name = str(input("画像ファイル名="))
#入力用にOpenCVで画像を読み込む
image_in = cv2.imread(image_name)
#顔の検出器を作成
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
#グレイスケールに変換
image_gray = cv2.cvtColor(image_in, cv2.COLOR_BGR2GRAY)
#顔認証を実行
face_list = face_cascade.detectMultiScale(image_gray, minNeighbors=20)
#---------------------------------------------------------------------------
#認証した部分に印をつける(枠で囲む)
for (x,y,w,h) in face_list:
#赤を用意
red = (0,0,255)
#顔の部部を囲む
cv2.rectangle(image_in, (x,y), (x+w, y+h), red, 1)
#顔の部分のみ取り出す
trim_face = image_in[y:y+h,x:x+w]
#RGBに変換する(OpenCVのBGRをRGBに変換する)
image_rgb = cv2.cvtColor(trim_face,cv2.COLOR_BGR2RGB)
#---------------------------------------------------------------------------
#OpenCVからpillowに変換
change_pillow = Image.fromarray(image_rgb)
#OpenCVのRGBからpillowのRGBに変換する
image_rgb = change_pillow.convert("RGB")
#画像のサイズを50×50にリサイズする(顔のみの画像)
resize_face = image_rgb.resize((image_size, image_size))
#---------------------------------------------------------------------------
#顔の部分のみの画像を数値に変換する
data = np.asarray(resize_face)
#リストを用意
X = []
#Xにdataを入れる
X.append(data)
#XをTensorFlowが扱いやすいようにNumpy型に変換する
X = np.array(X)
#---------------------------------------------------------------------------
#ニューラルネットワークのモデル関数を呼び出す
model = neural_model()
#画像をニューラルネットワークのモデルから予測する
result = model.predict([X])[0]
#一番値の大きい配列の添え字を返す
pred = result.argmax()
#精度を求める
percentage = int(result[pred]*100)
#結果を表示
print("\n{0} {1} %".format(face_classes[pred], percentage))
print()
#["my_face", "other_face", "other_face2"]のどれであるか?
print(result)
#---------------------------------------------------------------------------
#もし,"my_face"なら,
if face_classes[pred] == "my_face":
print()
#"本人です!"と表示
print(face_name[pred])
#もし,"other_face"なら,
elif face_classes[pred] == "other_face":
print()
#"本人ではないです"と表示
print(face_name[pred])
#もし,"other_face2"なら
elif face_classes[pred] == "other_face2":
print()
#"本人ではないです"と表示
print(face_name[pred])
#---------------------------------------------------------------------------
#顔のみの画像を表示
plt.imshow(image_rgb)
plt.show()
#---------------------------------------------------------------------------
そして,コマンドプロンプトで実行できるように,以下のコードを書きます.
#コマンドプロンプトで実行する
if __name__ == "__main__":
#main_predict()を呼びだす
main_predict()
最後に,Anaconda Promptで実行します.
Anaconda Promptで実行してみよう!
Anaconda Promptを開き,以下の文字を書きます.
- activate tf140
- cd Desktop
- cd face_predict.pyがあるファイル名
- python face_predict.py
そして,
画像ファイル名=
と聞かれるので,
画像ファイル名=画像ファイル名.jpg
と書くと,このように画像から自分の顔か他人の顔かを判定してくれます.

終わりに
今回は,畳み込みニューラルネットワークによって学習したデータを使って,
本人の顔か他人の顔かを判定してみました.
画像を読み込ませるときに,そのまま読み込ませるのではなく,
顔の部分のみを切り取ることで,正確に判定できることが分かりました.
次回は,第1章から第2章までのファイルを一つにまとめて,実行したいと思います.
それでは・・・