MNIST에 포함되어 있는 손글씨 이미지와 이미지가 의미한 숫자를 기록해 놓은 라벨을 출력해보는 방법을 설명합니다.  



예전에 보았던 텐서플로우 초보자 가이드(?)에선 28 X 28 사이즈의 이미지를 크기 784(=28x28)인 일차원 배열로 변환한 MNIST 데이터를 가져오는 것으로 시작했었습니다.  

지금은  keras 모듈을 사용하여 가져올 수 있어서  MNIST 데이터의 구조가 좀 달라진듯합니다.


문서 상으로 언급되는 MNIST 데이터 구조를 봐서는 이해가 잘안되서..  

위에서 언급한 두 가지 방법으로 MNIST 데이터를 가져와서 화면에 출력해보았습니다.



우선 예전에 사용했던 방법으로 tensorflow.examples.tutorials.mnist를 사용하여 작성된 코드입니다.


import numpy as np
import matplotlib.pyplot as plt

# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)


print("훈련 이미지 :",  mnist.train.images.shape)
print("훈련 라벨:",  mnist.train.labels.shape)
print("테스트 이미지 : ", mnist.test.images.shape)
print("테스트 라벨 : ", mnist.test.labels.shape)
print("검증 이미지 : ", mnist.validation.images.shape)
print("검증 라벨 : ", mnist.validation.labels.shape)
print('\n')


mnist_idx = 100


print('[label]')
print('one-hot vector label = ', mnist.train.labels[mnist_idx])
print('number label = ', np.argmax(mnist.train.labels[mnist_idx]))
print('\n')

print('[image]')

for index, pixel in enumerate(mnist.train.images[mnist_idx]):
   if index % 28 == 0:
       print('\n')
   else:
       print("%10f" % pixel, end="")
print('\n')


plt.figure(figsize=(5, 5))
image = np.reshape(mnist.train.images[mnist_idx], [28, 28])
plt.imshow(image, cmap='Greys')
plt.show()



1. 다음 두 줄에 의해서 MNIST 데이터를 다운로드 받게 됩니다.

처음 실행시에 MNIST 데이터를 다운로드 받아서 read_data_sets의 첫번째 인자로 지정한 경로에 저장하고 다음 실행부터는 압축을 풀어서 사용합니다.


from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)



Tensorflow 1.8 이상에서는 다음과 같은 경고문이 보입니다. 추후 버전에서 해당 함수가 제거될 것이기 때문에 다른 방법을 사용하라는 의미입니다.  포스팅 마지막에서 대안으로 keras를 이용하는 방법을 설명합니다.



WARNING:tensorflow:From C:/Users/webnautes/PycharmProjects/TensorFlow_Project/showMNISTImage.py:10: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.

Instructions for updating:

Please use alternatives such as official/mnist/dataset.py from tensorflow/models.





..


..

2. 훈련, 테스트, 검증 데이터 세가지가  각각 55000개, 10000개, 5000개 있습니다.

각 데이터는 28 x 28 이미지를  크기 784인 1차원 배열에 담아놓은 이미지 데이터와 해당 이미지가 의미하는 숫자를 크기 10인 1차원 배열에 담아놓은 라벨 데이터로 구성됩니다.


print("훈련 이미지 :",  mnist.train.images.shape)

print("훈련 라벨:",  mnist.train.labels.shape)

print("테스트 이미지 : ", mnist.test.images.shape)

print("테스트 라벨 : ", mnist.test.labels.shape)

print("검증 이미지 : ", mnist.validation.images.shape)

print("검증 라벨 : ", mnist.validation.labels.shape)

print('\n')


훈련 이미지 : (55000, 784)

훈련 라벨: (55000, 10)

테스트 이미지 :  (10000, 784)

테스트 라벨 :  (10000, 10)

검증 이미지 :  (5000, 784)

검증 라벨 :  (5000, 10)




