SGD와 Adam의 차이점은? 딥러닝 최적화 알고리즘 쉽게 이해하기

Bean·2025년 5월 22일
0

인공지능

목록 보기
39/123

딥러닝에서 SGDAdam은 대표적인 최적화 알고리즘(optimizer)입니다. 이들은 신경망의 손실(loss)을 줄이기 위해 가중치(weight)를 업데이트하는 방식에 차이가 있습니다.

1. SGD (Stochastic Gradient Descent)

Stochastic Gradient Descent, 즉 확률적 경사하강법은 가장 기본적인 최적화 알고리즘입니다.

작동 원리:

  • 한 번에 전체 데이터가 아니라 무작위로 뽑은 미니배치만 사용해서 가중치를 업데이트합니다.

  • 가중치 업데이트 식:

    θ=θηL(θ)\theta = \theta - \eta \cdot \nabla L(\theta)
    • θ\theta: 현재 가중치
    • η\eta: 학습률(learning rate)
    • L(θ)\nabla L(\theta): 손실 함수의 기울기(gradient)

장점:

  • 간단하고 메모리 사용량이 적음
  • 일부 경우, 일반화(generalization)가 잘 됨

단점:

  • 학습률을 잘 조정해야 함
  • 진동이 심함 (특히 곡면이 좁고 긴 손실 함수에서는)
  • 수렴 속도 느림

Pytorch 코드 구현:

1차 모멘텀(momentum) 포함 예시

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
  • 여기서 momentum=0.9면, 이전 기울기의 90%를 현재 업데이트에 반영해 더 부드러운 최적화가 가능해집니다.
  • SGD 기본 버전은 2차 모멘텀(분산 추적)은 포함하지 않습니다.

주요 옵션들

  • lr: 학습률 (learning rate)
  • momentum: 관성을 추가해 1차 모멘텀 효과를 줌 (기본값 0)
  • weight_decay: 가중치 감쇠 (L2 정규화)

momentum은 경사 하강법에서 이전 업데이트 방향을 일정 부분 기억해, 노이즈가 많은 경사에 흔들리지 않고 더 부드럽고 빠르게 최적값으로 가도록 도와주는 기법이에요. 쉽게 말해, ‘관성’을 이용해 움직임을 안정시키는 역할을 합니다.

weight_decay는 모델 파라미터 값이 너무 커지는 걸 막기 위해 가중치에 일정 비율의 벌점을 주는 방법이에요. 즉, 과적합(overfitting)을 줄이고 모델을 더 일반화시키기 위해 가중치를 작게 유지하는 정규화(regularization) 기법 중 하나입니다. 보통 L2 정규화와 같다고 생각하면 됩니다.


2. Adam (Adaptive Moment Estimation)

Adam모멘텀(Momentum)RMSProp의 장점을 결합한 최적화 알고리즘입니다.
즉, Adam의 핵심은 손실 함수의 gradient를 기반으로, 그 평균과 분산을 추적하여 가중치를 업데이트하는 것입니다.

장점:

  • 학습률을 자동 조정하기 때문에 튜닝이 쉬움
  • 수렴 속도 빠름
  • 잡음(noise)이나 희소 데이터에 강함

단점:

  • 메모리 사용량이 많음
  • 일반화 성능이 떨어질 수 있음 (때로는 SGD보다 test 성능이 나쁨)
  • 최근 논문에서는 장기적으로 SGD보다 수렴이 불안정할 수 있음이라는 지적도 있음

2.1. 손실 함수의 gradient 계산

Adam에서도 시작은 손실 함수 L(θ)L(\theta)에 대한 gradient를 계산하는 것부터입니다.

gt=θL(θt)g_t = \nabla_\theta L(\theta_t)
  • θt\theta_t: 현재 시점의 파라미터 (예: weight)
  • L(θt)L(\theta_t): 현재 파라미터에 대한 손실
  • gtg_t: 그 시점의 기울기 (gradient) — 즉, 손실 함수가 가장 많이 줄어드는 방향

2.2. 모멘텀 추정 (1차 모멘트: 평균 기울기)

이제 Adam은 단순히 gtg_t를 사용하는 것이 아니라, 이전까지의 평균 기울기를 함께 고려합니다. 이를 1차 모멘트 mtm_t라고 합니다:

mt=β1mt1+(1β1)gtm_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t
  • β1\beta_1: 보통 0.9로 설정, 과거 평균을 얼마나 반영할지 결정
  • 이 식은 지금까지의 gradient 평균을 지수적으로 가중합합니다 (지수이동평균)

2.3. 스케일 추정 (2차 모멘트: 기울기의 분산)

Adam은 또 하나, 기울기의 제곱 평균도 사용합니다. 이를 **2차 모멘트 vtv_t**라고 합니다:

vt=β2vt1+(1β2)gt2v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2
  • β2\beta_2: 보통 0.999로 설정
  • 기울기가 크고 변동이 큰 방향은 업데이트를 줄이기 위해 사용됨

2.4. 바이어스 보정 (초기 0값 보정)

초기에는 mtm_t, vtv_t가 0에서 시작하기 때문에 편향(bias)이 생깁니다. 이를 보정합니다:

m^t=mt1β1t,v^t=vt1β2t\hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t}

2.5. 최종 가중치 업데이트

이제 보정된 평균과 분산을 가지고 파라미터를 업데이트합니다:

θt+1=θtηm^tv^t+ϵ\theta_{t+1} = \theta_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}
  • η\eta: 학습률 (learning rate)
  • ϵ\epsilon: 수치 안정성을 위한 작은 값 (예: 10810^{-8})
  • 이 식은 방향은 평균 기울기 m^t\hat{m}_t를 따르되, 변동성이 큰 축(분산이 큰 방향)은 업데이트를 줄이고, 안정적인 방향은 더 크게 업데이트합니다.

2.6. 전체 요약

  1. 손실 함수 L(θt)L(\theta_t)로부터 gradient gt=θL(θt)g_t = \nabla_\theta L(\theta_t) 계산
  2. gtg_t로부터 평균과 분산 추정
  3. 이를 바탕으로 학습률을 좌표별로 적응적으로 조절
  4. 가중치 업데이트

직관적으로 요약 하자면 Adam은

  • 손실 함수에서 나온 기울기들을 추적하면서
  • 얼마나 일관되게 같은 방향으로 손실이 줄어들고 있는지(평균),
  • 얼마나 요동치는지(분산)를 계산해서
  • 각 파라미터마다 맞춤형 학습률을 적용하는 알고리즘입니다.

2.7 Pytorch 코드 구현

optimizer = optim.Adam(
    model.parameters(),
    lr=0.01,
    betas=(0.9, 0.999),  # (1차 모멘텀 decay, 2차 모멘텀 decay)
    eps=1e-8             # 수치 안정성용 작은 값
)

3. 정리: 비교표

항목SGDAdam
학습률고정 (수동 설정)자동 조정
속도느림빠름
구현 복잡도단순복잡
일반화 성능종종 더 좋음가끔 덜 좋음
튜닝 필요성높음낮음
메모리 사용적음많음
진동 억제없음 (진동 심함)있음 (모멘텀 사용)

3.1. 어떤 걸 써야 할까?

  • 빠르게 수렴하고 싶고 복잡한 튜닝을 피하고 싶다면: Adam
  • 일반화 성능을 더 중요하게 생각하거나, 최종 test 성능을 높이고 싶다면: SGD (특히 Momentum과 함께 사용)

profile
AI developer

0개의 댓글