LEC4 - Optimization
오늘 우리는 딥러닝을 학습시키기 위해서 필수적인, 경사하강법의 의미를 배울 것이고, 이 경사하강법의 과정을 우리는 optimization (최적화) 라고 이야기 하게 되는데, 여러 최적화 기법에 대해 알아보려고 한다.
경사하강법
경사하강법이란, 우리는 결국 train data 에 대한 loss 가 최소가 되는 지점을 찾고 싶은 것이고, 만약, 각 가중치에 대한 loss function 을 우리가 미분을 통해 구할 수 있다고 한다면, 미분 후 구할 수 있겠지만, 아쉽게도, 다 변수에 대한 고차원 함수를 미분한다는 개념자체가 없기 때문에 각 독립변수에 대한 편미분 값을 구한 뒤, update 하는 방식으로 학습을 할 수밖에 없다. 즉 각 변수에 대한 다소 단편적인 변화율만 보고 update 를 할 수밖에 없다는 것이다. 이는 우리가 눈을 가린채, 산에서 산행을 통해 아래로 점차 내려가는 것과 같다.
![]() |
![]() |
우리는 결국, 각 weight(parameter) 에 대한 편미분 값을 바탕으로 순차적인 업데이트를 통해 Loss 가 최소가 되는 weight 를 찾아낼 것이다. 이제 각 weight 를 업데이트를 어떤 식으로 할지를 보자.
1. Random Search
첫 번째로 알아볼 방법은 Random search 인데, 이는 랜덤하게 w를 변경하고, Loss 가 이전보다 개선되면, w를 갱신해가는데, 누가 봐도 결과가 좋을 것 같지는 않다.
2. gradient
우리가 산을 내려갈 때, 산비탈을 타고 내려가는 것처럼, Loss Func 이 그리는 면을 따라 최적의 w를 찾는 방법인데, 즉 편미분 값을 구해, 편미분 값 만큼 update 해서 loss를 점차 줄여나가자는 것이다.
2-1) Numeric Gradient(수치 해석적인 미분)
![]() |
![]() |
왼쪽식을 통해 우리는 수치해석적인 미분해를 구할 수 있는데, 이는 큰 단점이 있다. 우선, 시간이 오래 걸린다는 것이다. 우리가 다룰 loss 함수는 매우 고차원의 함수일텐데, 이에 대입을 진행하는 것은 너무 오래걸린다. 또, 이 수치해석 미분해는, 대략적인 해라는 것이다. 즉 특정지점에서 미분값이 이와 동일한지는 알 수 없다.
2-2) Analytic Gradient
![]() |
![]() |
뉴턴과 라이프니치와 같은 사람들이 이미 훌륭한 미분방정식을 구해두었으니, 이를 사용하자는 것이다. 이 방법은 빠르고, 심지어 정확하다. 신경망에서 이와 같은 Analytic Gradient 를 통한 update 방식은 back propagation 이라고 하며, 이후 6강에서 배울 것이다.
이런 최적화 과정이 올바른지를 확인하기 위해서는 분석해와 수치해를 비교하는데, 수치해를 사용할 수 있다. 아, 편미분 값은, 항상 본인의 분포 그래프의 증가하는 방향으로 gradient 가 계산된다. 그래서 -를 붙혀, negative gradient 를 사용한다.
3. 경사하강법을 진행해보자.
앞선 방법을 통해 우리가 gradient를 구해서, 이를 활용해 더 낮은 loss를 가지는 w를 찾아 가야한다는 것을 알게 되었다. 이 방법을 경사하강법이라고 하고, update를 위해서는 3가지의 hyperparameter가 필요한데,
1. weight initalization
초기 가중치를 어떤식으로 초기화 해줄지에 관한 것이다. 이후 10강에서 이와 관련해 자세히 다루게 될 것이다.
2. step size
우리가 총 이런 경사하강법을 통해 몇번의 update를 진행할지에 관한 것이다. 이런 step size는 일반적으로 고정값을 사용하는데, 이 step size는 각 컴퓨터의 성능을 고려해 정해야 한다.
3. Learning rate
우리가 한 번 움직일 때, gradient 만큼 움직인다고 하면 최적의 w를 지나치는 overshoot 문제가 발생할 수 있기 때문에, 우리는 LR을 곱한 값 만큼 update를 진행하게 되는데, 이를 결정하는 방법도 11강에서 배운다.
Gradient Descent 를 통한 W의 update 궤적은 loss func 이 이루는 면을 따라 그려지는데, 면의 기울기는 항상 loss curve의 최저점을 향해있지는 않기 때문에, 이런 curve가 그려진다. 즉 앞선 예시처럼 산행의 예시를 들면 오르막 내리막이 있다고 생각하면 된다.
4. 다양한 optimization method
4-1) Batch Gradient Descent
batch 란 우리가 한 번 update에 사용한 data의 수를 말하며, 전체 데이터를 사용하는 것을 일반적으로 Batch Gradient Descent 라고 한다. 장점은 전체 data를 보고, 학습을 진행하기 때문에, 비교적 학습이 안정적일 가능성이 있다. 단점으로는, 우리가 한 번의 update를 위해서는 너무 많은 computing 연산이 필요하기 때문에, 비효율적이다. 또한, 전체 data를 본다고 해도 global 최적점이 아닌, local 최적점에 빠질 위험이 여전히 있다.
4-2) Stochastic Gradient Descent(SGD)
SGD 에서는 전체 데이터가 아닌, 각 데이터를 보고 update를 하겠다는 것이다. 주의할 점이 데이터 한 개 보는게 한 번의 학습이 아니라, 각 데이터에 대해서 한 번 즉 전체 데이터를 모두 봤을 때 한 번의 epoch 이 지났다고 하는 것이다. 예를 들어 1개의 data를 보겠다고 하면, 총 데이터인 N번의 update가 일어나야, 한 번 update가 되었다고 할 수 있는 것이다. SGD 는 데이터 한개를 보고 update를 하는 것을 의미한다. 장점 : 빠른 수렴 (한 데이터 셋에도 N번의 update가 일어나기 때문에) 단점 : local optima나, 특정 이상한 data의 값에 대해서도 보다 크게 반응할 수 있다. 즉 불안정한 학습이 일어날 수 있다. 일부에서는 장점으로, 특정 데이터 하나를 보고 update 하기 떄문에, local optima에서 빠져나올 수 있다고도 하는데, 가능성은 있으나 이걸 장점이라고 하기는 애매한 것 같다.
이게 SGD 의 단점을 나타낸 그래프인데, 학습이 매우 큰 진동폭을 가지는 지그재그를 그리면서 학습된다는 것이다. 이 때문에 SGD는 Full Batch 보다 Overshoot 문제에도 취약하다고 볼 수 있다. 이런 그래프를 그리기 때문에, 노이즈가 낄수도 있다.
앞서 이야기한 것처럼, 데이터의 일부만 보고, update를 하기 때문에, local optima나 saddle point에 빠질 수도 있다. 이로 인해 학습이 크게 지연될 수 있다.
이래서 데이터 한 개를 update 하지는 않고, 일반적으로 batch -> minibatch 로 나눠서 학습시키는 방법을 많이 사용한다고 알고 있다.
SGD가 사용될 수 있는 이유는 몬테카를로 법칙인데, 이는 우리가 표본에 대한 무작위 추출을 여러번 하면, 원 분포를 근사할 수 있을 것이라는 이론적 배경이 있기 때문에 가능하다.
4-3) SGD + Momentum
그래서 일반적으로 SGD를 그대로 사용하기 보다는 momentum을 더해서 사용하게 되는데, 이는 이전 가중치들의 update의 평균을 유지하고 있다가, 이를 이용해서 update를 하겠다는 것이다. 즉 물리 세계에서의 관성을 더해주는 것이라 보면 된다.
Momentum는 SGD의 진행 추세라고 볼 수 있으며, 이를 위한 hyperparameter인 rho는 decay rate 등으로 부르며, 일반적으로 0.9 에서 0.99 로 설정한다고 한다. Momentum의 구현은 각 code 마다 다를 수 있으며, 비슷한 의미를 지니면 같다라고 본다.
장점은 이전 update들의 평균을 사용하면서 보다 안정적인 학습을 보장할 수 있으며, local minima 나 saddle point에서 관성의 힘을 통해 빠져나올 가능성이 높아진다. 또한 poor conditioning 도 막아줄 수 있다.
4-4) Nesterov Momentum (한 발더 가보자)
둘의 차이인데, Nesterov Momentum은 관성을 이용해 한 발자국 더 간후 update를 하자 라는 개념이다.
위의 ppt와 같은 방식으로, Nesterov Momentum 을 구현하는데, 이와 같은 방식으로 api등을 이용하기는 어려운데, 그렇기 때문에 아래 ppt와 같은 trick 을 통해 살짝 변형해서 사용한다. 구현상의 어려움 때문에 우회된 방식을 사용한다는 식으로 생각하면 된다.
4-4) AdaGrad
각 파라미터에 대해 학습률을 적응적으로 조정하여, 자주 발생하는 기울기에 대해서는 학습률을 낮추고, 드물게 발생하는 기울기에 대해서는 학습률을 높이자는 것이다. 이렇게 하면, 희소한 data에 대해서도 학습할 수 있고, 보다 비슷한 학습률을 통해 안정적인 학습이 가능할 것이다.
장점은 희소한 특징이 있는 문제에서 잘 작동하며, 모든 파라미터에 대한 적응적인 학습률을 제공한다. 단점으로는 학습률에 대해서 누적합을 사용하기 때문에, 학습이 다 진행되기도 전에, 학습률이 0에 가까워져 학습이 멈출 가능성이 있다.
우측 하단 글을 보면 알 수 있듯, 가파르면(불안정) 천천히 학습, flat(안정) 하면 빠른 학습을 보장할 수 있어, 좋다는 것이다. 하지만, 앞서 이야기 한 것처럼, 누적합을 사용하기 때문에, 학습이 멈출 수 있다.
4-5) RMSProp
Adagrad의 학습률 감소 문제를 해결하기 위해, 기울기의 제곱합이 아닌, 지수 이동 평균을 사용해 학습률을 조정한다.
RMSProp 에서 step size는 점점 줄어들기에, sgd + momentum 보다 overshoot이 훨씬 덜 할것이다. 앞선 adam의 장점을 그대로 가지면서, 단점을 개선한 것이다.
4-6) Adam : RMSProp + Momentum
Momentum 과 RMSProp의 장점을 합친 Adam 이라는 방식이 있는데 다음과 같이 나타낸다. momentum은 앞서 본대로 의미만 비슷하면 되기 때문에, 그냥 이동평균을 통한 구현을 해둔 것 같다. 이 때 한가지 슈퍼크랙이 있는데, 만일 beta2 가 1에 가까울 경우 t = 0에서 step size가 매우 커지기 때문에 우리는 bias coreection term을 추가하여 구현할 수 밖에 없다.
Adam 에서는 주로 위와 같은 Hyperparameter 값을 사용하며 대부분의 경우에 잘 작동한다. 아래의 표는 각 optimizer 별 특징을 정리한 표이다.
5. First-Order Optimization
지금까지 배운 optimization은 1차 미분을 이용한 first order optimization 이며, 당연히 Second-Order Optimization 도 있다. 이방식의 Loss의 Curvature와 step size가 반비례하기에 First-Order보다 더 robust한 Optimiztion 방식이다.
6. Second-Order Optimization
![]() |
![]() |
이렇게 되면 우리는 해당 지점의 곡률에 대한 정보를 얻어 update를 진행하기 때문에, 보다 global optima에 수렴할 수 있게 된다. 다만, 일차 미분도 이미 충분히 버거운데 반해, 이차 미분을 하는 것은 거의 불가능하다. 그래서 우리는 L-BFGS 를 사용해 근사하는 방법을 사용하는데, 이 마저도 연산의 양이 많아 잘 사용하지는 않는다.
7. L-BFGS
당연하게도, minibatch에 대해서는 잘 작동하지 않을 것이다. 즉 기대한 만큼의 성능을 뽑아낼 수는 없을 것이다. 왜냐하면, 곡률에 대한 계산을 하는데, 일부데이터의 곡률은 그다지 의미있는 방법이 아니기 때문이다. O(n^2) 에 가능은 하지만, 여전히 커서 하지는 않는다.