C.W.K.
Stream
Lesson 04 of 09 · published

Gradient Descent 와 Mini-Batch

~22 min · sgd, minibatch, noise

Level 0Curious
0 XP0/73 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Gradient descent 의 3 가지 맛

Batch (full) gradient descent — 전체 dataset 에서 gradient 계산, step 한 번, 반복. 부드럽지만 비싸 (epoch 당 gradient 1 개) 고 memory 안 들어가는 dataset 엔 불가능.

SGD — 한 번에 한 example gradient 계산, step, 반복. Noisy, 빠르고, GPU 효율적으로 쓰기 어려움.

Mini-batch SGD — 작은 batch (16, 32, 256, ...) 에서 gradient 계산, step. 일부 local minimum 탈출할 만큼 noisy, stable 할 만큼 부드럽고, GPU 쓸 만큼 batch. 모두가 실제 하는 거야.

왜 noise 가 generalization 에 도움

Mini-batch sampling 의 randomness 가 implicit regularizer 로 작용. Optimizer 가 true gradient 의 noisy 추정 따라가서, sharp local minimum 에 너무 공격적으로 settle 안 함 — sharp minimum 이 flat minimum 보다 generalize 나빠. 그래서 mini-batch SGD 가 자주 더 부드러운 full-batch update 보다 generalize 잘함, training loss 더 높이 converge 해도.

팁: 더 큰 batch 가 덜 noisy 한 gradient 주고 살짝 더 큰 learning rate 쓸 수 있게 해 (rule of thumb: linear scaling). 하지만 어느 점 넘어서면 더 큰 batch 가 wall-clock time 도움 안 되고 generalization 도 해칠 수 있어. 둘 다 tune.

Modern optimizer-aware mini-batch

Modern optimizer (Adam, AdamW) 가 parameter 당 gradient mean 과 variance 의 running estimate 유지해서 batch size 선택이 stable training 에 덜 critical. 여전히 hardware (memory, throughput) 와 generalization (작은 batch 가 자주 regularize 잘함) 위해 tune 하지만, 더 이상 wild gradient noise 통과해 optimizer baby-sit 안 해도 돼.

원칙: Stable training 주고 VRAM 에 들어가는 가장 큰 batch 골라. 그 다음 model 작동하면 다시 봐 — 같은 wall-clock 비용에 작은 batch 가 더 잘 train 하기도 해.

Code

Batched SGD step in PyTorch·python
import torch
from torch import nn, optim
from torch.utils.data import DataLoader, TensorDataset

X = torch.randn(10000, 20)
y = torch.randint(0, 5, (10000,))
loader = DataLoader(TensorDataset(X, y), batch_size=128, shuffle=True)

model = nn.Sequential(nn.Linear(20, 64), nn.ReLU(), nn.Linear(64, 5))
opt   = optim.SGD(model.parameters(), lr=0.05)
loss_fn = nn.CrossEntropyLoss()

for epoch in range(3):
    running = 0.0
    for xb, yb in loader:
        opt.zero_grad()
        logits = model(xb)
        loss = loss_fn(logits, yb)
        loss.backward()
        opt.step()
        running += loss.item() * xb.size(0)
    print(f"epoch {epoch} avg loss: {running / len(loader.dataset):.4f}")

External links

Exercise

같은 model 을 batch size 16, 64, 512 로 train. Steps-per-epoch 일정 유지. 최종 validation accuracy 그려. 어느 게 wall-clock 가장 빠르고 어느 게 가장 잘 generalize?

Progress

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

댓글 0

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

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