AI 주요 Optimizer 정리 (SGD, Momentum, Adagrad, RMSProp, Adam)

Introduction
인공지능, 그 중에서도 딥러닝을 공부함에 있어 optimizer를 공부하는 것은 매우 중요합니다. 왜냐하면 학습 과정에서 파라미터를 업데이트 하는 방법이기 때문입니다. 사실 SGD, RMSprop, Adam같은 optimizer가 있다는 것은 알고 있었지만 각각의 optimizer가 무엇인지 구체적으로 이해하고 정리해야 할 것 같아 이 포스팅을 하게 되었습니다.
optimizer를 한줄로 요약하면 뭘까요? 저는 다음과 같이 정의할 수 있다고 생각합니다.
최소의 Loss로 학습하는 방법을 찾는 알고리즘

다들 알겠지만 딥러닝은 Loss function를 정의하고, 그 Loss가 최소화 하도록 학습이 진행됩니다. 이때 Loss Function은 정답(label)과 모델이 예측한 값의 차이로 잡습니다.
위 사진을 보면 파라미터가 변함에 따라 loss가 변하는 loss function입니다. 다음과 같은 loss function에서 loss를 최소화하는 파라미터를 찾는 것! 그게 optimization(최적화)이고, 최적화 하는 알고리즘을 optimizer라고 합니다.
어떤 optimizer를 선택하느냐에 따라 local optimum를 찾게되는지, 학습속도와 같은 측면에서 차이가 크기에 학습에 적합한 optimizer를 찾는 것은 중요합니다. 이글의 맨위의 사진을 보면 각 Optimizer별 loss function이 어떻게 되는지 시각화해서 보여줍니다. 몇몇 optimizer는 매우 빠른 속도로 optimum을 찾아가는가하면, 일부는 천천히 찾아갑니다. 또한 SGD를 보면 local minima에 갇혀 더 작은 loss를 찾아가지 못하는 것을 볼 수 있습니다.

다음 figure는 optimizer를 공부할 때 자주 보게 되는 사진입니다. optimizer가 어떻게 파생되었고 어떤 개념을 바탕으로 발전해 나갔는지를 쉽게 이해할 수 있습니다.
optimizer의 시작은 GD(Gradient Descent)부터 시작합니다. 여기서 파생된 SGD를 바탕으로 2가지 계열로 나뉘게 됩니다. 바로 Momentum과 Adagrad 계열로 나뉘어 발전하게 되고, Adagrad에서 파생된 RMSProp과 Momentum의 개념이 결합되어 Adam으로 발전 되는 것을 볼 수 있다.
그래서 이번 글에서는 위에 나온 총 6개의 optimizer(GD, SGD, Momentum, Adagrad, RMSProp, Adam)에 대해 알아보려고 한다.
Gradient Descent

Gradient Decent는 가장 기본적인 optimizer이다. Gradient Decent를 수식으로 보면 다음과 같다.
\[W^{(t+1)} = W^{(t)} - \eta \frac{\partial \mathcal{L}}{\partial W}\]- $W^{(t)}$ : t번째 step일때의 Weight
- $\mathcal{L}$ : Loss
- $\eta$ : Learning Rate
다음과 같은 수식을 통해 Weight가 업데이트 됩니다. 정말 직관적인 수식인데 딥러닝의 backpropagation과정에서 얻은 gradient에 Learning Rate를 곱해서 Weight에 빼주면 다음 step의 Weight가 됩니다.
직관적으로 이해를 하자면 아래로 볼록인 2차함수에서 기울기가 양수인부분에서 기울기를 빼주면, 함수의 극소방향으로 향할 것입니다. 그래서 점점 작은 Loss 인 방향으로 향할 수 있는거죠.
여기서 Learning Rate는 가중치가 업데이트 되는 step의 크기를 결정하는 하이퍼 파라미터입니다. Learning Rate의 값은 너무 커서도 너무 작아서도 안되고, 적당한 값이여야만 합니다. 그 이유는 위의 사진과 같이 learning rate가 너무 크면 minima에 수렴하지 못할 것이고, 너무 작게 된다면 학습 속도가 너무 느리거나 local minima에 빠질 수 있습니다.

여기서 local minima이란 그 주위에서 최소값 즉 고등학교때 배운 개념으로는 극소값이 될것이고, global minima은 해당 전체 함수에서 가장 찾은 최소값을 말합니다. 이때 learning rate가 너무 작다면 극대값을 넘지 못하고 local minima에서 값을 찾아나갈 것입니다.
또 고차원의 parameter 공간에서 local minima에 걸리는 경우도 있지만 실제로는 saddle point(안장점)이 문제가 되는 경우가 많다. 이는 특정방향에서는 아래로 볼록이지만, 특정방향에서는 위로 볼록이여서 saddle point에서 벗어나는데 너무 오랜시간이 걸릴 수 도 있다.
SGD (Stochastic Gradient Descent)

