z2soo's Blog

Deep learning: 과적합 해결 dropout 본문

Big data & AI

Deep learning: 과적합 해결 dropout

z2soo 2020. 1. 13. 17:42
반응형

목차

과적합(overfitting)의 상황을 피하기 위해 고안된 dropout 방식에 대해 알아본다. 

 

  1. 과적합
  2. Dropout
  3. Dropout 활용 MNIST 예제

과적합

과적합이란?

학습한 모델이 training data set에 최적화되어 있는 상태를 의미하며, 영어로 over fitting 이라고 한다. 달리 말하면, 테스트 데이터에는 잘 들어맞지 않는 상태를 지칭한다. 학습한 모델이 training data set에는 약 98% 이상의 정확도를 가지지만, test data set에 대해서는 85% 정도 수준의 정확도가 나오면 overfitting이라고 규정한다. 


과적합을 해결 방법?

feature engineering 과정에서 ...

  • 일단 학습하는 데이터 수가 많아야 한다. (개인적으로 제어 가능한 영역은 아님)
  • 필요없는 feature(column)들은 학습에서 제한다.
  • 마찬가지로 중복되는 feature 또한 합치거나 단일화 시켜줘야 한다. 

학습하는 과정에서... 

  • 모든 perceptron을 활용하지 않고, 고의적으로 일부만 사용한다. 

Dropout

과적합에 대해 사람들이 연구하는 과정에서 2014년 논문이 하나 발표되었다. 모든 perceptron node가 학습에 참여하기 때문에 oerfitting이 발생한다고 보았고, overfitting을 피하기 위해서는 일부 logistic만 이용하면 된다고 생각한 것에서 시작한 논문이었다. 모든 logistic을 이용하면 굉장히 빡빡하게 만들어진다고 본 것으로 일부를 고의적으로 활용하지 않으며 학습하는 이 방식을 dropout 방식이라 부른다. 이에 대한 함수는 tensorflow에서 제공된다.

 

  • drop_rate = tf.placeholder( dtype = ) : 어떤 비율로 dropout을 진행할 지에 대한 placeholder 설정
  • tf.nn.dropout( 해당 layer 변수, rate = drop_rate ) : 해당 layer에 대해 해당 비율로 dropout을 진행

사용 예시

  • _layer2 = tf.nn.relu( tf.matmul( layer1, W2 ) + b2 ) : 기존 설정 layer 값을 _layer2 라고 따로 assign
  • layer2 = tf.nn.dropout( _layer2, rate = drop_rate )  : assign된 _layer2 값을 dropout 적용하여 layer2에 assign

사용시 유의할 점!

학습 시에는 dropout을 사용하여 일부 node는 고의적으로 제외하지만 (과적합을 피하기 위해), 

마지막에 test 할 때에는 모든 node를 사용해서 해야 한다. (dropout_rate = 0 으로 잡으면 된다. )

Dropout  활용 MNIST 예제

1. 모듈 삽입

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import warnings
warnings.filterwarnings(action='ignore')

2. 데이터 불러오기

mnist = input_data.read_data_sets('./data/mnist', one_hot=True)

3. 그래프 초기화

tf.reset_default_graph()

4. Placeholder

dropout_rate의 경우, 값이 하나인 scalar이기 때문에 shape은 설정할 필요가 없다. 

 

  • drop_rate = tf.placeholder( dtype = ) : 어떤 비율로 dropout을 진행할 지에 대한 placeholder 설정
X = tf.placeholder(shape=[None, 784], dtype=tf.float32)
Y = tf.placeholder(shape=[None, 10], dtype=tf.float32)
dout_rate = tf.placeholder(dtype=tf.float32)

5. W, bias

해당 과정에서 multi-layer 적용, ReLU 함수 적용, Xavier 초기값 설정 적용, dropout 적용이 됨에 유의하자!

 

코드에 대한 해석은 다음과 같다. 

_layer1에 대해서 deopout을 이용해 일부를 꺼버리고 동작을 시키지 않으려고 한다. 어떤 비율로 동작을 시키지 않을 것인지 rate로 정해주었고, 위에서 placeholder로 잡아두었다. placeholder에 대한 입력 값은 feed_dict 에서 입력한다. 이때, 0.3 = 30% 죽인다는 의미이다.

