CS231n Lecture 3-2: Optimization
파라미터
손실 함수(Loss function)과 Regularization 등 모든 것을 분석해서 밑바닥으로 순간이동할 수 있는 minimizer를 만들면 좋겠지만, 실제 Neural Network에서는 이러한 함수들이 매우 크고 복잡하다. 어떤 명시적인 솔루션으로 최적값(minima)를 직접 얻는 것은 불가능에 가깝다. 대신 다양한 반복적인(interative) 방법들을 사용한다. 임의의 지점에서 시작해서 점진적으로 성능을 향상시키는 것이다.
전략 #1: 임의 탐색(Random search)
생각해볼 수 있는 가장 단순한 방법 중 하나로 임의로 샘플링한
전략 #2: 경사면을 따라 내려가기(Follow the slope)
실제로 더 나은 전략은 지역적인 기하학적 특성(local geometry)을 이용하는 것이다. 골짜기의 밑바닥이 어딘지 눈으로 확인할 수는 없지만 두 발의 감각으로 땅의 경사를 알아낸 뒤 내려갈 수 있는 방향으로 조금 나아간다. 다시 땅의 경사를 알아내고 내려가는 방향으로 또 나아간다. 이를 반복하면 골짜기를 내려갈 수 있다는 접근이다. 세부적인 것만 잘 파악하면 꽤 잘 동작한다고 한다.
Gradient
1차원 함수
작은 스텝
실제로는
Gradient의 방향은 함수에서 가장 가파르게 올라가는 방향을 가르키는데, 반대로 gradient의 반대(negative gradient)방향은 가장 가파르게 내려가는 방향과 같다. 특정 방향의 기울기는 그 방향의 단위 벡터(unit vector)와 내적(dot product)한 값이 된다.
Numerical gradient
유한 차분법 (Finite difference methods)으로 구한 gradient의 근사값을 말한다. FDM은 쉽게 말해
현재
이를 마찬가지로 다른 모든 차원들에 대해서도 반복해주면 gradient의 계산이 가능하다. 하지만 시간이 굉장히 오래 걸려 끔직한 방법이다. 이 예시에서는
대신 Loss의 gradient를 계산하는 코드를 직접 작성 중이라고 할 때, FDM으로 구해진 값과 일치하는지 확인하는 디버깅 툴 정도로 활용이 가능하다. 대신 수치적으로 불안정하고 느리기 때문에 파라미터 개수를 줄이고 테스트하는게 좋다고 한다.
Analytic gradient
결국 loss function은
경사 하강법 (Gradient Descent)
Gradient를 계산하는 방법을 알고 나면, 이 값을 이용해서 최적의
1
2
3
4
5
# Vanilla Gradient Descent
while True:
weights_grad = evaluate_gradient(loss_fun, data, weights)
weights += - step_size * weights_grad # perform parameter update
경사 하강법에서는 먼저
여기서 step_size
는 하이퍼파라미터로 gradient의 반대 방향으로 “얼마나 나아갈지”를 나타낸다. 학습률(Learning rate)라고도 하며, 학습할 때 정해줘야하는 가장 중요한 하이퍼파라미터 중 하나이다.
학습시 모델 사이즈나 Regularization 강도와 같은 것들보다도 가장 먼저 Learning rate를 올바르게 정해준다고 한다.
다음은 2차원 공간에서의 간단한 예시를 보자.
Loss function을 나타낸 것으로 가운데 빨간 부분이 loss가 낮은 부분, 테두리의 푸른 부분들이 loss가 더 높은 곳이다. 임의의 점에
오른쪽 그림은 앞으로 배우게 될 또다른 Update rule들을 나타낸 것으로 여러 스텝을 한 번에 고려하는 더 좋은 방법들이다. 기본적인 gradient descent보다 실제로 더 좋은 성능을 보인다. 하지만 결국 기본적인 알고리즘은 매 스텝마다 내려간다는 것이다.
확률적 경사 하강법 (Stochastic Gradient Descent)
다시 정리하면
앞에서 정의한 loss function
Gradient descent는 loss function
전체 loss는 전체
그래서 실제로는 확률적 경사 하강법(stochastic gradient descent)라는 방법을 사용한다. 전체 데이터 셋의 gradient와 loss를 모두 계산하지 말고, 미니배치(minibatch)라는 작은 학습 셋들로 나눠 학습하는 방법이다. Minibatch의 gradient와 loss 값을 전체 데이터 셋의 “gradient 추정치”와 “loss 추정치”로 보는 것이다.
SGD는 거의 모든 DNN 알고리즘에서 사용되는 기본적인 학습 알고리즘으로 다음 네 줄로 학습 과정을 나타낼 수 있다.
1
2
3
4
5
6
### Vanilla Minibatch Gradient Descent
while True:
data_batch = sample_training_data(data, 256) # sample 256 examples
weights_grad = evaluate_gradient(loss_fun, data_batch, weights)
weights += - step_size * weights_grad # perform parameter update
참고로 Minibatch의 사이즈는 보통 2의 제곱수로 정하며 32, 64, 128 등을 주로 사용한다.
Interactive Web Demo
http://vision.stanford.edu/teaching/cs231n-demos/linear-classify/
위 링크를 통해 Linear classifier를 Gradient descent로 학습시킬 수 있는 Web Demo에 접속할 수 있다. 여러 Loss function을 적용해보며 어떻게 학습이 종료되는지 보고, 다양한 요소들의 trade-off를 비교해보며 다른 점을 이해해보자. 또한 Gradient descent를 통해 Linear classifier를 학습시키는 과정을 직접 보면서 직관을 얻어보도록 하자.