Fashion-MNIST 데이터 셋

Fashion-MNIST 데이터 셋은 Zalando의 논문 이미지로 60,000개의 학습데이터와 10,000개의 테스트데이터로 구성되어있다.

T-SNE를 이용해서 테스트 데이터를 2차원 평면에 enbedding 시키면 다음과 같은 그림을 얻을 수 있다. 동일한 색은 같은 의상을 의미한다.

Download

각 데이터는 785차원의 벡터이며 첫 번째 열은 label 값으로 의상의 종류를 나타낸다. 그리고 두 번째 열부터 785 번째 열까지 784 차원 벡터는 grayscale 이미지다. 즉, MNIST와 동일하게 28픽셀 28픽셀의 바운딩 형태를 784차원으로 펼친 것이다.

From Keras

Keras를 통해서 데이터를 받기 위해서는 1.9.0 이상의 Tensorflow가 필요하다.

import tensorflow as tf

fashion_mnist = tf.keras.datasets.fashion_mnist
(training_data, training_lab), (test_img, test_lab) = fashion_mnist.load_data()

Keras를 이용해서 데이터를 다운 받은 경우 train_imgtest_img 각 object의 shape은 (28, 28)로 설정되어 있다.

print("Training set (images) shape: {shape}".format(shape=training_img.shape))
print("Training set (labels) shape: {shape}".format(shape=training_lab.shape))

print("Test set (images) shape: {shape}".format(shape=test_img.shape))
print("Test set (labels) shape: {shape}".format(shape=test_lab.shape))
Training set (images) shape: (60000, 28, 28)
Training set (labels) shape: (60000,)
Test set (images) shape: (10000, 28, 28)
Test set (labels) shape: (10000,)

Label

Label은 one-hot vector가 아닌 0에서 9까지의 숫자로 표시 되어있다.

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

Why Fashion-MNIST

Fashion-MNIST 제작자가 밝힌 제작 의도는 다음과 같다.

  • MNIST is too easy. MNIST 같은 경우는 CNN을 이용하면 99.7%의 정확도를 얻을 수 있다. 뿐만 아니라 Hidden layer가 없는 softmax 모델로도 90%가 넘는 정확도를 보여준다. Fashion-MNIST 는 MNIST에 비해 정확도를 끌어올리기 쉽지 않다.
  • MNIST is overused.
  • MNIST can not represent modern CV tasks.

Load Fashion-MNIST data set

학습데이터(csv 파일)의 용량은 135.2MB이고 Panda에서 불러왔을 때 메모리 사용량은 358.9MB이다.

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 60000 entries, 0 to 59999
Columns: 785 entries, label to pixel784
dtypes: int64(785)
memory usage: 359.3 MB

Fashion-MNIST multiclass classification

의상의 종류를 분류하는 모델을 MLP(Multilayer Perceptron)와 CNN을 이용해서 만들어보자. 확인데이터(Validation)는 따로 두지 않았고 60,000개의 학습데이터는 batch size 100으로 분할 했다. Label이 one-hot vector가 아니기 때문에 TensorFlow에서 tf.one_hot를 사용해서 one-hot encoding하였다. AWS의 p2.xlarge 인스턴스로 연산하였다(일반 PC에서 돌리면 시간이 오래 걸림). 아래 MLP 모델과 CNN 모델의 목적은 Fashion-MNIST 분류 모델의 예를 위해서 작성한 것으로 각 parameter 튜닝을 통해서 더 나은 결과를 얻을 수 있다. 아래는 csv 파일을 불러와서 모델을 제작하는 코드다.

MLP(Multilayer Perceptron)

MLP 모델은 다음과 같이 구성하였다.

MNIST 데이터와 달리 테스트데이터의 정확도는 높지 않다.

Accuracy of Test data : 0.8177

MLP TensorFlow code for Fashion-MNIST

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf

%matplotlib inline

# 데이터 다운받기
! wget --no-check-certificate -P ./Data/fashionmnist/ -N https://mjgim.icim.or.kr/assets/data/fashion-mnist_train.csv
! wget --no-check-certificate -P ./Data/fashionmnist/ -N https://mjgim.icim.or.kr/assets/data/fashion-mnist_test.csv

# 데이터 불러오기 
# 학습데이터
training_data = pd.read_csv("Data/fashionmnist/fashion-mnist_train.csv")
training_lab =  np.array(training_data["label"])
del training_data["label"]
training_img = np.array(training_data)

# 테스트데이터
test_data = pd.read_csv("Data/fashionmnist/fashion-mnist_test.csv")
test_lab =  np.array(test_data["label"])
del test_data["label"]
test_img = np.array(test_data)

training_img = training_img/255
test_img = test_img/255

# Making fileque
def group_list(l, group_size):

    for i in range(0, len(l), group_size):
        yield l[i:i+group_size]

# 모델 구성
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.int32, [None])
Y_ = tf.one_hot(Y, depth=10,  dtype=tf.float32)

H0 = tf.layers.dense(X, 1024, activation=tf.nn.sigmoid)
H1 = tf.layers.dense(H0, 1024, activation=tf.nn.sigmoid)
H2 = tf.layers.dense(H1, 1024, activation=tf.nn.sigmoid)
H3 = tf.layers.dense(H2, 1024, activation=tf.nn.sigmoid)
H4 = tf.layers.dense(H3, 1024, activation=tf.nn.sigmoid)

