
Fashion-MNISTをCNNモデルで学習
こんにちは。
AI coordinatorの清水秀樹です。
前回の記事「TensorFlowでFashion-MNISTを試してみた」で学習モデルを作成した結果、簡単に過学習を起こしていたので、精度を上げるためにCNNで作成した学習モデルで検証してみたので、その結果をソースコードと合わせて紹介したいと思います。
開発環境
iMac (27-inch, Late 2012)
プロセッサ 2.9 GHz intel Core i5
macOS Sierra バージョン 10.12.4
Anaconda3-4.2.0-MacOSX-x86_64
python 3.5.2
tensorflow 1.0.0
keras 1.2.2
前回の結果との比較
以下、前回のモデル。
多層パーセプトロンでモデルを実装。
def build_model():
# モデルの作成
model = Sequential()
model.add(Dense(512, input_shape=(784,)))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(10))
model.add(Activation('softmax'))
# 損失関数の定義
model.compile(
loss='categorical_crossentropy',
optimizer=Adam(),
metrics=['accuracy'])
return model
その結果は、


そして今回作成したCNNモデルは、
def build_model():
model = Sequential()
#畳み込み層の作成
#1層目の追加 1024個の層を最初に作り、フィルター3*3のフィルターを32個作成
model.add(Convolution2D(32, 3, 3, border_mode="same", input_shape=in_shape))
model.add(Activation("relu"))
#2層目の畳み込み層
model.add(Convolution2D(32, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#プーリング層
model.add(MaxPooling2D(pool_size=(2, 2)))
#Dropoutとは過学習を防ぐためのもの 0.25は次のニューロンへのパスをランダムに1/4にするという意味
model.add(Dropout(0.5))
#3層目の作成
model.add(Convolution2D(64, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#4層目の作成
model.add(Convolution2D(64, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#プーリング層
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
#5層目
model.add(Convolution2D(128, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#6層目
model.add(Convolution2D(128, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#プーリング層
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
#平坦化
model.add(Flatten())
#7 全結合層 FC
model.add(Dense(100))
model.add(Activation("relu"))
#Dropout
model.add(Dropout(0.5))
#8層目 引数nub_classesとは分類の数を定義する。
model.add(Dense(nub_classes))
model.add(Activation('softmax'))
#ここまででモデルの層完成
#lossは損失関数を定義するところ
model.compile(loss="categorical_crossentropy",
metrics = ["accuracy"],
optimizer = "adam"
)
return model
その結果、


うまく学習できているみたい。
ソースコード全容
以下、ソースコードの紹介です。
import mnist_reader
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.layers.core import Dense, Activation, Flatten, Dropout
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils.visualize_util import plot
import matplotlib.pyplot as plt
def build_model():
model = Sequential()
#畳み込み層の作成
#1層目の追加 1024個の層を最初に作り、フィルター3*3のフィルターを32個作成
model.add(Convolution2D(32, 3, 3, border_mode="same", input_shape=in_shape))
model.add(Activation("relu"))
#2層目の畳み込み層
model.add(Convolution2D(32, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#プーリング層
model.add(MaxPooling2D(pool_size=(2, 2)))
#Dropoutとは過学習を防ぐためのもの 0.25は次のニューロンへのパスをランダムに1/4にするという意味
model.add(Dropout(0.5))
#3層目の作成
model.add(Convolution2D(64, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#4層目の作成
model.add(Convolution2D(64, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#プーリング層
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
#5層目
model.add(Convolution2D(128, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#6層目
model.add(Convolution2D(128, 3, 3, border_mode="same"))
model.add(Activation("relu"))
#プーリング層
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
#平坦化
model.add(Flatten())
#7 全結合層 FC
model.add(Dense(100))
model.add(Activation("relu"))
#Dropout
model.add(Dropout(0.5))
#8層目 引数nub_classesとは分類の数を定義する。
model.add(Dense(nub_classes))
model.add(Activation('softmax'))
#ここまででモデルの層完成
#lossは損失関数を定義するところ
model.compile(loss="categorical_crossentropy",
metrics = ["accuracy"],
optimizer = "adam"
)
return model
def plot_history(history):
# 精度の履歴をプロット
plt.plot(history.history['acc'],"o-",label="accuracy")
plt.plot(history.history['val_acc'],"o-",label="val_acc")
plt.title('model accuracy')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(loc="lower right")
plt.show()
# 損失の履歴をプロット
plt.plot(history.history['loss'],"o-",label="loss",)
plt.plot(history.history['val_loss'],"o-",label="val_loss")
plt.title('model loss')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(loc='lower right')
plt.show()
if __name__ == "__main__":
# Fashion-MNISTのデータの読み込み
# 訓練データ6万件、テストデータ1万件
# 28ピクセル × 28ピクセル
X_train, y_train = mnist_reader.load_mnist('data/fashion', kind='train')
X_test, y_test = mnist_reader.load_mnist('data/fashion', kind='t10k')
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32')
in_shape = (28, 28, 1)
nub_classes = 10
X_train /= 255
X_test /= 255
# 10次元配列に変換 //数字の5ならこんな感じ[0,0,0,0,1,0,0,0,0,0]
y_train = np_utils.to_categorical(y_train, 10)
y_test = np_utils.to_categorical(y_test, 10)
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# データで訓練 今回は時間省略のため2回で学習する
model = build_model()
history = model.fit(X_train, y_train,
nb_epoch=50, #学習させる回数 今回は2 回数はお好みで pytyonのnb_epochとはrangeの繰り返しのこと
batch_size=128, #無作為に128画像取得している。数字はなんでも良い
validation_data=(X_test, y_test)
)
#学習モデルの保存
json_string = model.to_json()
#モデルのファイル名 拡張子.json
open('mnist.json', 'w').write(json_string)
#重みファイルの保存 拡張子がhdf5
model.save_weights('mnist.hdf5')
# モデルの評価を行う
score = model.evaluate(X_test, y_test, verbose=1)
print('loss=', score[0])
print('accuracy=', score[1])
# modelに学習させた時の変化の様子をplot
plot_history(history)
nb_epoch = 50 で学習しています。
以下、結果です。
Epoch 48/50
60000/60000 [==============================] - 252s - loss: 0.2053 - acc: 0.9248 - val_loss: 0.1781 - val_acc: 0.9341
Epoch 49/50
60000/60000 [==============================] - 253s - loss: 0.2050 - acc: 0.9249 - val_loss: 0.1797 - val_acc: 0.9340
Epoch 50/50
60000/60000 [==============================] - 252s - loss: 0.2046 - acc: 0.9254 - val_loss: 0.1794 - val_acc: 0.9377
9984/10000 [============================>.] - ETA: 0sloss= 0.17943021461
accuracy= 0.9377
前回よりは良いようです。
もっと良い学習モデルがあれば是非教えてください。
また、これからDeep Learningの勉強をするなら、こちらで紹介する書籍も参考になりますので一読してみることをオススメします。
それではまた。
LEAVE A REPLY