Fashion-MNIST 데이터 셋

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

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

Download

각 데이터는 785차원의 벡터이며 첫 번째 열은 label 값으로 의상의 종류를 나타낸다. 그리고 두 번째 열부터 785 번째 열까지 784 차원 벡터는 \(28 \times 28=784\) grayscale 이미지다. 즉, MNIST와 동일하게 28픽셀 \(\times\) 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 모델은 다음과 같이 구성하였다.

\[\underbrace{X}_{784} \longrightarrow \underbrace{H0}_{1024} \longrightarrow \underbrace{H1}_{1024} \longrightarrow \underbrace{H2}_{1024} \longrightarrow \underbrace{H3}_{1024} \longrightarrow \underbrace{H4}_{1024} \longrightarrow \underbrace{H}_{10}\]

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