W1 = tf.get_variable("weight1", shape=[784,256], initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.Variable(tf.random_normal(shape=[256]), name='bias1')

# dropout 사용!!!
_layer1 = tf.nn.relu(tf.matmul(X,W1) + b1)
# layer1 = tf.nn.dropout(_layer1, rate=0.3)
# 다만, 이를 일일이 적지 않고 새로운 placeholder로 준다.
layer1 = tf.nn.dropout(_layer1, rate=dout_rate)

W2 = tf.get_variable("weight2", shape=[256,256], initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.Variable(tf.random_normal(shape=[256]), name='bias2')
_layer2 = tf.nn.relu(tf.matmul(layer1,W2) + b2)
layer2 = tf.nn.dropout(_layer2, rate=dout_rate)

W3 = tf.get_variable("weight3", shape=[256,10], initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.Variable(tf.random_normal(shape=[10]), name='bias3')

6. Hypothesis

logit = tf.matmul(layer2, W3) + b3
H = tf.nn.relu(logit)

7. Cost

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit, labels=Y))

8. Train

# AdamOptimizer 사용
train = tf.train.AdamOptimizer(learning_rate=0.01).minimize(cost)

9. Session, 초기화

sess = tf.Session()
sess.run(tf.global_variables_initializer())

10. 학습

학습을 진행할 때, dout_rate 에 대한 placeholder 의 값 또한 설정해줘야 한다.

num_of_epoch = 30
batch_size = 100

for step in range(num_of_epoch):    
    num_of_iter = int(mnist.train.num_examples / batch_size)
    cost_val = 0
    
    for i in range(num_of_iter):
        batch_x, batch_y = mnist.train.next_batch(batch_size)
        _, cost_val = sess.run([train, cost], feed_dict={X: batch_x,
                                                    Y: batch_y,
                                                        dout_rate: 0.3})
    if step % 3 == 0:
        print(f'cost: {cost_val}')

11. 정확도 및 예측

정확도에 대한 test를 진행할 때에는 모든 node를 사용해야 한다. 따라서 feed_dict 에서 drop out rate = 0으로 설정한다.  

predict = tf.argmax(H,1)
correct = tf.equal(predict, tf.argmax(Y,1))
accuracy = tf.reduce_mean(tf.cast(correct, dtype=tf.float32))

print(f'정확도:{sess.run(accuracy, feed_dict={X:mnist.test.images, Y: mnist.test.labels,dout_rate: 0})}')
    
# 중요한것! 학습 시에는 droupout을 사용하여 일부 node를 끄고 하지만(overfitting 피하기 위해),
# 마지막 test 할 때에는 모두 다 키고 해야함! (dropout rate=0으로 잡아야 함)

정리

어떠한 배경으로 multi-layer logistic regression 학습 방식이 등장하였고, 정확도를 높이고 다음과 같은 한계를 해결하기 위해 어떠한 해결 방법들이 제공되는지에 대해서 알아보았다. 

 

한계 해결 방안 효과
XOR 학습 불가 multi - layer logistic regression (다중계층) 논리회로 학습 프로그래밍 가능
Sigmoid 함수: Vanishing Gradient ReLU 함수 사용 정확도 증가 
가중치 W 랜덤 설정 Xavier 초기값 설정 사용 정확도 증가
과적합 dropout 사용 과적합 가능성 낮춤

 

 이 이후에도 정확도를 더 올리려면 이제 cnn, 앙상블 등 다른 방법을 사용해야 한다. 지금까지는 지도학습 중 이미지처리를 어떻게 진행하여 학습할 지에 대해 알아보았고, 이어서 이미지 처리를 어떻게 하는 것이 옳은지에 대해 발표된 내용을 가지고 학습해보도록 하겠다. 비지도 학습, clustering 등에 대한 부분은 이 내용을 가지고 개인적으로 공부해보도록 한다. 

반응형

'Big data & AI' 카테고리의 다른 글

Deep learning 예제: CNN 활용 과정 1  (0) 2020.01.14
Deep learning: CNN 개념  (0) 2020.01.14
Deep learning: Xavier 초기값 및 초기화  (0) 2020.01.13
Deep learning: ReLU 함수  (0) 2020.01.13
Deep learning 예제: MNIST  (0) 2020.01.13
Comments