LoginSignup
2
1

More than 5 years have passed since last update.

Keras-TF で、長方形の入力画像

Last updated at Posted at 2018-12-23

長方形の画像でも普通に Keras-TF で処理できるよ、というサンプル。

前提条件としては。

クラス0 : images/a000.pngimages/a999.png
クラス1 : images/b000.pngimages/b999.png
クラス2 : images/c000.pngimages/c999.png

という画像があって、サイズはいずれも 幅64pix, 高さ36pix。グレイスケール。

具体的には下表のような画像を用意した:

クラス 画像(横に10枚、縦に3枚連結したもの)
0 image.png
1 image.png
2 image.png

教師データとして 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% にならなかったのはちょっと残念。
モデルを追い込んでいないので仕方ないか。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1