본문 바로가기

Deep Learning for Computer Vision

EECS 498-007 / 598-005 Lecture 4 : Optimization

강의 링크

https://www.youtube.com/watch?v=YnQJTfbwBM8&list=PL5-TkQAfAZFbzxjBHtzdVCWE0Zbhomg7r&index=4

 

강의 슬라이드

https://web.eecs.umich.edu/~justincj/slides/eecs498/498_FA2019_lecture04.pdf

 

Optimization은 Loss를 최소화하는 W를 찾는 것으로 것으로  이 과정은 사람이

고지대에서 저지대로 가는 길을 찾는 것과 유사하다.

 

 

Linear regression 등의 간단한 모델에서는 간단한 미분을 통해 최소 Loss를 가지는 W를 찾을 수 있지만, 복잡한 모델에서는 Linear regression이 가지는 것과 같은 명료한 공식을 통해 최적의 W를 찾기란 매우 어려운 일이다.

그래서 일반적으로는 특정한 공식으로 최적의 W를 바로 찾기 보다는 최소 Loss를 가지는 이상적인 W값에 가깝게

조금씩 W를 변경해가는 방법을 이용한다.

 

첫번째로 알아볼 방법은 Random Search이다.

Random Search는 랜덤하게 W를 변경했을 때, Loss가 이전보다 개선되면 W를 갱신해가는데, 

CIFAR10에 대해서 기대 정확도가 95%인데 반해서, Random Search는 15.5%로 별로 좋지 않은 것을 

볼 수 있다.

 

다음으로 알아볼 방법은 사람이 산비탈을 타고 내려가는 것처럼, Loss Function이 그리는 면을 따라

최적의 W를 찾는 방법이다. Loss Function이 1차원인 경우 도함수를 이용해 한번에 구할 수 있지만,

그게 아닐 경우,  gradient를 이용한다.

 

Gradient는 벡터 W에서 1개의 element씩 번갈아가며 각 element에 대응하는 gradient를 구할 수 있는데,

이렇게 해서 Gradient를 구하는 방법을 Numeric Gradient라고 한다.

이 방법은 계산 횟수가 W의 크기에 비례하기에 W의 크기가 큰 상황에서는 비실용적이다.

그리소 도함수에서 h는 진짜 극한이 아니라 임의의 작은 값을 사용하므로 완전히 정확한 값을 구한다고도

할 수 없다.

 

그래서 일반적으로는 미분을 이용하여 Gradient를 구하는 Analytic Gradient를 이용한다.

 Analytic Gradient에 대해 자세히는 추후 6강에서 배울 예정이다.

 

Analytic Gradient는 정확하지만 그만큼 복잡해서 구현 과정에 있어 실수하기 쉽다.

그래서 새로운 Analytic Gradient를 개발했을때에는 실제 모델에 적용하기 전에 Numeric Gradient를 사용해 제대로 

구현되었는지 확인하는 Gradient Check라는 것을 해야한다.

 

앞선 방법으로 gradient를 찾았다면 이제는 gradient를 활용해 더 낮은 Loss를 가지는 W를 찾아 나가는 데,

이 방법을 Gradient Descent라고 한다. Gradient Descent에는 3개의 Hyperparameter가 있는데

 

첫 번째가 바로 W(weight)를 초기화하는 방법이다. Gradient Descent는 어떻게 W를 초기화하는지에 따라 결과나 과정이 달라지는데, 이 부분도 자세한 것은 추후 강의에서 다룬다고 한다.

 

두 번째 Hyperparameter는 Gradient를 활용해 더 나은 W를 찾아나가는 step을 몇 번이나 수행할지이다.

이 step의 횟수를 정하는 방법은 여러 가지가 있지만 딥러닝에서는 보통 고정된 횟수의 step을 사용한다.

step 횟수와 학습 소요 시간은 비례하기에 머신러닝에서 step의 횟수는 컴퓨터의 성능을 고려해서 정해야 한다.

 

마지막으로 세 번째는 바로 한 번의 step에서 이동할 거리, Learning rate이다. Learning rate가 높으면 최적의 W까지

더 적은 횟수의 step으로 도달 가능하지만 최적의 W를 지나쳐버리는 overshoot 문제가 생길 수 있고, 반대로 learning rate가 낮으면 정교하지만 더 오래 걸린다.

 

Gradient Descent에서 W의 궤적은 Loss Function이 이루는 면을 따라 그려지는데, 면의 기울기는 위 슬라이드처럼 항상 최소 Loss를 향해 기울어져있지는 않다. 그리고 step size, 즉 W의 변화량은 Gradient가 크면 크고, 작으면 작은

비례관계에 놓여있다.

 

Loss가 각 데이터의 합으로 이루어져 있는 것처럼 Gradient도 각 데이터의 합으로 이루어져 있다.

그래서 데이터가 많아지면 많아질수록 전체 Gradient를 계산하는 것에 많은 비용이 들기에

일반적으로 Gradient Descent를 약간 변형시켜 사용한다.

 

그중 하나가 바로 Stochastic Gradient Descent(SGD)이다.

이 방식은 모든 데이터에 대해 Gradient와 Loss를 구하기보다는 표본 데이터를 추출해서 일부만을 가지고 구하는데,

여기서 표본 데이터를 minibatch라고 하며 일반적으로 32, 64, 128 등의 크기로 사용한다.

 

SGD 또한 Hyperparameter가 필요한데, SGD에서의 Hyperparameter는 기존의 Gradient Descent에서 사용하는 것에 더해서 minibatch의 크기인 batch size, 데이터를 어떻게 선정할 것이냐에 관한 것인 Data sampling이 있다.

 

