lab07.md

Application & Tip

Learning rate, Evaluation

1. Learning rate

Linear regression과 Classification에서 학습은 GradientDescent를 이용하여 cost를 최소화 함

  • tf.train.GradientDescentOptimizer 함수의 파라미터로 learning_rate를 임의로 지정하여 전달

    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
    
  • 즉, learning rate는 학습의 속도를 나타냄

     

1) Learning rate에 따라 발생하는 문제

  • Overshooting (좌측그림)

    • 지정한 learning rate가 클 때 발생하는 문제
    • cost가 최소화 되지 않고 cost가 증가하여 그래프를 벗어나는 문제가 발생할 수 있음
  • Small learning rate (우측그림)

    • 지정한 learning rate가 작을 때 발생하는 문제
    • 학습이 종료될때까지 cost가 최소화 되지 않는 문제 발생


 

2) Learning rate를 지정하는 방법

  • Learning rate를 잘 지정하는 특별한 방법은 없으며 환경과 데이터에 따라 learning rate가 변경되어야 함

  • 먼저 learning rate를 0.01 정도로 지정하여 학습을 시작한 후 cost에 따라 변경하여 지정하는 것이 좋음

     

2. Data preprocessing

Learning rate에 따라 overshooting과 같은 문제가 발생할 수 있으므로, data preprocessing이 필요


1) Standardization

  • 특정한 분포들의 평균($\mu$)과 표준편차($\sigma$)를 이용하여 데이터를 변환

     

x_std[:,0] = (x[:,0]) -  x[:,0].mean()) / x[:,0].std()

 

2) Normalization

  • 실제값 범위를 표준값 범위(일반적으로 -1~1 또는 0~1)로 변환하는 과정

    • 최소값($x_{min}$), 최대값($x_{max}$)이용

       

 

3. Overfitting

Overfitting은 머신러닝의 가장 큰 문제점

 

1) Overfitting

생성한 모델이 training data set에 지나치게 잘 맞는 경우를 의미, test data set이나 실생활에서 사용할 수 없음

  • Overffing의 문제점

    • 모델이 과도하게 복잡해짐

    • 새 데이터를 올바르게 예측하지 못함

    • 범용성 있게 사용 불가능

       

2) Overfitting의 해결책

  • 더 많은 Training data

  • Feature의 수를 줄임

  • Regularization: feature의 수를 유지하면서 overfitting을 피하는 방법

     

3) Regularization

  • Regularization strength($\lambda$)를 곱해주는 것으로 각각 엘리먼트의 제곱 합의 값을 줄일 수 있음

    • Regularization strength는 일종의 패널티 값으로 이해
    • Regularization strength값이 커지면 underfitting 문제가 발생하여 accuracy가 떨어질 수 있음

     

 

4. Training, validation and test sets

1) Data set

  • 모든 데이터를 모델 학습에 이용하여 값을 예측하는 것은 안좋은 방법

    • 100% correct(accuracy) 이지만 모든것을 기억해야 하는 문제가 있음
  • 전체 original data set을 training data set와 test data으로 나눔

    • Training data set: 학습을 위한 data set
    • Test data set: 학습을 위해서는 사용하지 않음, 예측값과 실제값을 비교하는 최후 모델의 평가를 위한 data set
  • Training data set을 다시 training data set과 validation data set으로 나누기도 함

    • Training data set을 모의시험 하여 learning rate($\alpha$)와 regularization strength($\lambda$)값을 튜닝하기 위함

 

2) Online learning

  • 데이터 셋을 분할하거나 지속적으로 데이터를 수집할 때 사용
  • 이미 어떤 데이터를 통해 학습 시킨 모델을 계속해서 새로운 데이터로 학습시키며 점차 모델을 발전시키는 학습 형태

     

3) Accuracy

  • 예측(실제데이터와 모델이 예측한 값의 비교)이 얼마나 정확한가를 의미

     

Example Code

1. Learning rate and Evaluation