3. 훈련 데이터의 라벨(mnist.train.labels)을 출력해서 확인해봅니다. mnist_idx는 100번째 인덱스에 있는 라벨을 가져오기 위해 지정했습니다. 나중에 이미지를 가져올 때도 사용합니다.


mnist_idx = 100


print('[label]')

print('one-hot vector label = ', mnist.train.labels[mnist_idx])

print('number label = ', np.argmax(mnist.train.labels[mnist_idx]))

print('\n')



라벨은 one-hot 벡터로 저장됩니다. 데이터의 의미를 1차원 배열의 특정 위치에만 1을 기록하여 나타내는 방법입니다.

 

MNIST 데이터의 경우 0~9까지 10개의 숫자 이미지를 저장하기 때문에 크기 10인 1차원 배열을 사용합니다.

1차원 배열의 첫번째 값이 1이면 0을 의미하며 두번째 값이 1이면 1을 의미합니다.


아래 실행 결과를 예로 들면 숫자 7을 표현하기 위해  8번째 값만 1로 기록했습니다.


[label]

one-hot vector label =  [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]

number label =  7




4. 훈련 데이터의 이미지(mnist.train.images)를 출력해봅니다. 1차원 배열에 저장되어 있기 때문에 이미지의 가로 길이인 28마다 줄바꿈을 해주었습니다.  


print('[image]')


for index, pixel in enumerate(mnist.train.images[mnist_idx]):

   if index % 28 == 0:

       print('\n')

   else:

       print("%10f" % pixel, end="")

print('\n')



하나의 픽셀을 0~1 사이의 소수점으로 표현합니다.  숫자의 형태를 나타내기 위한 픽셀들은 0 초과하는 값을 가지게 됩니다.  0인 부분들은 배경이되는 부분입니다.





5. 그레이 영상으로 출력해봅니다.  앞에서 0보다 큰 값을 가진 부분들이 검은색으로 표현됩니다. 값이 클수록 진하게 보이는데 7의 형태를 보여주는 부분이 진한 것을 볼 수 있습니다.


plt.figure(figsize=(5, 5))

image = np.reshape(mnist.train.images[mnist_idx], [28, 28])

plt.imshow(image, cmap='Greys')

plt.show()





plt.imshow에서 cmap='Greys' 부분을 제거하면 인터넷상에서 볼 수 있는 이미지가 됩니다.





6. keras 모듈을 사용하도록 코드를 수정했습니다.

기존 방법과 다르게 검증 데이터가 없고 MNIST 데이터를 가져온 후 저장된 구조가 다릅니다.


import numpy as np
import matplotlib.pyplot as plt

from tensorflow import keras
mnist = keras.datasets.mnist
(train_images, train_labels),(test_images, test_labels) = mnist.load_data()


print("훈련 이미지 :",  train_images.shape)
print("훈련 라벨:",  train_labels.shape)
print("테스트 이미지 : ", test_images.shape)
print("테스트 라벨 : ", test_labels.shape)
print('\n')


mnist_idx = 100


print('[label]')
print('number label = ', train_labels[mnist_idx])
print('\n')

print('[image]')

for row in train_images[mnist_idx]:
   for col in row:
       print("%10f" % col, end="")
   print('\n')
print('\n')


plt.figure(figsize=(5, 5))
image = train_images[mnist_idx]
plt.imshow(image)
plt.show()



기존과 달리 28 x 28 배열에 저장된 손글씨 이미지가 저장되어 있습니다.

라벨의 경우에는 one-hot vector가 아닌 실제 해당되는 숫자가 저장되어 있습니다.

훈련 이미지 : (60000, 28, 28)

훈련 라벨: (60000,)

테스트 이미지 :  (10000, 28, 28)

테스트 라벨 :  (10000,)



[label]

number label =  5



[image]

생략..




포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

여러분의 응원으로 좋은 컨텐츠가 만들어집니다.
지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

유튜브 구독하기

+ Recent posts