딥러닝의 정석 예제 코드 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 알고리즘에 대해

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

간단한 칼만 필터(Kalman Filter) 소스 코드와 사용 예제

바로 프로젝트 적용 가능한 FIR Filter (low/high/band pass filter )를 c나 python으로 만들기

python winsound를 이용한 윈도우 환경에서 소리 재생 예제