머신러닝

2-18 Fashion MNIST 텐서플로우 머신 러닝 Simple 네트워크 예제

coding art 2020. 2. 27. 17:07
728x90

 

2017년 구글 텐서플로우 홈페이지 머신 러닝 예제로는 MNIST 손글씨 문제였으며 2018년에는 Iris flowers 데이터 문제가 게재되었었다. 2020년 현재에도 구글 텐서플로우 홈페이지 야기 저기에 그 흔적들이 남아있지만 Keras 중심으로 업그레이드가 진행되면서 다양한 예제들을 선보이고 있다. 비록 beginner 즉 초보자를 위한 예제라고는 하나 실제로 다루어 보면 어느 주제 하나라도 초보자가 그 내용을 이해하기는 쉽지 않다는 점을 지적해 둔다.

MNIST 손글씨 예제의 경우만 하더라도 TensorFlow2.0 이전의 기법으로 학습을 해왔지만 지금부터는 Keras API를 사용하는 문제로 격상되어버려 TensorFlow2.0 이전의 기법들과는 단절이 커 보인다. 이러한 갭을 매우기 위한 제 2의 예제로서 Fashion MNIST 문제를 고려해 보자.

Fashion MNIST 예제의 대상은 오브젝트가 숫자 “0”“9”에 이르는 10개의 숫자에서 이미지에 해당하는 오브젝트를 다루게 된다. 0 번은 티셔츠, 1번은 바지, 2번은 풀오버로 티셔츠나 내의 위에 입는 수준의 상의 의류이며, 3번은 여성용 드레스이며, 4번은 외출복에 해당하는 좀 두꺼운 코트를 의미한다. 6번 셔츠는 외출용 상의를 뜻한다. 그밖에 5번은 샌들, 7번은 운동화, 8번은 핸드백이며, 9번은 앵클 부트이다. 학습과 테스트를 위한 데이타들은 MNIST 손글씨와 마찬가지로 26X28 크기를 가지면서 흑백이미지로 공개되어 있으므로 참조하자. 이미지이기 때문에 숫자에 비해 간신히 그 형상이 구별이 될 정도이다. MNIST 숫자 이미지를 보면 구별하기가 쉬운 편이지만 Fashion 오브젝트는 아무래도 그 보다는 어려운 듯하다. 즉 인식률이 떨어질 수도 있을 것이다.

Fashion MNIST 문제의 특성은 MNIST 손글씨와 3색의 컬러 채널 데이터로 이루어진 CIFAR-10 이미지 판독 문제와의 중간쯤에 위치한다고 보면 된다.

 

Fashion MNIST 문제의 텐서플로우 코드는 데이터를 읽어 들이는 부분을 제외하고는 MNIST 손글씨 문제와 동일하다. 6만개의 학습 데이터와 1만개의 테스트용 데이터를 사용한다. 물론 2020년 구글 홈페이지 초보자를 위한 텐서플로우 섹션에서는 Keras 버전 딥러닝 뉴럴 레이어 네트워크를 선보이고 있지만 여기서는 그 보다 월등하게 간단한 단일 레이어 문제로 인식률을 시험해 보기로 한다.

각 오브젝트들의 Class 값은 One-hot code로 정의하고, Cost 함수는 활성화 함수로서 Softmax_Cross_Entropy를 사용하여 AdamOptimizer에 의한 경사하강법을 적용하여 확률분포를 계산한다.

이와 같은 Simple 네트워크에 의한 계산 인식률은 84.2% 안팎이다.

 

첨부된 코드를 다운받아 실행해 보자.

#fashion_mnist_simple.py

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import random

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("data/fashion", one_hot = True,
source_url='http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/')

### 신경망 모델 구성 ###
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])

W1 = tf.Variable(tf.random_normal([784, 10], stddev=0.01))
model = tf.matmul(X, W1)

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2
(logits = model, labels = Y))
optimizer = tf.train.AdamOptimizer(0.001).minimize(cost)

### 신경망 모델 학습 ###
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

batch_size = 100
total_batch = int(mnist.train.num_examples / batch_size)

for epoch in range(15):
  total_cost = 0

  for i in range(total_batch):
    batch_xs, batch_ys = mnist.train.next_batch(batch_size)

    _, cost_val = sess.run([optimizer, cost], feed_dict={X: batch_xs, Y: batch_ys})

    total_cost += cost_val

  print("Epoch:", "%04d" % (epoch + 1), "Avg. cost =", "{:.3f}".format(total_cost / total_batch))
print("Training Ended")

# Test Result
is_correct = tf.equal(tf.argmax(model, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
print("Accuracy:", sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))

#Graphic Result
labels = sess.run(model, feed_dict={X: mnist.test.images, Y: mnist.test.labels})

# Dictionary of labels
label_dict = {
    0: 'T-shirt/top',
    1: 'Trouser',
    2: 'Pullover',
    3: 'Dress',
    4: 'Coat',
    5: 'Sandal',
    6: 'Shirt',
    7: 'Sneaker',
    8: 'Bag',
    9: 'Ankle boot'
}

fig = plt.figure()
for i in range(10):
  j = random.randrange(1, 10000)
  subplot = fig.add_subplot(2, 5, i+1)
  subplot.set_xticks([])
  subplot.set_yticks([])
  subplot.set_title("%s" % label_dict[np.argmax(labels[j])])
  subplot.imshow(mnist.test.images[j].reshape((28, 28)), cmap=plt.cm.gray_r)
plt.show()