본문 바로가기
C.W.K.
Stream
Lesson 04 of 08 · published

학습률 조정기와 워밍업

~12 min · scheduler, lr, warmup, cosine

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

학습률을 일정하게 유지하는 건 거의 최선이 아니야

학습률 감쇠는 높은 값으로 시작해 점차 낮추는 방식이야. 딥러닝에서 적은 노력으로 얻을 수 있는 가장 확실한 개선 중 하나지. PyTorch에는 여러 학습률 조정기가 있지만 다음 세 가지를 자주 사용해:

  • StepLR: step_size 에포크마다 학습률에 gamma를 곱해. 간단하고 예측하기 쉬운 오래된 기본값이야.
  • CosineAnnealingLR: T_max 단계 동안 초기 학습률에서 eta_min까지 부드러운 코사인 곡선으로 낮춰. 현대적인 Transformer와 비전 학습에서 선호해.
  • OneCycleLR: 한 주기 안에서 워밍업한 뒤 감쇠해. Leslie Smith의 1cycle 정책을 구현하며 빠른 학습에 강해.

워밍업은 왜, 어떻게 쓸까?

현대적인 Transformer 학습은 거의 항상 수백 단계의 워밍업으로 시작해. 학습률을 0에서 목표값까지 선형으로 올린 뒤 감쇠하는 방식이야. 워밍업이 없으면 무작위로 초기화된 매개변수와 큰 손실이 거친 기울기를 만들고, 옵티마이저가 첫 단계부터 파괴적인 갱신을 할 수 있어. 워밍업을 쓰면 손실 지형의 안정된 구간으로 부드럽게 진입해.

워밍업과 코사인 감쇠를 함께 쓰려면 SequentialLR로 두 조정기를 연결하거나 사용자 정의 LambdaLR를 만들 수 있어. 직접 구현하고 싶지 않다면 Hugging Face의 get_cosine_schedule_with_warmup이 좋은 기준 구현이야.

알맞은 단위에서 갱신해

  • 에포크 단위 조정기(StepLR, 에포크 단위 CosineAnnealingLR)는 에포크마다 한 번 scheduler.step()을 호출해.
  • 단계 단위 조정기(OneCycleLR, 단계 단위 LambdaLR)는 배치마다 한 번 scheduler.step()을 호출해.

Code

StepLR와 CosineAnnealingLR·python
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR, CosineAnnealingLR

opt = optim.AdamW([torch.zeros(1, requires_grad=True)], lr=1e-3)

# StepLR: 1e-3 → (epoch 30) → 1e-4 → (epoch 60) → 1e-5
step_sched = StepLR(opt, step_size=30, gamma=0.1)

# CosineAnnealingLR: smooth decay from 1e-3 to 1e-6 over 100 epochs
cos_sched = CosineAnnealingLR(opt, T_max=100, eta_min=1e-6)

# Per-EPOCH schedulers — call once per epoch
for epoch in range(num_epochs):
    train_one_epoch(...)
    cos_sched.step()
OneCycleLR: 빠른 학습 선호 방식·python
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import OneCycleLR

steps_per_epoch = len(train_loader)
opt = optim.AdamW(model.parameters(), lr=1e-4)

scheduler = OneCycleLR(
    opt,
    max_lr=1e-3,                       # peak LR
    steps_per_epoch=steps_per_epoch,
    epochs=10,
    pct_start=0.1,                     # warmup is the first 10% of training
    anneal_strategy='cos',
)

# Per-STEP scheduler — call inside the batch loop
for epoch in range(10):
    for x, y in train_loader:
        opt.zero_grad()
        loss = criterion(model(x), y)
        loss.backward()
        opt.step()
        scheduler.step()                # per batch
워밍업 + 코사인: Transformer 구성법·python
import math
import torch.optim as optim
from torch.optim.lr_scheduler import LambdaLR

opt = optim.AdamW(model.parameters(), lr=1e-4)
warmup_steps = 1000
total_steps = 50_000

def lr_lambda(step):
    if step < warmup_steps:
        return step / warmup_steps
    progress = (step - warmup_steps) / max(1, total_steps - warmup_steps)
    return 0.5 * (1.0 + math.cos(math.pi * progress))

scheduler = LambdaLR(opt, lr_lambda)

# Per-step
for epoch in range(num_epochs):
    for batch in train_loader:
        opt.zero_grad()
        loss = criterion(model(batch), target)
        loss.backward()
        opt.step()
        scheduler.step()

External links

Exercise

같은 모델과 데이터셋으로 5에포크씩 네 번 학습해 봐. (a) 고정 학습률, (b) StepLR 감쇠, (c) CosineAnnealingLR, (d) 워밍업 뒤 코사인 감쇠를 사용해. 네 손실 곡선을 같은 축에 그리고 비교해. 보통 워밍업과 코사인을 함께 쓴 버전의 검증 손실이 가장 좋을 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.