딥러닝 입력 데이터 정규화 (Normalizing inputs)
학습을 수행하기 전에 값의 범위를 normalization
하는 것은 중요하다. 그 이유는 아래와 같다.
입력 변수가 MLP에서와 같이 선형 적으로 결합된다면 적어도 이론 상으로는 입력을 표준화하는 것이 거의 필요하지 않습니다.
그 이유는 해당weight
와bais
를 변경하여 입력 벡터를 재조정하면 이전과 완전히 똑같은 결과를 남길 수 있기 때문입니다.
그러나 입력을Standardization
하면 학습을 더 빨리하고 지역 최적의 상태에 빠지게 될 가능성을 줄이는 다양한 실용적인 이유가 있습니다.
또한, 표준화 된 입력을 통해Gradient Descent
및Bayesian estimation
을 보다 편리하게 수행 할 수 있습니다.
Normalization
수식 : (요소값 - 최소값) / (최대값 - 최소값)
설명 : 전체 구간을 0~1
사이의 값으로 맞춰 준다.
Standardization
수식 : (요소값 - 평균) / 표준편차
설명 : 평균은 0
표준편차는
$$\mu = \frac{1}{m} \sum_{i=1}^{m}{x^{(i)}}$$
$$x := x -\mu$$
$$\sigma^{2}=\frac{1}{m}\sum_{i=1}^{m}{(x^{(i)}-\mu)^{2}}$$
직관적 이해
아래와 같이 Unnormalized
된 상태에서는 Learning Rate
을 매우 작게 설정해야 정상적을 학습이 된다.
이유는 cost 그래프가 elongated
하기 때문이다. 따라서 elongated contour
의 모습을 가진다.
아래와 같이 Input
의 Range가 서로 다르다면 Gradient Descent Algorithm
을 적용하는것이 매우 까다로워지는 상황이 발생 한다.
하지만 normalization
을 적용하면 좀 더 spherical contour
를 가지게 된다.
이렇게 하면 좀 더 Gradient Descent Algorithm
으로 쉽게
그리고 빠르게
최적화 지점을 찾게 된다.
구현 코드
아래와 같은 코드를 가질 때
x가 1.0
y가 0.0
이렇게 1.0~0 사이의 값으로 입력과 출력이 정규화가 잘되면 학습이 잘 이뤄 진다.Learning rate
을 적절히 값을 잡아도 학습이 잘된다.
import tensorflow as tf
x = tf.constant(1.0, name='input')
w = tf.Variable(0.8, name='weight')
y = tf.mul(w, x, name='output')
y_ = tf.constant(0.0, name='correct_value')
loss = tf.pow(y - y_, 2, name='loss')
train_step = tf.train.GradientDescentOptimizer(0.025).minimize(loss)
for value in [x, w, y, y_, loss]:
tf.scalar_summary(value.op.name, value)
summaries = tf.merge_all_summaries()
sess = tf.Session()
summary_writer = tf.train.SummaryWriter('log_simple_stats', sess.graph)
sess.run(tf.initialize_all_variables())
for i in range(100):
if i % 10 ==0:
print("epoch {}, output: {}".format(i, sess.run(y)))
summary_writer.add_summary(sess.run(summaries), i)
sess.run(train_step)
epoch 80, output: 0.01321229338645935
epoch 90, output: 0.007910688407719135
하지만 x의 범위르 10배만 넓혀서 10으로 하면 학습이 실패 한다.
이 때는 Learning rate
을 더 작게 주어야 한다.
import tensorflow as tf
x = tf.constant(10.0, name='input')
w = tf.Variable(0.8, name='weight')
y = tf.mul(w, x, name='output')
y_ = tf.constant(0.0, name='correct_value')
loss = tf.pow(y - y_, 2, name='loss')
train_step = tf.train.GradientDescentOptimizer(0.025).minimize(loss)
for value in [x, w, y, y_, loss]:
tf.scalar_summary(value.op.name, value)
summaries = tf.merge_all_summaries()
sess = tf.Session()
summary_writer = tf.train.SummaryWriter('log_simple_stats', sess.graph)
sess.run(tf.initialize_all_variables())
for i in range(100):
if i % 10 ==0:
print("epoch {}, output: {}".format(i, sess.run(y)))
summary_writer.add_summary(sess.run(summaries), i)
sess.run(train_step)
epoch 70, output: nan
통상의 Learning Rate
의 문제와 비슷하게 발생 한다.
참고 사이트
'AI > TensorFlow, PyTorch, Keras, Scikit' 카테고리의 다른 글
TensorFlow 모델을 저장하고 불러오기 (save and restore) (3) | 2017.12.09 |
---|---|
Batch 크기의 결정 방법 (6) | 2017.12.07 |
rpy2와 Pandas를 활용한 R object 변환 (0) | 2017.08.08 |
Confusion Matrix in python (0) | 2017.08.03 |
Tensorflow Object Detection API (SSD, Faster-R-CNN) (0) | 2017.07.16 |