딥러닝의 정석 예제 코드 chapter 5 합성곱 신경망 MNIST
본 글은 딥러닝의 정석(Fundamentals of Deep Learning) 챕터 5의 합성 신경망에서 CNN을 사용하여 MINST 데이터를 학습하는 예제를 싣고 있다.
딥러닝의 정석의 예제 코드는 https://github.com/darksigma/Fundamentals-of-deep-learning-book에서 받을 수 있으나 몇몇 구문에서 오류가 발생하여 수정 하였다.
MINST 데이터를 학습하는 예제는 딥러닝의 정석 예제 코드 chapter 3 텐서플로로 신경망 구현하기 MNIST에서도 다룬 적이 있다. CNN을 사용한 예제에서는 Chapter 3의 MNIST 학습보다 Epoch는 더 작지만, Accuracy는 더 올라가는 것을 볼 수 있다.
[소스코드]
import tensorflow as tf
import shutil, os
from tensorflow.examples.tutorials.mnist import input_data
tf.reset_default_graph()
tf.set_random_seed(777)
mnist = input_data.read_data_sets("../MNIST_data/",one_hot=True)
# Architecture
n_hidden_1 = 256
n_hidden_2 = 256
# Parameters
learning_rate = 0.0001
training_epochs = 10
batch_size = 100
display_step = 1
def conv2d(input, weight_shape, bias_shape):
insize = weight_shape[0] * weight_shape[1] * weight_shape[2]
weight_init = tf.random_normal_initializer(stddev=(2.0/insize)**0.5)
bias_init = tf.constant_initializer(value=0)
W = tf.get_variable("W",weight_shape,initializer=weight_init)
b = tf.get_variable("b",bias_shape,initializer=bias_init)
conv_out = tf.nn.conv2d(input,W,strides=[1,1,1,1],padding='SAME')
return tf.nn.relu(tf.nn.bias_add(conv_out,b))
def max_pool2d(input, k=2):
return tf.nn.max_pool(input,ksize=[1,k,k,1],strides=[1,k,k,1],padding='SAME')
def layer(input, weight_shape, bias_shape):
weight_init = tf.random_normal_initializer(stddev=(2.0/weight_shape[0])**0.5)
bias_init = tf.constant_initializer(value=0)
W = tf.get_variable("W",weight_shape,initializer=weight_init)
b = tf.get_variable("b",bias_shape,initializer=bias_init)
return tf.nn.relu(tf.matmul(input,W)+b)
def inference(x,keep_prob):
x = tf.reshape(x, shape=[-1,28,28,1])
with tf.variable_scope("conv_1"):
conv_1 = conv2d(x,[5,5,1,32],[32])
pool_1 = max_pool2d(conv_1)
with tf.variable_scope("conv_2"):
conv_2 = conv2d(pool_1,[5,5,32,64],[64])
pool_2 = max_pool2d(conv_2)
with tf.variable_scope("fc"):
pool_2_flat = tf.reshape(pool_2,[-1,7*7*64])
fc_1 = layer(pool_2_flat,[7*7*64,1024],[1024])
fc_1_drop = tf.nn.dropout(fc_1,keep_prob)
with tf.variable_scope("output"):
output = layer(fc_1_drop,[1024,10],[10])
return output
#loss func
def loss(output, y):
xentropy = tf.nn.softmax_cross_entropy_with_logits(logits=output, labels=y)
loss = tf.reduce_mean(xentropy)
return loss
#Training
def training(cost, global_step):
tf.summary.scalar("cost",cost)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
train_op = optimizer.minimize(cost,global_step=global_step)
return train_op
#Evaluate
def evaluate(output, y):
correct_prediction = tf.equal(tf.argmax(output,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
tf.summary.scalar("validation",accuracy)
return accuracy
if __name__ == '__main__':
if os.path.exists('cnn_mnist_logs/'):
shutil.rmtree('cnn_mnist_logs/',ignore_errors=True)
with tf.Graph().as_default():
with tf.variable_scope('mnist_conv_model'):
x = tf.placeholder(tf.float32, [None,784]) #mnist data image of shape 28*28=784
y = tf.placeholder(tf.float32,[None,10]) #0~9 digits recognition -> 10 classes
keep_prob = tf.placeholder(tf.float32)
output = inference(x,keep_prob)
cost = loss(output,y)
global_step = tf.Variable(0,name='global_step',trainable=False)
train_op = training(cost,global_step)
eval_op = evaluate(output,y)
summary_op = tf.summary.merge_all()
saver=tf.train.Saver()
sess=tf.Session()
summary_writer = tf.summary.FileWriter('cnn_mnist_logs/',graph_def=sess.graph_def)
init_op = tf.global_variables_initializer()
sess.run(init_op)
#saver.restore(sess, "cnn_mnist_logs/model-checkpoint-6050")
#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):
minibatch_x, minibatch_y = mnist.train.next_batch(batch_size)
sess.run(train_op,feed_dict={x:minibatch_x, y:minibatch_y, keep_prob:0.5})
avg_cost += sess.run(cost,feed_dict={x:minibatch_x, y:minibatch_y, keep_prob:0.5})/total_batch
if epoch % display_step == 0:
print("Epoch:", '%04d'%(epoch+1),'cost=','{:.9f}'.format(avg_cost))
summary_str,accuracy = sess.run([summary_op,eval_op], feed_dict={x:mnist.validation.images, y:mnist.validation.labels, keep_prob:1})
print("validation accuracy :",accuracy)
summary_writer.add_summary(summary_str,sess.run(global_step))
saver.save(sess,'cnn_mnist_logs/model-checkpoint',global_step=global_step)
print("Optimization Finished!")
accuracy = sess.run(eval_op, feed_dict={x: mnist.test.images, y: mnist.test.labels, keep_prob:1})
print("Test Accuracy:", accuracy)
위 소스를 통해 만들어진 모델의 그래프는 아래와 같다.
[실행 결과]
Epoch: 0001 cost= 0.353747553
validation accuracy : 0.976
Epoch: 0002 cost= 0.090692370
validation accuracy : 0.9862
Epoch: 0003 cost= 0.060509424
validation accuracy : 0.9886
Epoch: 0004 cost= 0.047041865
validation accuracy : 0.988
Epoch: 0005 cost= 0.037265458
validation accuracy : 0.9904
Epoch: 0006 cost= 0.030643947
validation accuracy : 0.9906
Epoch: 0007 cost= 0.026428386
validation accuracy : 0.9912
Epoch: 0008 cost= 0.022958892
validation accuracy : 0.9916
Epoch: 0009 cost= 0.019462617
validation accuracy : 0.991
Epoch: 0010 cost= 0.018246229
validation accuracy : 0.9914
Optimization Finished!
Test Accuracy: 0.9904
텐서보드를 사용해 본 학습 cost/validation accuracy 그래프는 아래와 같다.
텐서보드는 아래와 같이 실행하면 된다.
> tensorboard --logdir=<절대 경로의 log 폴더위치>
ex> d:\>tensorboard --logdir=d:\deep_learning\cnn_mnist_logs
관련 글:
댓글
댓글 쓰기