keras ver.2系でcifar10 やってみました

kerasでcifar10、というのは別に高度な課題でも何でもなく、チュートリアルレベルの難易度です
実際に解説記事やソースコードはネット上にたくさん転がっています

読者の皆さんは、ではなぜ今更これをやるのか、と感じると思います
その理由ですが、実はkerasは今年の三月にメジャーアップデートされました
それに伴ってコードの書き方に少し変更が発生しているので、簡単なcifar10のプログラムをサンプルとして残しておこうと思いました

コード全体

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization
from keras.utils import to_categorical

from keras.datasets import cifar10

# cifar10は10クラスへの分類問題
num_classes = 10

(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# 入力値は0~1の間にしとかないと、たまに学習が進まなくなる
x_train = x_train.astype("float32")
x_test = x_test.astype("float32")
x_train /= 255.0
x_test /= 255.0

# 0 ~ 9までの整数値から、10次元のone-hotベクトルへ変換する
# 他クラス分類をするときはほぼ必須
y_train = to_categorical(y_train, num_classes)
y_test = to_categorical(y_test, num_classes)

# ---ここからモデルの設定---
model = Sequential()

# 最初の層はinput_shapeが必須
model.add(Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu", input_shape=x_train[0].shape))
model.add(Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(Dropout(0.5))

model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(BatchNormalization())

model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(BatchNormalization())

# ここまでの層の出力は行列
# Flattenで行を結合してベクトルにする$
model.add(Flatten())
model.add(Dense(512, activation="relu"))
model.add(Dense(512, activation="relu"))
# 分類問題の時、出力層のactivationはだいたいsoftmax
model.add(Dense(num_classes, activation="softmax"))
# ---ここまでモデルの設定---

# 損失関数や最適化アルゴリズムなどを選択
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

# ここで学習
model.fit(x_train, y_train, batch_size=32, epochs=3, verbose=1, validation_data=(x_test, y_test))

core = model.evaluate(x_test, y_test)
print("Test loss:", score[0])
print("Test accuracy:", score[1])

学習データの呼び出し

kerasが標準で備えているcifar10データセットを使用します
ここでの注意点は、入力の値を正規化しておくこと

# 入力値は0~1の間にしとかないと、たまに学習が進まなくなる
x_train = x_train.astype("float32")
x_test = x_test.astype("float32")
x_train /= 255.0
x_test /= 255.0
それと、教師データは0 ~ 9の整数値が入っているので、one-hot配列に変換しておくことです
# 0 ~ 9までの整数値から、10次元のone-hotベクトルへ変換する
# 他クラス分類をするときはほぼ必須
y_train = to_categorical(y_train, num_classes)
y_test = to_categorical(y_test, num_classes)

モデルの記述

今回はあくまで学習自体が目的なので、モデルのハイパーパラメータとかは何も考えてません
このままコピペするとたぶん過学習するので、そこは工夫のしどころです

# ---ここからモデルの設定---
model = Sequential()

# 最初の層はinput_shapeが必須
model.add(Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu", input_shape=x_train[0].shape))
model.add(Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(Conv2D(32, kernel_size=(3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(Dropout(0.5))

model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(BatchNormalization())

model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D())
model.add(BatchNormalization())

# ここまでの層の出力は行列
# Flattenで行を結合してベクトルにする$
model.add(Flatten())
model.add(Dense(512, activation="relu"))
model.add(Dense(512, activation="relu"))
# 分類問題の時、出力層のactivationはだいたいsoftmax
model.add(Dense(num_classes, activation="softmax"))
# ---ここまでモデルの設定---

残りのコンパイルなどはあまり変わりないので省略します

結果

そんなに精度は高くありませんが、設定が適当なのでこんなものでしょう
epochを増やす、モデルの層を厚くする、などなど、まだまだ工夫の余地は大いにあります

50000/50000 [==============================] - 313s - loss: 1.5405 - acc: 0.4371 - val_loss: 1.4839 - val_acc: 0.4887
Epoch 2/3
50000/50000 [==============================] - 206s - loss: 1.0894 - acc: 0.6135 - val_loss: 1.1706 - val_acc: 0.6114
Epoch 3/3
50000/50000 [==============================] - 246s - loss: 0.8831 - acc: 0.6889 - val_loss: 0.8549 - val_acc: 0.6956
10000/10000 [==============================] - 32s
Test loss: 0.854937008095
Test accuracy: 0.6956

シェアする

  • このエントリーをはてなブックマークに追加

フォローする