Help us understand the problem. What is going on with this article?

[Keras/TensorFlow] Kerasで自前のデータから学習と予測

More than 1 year has passed since last update.

目的

ゼロからKerasとTensorFlow(TF)を自由自在に動かせるようになる。
そのための、End to Endの作業ログ(備忘録)を残す。
※環境はMacだが、他のOSでの汎用性を保つように意識。
※アジャイルで執筆しており、精度を逐次高めていく予定。

環境

  • Mac: 10.12.3
  • Python: 3.6
  • TensorFlow: 1.0.1
  • Keras: 2.0.2

To Do

Keras導入編

Keras(Tensorflow)の環境構築
KerasでMINSTの学習と予測
KerasでTensorBoardの利用
Kerasで重みファイルの保存/読み込み
Kerasで自前データの学習と予測 <---いまココ
Kerasで転移学習

学習のテクニック編

KerasでCV
Kerasでグリッドサーチ、ランダムサーチ
Kerasで最適化手法の調整
Kerasで画像の水増し
Kerasで学習過程の可視化
Kerasで事前学習

Kerasのデータセット

Kerasには自前の画像データセットはある。
https://keras.io/ja/datasets/

  • CIFAR10
  • CIFAR100
  • MINST

読み込みは簡単。

from keras.datasets import cifar10

(X_train, y_train), (X_test, y_test) = cifar10.load_data()

中身は2つのタプルになっているそうだ。

  • X_train, X_test: shape (nb_samples, 3, 32, 32)のRGB画像データのuint8配列.
  • y_train, y_test: shape (nb_samples,)のカテゴリラベル(0-9の範囲のinteger)のuint8配列.

一方で、そこに存在しないデータセットを利用した学習の方法を考える。

参考

http://aidiary.hatenablog.com/entry/20170110/1484057655

必要なパーツ

クラス宣言部分

train_datagen = ImageDataGenerator(
    rescale=1.0 / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1.0 / 255)

入力フォルダ指定部分

train_generator = train_datagen.flow_from_directory(
    'data/train',
    target_size=(256, 256),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    'data/validation',
    target_size=(256, 256),
    batch_size=batch_size,
    class_mode='categorical')

カテゴリと割り当てられてクラス番号の対応の確認

print(train_generator.class_indices)

予測の部分

history = model.fit_generator(
    train_generator,
    samples_per_epoch=10,
    nb_epoch=nb_epoch,
    validation_data=validation_generator,
    nb_val_samples=10)

※単品の画像の場合はload_img('image.jpg',target(256,256))でロードできる。

学習用データ

kaggleより、犬、猫の画像をダウンロード。学習データ:犬200枚/猫200枚、テストデータ:犬200枚/猫200枚、とした。
https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition

フォルダ構造

$ find ./data -type d  | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"
 |-data
 | |-train
 | | |-cats
 | | |-dogs
 | |-validation
 | | |-cats
 | | |-dogs

実行

cat_dog.py
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator


batch_size = 32
epochs = 1


model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(128, 128, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('softmax'))

model.summary()

model.compile(loss='categorical_crossentropy',
               optimizer='adam',
               metrics=['accuracy'])


train_datagen = ImageDataGenerator(
    rescale=1.0 / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1.0 / 255)


train_generator = train_datagen.flow_from_directory(
    'data/train',
    target_size=(128, 128),
    batch_size=batch_size,
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    'data/validation',
    target_size=(128, 128),
    batch_size=batch_size,
    class_mode='categorical')


history = model.fit_generator(
    train_generator,
    samples_per_epoch=200,
    nb_epoch=epochs,
    validation_data=validation_generator,
    nb_val_samples=200)

from keras.utils import plot_model
plot_model(model, to_file="model.png", show_shapes=True)

以下、実行結果。

Epoch 1/1
6/6 [==============================] - 87s - loss: 1.4899 - acc: 0.5625 - val_loss: 0.7940 - val_acc: 0.5014

モデルの可視化

https://keras.io/visualization/
Keras2になったため、以前と少し変わっている。

from keras.utils import plot_model
plot_model(model, to_file="model.png", show_shapes=True)

model.png

スクリプトの説明

model.add(Convolution2D(32, 3, 3, input_shape=(128, 128, 3)))

https://keras.io/ja/layers/convolutional/#convolution2d
(128, 128, 3)は入力画像のサイズを表す。128*128 pixlでRGBの3種類があるため3である。
32, 3, 3は、32枚のフィルタ 、サイズは3*3を表す。
(128, 128, 3)の画像がこのレイヤーを通ると、(126, 126, 32)になる。

model.add(Activation('relu'))

https://keras.io/ja/layers/core/#activation
活性化関数。画像ではreluがよく使われる。

model.add(MaxPooling2D(pool_size=(2, 2)))

入力のサイズを半分にする。
入力が(126, 126, 32)で、このレイヤーを通ると約半分の(61, 61, 32)になる。

model.add(Flatten())

https://keras.io/ja/layers/core/#flatten
平坦化。
入力(30, 30, 64)に対して、出力は(*, 57600)となる。
57600 =30x30x64

model.add(Dense(64))

https://keras.io/ja/layers/core/#dense
通常の全結合。
(, 57600)->(,64)となる。

model.add(Dropout(0.5))

https://keras.io/ja/layers/core/#dropout
50%の確率で各ユニットの出力を利用。

ImageDataGenerator

https://keras.io/ja/preprocessing/image/
rescale=1.0 / 255 # デフォルトはNone.Noneか0ならば,適用しない.それ以外であれば,(他の変換を行う前に) 与えられた値をデータに積算する
shear_range=0.2 # 浮動小数点数.シアー強度(反時計回りのシアー角度(ラジアン)).
zoom_range=0.2 # 浮動小数点数または[lower,upper].ランダムにズームする範囲.
horizontal_flip=True # 真理値.水平方向に入力をランダムに反転します

fit_generator

https://keras.io/ja/models/model/
samples_per_epoch=200 #
nb_val_samples=200 #

End

agumon
Deep Learningで良いソリューションを作りたい今日このごろ、ただいまスキルのキャッチアップ中です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away