
ファッション画像?でMNIST
こんにちは。
AI coordinatorの清水秀樹です。
Fashion-MNISTというデータセットが公開されたので早速試してみました。
MNISTとの違いは数字データがファッション画像になっているところです。
どんなデータが入っているかというと、
ラベル データ
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot
なんで、そんなデータセットができたのかというと、公式サイトには以下のように書かれていました。
・MNISTは簡単すぎるし、既にみんな使っているから
だそうです。
う〜ん、なるほど。
いまいちピンとこないので、実際に動かしてみました。
参考サイト
以下、サイト(日本語版)を参考にしました。
TensorFlow: TensorFlow で Fashion-MNIST
開発環境
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
どんな画像が入っているのか除いてみました。
とりあえず1枚のトレーニング画像とテストデータを抜き出してみました。
以下のソースコードで簡単に抜き出せます。
# -*- coding: utf-8 -*-
import mnist_reader
import sys
import numpy as np
from keras.utils import np_utils
from PIL import Image
X_train, y_train = mnist_reader.load_mnist('data/fashion', kind='train')
X_test, y_test = mnist_reader.load_mnist('data/fashion', kind='t10k')
#訓練画像
train_no = 0
outImg = Image.fromarray(X_train[train_no].reshape((28,28))*255).convert("RGB")
outImg.save("train.png")
#テスト画像
test_no = 0
outImg = Image.fromarray(X_test[test_no].reshape((28,28))).convert("RGB")
outImg.save("test.png")
抜き出した画像は ‘train.png’と’test.png’という名前で保存されます。
ちっさ!!
そりゃそうですね。28×28サイズですから。
MNISTと比較してみた。
従来の数字のみのMNISTと、今回公開されたFashion-MNISTを比較してみます。
まずは従来の数字のみMNISTの結果です。
Epoch = 2で試した結果、
Train on 60000 samples, validate on 10000 samples
Epoch 1/2
60000/60000 [==============================] - 8s - loss: 0.2515 - acc: 0.9239 - val_loss: 0.1021 - val_acc: 0.9690
Epoch 2/2
60000/60000 [==============================] - 7s - loss: 0.1018 - acc: 0.9686 - val_loss: 0.0950 - val_acc: 0.9679
9888/10000 [============================>.] - ETA: 0sloss= 0.0949767166178
accuracy= 0.9679
accuracy = 0.9679と、たった2回の学習でかなりの精度が出ています。
続いて、Fashion-MNISTの結果です。
Train on 60000 samples, validate on 10000 samples
Epoch 1/2
60000/60000 [==============================] - 7s - loss: 0.5189 - acc: 0.8126 - val_loss: 0.3969 - val_acc: 0.8528
Epoch 2/2
60000/60000 [==============================] - 7s - loss: 0.3864 - acc: 0.8600 - val_loss: 0.3377 - val_acc: 0.8764
9280/10000 [==========================>...] - ETA: 0sloss= 0.337676012874
accuracy= 0.8764
accuracy = 0,8764となりました。
確かに、数字のみMNISTよりもFashion-MNISTの方が精度が出にくい感じですね。
難易度が上がったことが実感できました。
Fashion-MNISTを試したソースコード
試したい方は、以下のサイトからデータをクローンしましょう。
実行するには、公式サイトにも記載があるように、
utils/mnist_reader を使用する必要があります。
筆者は、いきなりこれにハマりました。
import mnist_reader
を実行するために、utils/mnist_reader が必要になります。
このモジュールは、上記サイトからクローンしたフォルダ内にあります。
これがないと、データをimportできません。
以下、今回使用したソースコードになります。
数字版MNISTの使い回しなので、コメントなど適当なのはご容赦ください。
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.utils.visualize_util import plot
import matplotlib.pyplot as plt
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
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__":
# MNISTのデータの読み込み
# 訓練データ6万件、テストデータ1万件
# 28ピクセル × 28ピクセル = 784ピクセルのデータ
# 色は0〜255
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(60000, 784).astype('float32')
X_test = X_test.reshape(10000, 784).astype('float32')
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)
# データで訓練 今回は時間省略のため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)
精度を出すために、epoch = 50 で実施してみた結果、
Epoch 49/50
60000/60000 [==============================] - 8s - loss: 0.1336 - acc: 0.9479 - val_loss: 0.3355 - val_acc: 0.9029
Epoch 50/50
60000/60000 [==============================] - 7s - loss: 0.1351 - acc: 0.9477 - val_loss: 0.3284 - val_acc: 0.9009
9280/10000 [==========================>...] - ETA: 0sloss= 0.328375703002
accuracy= 0.9009


なるほど。
epoch = 10 あたりから、過学習が発生しています。
精度をあげるには学習モデルの工夫が必要そうですね。
確かに従来のMNISTよりFashion-MNISTの方が難易度が上がっていますね。
どんな学習モデルにすれば精度が出るのか考えることで、色々勉強になりそうです。
興味がある方は参考にしてみてください。
また、これからDeep Learningの勉強をするなら、こちらで紹介する書籍も参考になりますので一読してみることをオススメします。
それではまた。
コメントはまだありません。