
ゆうき( @BASEBALLY15 )です^^
第1章では,カスケードファイルを使って,顔を判断し画像として保存しましたね.
そうですね^^
第2章の前半では,保存した画像を学習用とテスト用に分けて,
畳み込みニューラルネットワークで学習させたいと思います^^

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

今回は,第2章の『face_generation_aug.py』と『face_cnn.py』を作っていきたいと思います.
『face_generation_aug.py』 では,第1章で保存した画像を学習用とテスト用に分けます.
そして, 『face_cnn.py』 では,分けた画像を,ニューラルネットワークによって判定し.
その結果をファイルに保存します.

それでは,コードを見ていきましょう^^
まずは, 『face_generation_aug.py』 を作ります.
画像を学習用とテスト用に分けよう!
ファイル名: face_generation_aug.py
ライブラリ
#画像に処理をするためのライブラリ
from PIL import Image
#ディレクトリやファイルに処理をするためのライブラリ
import os, glob
import numpy as np
#データを学習用とテスト用に分けるためのライブラリ
from sklearn import model_selection
コード
def generate():
#-------------------------------------------------------------
#クラスを作成
face_classes = ["my_face", "other_face", "other_face2"]
#クラスの数(=3)
num_face_classes = len(face_classes)
#画像のサイズを指定
image_size = 50
#使うデータ数(コマンドプロンプト上で指定する)
use_count = int(input("使うデータ数="))
#半分のデータをテストデータに使う(全データの3割)
test_data_count = int(use_count*0.3 )
#-------------------------------------------------------------
##画像の読み込みを行う##
#画像データの配列を用意
X_train = []
X_test = []
#ラベルのデータを用意
Y_train = []
Y_test = []
#-------------------------------------------------------------
#画像データとラベルデータに分割
for index, classlabel in enumerate(face_classes):
#画像のディレクトリ名
photo_dir = "./" + classlabel
#画像を一枚ずつ取得
files = glob.glob(photo_dir + "/*.jpg")
#写真をRGB化し,変更を加える
for i, file in enumerate(files):
#もし,100枚以上なら,終了
if i >= use_count: break
#画像を開く
image = Image.open(file)
#RGB化する
image = image.convert("RGB")
#サイズを50×50にリサイズする
image = image.resize((image_size, image_size))
#画像データを数値に変換する
data = np.asarray(image)
#-------------------------------------------------------------
#もし,枚数がtest_data_countまでなら
if i < test_data_count:
#テストデータに加える
X_test.append(data)
Y_test.append(index)
#それ以外なら
else:
#学習用の画像に変更を加える
for face_angle in range(-5, 5, 5):
#回転(-5度から5度までを5度ずつ)
img_roll = image.rotate(face_angle)
#画像データを数値に変換する
data = np.asarray(img_roll)
#学習用のリストに追加
X_train.append(data)
Y_train.append(index)
#反転(左右)
img_rurn1 = img_roll.transpose(Image.FLIP_LEFT_RIGHT)
#画像データを数値に変換する
data = np.asarray(img_rurn1)
#学習用のリストに追加
X_train.append(data)
Y_train.append(index)
#-------------------------------------------------------------
#XとYをnumpy形式に変換する(TensorFlowでは,numpy形式の方が扱いやすい)
X_train = np.array(X_train)
X_test = np.array(X_test)
Y_train = np.array(Y_train)
Y_test = np.array(Y_test)
#-------------------------------------------------------------
#学習用とテスト用のデータをまとめておく
xy_box = (X_train, X_test, Y_train, Y_test)
#Numpy形式でファイルを保存しておく
np.save("./face.npy", xy_box)
このコードを書くと,このように『face.npy』というファイルが作られます.

そして,このファイルを使って,ニューラルネットワークで画像の判定を行っていきたいと思います.
畳み込みニューラルネットワークで画像を判定してみよう!
ファイル名: face_cnn.py
ライブラリ
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
#0と1に分割するために使う
from keras.utils import np_utils
import numpy as np
コード
まずは,クラスと画像のサイズを決めます.
クラスを作成し,画像サイズを決めよう!
#クラスを作成
face_classes = ["my_face", "other_face", "other_face2"]
#クラスの数(=3)
num_face_classes = len(face_classes)
#画像のサイズを指定
image_size = 50
そして,メインとなる関数を作ります.
メインとなる関数を作ろう!
###メインの関数###
def cnn_main():
#ファイルからデータの配列に読み込む
X_train, X_test, Y_train, Y_test = np.load("./face.npy", allow_pickle=True)
#読み込んだデータの正規化
X_train = X_train.astype("float")/256
X_test = X_test.astype("float")/256
#ラベルを1と0に分ける(One-Hotベクトル化)
Y_train = np_utils.to_categorical(Y_train, num_face_classes)
Y_test = np_utils.to_categorical(Y_test, num_face_classes)
#学習用とテスト用の関数を持ってくる
model = train_model(X_train, Y_train)
evaluate_model(model, X_test, Y_test)
次に,学習用の関数を用意します.
(※畳み込みニューラルネットワークの肝となる部分です!)
畳み込みニューラルネットワークの関数を作ろう!
##学習用の関数を用意する##
def train_model(X, Y):
#------------------------------------------------
model = Sequential()
model.add(Conv2D(32,
kernel_size=(3,3),
padding="same",
input_shape=X.shape[1:]))
#マイナスの値を除去
model.add(Activation("relu"))
#------------------------------------------------
model.add(Conv2D(32,
kernel_size=(3,3)))
#0以下を除去(活性化関数)
model.add(Activation("relu"))
#2×2の範囲で,最大の値を取得
model.add(MaxPooling2D(pool_size=(2,2)))
#過学習の抑制(ランダムでニューロンを無効化)
#偏ったニューロンに依存しないため
#25%無効化
model.add(Dropout(rate=0.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.fit(X, Y, batch_size=32, epochs=20)
#モデルの保存
model.save("./face_cnn.h5")
#modelを結果として返す
return model
そして,テスト用の関数を用意します.
テスト用の関数を作ろう!
###テスト用の関数を用意する###
def evaluate_model(model, X, Y):
scores = model.evaluate(X, Y, verbose=1)
print("Test Loss:", scores[0])
print("Test Accuracy:", scores[1])
最後に,Anaconda Peompt上で,実行するために以下のコードを書いておきます.
#cnn_data()関数をコマンドプロンプト上で呼び出す
if __name__ == "__main__":
cnn_main()
Anaconda Prompt上で実行してみよう!
Anaconda Promptを開き,以下の文字を書きます.
- activate tf140
- cd Desktop
- cd face_cnn.pyがあるディレクトリ名
- python face_cnn.py
これを実行すると,ニューラルネットワークによって,画像の判定を行ってくれます.
そして,このようにファイルが作られます.

(※だいたい10分から20分くらいかかります.)
終わりに
今回は,画像を学習用とテスト用に分けて,
畳み込みニューラルネットワークによって,判定を行いました.
次回(第2章 後半)では,畳み込みニューラルネットワークによって判定した結果を使って,
自分の顔や他人の顔の画像を判定したいと思います.
それでは・・・