본문 바로가기
HRDI_AI/머신러닝_딥러닝 핵심 기술과 실무 중심 생성형 AI 프로젝트

AdamW란 무엇인가, 왜 쓰는가, 수식/직관/실전 세팅까지

by Toddler_AD 2025. 11. 27.

1. Adam 복습: 모멘텀 + RMSProp의 하이브리드

Adam은 딥러닝에서 가장 많이 쓰는 옵티마이저 중 하나입니다.
이름 자체가 Adaptive Moment Estimation의 줄임말이고,
아이디어는 간단히 말하면:

1차 모멘트(평균) + 2차 모멘트(분산)를 추적해서,
파라미터마다 “자기만의 학습률”을 갖게 하자.

1-1. 기본 SGD와의 차이

SGD는 아주 단순합니다:

 

  • θ : 현재 파라미터
  • gt : 현재 step의 gradient
  • η : 학습률(learning rate)

여기선 모든 파라미터가 같은 학습률을 쓰죠.

1-2. Adam의 업데이트 규칙 (개념)

Adam은 각 파라미터에 대해:

  • 1차 모멘트(평균) mtm_t: gradient의 이동 평균
  • 2차 모멘트(분산) vtv_t: gradient 제곱의 이동 평균

을 관리합니다.

여기서 β1,β2\beta_1, \beta_2모멘텀 계수입니다 (보통 0.9, 0.999).

초기 단계의 편향을 보정하기 위해:

그리고 최종 업데이트는:

여기서:

  • 분모가 크면(변동성이 크면) → step이 작아지고
  • 분모가 작으면(변동성이 작으면) → step이 커지는 구조라,

파라미터마다 데이터에 맞게 “적응적인 학습률”이 생기는 효과가 있습니다.


2. AdamW가 나온 이유: Weight Decay를 제대로 쓰고 싶다

딥러닝에서 자주 쓰는 정규화 기법 중 하나가 Weight Decay (가중치 감쇠) 입니다.
보통 L2 정규화와 같이 설명되죠.

2-1. SGD에서의 Weight Decay (L2 정규화)

SGD + L2 정규화를 쓰면 loss에 다음 항이 더해집니다.

미분하면:

그래서 업데이트는:

이를 정리하면:

즉,

  1. gradient 방향으로 업데이트하면서
  2. 동시에 파라미터 자체를 일정 비율로 줄이는(감쇠시키는) 효과가 있습니다.

2-2. 문제: Adam에 L2를 그대로 넣으면 꼬인다

Adam에 위와 같은 식으로 L2 정규화를 넣으면,

이거 전체를 Adam의 분자/분모에 넣어버립니다:

이렇게 되면 “정규화 효과(Weight Decay)”까지 adaptive scaling의 영향을 받습니다.

  • 어떤 파라미터는 과도하게 많이 decay되고,
  • 어떤 파라미터는 거의 decay가 안 되는 식으로 일관성이 깨집니다.

논문 Decoupled Weight Decay Regularization (Loshchilov & Hutter, 2017)에서 이 문제를 지적하고,
“Weight Decay는 gradient와 분리(decouple)해서 처리해야 한다” 라고 주장합니다.


3. Adam vs AdamW 수식 비교

AdamW의 핵심 아이디어는 딱 하나입니다.

“Weight Decay는 gradient에 섞지 말고,
업데이트 마지막에 파라미터에서 직접 빼자.”

3-1. Adam (L2를 gradient에 섞은 경우)

gt 전체를 Adam에 넣습니다.

3-2. AdamW (Weight Decay를 분리한 경우)

AdamW에서는:우선 순수 gradient만 써서 Adam step을 계산합니다.



그 다음에 weight decay 항을 별도로 적용합니다.

PyTorch 구현에서는 보통 이렇게 보입니다 (개념 코드):

# 1) Adam update (gradient 기반)
p.data.addcdiv_(exp_avg, denom, value=-step_size)

# 2) Weight Decay 따로 적용
if weight_decay != 0:
    p.data.add_(p.data, alpha=-lr * weight_decay)
 

여기서 중요한 점:

  • gradient 쪽에는 weight_decay를 섞지 않는다.
  • weight decay는 파라미터에 직접 -lr * wd 만큼 곱해주는 형태로 “분리”된다.

그래서 이름이 AdamW (Adam + Weight decay decoupled) 입니다.


4. AdamW 하이퍼파라미터 해설

로그에 찍힌 값 기준으로:

lr: 0.0
betas: (0.9, 0.999)
eps: 1e-08
weight_decay: 0.0

4-1. learning rate (lr)

  • 가장 중요한 파라미터.
  • T5, BERT 같은 Transformer 계열에서는
    • 보통 1e-5 ~ 5e-4 사이에서 많이 튜닝.
  • 우리 코드에서는 learning_rate=5e-4로 설정했으니,
    • 로그에 initial_lr: 0.0005로 찍히는 것이 정상입니다.
    • lr: 0.0은 아직 스케줄러 초기화 직후, 첫 step에서 설정될 값이 들어가기 전 상태라 그렇습니다 (train 돌면 바뀜).

4-2. betas = (β₁, β₂)

  • beta1 = 0.9
    1차 모멘트(gradient 평균)의 관성.
    • 1에 가까울수록 “이전 gradient를 오래 기억”합니다.
    • 너무 크면 반응이 느려지고, 너무 작으면 값이 요동침.
  • beta2 = 0.999
    2차 모멘트(gradient 제곱 평균)의 관성.
    • 보통 0.999~0.9999 정도를 사용.
  • 대부분의 NLP/비전 작업에서 기본값 (0.9, 0.999)를 그대로 쓰는 경우가 많습니다.

