머신러닝

3-2 Covariance Softmax 뉴럴 네트워크 적용MNIST 문자 인식률 계산

coding art 2019. 8. 26. 21:52
728x90

Covariance항을 고려한 Softmax 공식을 사용하는 인식률계산에서 더 나아가 뉴럴 네트워크 레이어를 하나 추가한 딥 러닝의 영향을 관찰해 보자. MNIST 입력 데이타가 1X784 이므로 784X124 hidden layer를 사용하여 처리 후 activation 단계에서 hypothesis124X10 으로 최종 처리하여 Softmax 에 입력하자. 뉴럴 네트워크를 사용하되 ReLU는 사용하지 않기로 한다.

 

GradientDescentOptimizer를 사용하여 계산한 결과와 Adam Optimizer를 사용한 결과를 비교해 보기로 하자. AdamOptimizer (Adaptive moment optimization) 사용에서는 다음과 같이 4가지 파라메터 값 설정이 필요하며 여기서는 default로 설정하기로 한다.

learning rate = 0.001, beta1 = 0.9, beta2 = 0.999, epsilon = 1e-08

 

AdamOptimizerhidden layer가 없는 단순 네트워크에 적용해 보면 α 값이 0.0 인 경우에만 계산이 가능하며 92.5% 인식률이 얻어진다. 하지만 α≻0 이면 계산이 불가능하다. 따라서 AdamOptimizer 사용을 위해서는 적어도 하나 이상의 hidden layer를 도입하여 최소 크기의 뉴럴 네트워크를 구성할 필요가 있다.




계산 결과표를 비교해 보면 AdamOptimizer를 사용할 경우 α≻0.02일 때에 거의 97.5% 수준의 인식률을 준다. α값이 변해도 인식률 값은 거의 일정하다. 반면에 Gradient Descent Optimizer를 사용할 경우와는 패던이 현저히 다른 바 이 문제 자체의 비선형성에 기인하는 듯하다. 같은 문제를 풀어도 그 해법이 다를 경우나 초기치가 다르거나 하면 비선형 문제에서는 유일한 결과를 주는 것이 아니라 여러 개의 결과를 보여 줄 수 도 있다는 점을 참조하자.

 

#mnist_nn_covariance_adam_01.py


import random
import time
#import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

start_time = time.time()
tf.set_random_seed(777)  #reproducibility

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

#parameters
learning_rate = 0.001
training_epochs = 1
batch_size = 100
dof1 = 124
dof2 = 10
alpha = 0.0002

X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])

for n in range(0, 10):
    W0 = tf.Variable(tf.random_normal([784, dof1], stddev=0.01))
    b0 = tf.Variable(tf.random_normal([dof1], stddev=0.01))
    W1 = tf.Variable(tf.random_normal([784, dof1], stddev=0.01))
    b1 = tf.Variable(tf.random_normal([dof1], stddev=0.01))
    W2 = tf.Variable(tf.random_normal([784, dof1], stddev=0.01))
    b2 = tf.Variable(tf.random_normal([dof1], stddev=0.01))
    L1 = (tf.matmul(X, W0) + b0 + alpha * (tf.matmul(X, W2) + b2)*(tf.matmul(X, W1) + b1))
    #weights & bias for nn layers
    W3 = tf.Variable(tf.random_normal([dof1, dof2], stddev=0.01))
    b3 = tf.Variable(tf.random_normal([dof2], stddev=0.01))
    hypothesis = (tf.matmul(L1, W3) + b3)
    #define cost/loss & optimizer
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=hypothesis, labels=Y))
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
    #optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
   
    #initialize
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = 20000
        #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)
            feed_dict = {X: batch_xs, Y: batch_ys}
            c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
            avg_cost += c / total_batch
           
        print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
        print('Learning Finished!')
       
        #Test model and check accuracy
        correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        print('Accuracy:', sess.run(accuracy, feed_dict={ X: mnist.test.images, Y: mnist.test.labels}))
       
        #Get one and predict
        r = random.randint(0, mnist.test.num_examples - 1)
        print('case=:', n,'alpha=:', alpha, ' lr=:', learning_rate)
        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]}))
       
        alpha = alpha + 0.0002

end_time = time.time()
print( "Completed in ", end_time - start_time , " seconds")