長方形の画像でも普通に Keras-TF で処理できるよ、というサンプル。
前提条件としては。
クラス0 : images/a000.png
〜 images/a999.png
クラス1 : images/b000.png
〜 images/b999.png
クラス2 : images/c000.png
〜 images/c999.png
という画像があって、サイズはいずれも 幅64pix, 高さ36pix。グレイスケール。
具体的には下表のような画像を用意した:
クラス | 画像(横に10枚、縦に3枚連結したもの) |
---|---|
0 | |
1 | |
2 |
教師データとして 600枚×3クラス( 000〜599 )
テストデータとして 400枚×3クラス( 600〜999 )
利用した。
Python3.6
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
import numpy as np
import random
import cv2
import os
batch_size = 128
num_classes = 3
epochs = 20
# input image dimensions
img_rows, img_cols = 36, 64
train_count = 600
test_count = 400
types = [chr(c+ord("a")) for c in range(num_classes)]
def srces(x0, c):
s = []
for t in types:
for x in range(c):
s.append("images/%s%03d.png" % (t, (x+x0)))
random.shuffle(s)
return s
def x_matrix(srces):
arrays = [cv2.imread(fn, -1).reshape(1, img_rows, img_cols, 1)
for fn in srces]
return np.concatenate(arrays).astype('float32') / 255
def type_of(fn):
return ord(os.path.basename(fn)[0]) - ord("a")
def y_matrix(srces, num_classes):
arrays = [np.array(type_of(fn)) for fn in srces]
y = np.vstack(arrays).reshape(len(arrays),)
return keras.utils.to_categorical(y, num_classes)
def prepare_model(input_shape):
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
return model
def main():
train_srces = srces(0, train_count)
test_srces = srces(train_count, test_count)
x_train = x_matrix(train_srces)
y_train = y_matrix(train_srces, num_classes)
x_test = x_matrix(test_srces)
y_test = y_matrix(test_srces, num_classes)
input_shape = (img_rows, img_cols, 1)
model = prepare_model(input_shape)
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
main()
最終出力は
Test loss: 0.02713265500109022
Test accuracy: 0.9908333333333333
という感じになった。
簡単なデータだったので 100% にならなかったのはちょっと残念。
モデルを追い込んでいないので仕方ないか。