MNIST Data
<p dir="auto"><img src="https://images.hive.blog/768x0/https://cdn-images-1.medium.com/max/584/1*9Mjoc_J0JR294YwHGXwCeg.jpeg" srcset="https://images.hive.blog/768x0/https://cdn-images-1.medium.com/max/584/1*9Mjoc_J0JR294YwHGXwCeg.jpeg 1x, https://images.hive.blog/1536x0/https://cdn-images-1.medium.com/max/584/1*9Mjoc_J0JR294YwHGXwCeg.jpeg 2x" /><br />
그동안 우리가 학습한 내용을 활용해서 이미지 분류 작업을 할 수 있다. 위의 그림과 같이 여러 사람이 다양한 형태로 표기한 숫자 이미지 파일을 픽섹 단위로 분해해서 학습할 수 있다는 의미다. 임의의 새로운 숫자 이미지 파일이 들어와도 어떤 숫자인지 분류하기 위한 목적이다.
<pre><code>import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# Check out https://www.tensorflow.org/get_started/minist/beginners
# for more information about the mnist dataset
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)
nb_classes = 10
<p dir="auto"><code>TensorFlow에서 예시로 제공해주는 데이터가 이미 있으므로 이를 활용해서 연습할 수 있다. <code>tensorflow.example.tutorials.mnist 라이브러리에서 <code>input_data를 가져온 후 <code>MNIST_data를 읽어온다. 이때 <code>one_hot을 <code>True로 설정해두면 우리가 따로 작업하지 않아도 결과 데이터를 <code>one-hot-encoding 형태로 가져올 수 있다. 우리가 분류하기 원하는 총 결과값은 <code>0 ~ 9까지 총 10개의 <code>label이다.
<p dir="auto"><img src="https://images.hive.blog/768x0/https://lh3.googleusercontent.com/jfwqx5A2C1HVrtVOjlRKQNdPGWxrPpnWYYrzOwyUn1WO92mLcXipRv7VNpDML-ALCrtKtZ7izq4=w326-h339-no" srcset="https://images.hive.blog/768x0/https://lh3.googleusercontent.com/jfwqx5A2C1HVrtVOjlRKQNdPGWxrPpnWYYrzOwyUn1WO92mLcXipRv7VNpDML-ALCrtKtZ7izq4=w326-h339-no 1x, https://images.hive.blog/1536x0/https://lh3.googleusercontent.com/jfwqx5A2C1HVrtVOjlRKQNdPGWxrPpnWYYrzOwyUn1WO92mLcXipRv7VNpDML-ALCrtKtZ7izq4=w326-h339-no 2x" />
<p dir="auto">우리가 분석해야 할 <code>X 값은 위 그림과 같이 가로 세로 28 * 28의 총 784개 픽셀이다. 그동안 10여 개의 <code>feature를 학습했던 것보다 훨씬 많은 수의 학습이 이루어진다. <code>feature의 개수와 결과값 <code>Y의 <code>label 개수를 고려해 아래의 코드와 같이 차원을 설정한다.
<pre><code># MNIST data image of shape 28 * 28 = 784
X = tf.placeholder(tf.float32, [None, 784])
# 0 ~ 9 digit recognition = 10 classes
Y = tf.placeholder(tf.float32, [None, nb_classes])
W = tf.Variable(tf.random_normal([784, nb_classes]))
b = tf.Variable(tf.random_normal([nb_classes]))
<p dir="auto">특정 숫자로 제한된 결과값을 도출하기 위한 학습이기 때문에 <code>softmax classification을 사용할 것이다. 앞서 배웠던 내용과 동일하다.
<pre><code># Hypothesis (using softmax)
hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
# Test Model
is_correct = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
# Calculate Accuracy
accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
<p dir="auto">여기서 한 가지 이슈가 발생한다. <code>TensorFlow에서 제공하는 <code>train_data의 개수는 55,000개다. 전체 데이터를 한 번에 학습시키기에는 메모리가 부족하거나 과부하가 걸릴 수 있다. 이를 해결하기 위해 여러개의 <code>batch로 나누어 여러번 학습을 진행하는 것이 효율적이다. <code>batch는 전체 데이터 중 몇 개의 덩어리로 나눈 개념으로 이해하면 된다.
<pre><code># parameters
training_epochs = 15
batch_size = 100
with tf.Session() as sess:
# Initialize Tensorflow Variables
sess.run(tf.global_variables_initializer())
# Training cycle
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples / batch_size)
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
c, _ = sess.run([cost, optimizer], feed_dict={X: batch_xs, Y: batch_ys})
avg_cost += c / total_batch
print('Epoch: ', '%04d' % (epoch + 1), 'Cost: ', '{:.9f}'.format(avg_cost))
<p dir="auto"><code>epoch이라는 개념도 나온다. 전체 55,000개 데이터를 한번씩 모두 학습하면 <code>1 epoch이 된다. 위 코드에서 우리는 <code>training_epochs=15로 설정했으므로 전체 55,000개 데이터를 15번, 즉 55,000 * 15 = 825,000개 데이터를 학습하게 된다.
<p dir="auto"><code>training_epochs = 15을 반복하는 <code>for loop 안에 전체 55,000개 데이터를 <code>batch_size = 100으로 나눈 550번 반복해서 학습을 진행하는 <code>for loop이 포함되어 있다. 각 <code>epoch마다 <code>cost를 계산할 수 있다.
<pre><code>Epoch: 0001 Cost: 2.817744847
Epoch: 0002 Cost: 1.090436493
Epoch: 0003 Cost: 0.863765682
Epoch: 0004 Cost: 0.753992744
Epoch: 0005 Cost: 0.685377607
Epoch: 0006 Cost: 0.637151059
Epoch: 0007 Cost: 0.600648493
Epoch: 0008 Cost: 0.571259752
Epoch: 0009 Cost: 0.547828114
Epoch: 0010 Cost: 0.528008322
Epoch: 0011 Cost: 0.510270363
Epoch: 0012 Cost: 0.496145278
Epoch: 0013 Cost: 0.482756565
Epoch: 0014 Cost: 0.471168885
Epoch: 0015 Cost: 0.460864195
<p dir="auto">학습이 진행될수록 <code>cost가 감소하는 것을 확인할 수 있다.
<pre><code># Test the model using test sets
print('Accuracy: ', accuracy.eval(session=sess, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
<p dir="auto">마찬가지로 학습 모델의 최종적인 <code>Accuracy도 계산할 수 있다. 참고로 <code>sess.run이 아닌 <code>함수명.eval(session=sess,...)로도 세션을 실행할 수 있다. 간단한 <code>tensor를 실행시킬 때 사용할 수 있는 방법이다.
<pre><code>Accuracy: 0.8901
<p dir="auto"><code>89.01%의 정확도를 보인다. 뛰어나다고는 할 수 없지만 간단한 코드 몇줄로 효과적인 학습을 진행했다고 볼 수 있다.
<pre><code>import matplotlib.pyplot as plt
import random
# Get one and predict
r = random.randint(0, mnist.test.num_examples - 1)
print('Label: ', sess.run(tf.argmax(mnist.test.labels[r:r+1], 1)))
print('Prediction: ', sess.run (tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r+1]}))
plt.imshow(mnist.test.images[r:r+1].reshape(28, 28), cmap='Greys', interpolation='nearest')
plt.show()
<p dir="auto">실제로 우리의 학습이 잘 이루어졌는지 <code>test_data를 활용해 검증해보자. 전체 <code>test 데이터 중에서 하나의 숫자를 임의로 뽑아낸다. 해당 <code>label이 우리가 가설로 세워 도출한 예측값과 실제로 일치하는지 비교해본다.
<p dir="auto">더불어 <code>matplot 라이브러리를 사용해 해당 이미지 값을 나타내보자.
<pre><code>Label: [4]
Prediction: [4]
<p dir="auto"><img src="https://images.hive.blog/768x0/https://lh3.googleusercontent.com/2KbD-OF_nd-JLyobhnZ05XU4cVFTEyI9k8h_tz1W6GfHYaKlIMamcBSEJQ6vKJ1lr6KMD6UTUoS7Cj9JJqJndKp1KzNDGe6XiPg910Qlz0b_lMRnDISvbs1PkNz3LI39YM1bwOICwtoFrZTxk7j6lC8TE2Dc_5eoCDVuVdxKYCBFlnAt5l9mGGfaU7K7FGR7T0Bx8pkz3XYJpN8BXCqrU-ejEpWkJ1m5OHXPouyc7sNN54gnIdg3DXSkmtVIHsiZoqd4Ah9ni7XcpPcgQOb8eHnEeniDlqpVwDDKVpOIaOagp5Lqg0zg6Ngv65aJ8MCn1l-55RZpxo5Hy4XuK5OwgdDo2f5ArX0Q1VtL2LrgXa1QNV-cmqMufNL8T1rlBBxJOq-8EAwypMq_ZGF9HGl3xr1XA9lc6bIkjN0v7RiaVHX-g0GDkKm6DXXiDwuWOPJwkkNIPI_GOPC8dLKxzpCwqHwqMVKG5UOE7K274MilEGvKqCv3exF6q_oibaGZueXaLo1VNL1OjI7jKN3r7qkbtMnU8MmAfSxOFYv_kfEaUbXoDj647EEFcTZfz1OWhzhwobicQJN_WrUq1GVCX9aDihdCwTvfwIDhp7dtVeGw=w255-h252-no" srcset="https://images.hive.blog/768x0/https://lh3.googleusercontent.com/2KbD-OF_nd-JLyobhnZ05XU4cVFTEyI9k8h_tz1W6GfHYaKlIMamcBSEJQ6vKJ1lr6KMD6UTUoS7Cj9JJqJndKp1KzNDGe6XiPg910Qlz0b_lMRnDISvbs1PkNz3LI39YM1bwOICwtoFrZTxk7j6lC8TE2Dc_5eoCDVuVdxKYCBFlnAt5l9mGGfaU7K7FGR7T0Bx8pkz3XYJpN8BXCqrU-ejEpWkJ1m5OHXPouyc7sNN54gnIdg3DXSkmtVIHsiZoqd4Ah9ni7XcpPcgQOb8eHnEeniDlqpVwDDKVpOIaOagp5Lqg0zg6Ngv65aJ8MCn1l-55RZpxo5Hy4XuK5OwgdDo2f5ArX0Q1VtL2LrgXa1QNV-cmqMufNL8T1rlBBxJOq-8EAwypMq_ZGF9HGl3xr1XA9lc6bIkjN0v7RiaVHX-g0GDkKm6DXXiDwuWOPJwkkNIPI_GOPC8dLKxzpCwqHwqMVKG5UOE7K274MilEGvKqCv3exF6q_oibaGZueXaLo1VNL1OjI7jKN3r7qkbtMnU8MmAfSxOFYv_kfEaUbXoDj647EEFcTZfz1OWhzhwobicQJN_WrUq1GVCX9aDihdCwTvfwIDhp7dtVeGw=w255-h252-no 1x, https://images.hive.blog/1536x0/https://lh3.googleusercontent.com/2KbD-OF_nd-JLyobhnZ05XU4cVFTEyI9k8h_tz1W6GfHYaKlIMamcBSEJQ6vKJ1lr6KMD6UTUoS7Cj9JJqJndKp1KzNDGe6XiPg910Qlz0b_lMRnDISvbs1PkNz3LI39YM1bwOICwtoFrZTxk7j6lC8TE2Dc_5eoCDVuVdxKYCBFlnAt5l9mGGfaU7K7FGR7T0Bx8pkz3XYJpN8BXCqrU-ejEpWkJ1m5OHXPouyc7sNN54gnIdg3DXSkmtVIHsiZoqd4Ah9ni7XcpPcgQOb8eHnEeniDlqpVwDDKVpOIaOagp5Lqg0zg6Ngv65aJ8MCn1l-55RZpxo5Hy4XuK5OwgdDo2f5ArX0Q1VtL2LrgXa1QNV-cmqMufNL8T1rlBBxJOq-8EAwypMq_ZGF9HGl3xr1XA9lc6bIkjN0v7RiaVHX-g0GDkKm6DXXiDwuWOPJwkkNIPI_GOPC8dLKxzpCwqHwqMVKG5UOE7K274MilEGvKqCv3exF6q_oibaGZueXaLo1VNL1OjI7jKN3r7qkbtMnU8MmAfSxOFYv_kfEaUbXoDj647EEFcTZfz1OWhzhwobicQJN_WrUq1GVCX9aDihdCwTvfwIDhp7dtVeGw=w255-h252-no 2x" /><br />
위와 같이 <code>Label : 4에 대해 우리의 학습 예측값도 <code>Prediction : 4로 일치됐다.
<hr />
pairplay 가 kr-dev 컨텐츠를 응원합니다! :)
5월 다시 파이팅해요!
호출에 감사드립니다!