4-3. eps

  • 분모가 0에 가까워지는 것을 방지하기 위한 아주 작은 값:

  • eps=1e-8 정도가 일반적인 기본값.
  • 너무 크면 학습률이 줄어들고, 너무 작으면 수치적으로 불안정해질 수 있음.
  • 실무에서는 거의 건드리지 않고 default 사용.

4-4. weight_decay

  • 파라미터를 0쪽으로 끌어당기는 힘의 크기.
  • 일반적으로:
    • 언어 모델/Transformer: 0.01 또는 0.001 등
    • LayerNorm, Bias 등에는 보통 weight decay를 꺼둡니다 (파라미터 그룹으로 분리).
  • 지금 로그에 weight_decay: 0.0으로 나온 것은:
    • 우리가 Seq2SeqTrainingArguments에서 weight_decay를 지정하지 않았거나,
    • HF 쪽이 특정 파라미터 그룹에만 weight_decay=0.0을 적용한 것일 수 있습니다.
    • (일반적으로는 weight_decay=0.01 정도를 많이 사용합니다.)

5. AdamW의 장점과 주의점

5-1. 장점

  1. Weight Decay가 정석적으로 작동
    • Adam에 L2 정규화를 그대로 넣었을 때의 왜곡 문제를 해결.
    • 논문에서도 AdamW가 더 나은 generalization(일반화 성능)을 보였다고 보고됩니다.
  2. Transformer / NLP에서 사실상 표준
    • BERT, GPT, T5, ViT 등 대부분의 최신 모델들이 AdamW 또는 변형을 사용.
    • Hugging Face의 Trainer 기본값이 AdamW인 것도 이 때문입니다.
  3. 파라미터 그룹별 세밀한 제어
    • 예:
      • 가중치(weight)에는 weight_decay=0.01
      • bias와 LayerNorm에는 weight_decay=0.0
    • 이렇게 그룹을 나누어 정규화 강도를 조절하기 쉽습니다.

5-2. 주의점

  1. learning rate가 여전히 핵심
    • 아무리 AdamW여도 LR이 너무 크면:
      • gradient 폭발 → grad_norm 폭주 → NaN
    • 특히 fp16로 갈 때는 더 민감해집니다.
  2. weight_decay를 과하게 주면
    • 파라미터가 과도하게 0으로 끌려가고,
    • 표현력이 떨어져 underfitting이 생길 수 있습니다.
  3. warmup과 함께 쓰는 것이 일반적
    • Transformer 계열은 보통:
      • 초기에 LR을 천천히 올려주는 warmup
      • 이후에는 점점 줄이는 scheduler
    • AdamW + warmup은 거의 정석 조합입니다.

6. 우리 로그와 연결해서 읽어보기

before create: None
after create: AdamW (
Parameter Group 0
    amsgrad: False
    betas: (0.9, 0.999)
    capturable: False
    decoupled_weight_decay: True
    differentiable: False
    eps: 1e-08
    foreach: None
    fused: True
    initial_lr: 0.0005
    lr: 0.0
    maximize: False
    weight_decay: 0.0

Parameter Group 1
    amsgrad: False
    betas: (0.9, 0.999)
    capturable: False
    decoupled_weight_decay: True
    differentiable: False
    eps: 1e-08
    foreach: None
    fused: True
...
lr: 0.0
betas: (0.9, 0.999)
eps: 1e-08
weight_decay: 0.0

이걸 해석하면:

  • 옵티마이저 종류: AdamW
    → Hugging Face 기본값 그대로, “Decoupled Weight Decay Regularization”이 적용된 Adam.
  • betas: (0.9, 0.999)
    → gradient 평균과 분산을 추적하는 모멘텀 계수. 기본값.
  • eps: 1e-08
    → 분모 안정화용 작은 값. 기본값.
  • initial_lr: 0.0005
    → 우리가 Seq2SeqTrainingArguments에서 준 learning_rate=5e-4.
  • lr: 0.0
    → 아직 학습이 시작되기 전, 스케줄러가 한 번도 step을 업데이트하지 않은 상태에서 찍힌 값.
    실제 train이 돌면 warmup/scheduler에 따라 이 값이 바뀌며,
    그 순간의 실질적인 learning rate로 사용됩니다.
  • weight_decay: 0.0
    → 현재 이 파라미터 그룹에는 weight decay가 적용되지 않는 상태.
    필요하다면 training_args에서 weight_decay=0.01 정도를 주고,
    HF의 default 파라미터 그룹 분할 로직을 활용할 수 있습니다.

마무리: 

AdamW는 Adam 옵티마이저에서 Weight Decay(가중치 감쇠)를
gradient에서 분리(decouple)해서 적용한 버전이다.

순수 gradient에 대해서는 Adam처럼 모멘텀과 적응적 학습률을 사용하고,
Weight Decay는 파라미터에 따로 곱해 주기 때문에
정규화 효과가 왜곡되지 않고, 특히 Transformer 계열 모델에서
더 안정적인 학습과 더 나은 일반화 성능을 보여준다.
그래서 Hugging Face Trainer의 기본 옵티마이저가 바로 AdamW다.