그리고 batch size의 경우 컴퓨터의 GPU의 메모리 크기가 허용하는 한, 최대한 크게 잡는 것이 좋으며,

Data Sampling은 Image Classification에서는 그다지 중요한 Hyperparameter가 아니지만,

ranking이나 prediction 등에서는 중요할 수도 있다.

 

SGD에서는 표본 데이터를 가지고 Gradient와 Loss를 구하기에 표본 데이터의 분포가 전체 데이터의 분포와 

최대한 유사하도록 표본을 선정해야 한다.

 

SGD에는 아쉽게도 몇몇 문제가 있는데, 먼저 Gradient Descent가 지그재그를 그리며 진행되어 그래서 더 많은

step이 소요된다는 점이다. 이 때문에 SGD는 Full Batch보다 Overshoot문제에도 더 취약하다.

 

또한 Local Minimum에 빠질 위험이 높으며 고차원의 데이터에서는 gradient가 0인 saddle point에 위치해서

학습이 크게 지연될 수 있다.

그리고 SGD는 애초에 일부 데이터로만 학습을 진행하기에 Loss Function에서의 W의 궤적이 항상 Loss의 기울기를

따르는 것이 아니라 거꾸로 돌아가기도 하는 등의 노이즈가 끼는 경우가 많다.

 

그래서 순수한 SGD를 사용하기보다는 약간 변형시켜서 사용하는데

대표적인 방법들 중 하나가 바로 SGD + Momentum으로 Linear 모델 말고도 딥러닝 모델에서도 많이 쓰이는 방법이다.

여기서 Momentum은 SGD의 진행 추세라고 볼 수 있으며,

이를 위한 Hyperparameter rho는 friction 혹은 decay rate라고 부른다.

 

SGD + Momentum은 정해진 방법으로만 사용하는 것이 아니라 세부 구현은 약간씩 다를 수 있다.

 

SGD + Momentum에서 Momentum은 앞에서 SGD의 진행 추세라고 언급했는데, 이는 SGD의 관성이라고도 할 수 있다.

그래서 SGD에서 W가 Local Minimum이나 Saddle point를 만나더라도, 이 '관성'의 영향을 받아 쉽게 탈출할 수 있다.

또한 지그재그로 움직이게 되는 Poor Conditioning도 완화해준다.

 

지금까지 배운 SGD + Momentum은 지난 step의 정보를 반영한 추세 velocity와 gradient가 합쳐져서 다음의 step이

정해진다. 하지만 이 방식 말고도 현재의 위치에서 velocity만큼 이동했을 때의 gradient를 이용해서 step을 정하는

Nesterov Momentum이라는 방식도 있다.

 

 

위와 같은 방식으로 Neserov Momentum을 구하는데, 이 방식으로 api 등을 이용하기는 쉽지 않아서

살짝 변형해서 적용한다. 

SGD의 변형으로는 SGD + Momentum 말고도 adaptive learning rate를 활용한 AdaGrad란 방법도 있는데

AdaGrad에서는 gradient가 클 경우, 큰 값으로 나누기에 step size가 작아지고, 작을 경우, 작은 값으로 나누기에 (1보다 작은 값) step size가 커진다. 그래서 gradient descent의 진행이 지그재그를 이루는 Poor Conditioning을 완화시킬 수

있다. 하지만 AdaGrad는 step이 많이 진행되면 진행될수록  grad_squared가 커져서 gradient descent가 

멈춰버릴 가능성이 있다.

 

그래서 AdaGrad를 개선한 RMSProp이란 방식이 제안되었다.

 

RMSProp에서 step size는 점점 줄어들기에 SGD + Momentum에 비해 overshoot이 훨씬 덜 한 것을 볼 수 있다.

 

 

그리고 SGD + Momentum과 RMSProp의 장점을 합친 Adam이라는 방식도 있는데, 

Adam에서 Hyperparameter는 beta1과 beta2가 추가로 있는데, beta2가 1에 가까울 경우 t = 0에서 step size가

매우 매우 커지기에 Bias correction을 추가한 형태로 사용한다.

Adam에서는 주로 위와 같은 Hyperparameter 값을 사용하며 Adam은 매우 robust 한 optimizer로 대부분의 경우

잘 작동한다.

지금까지 배운 Optimization 알고리즘은 위와 같은 표로 나타낼 수 있다.

 

지금까지 배운 Optimization은 모두 First derivative만을 이용한 First-Order Optimization이며

당연히 Second-Order Optimization도 있다. 이 방식은 Loss의 Curvature와 step size가 반비례하기에 First-Order보다 

더 robust한 Optimization 방식이다.

하지만 그만큼 오래 걸리기에 그다지 사용되지는 않는다.

 

이 부분은 강의에서 강의 시간이 별로 안 남아서 그냥 생략하고 넘어갔는데 이런 게 있다 정도만 알고 넘어가면

될 듯하다.

 

어쨌든 일반적으로는 Adam이 좋으며 모델을 잘만 튜닝한다면 SGD + Momentum이 Adam보다 더 좋을 수 있다고

한다. 그리고 데이터의 차원이 낮아 full batch로 문제를 해결할 수 있으면 L-BFGS와 같은 방식을 고려해보는 것도

괜찮다고 한다.

 

요약

 

 

 

 

아래는 강의 중에 Linear Classifier를 시각화 도구라고 잠깐 소개를 하고 넘어갔었는데, 나쁘지 않게 만든 것 같다.

vision.stanford.edu/teaching/cs231n-demos/linear-classify/

 

Multiclass SVM optimization demo

Parameters \(W,b\) are shown below. The value is in bold and its gradient (computed with backprop) is in red, italic below. Click the triangles to control the parameters. Multiclass SVM loss formulation:

vision.stanford.edu

 

728x90