111

この記事は最終更新日から3年以上が経過しています。

@haru1977

kerasでCNN 自分で拾った画像でやってみる

kerasでCNN 拾ってきた画像でいろいろやってみます

ここでは、Python2.7.6 で行なっています。また、主に以下のパッケージを利用しています。
Keras (2.0.4)
tensorflow (1.1.0)

はじめに


kerasでCNNにチャレンジしてみました。例題のデータセットだけだと面白くないので、自分で拾ってきた画像をCNNで分類しました。

ここではCNNの理論的な部分はある程度わかっている前提で、処理の部分に焦点を当てています。
分析環境は、AWSのEC2を利用。

なお、画像に関しては必要な部分の切り出しを行なった上で実行しています。
(私はOpenCVで行いました)

分析環境について


TensorFlowをGPUで動くよう、環境を構築したかったのですが初心者には難しく…
AWSですでに環境が構築されているAMI(Bitfusion Ubuntu 14 TensorFlow)があったので、こちらを利用しています。
必要なパッケージも既に入ってます。

なお、上記のAMIはPython3も入っているので、そちらでも利用できるかと思います。
(なおコストはかかるので、その点はちゃんと確認ください。デフォルトのEBSサイズが100GBなので、そこも注意です)

必要なパッケージのインポート



# 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
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

内容についてはkerasのホームページなどを参照ください。
keras.preprocessing を利用すると前処理がラクにできます。

画像の読み込みと行列への変換 データセットの作成


temp_img = load_img('./test/test1.jpg', target_size=(64,64))

これで画像を読み込めます。target_sizeで読み込みのサイズも指定することができます。
モデルには決まったサイズの画像をinputするので、前処理で画像のサイズを揃えていない場合はここで揃えます。

モデルには行列へ変換して投入します。画像を行列へ変換するのは以下で可能です。

temp_img_array  = img_to_array(temp_img)

shapeで形を見ると、(64, 64, 3)になっています。
これは、64×64の画像に関し各ピクセルの色(RGB)の情報を持っている、ということなんだと思います。

さて、これらを利用してデータセットを作成します。
ここでは、test1フォルダにある対象Aの画像(例えば猫)が、test2フォルダには違う対象B(例えば犬)が入っているとします。

# フォルダの中にある画像を順次読み込む
# カテゴリーは0から始める

X = []
Y = []

# 対象Aの画像
for picture in list_pictures('./test1/'):
    img = img_to_array(load_img(picture, target_size=(64,64)))
    X.append(img)

    Y.append(0)


# 対象Bの画像
for picture in list_pictures('./test2/'):
    img = img_to_array(load_img(picture, target_size=(64,64)))
    X.append(img)

    Y.append(1)


# arrayに変換
X = np.asarray(X)
Y = np.asarray(Y)

Xに画像の情報をインプットし、Yにクラスの情報を付与しています。
続いて、画素値の正規化、クラスのデータ変換(One-Hot表現というらしい)を行います。


# 画素値を0から1の範囲に変換
X = X.astype('float32')
X = X / 255.0

# クラスの形式を変換
Y = np_utils.to_categorical(Y, 2)

# 学習用データとテストデータ
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))

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))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))       # クラスは2個
model.add(Activation('softmax'))

# コンパイル
model.compile(loss='categorical_crossentropy',
              optimizer='SGD',
              metrics=['accuracy'])

# 実行。出力はなしで設定(verbose=0)。
history = model.fit(X_train, y_train, batch_size=5, epochs=200,
                   validation_data = (X_test, y_test), verbose = 0)

historyの中には学習の履歴があるので、確認できます。
以下では、学習データとテストデータのaccuracyをプロットしています。


plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(['acc', 'val_acc'], loc='lower right')
plt.show()

検証データに適用し、実際に適用しconfusion matrixを作成します。


# テストデータに適用
predict_classes = model.predict_classes(X_test)

# マージ。yのデータは元に戻す
mg_df = pd.DataFrame({'predict': predict_classes, 'class': np.argmax(y_test, axis=1)})

# confusion matrix
pd.crosstab(mg_df['class'], mg_df['predict'])

まとめ


DeepLearningは敷居が高かったのですが、keras使えば書きやすいと思いました。
また、分析環境は既に構築されているものを利用するとラクです。

モデルの精緻化に関してはこれから勉強します。
初心者なので間違っている部分があるかもしれませんが、もし何かあればご指摘いただけるとありがたいです。
最後までお読みいただき、ありがとうございました。

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
haru1977
この記事は以下の記事からリンクされています
bobrockCNNによる学習データからリンク
過去の4件を表示する

コメント

貴重なサンプルを提示して頂いてありがとうございます。
掲示のプログラムを参考に、自分が持っている画像で試してみたのですが、以下のようなエラーが出ます。
使用している画像は、添付のカラーのjpgなのですが、次元がおかしいようなエラーに思えますが、原因がわかりません。
もし、解決策等のヒントがございましたら、ご教示いただけますと助かります。
C:\WORK\AIT_ROAD\20180324_AIT_ROAD\image_sequences_processed>python keras_go.py
Using TensorFlow backend.
Traceback (most recent call last):
File "keras_go.py", line 81, in
history = model.fit(X_train, y_train, batch_size=5, epochs=200,validation_data = (X_test, y_test), verbose = 1)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\models.py", line 960, in fit
validation_steps=validation_steps)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1581, in fit
batch_size=batch_size)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1414, in _standardize_user_data
exception_prefix='input')
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 141, in _standardize_input_data
str(array.shape))
ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (0, 1)
image-10590.jpg

0
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
今まで買ってよかった技術書を紹介しよう!
~
Docker上のみでシステムを作るときの構成
~