SGD를 한국어로 번역하면 확률적 경사하강법입니다. 일반 gradient descent는 전체 데이터셋을 이용하여 1에폭당 1회의 업데이트를 진행합니다. 이방식은 안정적이지만 학습속도가 느리고 local minima를 탈출하기 어렵습니다. 그래서 SGD는 전체 배치를 여러 샘플로 나누어 랜덤하게 샘플링된 샘플로 여러번 업데이트 하게 됩니다.
SGD는 샘플 단위 SGD와 미니 배치 SGD가 존재합니다. 하나의 데이터 샘플 단위로 SGD를 진행하면 데이터 하나의 정보만으로 가중치가 업데이트되며 계산비용이 적지만 노이즈가 많아 학습이 불안정해집니다. 그래서 일반적으로 딥러닝에서는 미니배치 SGD를 사용합니다. 미니배치 SGD의 경우 미니배치로부터 loss의 평균 기울기를 계산해 업데이트할 수 있습니다.
Momentum
\[\begin{aligned} v_{t+1} &= \gamma \, v_t + \eta \,\nabla_\theta \mathcal{L}(\theta_t), \\ \theta_{t+1} &= \theta_t - v_{t+1}. \end{aligned}\]- $\gamma$ : 모멘텀 계수
- $v_t$ : velocity , 모멘텀 항
- $\theta_t$ : t번째 parameter(모델 가중치)
momentum은 SGD에서 이전 스탭의 업데이트 방향을 일정 비율만큼(모멘텀 계수만큼) 유지하며 새로운 기울기를 반영한다. 이렇게 하여 누적된 ‘velocity’는 관성처럼 작용해 사소한 local minima나 노이즈에 흔들리지 않도록 도와준다.
Adagrad(Adaptive Gradient)
\[\begin{aligned} G_{t} &= G_{t-1} + g_t \odot g_t \\ \theta_{t+1} &= \theta_{t} - \frac{\eta}{\sqrt{G_t} + \epsilon} \odot g_t \end{aligned}\]- $g_t = \nabla_\theta \mathcal{L}(\theta_t)$ : 손실함수에 대한 기울기, 즉 $\theta_t$에서 손실함수에 대한 기울기
- $G_{t}$ : 과거 모든 스탭의 기울기의 제곱을 누적한 벡터
- $\odot$ : element-wise 연산, 원소별 연산을 의미
- $\epsilon$ : 0으로 나누는걸 방지하는 매우 작은 값
Adagrad는 파라미터별 기울기와 분포가 다를 수 있는 문제를 방지하기 위해 각 파라미터별 원소마다 따로 계산됩니다. 이때 파라미터가 업데이트 되는 식에서 $\eta$를 $\sqrt{G_t} + \epsilon$로 나눈 값이 유효학습률이 되며, 이 유효학습률이 파라미터마다 다르게 계산된다는 특징을 갖고 있습니다.
Adagrad는 sparse feature를 학습하는데에 유리합니다. 예를 들어 NLP에서 자주 사용하지 않는 단어의 경우 기울기가 업데이트 될 일이 많이 없지만 이럴 경우 동적으로 학습률이 변화하여 이러한 표현도 잘 학습할 수 있게 됩니다. 또한 learning rate는 하이퍼 파라미터인데, 모멘텀처럼 추가 하이퍼파라미터가 없어 쉽게 설정할 수 있습니다.
RMSProp(Root Mean Square Propagation)
\[\begin{aligned} E[g^2]_t = \rho \, E[g^2]_{t-1} + (1-\rho)\, \bigl(g_t \odot g_t\bigr) \\ \theta_{t+1} = \theta_{t} - \frac{\eta}{\sqrt{E[g^2]_t} + \epsilon}\,\odot\, g_t \end{aligned}\]- $E[g^2]_t$ :t 시점의 기울기 제곱(원소별) EMA
- $\rho$ : 감쇠율 (0.9, 0.95, 0.99 등) Adagrad는 파라미터별 업데이트를 한다는 점은 좋으나 학습이 진행됨에 따라 기울기가 계속 누적되어 learning rater가 단조감소한다. 따라서 RMSProp에서는 여기에 지수이동평균(EMA) 기법을 추가한다. 이를 통해 learning rate가 빠르게 축적되는 현상을 방지할 수 있다.
Adam(Adaptive Moment Estimation)
Adam optimizer는 위의 Momentum과 RMSProp의 개념을 합친 알고리즘이다. 이를 통해 파라미터별 동적 학습률을 부여하며 빠른 수렴과 안정성까지 추구하여 가장 사랑 받는 optimizer중 하나이다.
\[\begin{aligned} m_t = \beta_1 \, m_{t-1} + (1 - \beta_1)\, g_t\\ v_t = \beta_2 \, v_{t-1} + (1 - \beta_2)\, (g_t \odot g_t)\\ \hat{m}_t = \frac{m_t}{1 - \beta_1^t}\\ \hat{v}_t = \frac{v_t}{1 - \beta_2^t}\\ \theta_{t+1} = \theta_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} \end{aligned}\]Adam optimizer는 다음과 같이 총 5단계로 업데이트가 진행된다.
- 기울기를 위한 모멘텀 기울기 업데이트
- learning rate를 위한 모멘텀 기울기 업데이트
- 1번에 대한 bias 보정
- 2번에 대한 bias 보정
- 파라미터 업데이트
여기서 1, 2, 5단계는 위에서 다뤘던 내용이라 크게 어려움이 없지만, 3,4 단계의 bias 보정의 경우 학습 초기에 기울기가 0벡터부터 시작했을 때 실제 기울기보다 값이 적게 추정될 수 있는 문제를 해소하기 위해 스케일을 키워주는 것이다.
이 이외에도 AdamW와 같이 정규화가 재대로 적용시키기 위한 optimizer도 있지만 생략하도록 하겠다.