고양이의 종류를 판별하는 AI를 만들어 본다.

이미지 인식과 Qiita의 기사 투고의 공부를 위해서 정말 좋아하는 고양이 2마리의 종류를 판별하는 프로그램을 만들어 보았습니다.

개인의 학습용이므로 소스는 거의 copipe입니다 (부끄럽다..)

한층 더 화상을 준비하는 것이 귀찮았기 때문에 기르고 있는 고양이와 같은 종류의 화상을 넷으로부터 집어 왔습니다…(∩ˊ꒳ˋ∩)

먼저 이미지를 numpy 배열 형식으로 변환하여 저장합니다.

data.py
from PIL import Image
import os, glob
import numpy as np
import random, math

#学習用画像が保存されているディレクトリ
train_dir = "./train"

#テスト用画像が保存されているディレクトリ
test_dir = "./test"

# 猫の種類
categories = ["ノルウェージャン","アビシニアン"]
# 画像データ用配列
X = []
# ラベルデータ用配列
Y = []

#画像データごとにadd_sample()を呼び出し、X,Yの配列を返す関数
def make_sample(files):
    global X, Y
    X = []
    Y = []
    for cat, fname in files:
        add_sample(cat, fname)
    return np.array(X), np.array(Y)

def add_sample(cat, fname):
    img = Image.open(fname)
    img = img.convert("RGB")
    img = img.resize((150, 150))
    data = np.asarray(img)
    X.append(data)
    Y.append(cat)

#学習用画像
trainfiles = []
#テスト用画像
testfiles = []

for idx, cat in enumerate(categories):
    image_dir = train_dir + "/" + cat
    files = glob.glob(image_dir + "/*.jpg")
    for f in files:
        trainfiles.append((idx, f))

for idx, cat in enumerate(categories):
    image_dir = test_dir + "/" + cat
    files = glob.glob(image_dir + "/*.jpg")
    for f in files:
        testfiles.append((idx, f))

X_train, y_train = make_sample(trainfiles)
X_test, y_test = make_sample(testfiles)
xy = (X_train, X_test, y_train, y_test)
#データを保存する
np.save("./data/tea_data.npy", xy)

이어 학습과 결과 확인입니다.

test.py
from keras import layers, models,optimizers

from PIL import Image
import os, glob
import numpy as np
import random, math
import matplotlib.pyplot as plt
from keras.utils import np_utils

#カーネルが死なないようにするおまじない。。
os.environ ['KMP_DUPLICATE_LIB_OK'] = 'True'

model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation="relu",input_shape=(150,150,3)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(512,activation="relu"))
#ここの「2」は判別する猫の種類数
model.add(layers.Dense(2,activation="sigmoid")) 
model.compile(loss='categorical_crossentropy',optimizer='adadelta',metrics=['accuracy'])

#保存した画像データ
X_train, X_test, y_train, y_test = np.load("./data/tea_data.npy")

#データの正規化
X_train2 = X_train.astype("float") / 255
X_test2  = X_test.astype("float")  / 255

#kerasで扱えるようにcategoriesをベクトルに変換
y_train2 = np_utils.to_categorical(y_train2, nb_classes)
y_test2  = np_utils.to_categorical(y_test2, nb_classes)

model = model.fit(X_train2,y_train2,epochs=2,batch_size=1,validation_data=(X_test2,y_test2))

score = model.model.evaluate(x=X_test,y=y_test)

print('loss=', score[0])
print('accuracy=', score[1])

# データの可視化(テストデータの先頭の5枚)
for i in range(5):
    plt.subplot(2, 5, i+1)
    plt.imshow(X_test[i], 'gray')

# 予測(テストデータの先頭の5枚)
pred = np.argmax(model.predict(X_test[0:5]), axis=1)
print(pred)

출력 결과↓
0은 노르웨이 장 포레스트 고양이, 1은 아비시니안입니다. 무사히 전문 정답 해 주었습니다.
화상을 물 늘린 탓인지, 에포크수는 2회가 베스트였습니다.



좋은 웹페이지 즐겨찾기