딥러닝의 정석 예제 코드 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




댓글

이 블로그의 인기 게시물

간단한 cfar 알고리즘에 대해

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

아두이노(arduino) 심박센서 (heart rate sensor) 심박수 측정 example code

리눅스 디바이스 드라이버 기초와 예제

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법