Python

深層学習を用いて画像判定AIを作ってみよう。(その4画像判定・改善)

2018年11月17日

画像判定

今回は、画像判定のプログラムを作っていきます。

以前に、"tiger","snake","monkey"の3つの画像を保存しましたが、今回作る画像判定は、ある画像を渡したときに、この3つのうちどれに該当するかというものです。

以下がどの画像かを推定するためのプログラムです。

from keras.models import Sequential,load_model
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils
from PIL import Image
import keras
import numpy as np
import os,sys

image_path = "./image"
classes = os.listdir(image_path)

num_classes = len(classes)
image_size = 50

def build_model():

        model = load_model('./image_cnn.h5')

        return model

def main():
    image = Image.open(sys.argv[1])
    image = image.convert('RGB')
    image = image.resize((image_size,image_size))
    data = np.asarray(image)
    X = []
    X.append(data)
    X = np.array(X)
    model = build_model()

    result = model.predict([X])[0]
    predicted = result.argmax()
    percentage = int(result[predicted] * 100)
    print("{0}({1}%)".format(classes[predicted],percentage))

if __name__ == "__main__":
    main()

このプログラムの引数に画像判定したいファイルをおき実行します。

今回は、画像収集に使用した"tiger"の画像の1つを名前を変更し使用しました。この判定に使う画像は、predict.pyと同じディレクトリに置いておきます。

"python predict.py tiger.jpg"と実行した結果が以下のようになります。

実行結果で、tiger(100%)と出力されていますね。これは訓練で使用している画像データなのでちゃんと画像判定ができていますが、使用する画像に、その動物以外のものや、背景が大きく写っているものは、画像判定がきちんとできない場合があります。

これを改善していくには、画像の中の領域を検知したり、そもそも訓練用の画像データに適切でないものを取り除いたりと改善の余地は多くあります。

まず画像のデータ量が少ないと思われますが、質の良い画像はそんなに多く転がっていないので、その画像を回転させて使いまわしていきます。画像を少し回転させた画像は別データとして扱われるので、1枚の画像を±20~0度の範囲で、1枚の画像を5枚分としたものと左右反転させたものを加えて増量していきます。以下が改善したプログラムです。

from PIL import Image
import os,glob
import numpy as np
from sklearn import model_selection


image_path = "./image"
classes = os.listdir(image_path)
num_classes = len(classes)

image_size = 50
num_testdata = 150

X_train = []
Y_train = []
X_test = []
Y_test = []

for index,classlabel in enumerate(classes):
    photos_dir = "./image/" + classlabel
    files = glob.glob(photos_dir + "/*.jpg")
    for i,file in enumerate(files):
        if i > 300: break
        image = Image.open(file)
        image = image.convert("RGB")
        image = image.resize((image_size, image_size))
        data = np.asarray(image)
        
        if i < num_testdata:
        
        	X_test.append(data)
        	Y_test.append(index)
        	
        else:
        	
        	for angle in range(-20,20,5):
        	
        		img_r = image.rotate(angle)
        		data = np.asarray(img_r)
        		X_train.append(data)
        		Y_train.append(index)
        		
        		img_trans = image.transpose(Image.FLIP_LEFT_RIGHT)
        		data = np.asarray(img_trans)
        		X_train.append(data)
        		Y_train.append(index)

X_train = np.array(X_train)
y_train = np.array(Y_train)

X_test = np.array(X_test)
y_test = np.array(Y_test)

xy = (X_train, X_test, y_train, y_test)
np.save("./image_data_aug.npy", xy)

これで、新しいNPYデータを保存するので、"image_data_aug.npy"として名前を変更しています。また、"image_cnn.py"の中で、"image_data.npy"となっている部分を"image_data_aug.npy"に変更します。また同じように、"image_cnn.h5"となっている部分を"image_cnn.h5"と変更します。

これで、"python image_cnn.py"と実行したところ、以下のようになりました。訓練用データ、テスト用データは微量ですがaccuracyは増加しました。

他にも先ほど述べたように改善する余地としては、

  • 画像の選定
  • image_cnn.pyで"model.fit(X, y, batch_size=32, epochs=100)"ここのbatch_sizeやepochsの値を大きくする。

実際に、上の画像が、epochs=200としたもの、下の画像が、batch_size=128としたものです。どちらもテスト用データのAccuracyが増加しています。

画像判定のプログラムの紹介は以上になります。

よく読まれている記事

1

DeepFaceLab 2.0とは DeepFaceLab 2.0は機械学習を利用して動画の顔を入れ替えるツールです。 以前にDeepFaceLab 1.0を記事としてアップしていましたが、2.0は以 ...

2

自作PCで、多くのパーツをCorsair製品で揃えたので、iCUEでライティング制御していきました。 私のPCでは、表示されている4つのパーツが制御されています。ここで、HX750i電源ユニットは、L ...

3

コンピュータは有限桁の数値しか扱う事はできないので、桁数の多い場合や無限小数の場合は四捨五入され切り捨てられます。なので実際の数値とは多少の誤差が生じますが、これを丸め誤差といいます。 なので、コンピ ...

-Python