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

[코드로 이해하는 딥러닝 15] - 초기화(initialization)의 중요성

by 노마드공학자 2021. 1. 1.

[코드로 이해하는 딥러닝 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

[코드로 이해하는 딥러닝 11-EX] - MNIST를 DNN으로 학습해보기/Adam optimizer https://limitsinx.tistory.com/39

[코드로 이해하는 딥러닝 12] - RELU(Rectified Linear Unit) https://limitsinx.tistory.com/40

[코드로 이해하는 딥러닝 13] - .txt(.csv)파일로 저장하기 https://limitsinx.tistory.com/44

[코드로 이해하는 딥러닝 14] - Drop out https://limitsinx.tistory.com/45

 

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

※해당 글은 PC에서 보기에 최적화 되어있습니다.

 

초기화의 종류, 출처 : https://www.youtube.com/watch?v=tMjdQLylyGI

토론토 대학교의 힌튼교수가, 기존 머신러닝의 한계점을 정리한 논문을 발표할때 가장 핵심은 이것이였습니다.

 

 

"Weighting과 Bias의 초기화를 잘해야한다."

 

 

초기화를 어떻게 해주느냐에 따라 학습 성능과 시간이 엄청나게 차이가납니다.

Random하게 코드를 동일한 코드로 여러번 돌려보신분들은, 똑같은 조건으로 학습을 시켜도

 

계산시간과 정확도가 천차만별이라는것을 확인하셨을 겁니다!

 

 

이제까지는 weighting과 bias를 모두 random하게 초기화하여 코드를 구현했기때문입니다.

 

하지만, 이 글 이후로는 초기화를 선언할때, Gaussian pdf를 가지는 형태로 선언할 것입니다.

 

Gaussian

왜 하필 Gaussian이냐? 라는 질문에는, 칼만필터(Kalman Filter)를 사용하면 대부분의 제어를 해석할 수 있는것과 마찬가지로, 세상에는 Gauss distribution을 띄는것이 많기때문입니다! 라고 대답하고 싶네요

 

Gaussian이 아니라도 초기화 방법은 정말 많습니다! 복잡하고 Deep한 기술들도 많죠. 

 

하지만, 기본을 정리하는 글이니 일단은, 가장 일반적으로 사용되는 가우스함수의 형태로 초기화를 진행하고자 합니다.

 

어떠한 형태라도 아무렇게나 랜덤하게 초기화를 무작위로 하는거보단 분명 성능향상이 눈에 보일것입니다!

 

[코드 전문]

import tensorflow.compat.v1 as tf

tf.disable_v2_behavior()

import random

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])

 

W1 = tf.get_variable("W1"shape=[784256],

                     initializer=tf.truncated_normal_initializer(stddev=0.1))

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

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

 

W2 = tf.get_variable("W2"shape=[256256],

                     initializer = tf.truncated_normal_initializer(stddev=0.1))

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

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

 

W3 = tf.get_variable("W3"shape=[25610],

                     initializer = tf.truncated_normal_initializer(stddev=0.1))

                     #initializer=tf.contrib.layers.xavier_initializer()

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]}))

 

[코드 분석-1]

 

Layer마다 적용되는 코드가 모두 동일하므로 input layer코드만 한번 보겠습니다.

기존에는 w1=tf.get_Variable("w1",shape=[784,256]) 정도에서 끝이 났었는데요,

 

이 뒤에 initailizer=tf.truncated_normal_initializer(stddev=0.1)이라는 코드를 추가해줌으로써,

 

표준편차(Standard deviation)이 0.1인 Gaussian distribution을 가지는 weighting값으로 초기화를 하겠다! 라고 선언해주는것입니다.

 

저는 주로 여기에 Mean(평균)=0도 추가해서 초기화를 하는데요

initalizer=tf.truncated_normal_initializer(mean=0, stddev=0.1)로 작성해주시면 됩니다.

 

경우에따라, 본인이 어느정도 weighting과 bias의 평균, Standard deviation의 초기값을 어느정도로 두면 되겠다! 라는 감이 잡히실때는, 그에 맞게 값을 정해주시고 진행하면 훨씬더 빠르고 높은 정확도의 학습효과를 얻으실 수 있습니다.

 

 

 

 

댓글