학습에는 training data set을 model 테스트에는 test data set을 사용

  • 소스코드

    import tensorflow as tf
    
    # training dataset
    x_data = [[1, 2, 1], [1, 3, 2], [1, 3, 4], [1, 5, 5], [1, 7, 5], [1, 2, 5], [1, 6, 6], [1, 7, 7]]
    y_data = [[0, 0, 0], [0, 0, 1], [0, 0, 1], [0, 1, 0], [0, 1, 0], [0, 1, 0], [1, 0, 0], [1, 0, 0]]
    
    # test dataset
    x_test = [[2, 1, 1], [3, 1, 2], [3, 3, 4]]
    y_test = [[0, 0, 1], [0, 0, 1], [0, 0, 1]]
    
    X = tf.placeholder("float", [None, 3])
    Y = tf.placeholder("float", [None, 3])
    
    W = tf.Variable(tf.random_normal([3, 3]))
    b = tf.Variable(tf.random_normal([3]))
    
    hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
    cost = tf.reduce_mean(-tf.reduce_sum(Y*tf.log(hypothesis), axis=1))
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
    
    '''
    # big learning rate
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.5).minimize(cost)
    
    # small learning rate
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-10).minimize(cost)
    '''
    
    # test model
    prediction = tf.argmax(hypothesis, 1)
    is_correct = tf.equal(prediction, tf.argmax(Y, 1))
    accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        for step in range(201):
            cost_val, W_val, _ = sess.run([cost, W, optimizer],
                                          feed_dict={X: x_data, Y: y_data})
            print("step:{}, cost:{}, W:{}".format(step, cost_val, W_val))
    
        print("\nPrediction: ", sess.run(prediction, feed_dict={X: x_test}))
        print("\nAccuracy: ", sess.run(accuracy, feed_dict={X: x_test, Y: y_test}))
    
  • 결과

    (...)
    step:198, cost:0.6307041645050049, W:[[-1.0179197   1.0029908   1.5980065 ]
     [ 0.5376595   0.3441221   0.3152033 ]
     [ 1.0510079   0.7980461   0.26807705]]
    step:199, cost:0.6298766732215881, W:[[-1.0219159   1.0022653   1.6027282 ]
     [ 0.5378086   0.3443701   0.31480628]
     [ 1.0524209   0.7982381   0.26647204]]
    step:200, cost:0.6290534734725952, W:[[-1.0259045   1.001546    1.6074361 ]
     [ 0.53795606  0.34461716  0.3144118 ]
     [ 1.0538331   0.79842794  0.26487   ]]
    
    Prediction:  [2 2 2]
    
    Accuracy:  1.0
    

 

1) Big learning rate: overshooting

  • Big learning rate 지정 소스 코드: learning rate를 1.5로 지정

    optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.5).minimize(cost)
    
  • 결과: 학습이 되지 않고 발산이 됨

    step:0, cost:6.2002129554748535, W:[[-1.9641786   1.2899761  -1.3891757 ]
     [ 1.1825768   1.8974146  -4.0632467 ]
     [ 0.84914625  0.9796692  -4.0303288 ]]
    step:1, cost:10.956174850463867, W:[[-1.594028   0.5448255 -1.0141757]
     [ 3.6063232 -1.651332  -2.9382467]
     [ 3.2675161 -2.5637007 -2.9053288]]
    step:2, cost:nan, W:[[nan nan nan]
     [nan nan nan]
     [nan nan nan]]
    step:3, cost:nan, W:[[nan nan nan]
     [nan nan nan]
     [nan nan nan]]
    (...)
    Prediction:  [0 0 0]
    
    Accuracy:  0.0
    

 

2) Small learning rate

  • Small learning rate 지정 소스 코드: learning rate를 1e-10으로 지정

    optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-10).minimize(cost)
    
  • 결과: 학습이 느리게 진행됨, local minimize에서 벗어나지 못함, 예측 정확도가 낮음

    step:0, cost:9.160271644592285, W:[[-1.569604    0.8670777   1.6502079 ]
     [ 1.7600275   0.34616604 -1.6269072 ]
     [ 0.91174084 -1.7635736  -0.40749222]]
    step:1, cost:9.160271644592285, W:[[-1.569604    0.8670777   1.6502079 ]
     [ 1.7600275   0.34616604 -1.6269072 ]
     [ 0.91174084 -1.7635736  -0.40749222]]
     (...)
     step:199, cost:9.160271644592285, W:[[-1.569604    0.8670777   1.6502079 ]
     [ 1.7600275   0.34616604 -1.6269072 ]
     [ 0.91174084 -1.7635736  -0.40749222]]
    step:200, cost:9.160271644592285, W:[[-1.569604    0.8670777   1.6502079 ]
     [ 1.7600275   0.34616604 -1.6269072 ]
     [ 0.91174084 -1.7635736  -0.40749222]]
    
    Prediction:  [1 2 0]
    
    Accuracy:  0.33333334
    

 

2. Non-normalized input

