DeepLearning初心者がFashionMNISTを試してみる

2020年12月30日

TensorFlowのチュートリアルで紹介されているFashion MNISTを使って、本当に画像分類ができるかどうか試してみます。

Fashion MNISTとは

Fashion MNISTとは深層学習用に画像分類問題のサンプルとして作られたものです。Tシャツやカバンや靴などを10種類の画像がありこれらを学習させて分類問題に取り組めます。こんな感じの画像です。

Fashion MNIST MIT License

サンプルでは画像を学習させてTシャツやカバンや靴などが見事に分類できるようにKerasで学習させています。

この結果を元に、本当に分類できるか挑戦してみます。

Kerasで画像分類

それでは実際にKerasでFashion MNISTを学習させて画像分類に挑戦してみます。

KerasでFashion MNISTの学習

まずはサンプル通りにFashion MNISTの画像を用いて学習を行います。

# TensorFlow と tf.keras のインポート
import tensorflow as tf
from tensorflow import keras
 
# ヘルパーライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
 
# fashion mnistのダウンロード
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
 
# アイテムの分類
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
 
# データの前処理
train_images = train_images/255.0
test_images = test_images/255.0
 
# DeepLearningの処理(モデルの構築)
# 層の設定
model = keras.Sequential([
                          keras.layers.Flatten(input_shape=(28,28)),
                          keras.layers.Dense(128, activation='relu'),
                          keras.layers.Dense(10, activation='softmax')
])
 
# コンパイル設定
model.compile(optimizer='adam',
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy']
              )
 
# モデルの訓練
model.fit(train_images, train_labels, epochs=5)
 
# 正解率の評価
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
【実行結果】
Epoch 1/5
60000/60000 [==============================] - 4s 60us/step - loss: 0.5072 - acc: 0.8209
Epoch 2/5
60000/60000 [==============================] - 2s 40us/step - loss: 0.3789 - acc: 0.8636
Epoch 3/5
60000/60000 [==============================] - 2s 40us/step - loss: 0.3404 - acc: 0.8766
Epoch 4/5
60000/60000 [==============================] - 2s 39us/step - loss: 0.3168 - acc: 0.8833
Epoch 5/5
60000/60000 [==============================] - 2s 38us/step - loss: 0.2978 - acc: 0.8908

Test accuracy: 0.8696

これで学習は完了しました。次に画像を準備します。

分類対象の画像を準備

今回はTシャツの画像を用意しました。

出典:uniqlo

この画像をOpenCVを使って画像分類できるように前処理を行います。

画像の読込と整形

ここではFashion MNISTの画像とデータを合わせる為に次のような処理を行っています。

  1. 画像をグレースケールに変換
  2. 背景を白に変換
  3. 画像サイズを28×28に変換
  4. 次元の追加(Fashion MNISTとデータの次元を合わせる為)
# OpenCVのインポート
import cv2
# 画像を読み込んでグレースケールに変換
img = cv2.imread('img/org_tshirt.jpg', cv2.IMREAD_GRAYSCALE)
 
# 背景を白
cv2.floodFill(img, None, seedPoint=(4,4), newVal=(0), loDiff=(1), upDiff=(1) )
 
# 画像を28×28に縮小
img = cv2.resize(img,(28,28)) #(width,height)
plt.imshow(img)
 
# 次元の追加
ts_image = img[np.newaxis,:,:]

推論処理

それでは推論処理を行って結果を確認したいと思います。

# 推論処理
predictions = model.predict(ts_image)
pred_index = np.argmax(predictions[0])

結果

結果表示用の関数

ここで結果をグラフとして表示する為の関数を定義します(これもTensorFlowのチュートリアルに掲載されています)。

# 画像と分類名・予測した分類を表示する為の関数
def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])

    plt.imshow(img, cmap=plt.cm.binary)

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'
    else:
        color = 'red'

    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                    100*np.max(predictions_array),
                                    class_names[true_label]),
                                    color=color)

# 予測した結果を棒グラフで表示する為の関数
def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array[i], true_label[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    thisplot = plt.bar(range(10), predictions_array, color="#777777")
    plt.ylim([0, 1]) 
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('blue')

結果

結果は次のようになります。

# 画像の番号(一つしかないので0)
i = 0
# Tシャツのラベルは0なので、正解ラベルを0に設定
true_labels = np.array([0])
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions, true_labels, ts_image)
plt.subplot(1,2,2)
plot_value_array(i, predictions,  true_labels)
plt.show()
【実行結果】

結果を文字でも表示します。

pred = predictions[0]
for i, acc in enumerate(pred):
    print(class_names[i], "=", int(acc))
print("---------------------------")
print("予測した結果=", class_names[pred.argmax()])
【実行結果】
T-shirt/top = 0
Trouser = 0
Pullover = 0
Dress = 0
Coat = 0
Sandal = 1
Shirt = 0
Sneaker = 0
Bag = 0
Ankle boot = 0
---------------------------
予測した結果= Sandal

(参考)ラベルと画像の対応表

参考までに、ラベルと画像の関係は次のようになっています。

LablClass
0T-shirt/top
1Trouser
2Pullover
3Dress
4Coat
5Sandal
6Shirt
7Sneaker
8Bag
9Ankle boot