H = tf.layers.dense(H4, 10, activation=tf.nn.softmax)

loss = - tf.reduce_mean(tf.reduce_sum(Y_ * tf.log(H), reduction_indices=[1]))
train = tf.train.AdamOptimizer(0.0001).minimize(loss)

correct_prediction = tf.equal(tf.argmax(H,1), tf.argmax(Y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

sess = tf.Session()
sess.run(tf.global_variables_initializer())

cost_list = []
acc_list = []

batch_size = 100
n_epoch = 10

for i in range(n_epoch):
    cost = 0.
    x_batch = group_list(training_img, batch_size)
    y_batch = group_list(training_lab, batch_size)

    for j in range(60000//batch_size):
        batch_xs = next(x_batch)
        batch_ys = next(y_batch)
        _, c = sess.run([train, loss], feed_dict={X: batch_xs, Y: batch_ys})
        cost += c/(60000//batch_size)
    cost_list.append(cost)

    acc = sess.run(accuracy, feed_dict={X: test_img, Y: test_lab})
    acc_list.append(acc)

plt.figure(figsize=(12,10))
plt.subplot(221)
plt.title("Cost of Trining data")
plt.xlabel("Steps")
_ = plt.plot(cost_list, "c")


plt.subplot(222)
plt.title("Accuracy of Test data")
plt.xlabel("Steps")
_ = plt.plot(acc_list, "k--")

print("Accuracy of Test data : %s" %acc)

CNN(Convolutional neural network)

당연한 것이지만 CNN으로 모델을 구성하는 것이 MLP 모델과 비교해서 높은 정확도를 보여주었다.

Accuracy of Test data : 0.9176

CNN TensorFlow code for Fashion-MNIST

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf

%matplotlib inline

# 데이터 다운받기
! wget --no-check-certificate -P ./Data/fashionmnist/ -N https://mjgim.icim.or.kr/assets/data/fashion-mnist_train.csv
! wget --no-check-certificate -P ./Data/fashionmnist/ -N https://mjgim.icim.or.kr/assets/data/fashion-mnist_test.csv

# 데이터 불러오기
training_data = pd.read_csv("Data/fashionmnist/fashion-mnist_train.csv")
training_lab =  np.array(training_data["label"])
del training_data["label"]
training_img = np.array(training_data)

test_data = pd.read_csv("Data/fashionmnist/fashion-mnist_test.csv")
test_lab =  np.array(test_data["label"])
del test_data["label"]
test_img = np.array(test_data)

training_img = training_img/255
test_img = test_img/255

# Making fileque
def group_list(l, group_size):

    for i in range(0, len(l), group_size):
        yield l[i:i+group_size]

# 모델 구성
X = tf.placeholder(tf.float32, [None, 784])
X_reshape = tf.reshape(X, shape=[-1,28,28,1])

Y = tf.placeholder(tf.int32, [None])
Y_ = tf.one_hot(Y, depth=10,  dtype=tf.float32)

conv1 = tf.layers.conv2d(inputs=X_reshape, filters=32, kernel_size=[2, 2], padding="SAME", activation=tf.nn.relu)
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], padding="SAME", strides=2)
H1 = tf.layers.dropout(inputs=pool1, rate=0.3)

conv2 = tf.layers.conv2d(inputs=H1, filters=32, kernel_size=[2, 2], padding="SAME", activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], padding="SAME", strides=2)
H2 = tf.layers.dropout(inputs=pool2, rate=0.3)

H3 = tf.layers.dense(tf.layers.flatten(H2), 1024, activation=tf.nn.relu)
H4 = tf.layers.dense(H3, 512, activation=tf.nn.relu)

H_2 = tf.layers.dense(H4, 512, activation=tf.nn.relu)
H_1 = tf.layers.dense(H_2, 512, activation=tf.nn.relu)

H = tf.layers.dense(H_1, 10, activation=tf.nn.softmax)

loss = - tf.reduce_mean(tf.reduce_sum(Y_ * tf.log(H), reduction_indices=[1]))
train = tf.train.AdamOptimizer(0.0001).minimize(loss)

correct_prediction = tf.equal(tf.argmax(H,1), tf.argmax(Y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

sess = tf.Session()
sess.run(tf.global_variables_initializer())

cost_list = []
acc_list = []


batch_size = 100
n_epoch = 10

for i in range(n_epoch):
    cost = 0.
    x_batch = group_list(training_img, batch_size)
    y_batch = group_list(training_lab, batch_size)

    for j in range(60000//batch_size):
        batch_xs = next(x_batch)
        batch_ys = next(y_batch)
        _, c = sess.run([train, loss], feed_dict={X: batch_xs, Y: batch_ys})
        cost += c/(60000//batch_size)
    cost_list.append(cost)

    acc = sess.run(accuracy, feed_dict={X: test_img, Y: test_lab})
    acc_list.append(acc)

plt.figure(figsize=(12,10))
plt.subplot(221)
plt.title("Cost of Trining data")
plt.xlabel("Steps")
_ = plt.plot(cost_list, "c")


plt.subplot(222)
plt.title("Accuracy of Test data")
plt.xlabel("Steps")
_ = plt.plot(acc_list, "k--")

print("Accuracy of Test data : %s" %acc)

Reference