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_img
와 test_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)