【Python/Keras】CNN(畳み込みニューラルネット)で画像の分類

Pythonの機械学習モジュール「Keras」でCNN(畳み込みニューラルネット)を実装し、画像を分類する方法をソースコード付きでまとめました。

CNN(畳み込みニューラルネット)で画像の分類

画像に対して深層学習(ディープラーニング)を行う場合は、CNN(畳み込みニューラルネットワーク)を用いるのが一般的です。
そこで、今回は、Python + KerasでCNNを実装し、画像の2分類(正解・不正解)を行ってみました。

関連ページ
関連 【CNN】畳み込みニューラルネットワークの原理・仕組み

サンプルコード

サンプルプログラムのソースコードです。

# -*- coding: utf-8 -*
import keras
from keras.utils import np_utils
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.preprocessing.image import array_to_img, img_to_array, list_pictures, load_img
import numpy as np
from sklearn.model_selection import train_test_split

def main():
    X = []
    Y = []

    # 学習データの取得(正解画像)
    for filepath in list_pictures('./pos/'):
        img = img_to_array(load_img(filepath, target_size=(64,64)))
        X.append(img)
        Y.append(0) # 教師データ(正解)


    # 学習データの取得(非正解画像)
    for filename in list_pictures('./neg/'):
        img = img_to_array(load_img(filepath, target_size=(64,64)))
        X.append(img)
        Y.append(1) # 教師データ(正解)

    # NumPy配列に変換
    X = np.asarray(X)
    Y = np.asarray(Y)

    # float32型に変換
    X = X.astype('float32')

    # 正規化(0~1)
    X_train = X / 255.0
    X_test = X / 255.0

    # クラスの形式を変換
    Y = np_utils.to_categorical(Y, 2)
    y_train = Y
    y_test = Y
    # 学習用データとテストデータに分割
    #X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=111)

    # CNNを構築
    model = Sequential()
    model.add(Conv2D(32, (3, 3), padding='same', input_shape=X_train.shape[1:]))
    model.add(Activation('relu'))
    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25)) # 過学習防止用:入力の25%を0にする(破棄)

    model.add(Conv2D(64, (3, 3), padding='same'))
    model.add(Activation('relu'))
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25)) # 過学習防止用:入力の25%を0にする(破棄)

    model.add(Flatten())
    model.add(Dense(512))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))          # 過学習防止用:入力の50%を0にする(破棄)
    model.add(Dense(2))              # 出力は二次元(正解・不正解の2クラス)
    model.add(Activation('softmax')) # 活性化関数(softmax)
    # コンパイル(勾配法:SGD、損失関数:categorical_crossentropy、評価関数:accuracy)
    model.compile(loss='categorical_crossentropy', optimizer='SGD', metrics=['accuracy'])

    # 構築したモデルで学習
    history = model.fit(X_train, y_train, batch_size=5, epochs=200, validation_data = (X_test, y_test), verbose = 0)

    # モデルの検証・性能評価
    score = model.evaluate(X_train, y_train, verbose=0)
    print('Test loss:', score[0])
    print('Test accuracy:', score[1])

if __name__ == '__main__':
    main()

posディレクトリの直下に正解画像、negディレクトリの直下に不正解画像を多数用意して学習させます。
教師データは0が正解、1が不正解です。

関連記事
1 Python入門 基本文法
2 【Python/Keras】ディープラーニング入門・使い方
関連記事