Lec 07-1 학습 rate, Overfitting, 일반화(Regularization)
https://www.youtube.com/watch?v=1jPjVoDV_uo
- Learning_rate : 이제까지는 임의의 값을 사용했음
- 이 값을 크게 할 경우, 진동하거나 발산(overshooting)할 수 있음.
- 아주 작은 값을 사용할 경우, 시간이 너무 많이 걸리고, local minimum에서 정지
- 어떤 값이 좋은가는 특별한 법칙은 없다. 0.01로 시작하고, 나오는 cost 값에 따라서 줄이거나 늘리는 방법을 사용하면 된다.
- Data(X)의 전처리. (Gradient descent용)
- 아래와 같이 x1, x2의 범위가 차이가 크면, 왜곡된 형태가 되어 데이터 처리가 힘들 수 있다.
- 이 경우, 아래와 같이 중심을 원점에 일치시키거나(zero-centered), 각변수가 차지하는 범위가 비슷하도록(normalize) 해준다.
- 표준화(Standardization) 방법
$$ x_j^\prime = \frac{x_j - \mu_j}{\sigma_j} $$
- python code : X_std[:,0] = (X[:,0] -X[:,0].mean() / X[:,0].std()
- Overfitting
- 학습데이터에는 정말 잘 맞지만, 실제 데이터로는 잘 안맞는 경우. 예를 들어 아래그림에서 모델2는 학습데이터에서는 100%이지만 실 데이터에서는 문제가 생길 수도 있음.
- Overfitting을 줄이는 방법
- 학습데이터를 늘려라
- feature의 수를 줄여라
- Regularization (일반화)
- Weight를 큰 숫자를 사용하지 말라 (구부리지 말라.) 아래와 같이 Cost function 에 $ \lambda \sum W^2 $를 추가하여 Weight 항이 작아질 수록 Cost가 작아지도록 하는 방법을 사용한다. 이때, $ \lambda $ 는 Regularization Strenth라고 하여, 작은 값을 사용하면 일반화를 중요하지 않게 생각한다는 의미이다.
- l2reg = 0.001 * tf.reduce_sum(tf.square(W) 를 cost 함수에 추가한다
Lec 07-2 Training/Testing 데이터셋
https://www.youtube.com/watch?v=KVv1nMSlPzY
- 머신러닝의 성능 평가방법
- training set을 사용하여 평가하는 방법? - 거의 100%에 가까울 것임.
- 70%를 training set으로 하여 학습하여 모델을 만들고, 남은 30%를(test set) 사용하여 평가해야
- 경우에 따라선 데이터셋을 Training/Validation/Testing 세트로 구분하여 사용.
- Validation set는 $\alpha, \lambda $를 평가하는 데 사용
- Online Learning : training set가 너무 많아서 한꺼번에 처리할 수 없을 때.
- 큰 데이터를 일정갯수로 잘라서 학습시킴.
- 나중에 새로운 데이터가 추가되더라고 갱신만 하면 되는 잇점.
- 정확도 측정
- 실제 $Y$ 값과, $ \bar Y$ 를 비교
- 이미지 인식 분야는 95%-99% 수준에 달함.
Lab 07-1 training/test dataset, learning rate, normalization
https://www.youtube.com/watch?v=oSJfejG2C3w
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]]
Y=tf.placeholder(tf.float32, [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)
#Correct prediction Test model
prediction = tf.argmax(hypothesis, 1)
is_correct = tf.equal(prediction, tf.arg_max(Y,1))
accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
# Launch graph
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})
if (step % 1 == 0) :
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의 문제.
- 위의 프로그램에서 learning_rate를 1.5로 주면 발산한다.
- 위의 프로그램에서 learning rate를 1e-10으로주면 정지한다.
Non_normalized inputs
- 아래 그림에서, xy의 3열은 다른 열에 비해 100배 이상이다. 이로 인해, 분포가 그 아래에 있는 것처럼 한쪽만 짜부라든 모양이된다.
- 이러한 데이터를 그냥 돌려보면, 모델 학습이 안될 가능성이 높다. 밖으로 튀어나가기 십상이기 때문에
Normalized inputs
- 아래와 같이 MinMaxScaler 등을 이용해서 정규화시키면 분포가 일정해져서 결과가 잘 나온다.
Lab 07-2 Meet MNIST Dataset
https://www.youtube.com/watch?v=ktd5yrki_KA
- MNIST 데이터셋이란 - 우편번호 자동 처리를 위해 만들어 놓은 손글씨 모음 데이터셋
- 28*28 =784 픽셀.
import tensorflow as tf
import matplotlib.pyplot as plt
import random
# 자세한 내용은 https://www.tensorflow.org/tutorials/layers
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 처음 실행하면 지정한 폴더에 데이터가 다운로드됨
nb_classes = 10
X=tf.placeholder(tf.float32, [None, 784]) # 28*28 이 여러개 있음.
Y=tf.placeholder(tf.float32, [None, nb_classes]) # one-hot 데이터. 클래스(nb_classes)는 10개
W=tf.Variable(tf.random_normal([784, nb_classes]))
b=tf.Variable(tf.random_normal([nb_classes]))
# hypothesis : softmax를 사용
hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
# cross entropy cost
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
is_correct = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y,1)) # one hot 값과 hypotheis 값 일치?
# Training epoch/batch
# epoch란 전체 training 데이터셋을 한번 돈 것.
# batch size란 한번에 training 시키는 데이터의 크기. 클수록 메모리 소요가 높아짐
# 예를들어 training 데이터가 1000개 이고, batch size가 500 이면, 1 epoch를 완수하는데 2번의 반복
# 아래와 같이 학습하는 것이 일반적인 절차임
training_epochs = 15
batch_size=100
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(training_epochs): #15회
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(100) # 100개씩 읽어들임.
c, _ = sess.run([cost, optimizer], feed_dict={X:batch_xs, Y: batch_ys})
avg_cost += c / total_batch
print('Epoch : ', '%04d' % (epoch +1), 'cost =', '{:.9f}'.format(avg_cost))
print("Accuracy: ", accuracy.eval(session= sess,
feed_dict = {X: mnist.test.images, Y: mnist.test.labels})) #학습에 사용하지 않은 데이터..
#그림 그려보기
#하나를 가져와서 예측해보자
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()
실행결과
Epoch : 0001 cost = 2.890159705
Epoch : 0002 cost = 1.087193211
Epoch : 0003 cost = 0.857237154
Epoch : 0004 cost = 0.751001975
----
Epoch : 0014 cost = 0.475028615
Epoch : 0015 cost = 0.465113584
Accuracy: 0.8902