CIFAR-10は一般的な物体画像のデータセットであり、画像検出のテストとしてよく利用されます。
そこで今回はKerasを用いて畳み込みニューラルネットワーク(CNN)を作成し、CIFAR-10の学習を行いました。
CIFAR-10
CIFAR-10は飛行機、鳥、犬などの一般的な物体画像のデータベースです。
CIFAR-10の画像数は60000枚であります。そのうち50000枚は学習用のセットであり、10000枚はテスト用のセットです。
画像サイズ縦32×横32のRGB画像で、画像のクラス数はMNISTと同様に10クラスです。
CIFAR-10は80 Million Tiny Imagesのサブセットです。元となる80 Million Tiny Imagesは画像数8000万枚の巨大なデータセットです。
CIFAR-10はMNISTと同様非常に有名であり、ニューラルネットワーク等のテストとしてよく用いられます。
KerasからCIFAR-10へのアクセスは次のように行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
################################################## # CIFAR10 ################################################## from keras.datasets import cifar10 (x_train, t_train), (x_test, t_test) = cifar10.load_data() x_train = x_train.reshape(x_train.shape[0], 32, 32, 3) x_test = x_test.reshape(x_test.shape[0], 32, 32, 3) x_train = x_train.astype("float32") x_test = x_test.astype("float32") x_train /= 255 x_test /= 255 #one-hot表記に変換 t_train = np_utils.to_categorical(t_train, 10) t_test = np_utils.to_categorical(t_test, 10) |
作成モデル
使用した多層パーセプトロンのモデルを示します。
- 階層は畳み込み層2、全結合層2としました。
- 活性化関数はRelu関数を使用
- 出力層にはソフトマックスを使用
- 誤差関数には交差エントロピー誤差関数を使用
コード
使用したコードを下記に示します。実行はPython 3.6、TensorFlow 1.8、Keras 2.2.2を用いました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
import numpy as np import keras import random as rnd from keras.datasets import cifar10 from keras.models import Sequential from keras.layers.core import Dense, Activation, Flatten from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.callbacks import TensorBoard from keras.optimizers import SGD from keras.utils import np_utils np.random.seed(1991) ################################################## # CIFAR10 ################################################## (x_train, t_train), (x_test, t_test) = cifar10.load_data() x_train = x_train.reshape(x_train.shape[0], 32, 32, 3) x_test = x_test.reshape(x_test.shape[0], 32, 32, 3) x_train = x_train.astype("float32") x_test = x_test.astype("float32") x_train /= 255 x_test /= 255 #one-hot表記に変換 t_train = np_utils.to_categorical(t_train, 10) t_test = np_utils.to_categorical(t_test, 10) ################################################## # Function ################################################## def tensorboard_cb(root_dir="./logs", batch_size=32, model_num=1): log_dir = "{0}/model_{1}_{2}".format(root_dir, model_num, rnd.randrange(1000)) return TensorBoard(log_dir=log_dir, batch_size=batch_size, write_images=1,histogram_freq=1,write_grads=True) ################################################## # Classs ################################################## class my_Net: def __init__(self): self.Epoch = 20 self.Batch_size = 50 self.Verbose = 1 #ログの出力モード切替 : 1 プログレスバーで表示 self.output_size = 10 self.optimize = SGD() self.hidden_units = 128 self.Validation_split = 0.2 #訓練データの中で検証データとして扱う割合 self.shape = (32, 32, 3) self.callbacks = [tensorboard_cb(batch_size=self.Batch_size)] self.model = Sequential() def make_net(self): #畳み込み self.model.add(Conv2D(32, kernel_size=3, padding="same", input_shape=self.shape, activation="relu")) #畳み込み1層目 self.model.add(MaxPooling2D(pool_size=(2,2))) self.model.add(Conv2D(64, kernel_size=3, padding="same", activation="relu")) #畳み込み2層目 self.model.add(MaxPooling2D(pool_size=(2,2))) #全結合 self.model.add(Flatten()) self.model.add(Dense(512, activation="relu")) #全結合1層目 self.model.add(Dense(self.output_size)) #全結合2層目 self.model.add(Activation("softmax")) self.model.summary() def model_compile(self): self.model.compile(loss="categorical_crossentropy", #交差エントロピー誤差関数 optimizer=self.optimize, #確率的勾配下降法 metrics=["accuracy"]) def make_model(self): self.make_net() self.model_compile() def train(self, x, t): self.model.fit(x, t, batch_size=self.Batch_size, epochs=self.Epoch, callbacks=self.callbacks, verbose=self.Verbose, validation_split=self.Validation_split) def score(self, x, t): return self.model.evaluate(x, t, verbose=self.Verbose) ################################################## # Main ################################################## net = my_Net() net.make_model() net.train(x_train, t_train) score = net.score(x_test, t_test) print("\nTest loss:", score[0]) print("\nTest accuracy:", score[1]) |
多層パーセプトロンの場合と同様Kerasを使用すれば、TensorFlowと比べ簡単にモデルを作成することができました。
実行結果
実行結果を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
Using TensorFlow backend. _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_1 (Conv2D) (None, 32, 32, 32) 896 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 16, 16, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 16, 16, 64) 18496 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 8, 8, 64) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 4096) 0 _________________________________________________________________ dense_1 (Dense) (None, 512) 2097664 _________________________________________________________________ dense_2 (Dense) (None, 10) 5130 _________________________________________________________________ activation_1 (Activation) (None, 10) 0 ================================================================= Total params: 2,122,186 Trainable params: 2,122,186 Non-trainable params: 0 _________________________________________________________________ Train on 40000 samples, validate on 10000 samples 省略 Epoch 16/20 40000/40000 [==============================] - 6s 158us/step - loss: 0.8027 - acc: 0.7233 - val_loss: 1.0165 - val_acc: 0.6533 Epoch 17/20 40000/40000 [==============================] - 6s 158us/step - loss: 0.7620 - acc: 0.7349 - val_loss: 1.0439 - val_acc: 0.6479 Epoch 18/20 40000/40000 [==============================] - 6s 153us/step - loss: 0.7255 - acc: 0.7496 - val_loss: 0.9938 - val_acc: 0.6636 Epoch 19/20 40000/40000 [==============================] - 6s 157us/step - loss: 0.6849 - acc: 0.7647 - val_loss: 0.9813 - val_acc: 0.6711 Epoch 20/20 40000/40000 [==============================] - 6s 156us/step - loss: 0.6475 - acc: 0.7784 - val_loss: 0.9747 - val_acc: 0.6774 10000/10000 [==============================] - 1s 93us/step Test loss: 0.9715811299324035 Test accuracy: 0.6716 |
学習の結果判定率は67.2 %となりました。
この判定率自体は低い値となってしまいましたが、原因としてはネットワークの階層が浅く、学習方法も単純なものを選んだからだと思います。
今後は学習方法やネットワークの深さを変えて行い、判定率が向上するか見てみたいと思います。
まとめ
- 一般的な物体の画像データセットとしてCIFAR-10がある
- Keras版CNNを作成し、CIFAR-10データセットの学習を行った
- 学習の結果判定率は67.2 %となった
- 今後ネットワークの深さや学習方法を変更し、判定率の向上をめざす
関連記事