본문 바로가기
DeepLearning Framework & Coding/Tensorflow 1.X

[코드로 이해하는 딥러닝 11-EX] - MNIST를 DNN으로 학습해보기/Adam optimizer

by 노마드공학자 2020. 12. 25.

[코드로 이해하는 딥러닝 0] - 글연재에 앞서 https://limitsinx.tistory.com/27

[코드로 이해하는 딥러닝 1] - Tensorflow 시작 https://limitsinx.tistory.com/28 

[코드로 이해하는 딥러닝 2] - Tensorflow 변수선언 https://limitsinx.tistory.com/29

[코드로 이해하는 딥러닝 3] - Tensorflow placeholder변수 https://limitsinx.tistory.com/30

[코드로 이해하는 딥러닝 4] - 선형회귀(Linear Regression) https://limitsinx.tistory.com/31

[코드로 이해하는 딥러닝 5] - 다중선형회귀(Multiple Linear Regression) https://limitsinx.tistory.com/32

[코드로 이해하는 딥러닝 6] - 회귀(Regression)에 대한 다른 접근 https://limitsinx.tistory.com/33

[코드로 이해하는 딥러닝 7] - .txt(.csv)파일 불러오기 https://limitsinx.tistory.com/34

[코드로 이해하는 딥러닝 8] - Logistic Regression(sigmoid) https://limitsinx.tistory.com/35

[코드로 이해하는 딥러닝 9] - Softmax Regression(multiple classification) https://limitsinx.tistory.com/36

[코드로 이해하는 딥러닝 10] - MNIST 데이터 분류/One hot encoding https://limitsinx.tistory.com/37

[코드로 이해하는 딥러닝 11] - Deep Neural Network/XOR https://limitsinx.tistory.com/38

 

※이 전글에서 정리한 코드/문법은 재설명하지 않으므로, 참고부탁드립니다

 

 

이번에는 [코드로 이해하는 딥러닝 10] 의 MNIST 데이터를, DNN으로 학습해보도록 하겠습니다.

 

이번 글은, 기존에 정리했던 글 2개를 합쳐서 한번 돌려보는것이기에, 딱히 코드분석을 할 내용은 없습니다.

 

코드구현시 참고용으로 봐주시면 될것같습니다 :)

 

 

[코드 전문]

import tensorflow.compat.v1 as tf

tf.disable_v2_behavior()

import numpy as np

#W1=tf.Variable(tf.random_uniform([2,5],-1.0,1.0), name='weight1') : -1과 1사이에서 초기화

 

import random

# import matplotlib.pyplot as plt

 

from tensorflow.examples.tutorials.mnist import input_data

 

tf.set_random_seed(777)  # reproducibility

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

 

# parameters

learning_rate = 0.001

training_epochs = 15

batch_size = 100

 

# input place holders

X = tf.placeholder(tf.float32, [None784])

Y = tf.placeholder(tf.float32, [None10])

 

# weights & bias for nn layers

W1 = tf.Variable(tf.random_normal([784256]))

b1 = tf.Variable(tf.random_normal([256]))

L1 = tf.nn.softmax(tf.matmul(X,W1) + b1)

 

W2 = tf.Variable(tf.random_normal([256256]))

b2 = tf.Variable(tf.random_normal([256]))

L2 = tf.nn.softmax(tf.matmul(L1,W2) + b2)

 

W3 = tf.Variable(tf.random_normal([25610]))

b3 = tf.Variable(tf.random_normal([10]))

hypothesis = tf.matmul(L2,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)

 

# initialize

sess = tf.Session()

sess.run(tf.global_variables_initializer())

 

# train my model

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)

        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("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()

 

 

[코드 분석-1]

여기서 파라미터들을 어떻게 조절해주느냐에 따라 최종 학습모델 결과물의 정확도가 달라지는데요

 

learning rate를 키워서 발산하는모습도, 엄청나게 낮춰서 underfitting이 되는모습도...

training_epochs를 엄청나게 늘려,줄여보기도 하면서 결과를 한번 비교해보시면 도움이 될것 같습니다!

 

[코드 분석-2]

softmax로 각 Hidden Layer들을 통과시켜주며, cost optimizing을 하는모습입니다.

여기서 새로 등장한 개념은! 바로 Adam Optimizer라는것입니다.

 

이제까지는 Gradient Descent Optimizer를 했었죠??

하지만, 앞으로는 Adam optimzer를 사용할 계획인데요, Adam Optimizer가 무엇인지 간략히 말씀드리겠습니다.

 

Gradient Descent는 미분을 통해 기울기를 얻어내고, Cost가 최소가 되는 지점을 향해 점점 다가가는 것이였습니다.

Gradient Descent, 출처 : wikimedia

 

Cost가 0인 밑바닥부분에 점점다가갈때, Learning-rate를 자동으로 좀 바꿔줄순 없을까?

 

라는 아이디어에서 Adam optimizer는 시작합니다.

 

즉, 극소점을 향해 점점 다가갈때, 이전의 기울기 값이크면 Learning rate도 크게해서 점점 빨리,

이전의 기울기 값이 작으면 Learning rate를 작게해서 느리게 가는것입니다.

"관성"을 최적화 기법에 사용하는것이죠!

 

그런데... 이렇게 관성에 따라가다보면.. 이전 미분기울기값이 작아지고, 또작아지고, 또작아지고...하다보면

learning rate가 0으로 수렴하게되죠.. 그러면 결국 학습이 안되구요

이런 문제를 해결한 것이 RMSProp이라는 스킬입니다.

즉, learning rate에 epsilon이라고하는 작은 상수를 더해주어, 절대로 0은되지않도록! 하는 것인데요

 

이 두가지 스킬을 섞어서 만든것이 Adam Optimizer입니다.

 

정리하자면,

 

"Adam optimizer : Gradient Descent에서 momentum(관성)과 epsilon을 추가한 최적화 기법"

 

입니다.

사실, 정확하게 이해못하셔도 전혀 상관없습니다.

그냥 코드에, adam optimizer라고 써주시기만 하면 Gradient Descent보다 나은 결과를 얻을수있구나~~정도만 알고계셔도 무방합니다.

 

우리는 수학자가 아니니까요!

 

[코드 분석-3]

 

이하 코드는, 동일합니다.

 

모델링한 neural network를 통해 mnist data를 학습해보고 정확도와, 랜덤한 어떤 테스트데이터를 뽑아 제대로 예측하는지 확인해보는 코드입니다 :)

 

[결과값]

15번의 epoch결과

정확도는 0.8405

3이라는 숫자를 정확하게 예측하는것까지 확인할 수 있습니다.

 

Summary

 

Adam optimizer에 대해 완벽하게 수학적으로 유도하실 필요 "전혀" 없습니다.

컨셉만 알고 계시면됩니다.

 

"기존 Gradient Descent의 Learning rate를 active하게 바꿔주기위해 momentum(관성)을 추가하였고, 이로 인해 learning rate가 0으로 수렴하는 문제를 해결하기위해 RMSProp라는 스킬을 써주었다."

 

이정도면 해주셔도 전혀 무방합니다.

 

이것도 어려우시면 그냥 코드로 Gradient Descent보다 Adam이 나으니 Adam만 복사붙여넣기해서 돌려주셔도 됩니다 :)

댓글