Application & Tips
간단히 몇가지 알아둬야할 것을 정리해보자.
Large Learning Rate : Overshooting
너무 큰 rate를 적용함으로서, 값이 발산하는 경우.
Small Learning Rate
매우 조금씩 내려가서, 너무 오래걸리거나 local minimum에 빠지는 경우
Learning rate 를 정하는 것은 환경마다 다르므로 답은 없다.
보통 시작은 0.01로 정한다.
cost function
을 확인하고, 발산하는지 혹은 너무 느린지 확인하는게 좋다.
preprocessing
은 선처리라고 한다.
normalize
라고 하는 방법이 있는데, 흩어져 있는 데이터를 중심으로 모아준다고 보면 된다.
learning_rate를 잘 잡았는데, 잘 되지 않을 때가 있다.
그럴 때 preprocessing으로 확인하는 방법이 있으니 확인하면 좋다.
Overfitting
이라는 것은 Learning을 너무 많이해서 Test Data가 맞지 않아버리는 경우다.
Overfitting은 training Data를 늘리기
, 특징을 줄이기
, Regularization(일반화)
다.
Regularization은 우리가 가진 weight을 조금 조절하는 것이다.
cost 함수에 Regularization을 더해 선을 펴는 작업을 한다.
그럼 Performance 를 확인하는 방법을 알아보자.
우리는 training set
으로 model을 학습시킨다.
그런데, 이 training set
으로 확인하는 건 무조건 100% 맞으므로 좋지 못하다.
따라서 데이터를 잘라서, training set
과 test set
으로 나눈다.
여기서 한가지를 더 나누어 Validation set
을 만든다.
이 Validation set은 알파, 람다와 같은 데이터를 튜닝한다.
그리고, Data set이 매우 많을 때, 한번에 하긴 힘드니 Online Learning
을 시키기도 한다.
이것은, 100만개가 있을 때, 10만개씩 잘라서 학습을 시키는 것이다.
이때 중요한 것은 앞서 러닝한 모델의 데이터가 그대로 남아있어야 한다.
그럼 실습을 해보자.
이번에 할 실습은 Training과 Test dataset을 나누어 학습하는 것이다.
import tensorflow as tf
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,1],[0,0,1],[0,0,1],[0,1,0],[0,1,0],[0,1,0],[1,0,0],[1,0,0]]
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)
prediction = tf.arg_max(hypothesis, 1);
is_correct = tf.equal(prediction, tf.arg_max(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_val, W_val)
print("Prediction: ", sess.run(prediction, feed_dict={X: x_test}))
print("Accuracy: ", sess.run(accuracy, feed_dict={X: x_test, Y: y_test}))
위 예시는 이전에 한 것과 비슷하니 잘 알 수 있을 것이다.
이 때, Learning Rate
를 발산하거나, 매우 오래걸리고 local minimum에 빠질 수도 있게 만들어 확인해 보도록 하자.
해당 rate를 1.5로 하거나 10.0 으로 해보면 정확도가 0에 가까워지는 걸 알 수 있다.
그 떄, 나오는 수들을 보면 마지막에 Nan
이 나오는걸 볼 수 있다.
그럼 이제 Non-normalized inputs를 보도록 하자.
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]])
이런 데이터가 있다고 하자, 그럼 중간중간 매우 큰 수들이 있어서, 마치 등고선 같은 그림이 그려진다.
그럼, 지그재그로 러닝이 오가는 상황이 생기게 된다.
import tensorflow as tf
import numpy as np
tf.set_random_seed(777) # for reproducibility
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]])
x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]
# placeholders for a tensor that will be always fed.
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
hypothesis = tf.matmul(X, W) + b
# Simplified cost/loss function
cost = tf.reduce_mean(tf.square(hypothesis - Y))
# Minimize
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)
# Launch the graph in a session.
sess = tf.Session()
# Initializes global variables in the graph.
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, "Cost: ", cost_val, "\nPrediction:\n", hy_val)
분명 소스코드는 이쁜데, 값이 이상하게 나온다.
여기서 Normalize
를 쓰고, 이때 쓰는 함수가 MinMaxScaler
다.
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)
해당 공식을 그대로 만들었다고 보면 된다.
import tensorflow as tf
import numpy as np
tf.set_random_seed(777) # for reproducibility
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]])
# very important. It does not work without it.
xy = MinMaxScaler(xy)
print(xy)
x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]
# placeholders for a tensor that will be always fed.
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
hypothesis = tf.matmul(X, W) + b
# Simplified cost/loss function
cost = tf.reduce_mean(tf.square(hypothesis - Y))
# Minimize
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)
# Launch the graph in a session.
sess = tf.Session()
# Initializes global variables in the graph.
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, "Cost: ", cost_val, "\nPrediction:\n", hy_val)
다음에 계속 하도록 하자.