1) Non-normalized input

  • 소스코드

    import tensorflow as tf
    import numpy as np
    
    '''
    def MinMaxScaler(data):
        numerator = data - np.min(data, 0)
        denominator = np.max(data, 0) - np.min(data, 0)
        # noise term prevents the zero division
        return numerator / (denominator + 1e-7)
    '''
    
    xy = np.array([[828.659973, 833.450012, 908100, 828.349976, 831.659973],
                   [823.02002, 828.070007, 1828100, 821.655029, 828.070007],
                   [819.929993, 824.400024, 1438100, 818.97998, 824.159973],
                   [816, 820.958984, 1008100, 815.48999, 819.23999],
                   [819.359985, 823, 1188100, 818.469971, 818.97998],
                   [819, 823, 1198100, 816, 820.450012],
                   [811.700012, 815.25, 1098100, 809.780029, 813.669983],
                   [809.51001, 816.659973, 1398100, 804.539978, 809.559998]])
    '''
    print(xy)
    
    xy = MinMaxScaler(xy)
    print("\n>> Normalized input\n", xy)
    '''
    x_data = xy[:, 0:-1]
    y_data = xy[:, [-1]]
    
    X = tf.placeholder(tf.float32, shape=[None, 4])
    Y = tf.placeholder(tf.float32, shape=[None, 1])
    W = tf.Variable(tf.random_normal([4, 1]), name='weight')
    b = tf.Variable(tf.random_normal([1]), name='bias')
    
    hypothesis = tf.matmul(X, W) + b
    cost = tf.reduce_mean(tf.square(hypothesis - Y))
    
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
    train = optimizer.minimize(cost)
    
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
    
    for step in range(101):
        cost_val, hy_val, _ = sess.run([cost, hypothesis, train],
                                       feed_dict={X: x_data, Y: y_data})
        print("Step: {}, \tCost: {}, Prediction: {}".format(step, cost_val, hy_val))
    

  • 결과

    (...)
    Step: 5, 	Cost: inf, Prediction: [[inf]
     [inf]
     [inf]
     [inf]
     [inf]
     [inf]
     [inf]
     [inf]]
    Step: 6, 	Cost: nan, Prediction: [[nan]
     [nan]
     [nan]
     [nan]
     [nan]
     [nan]
     [nan]
     [nan]]
    (...)
    
    • NaN이 출력된 이유: 각 데이터의 값이 심하게 차이가 나서 생기는 문제, 즉 normalization 되지 않아서 생기는 문제

2) Normalization input

  • Normalization input Data

    def MinMaxScaler(data):
        numerator = data - np.min(data, 0)
        denominator = np.max(data, 0) - np.min(data, 0)
        # noise term prevents the zero division
        return numerator / (denominator + 1e-7)
    
    xy = np.array([[828.659973, 833.450012, 908100, 828.349976, 831.659973],
                   [823.02002, 828.070007, 1828100, 821.655029, 828.070007],
                   [819.929993, 824.400024, 1438100, 818.97998, 824.159973],
                   [816, 820.958984, 1008100, 815.48999, 819.23999],
                   [819.359985, 823, 1188100, 818.469971, 818.97998],
                   [819, 823, 1198100, 816, 820.450012],
                   [811.700012, 815.25, 1098100, 809.780029, 813.669983],
                   [809.51001, 816.659973, 1398100, 804.539978, 809.559998]])
    
    print(xy)
    
    xy = MinMaxScaler(xy)
    print("\n>> Normalized input\n", xy)
    
  • Normalized input data

    [[8.28659973e+02 8.33450012e+02 9.08100000e+05 8.28349976e+02
      8.31659973e+02]
     [8.23020020e+02 8.28070007e+02 1.82810000e+06 8.21655029e+02
      8.28070007e+02]
     [8.19929993e+02 8.24400024e+02 1.43810000e+06 8.18979980e+02
      8.24159973e+02]
     [8.16000000e+02 8.20958984e+02 1.00810000e+06 8.15489990e+02
      8.19239990e+02]
     [8.19359985e+02 8.23000000e+02 1.18810000e+06 8.18469971e+02
      8.18979980e+02]
     [8.19000000e+02 8.23000000e+02 1.19810000e+06 8.16000000e+02
      8.20450012e+02]
     [8.11700012e+02 8.15250000e+02 1.09810000e+06 8.09780029e+02
      8.13669983e+02]
     [8.09510010e+02 8.16659973e+02 1.39810000e+06 8.04539978e+02
      8.09559998e+02]]
    
    >> Normalized input
     [[0.99999999 0.99999999 0.         1.         1.        ]
     [0.70548491 0.70439552 1.         0.71881782 0.83755791]
     [0.54412549 0.50274824 0.57608696 0.606468   0.6606331 ]
     [0.33890353 0.31368023 0.10869565 0.45989134 0.43800918]
     [0.51436    0.42582389 0.30434783 0.58504805 0.42624401]
     [0.49556179 0.42582389 0.31521739 0.48131134 0.49276137]
     [0.11436064 0.         0.20652174 0.22007776 0.18597238]
     [0.         0.07747099 0.5326087  0.         0.        ]]
    
  • 결과: 소스코드에서 normalization하는 주석 부분을 제거하고 실행해야 함

    (...)
    Step: 100, 	Cost: 1.0541142225265503, Prediction: [[-0.1801064 ]
     [ 0.01909077]
     [-0.29041588]
     [-0.67692447]
     [-0.43428123]
     [-0.595112  ]
     [-0.87752855]
     [-1.0806464 ]]


'AI&BigData > Deep Learning' 카테고리의 다른 글

Lab10-1. ReLU: Better non-linearity  (0) 2018.05.18
Lab09-3. Sigmoid Backpropagation  (0) 2018.05.18
Lab09-2. TensorBoard  (0) 2018.05.05
Lab09-1. NN for XOR  (0) 2018.04.27
Lab08-2. Deep Learning의 기본 개념  (0) 2018.04.26
Lab08-1. Tensor Manipulation  (0) 2018.04.20
Lab07-2. MNIST data  (0) 2018.04.18
Lab06. Softmax Classification  (0) 2018.04.18
Lab05. Logistic classification  (0) 2018.04.18