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

학습 루프: Forward, Backward, Step

~8 min · training-loop, optimizer, epoch

Level 0수학 초심자
0 XP0/59 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

3-step 춤

모던 모델 학습 = 같은 루프, 수백만 번 반복:

  1. Forward pass: 배치 망 통과, loss 계산.
  2. Backward pass: backprop 이 모든 파라미터 gradient 계산.
  3. Step: 옵티마이저가 gradient 사용해 파라미터 갱신.

Loss 안 떨어질 때까지 반복. 끝. 세상 모든 신경망이 학습되는 법.

표준 PyTorch idiom

딥러닝에서 이 패턴 수천 번 작성:

for batch in dataloader:
    optimizer.zero_grad()      # 옛 gradient 클리어
    pred = model(batch.x)      # forward pass
    loss = loss_fn(pred, batch.y)
    loss.backward()            # backward pass — backprop 여기 실행
    optimizer.step()           # 파라미터 갱신

다섯 줄. 학습 루프 전체. 이 리듬 외워; 딥러닝의 모든 fancy 한 게 이 위에.

흔한 옵티마이저

  • SGD — vanilla. .
  • SGD + momentum — 과거 gradient 누적. 더 부드러운 trajectory.
  • Adam — 파라미터별 적응 학습률. 모던 default. 튜닝 거의 없이 작동.
  • AdamW — Adam + 적절한 weight decay. 큰 transformer 모델 best default.
Forward → Backward → Step. 유니버설 학습 루프. 모든 fancy 한 게 이 세 step 의 wrapping/extending.

Code

완전한 학습 루프·python
import torch
import torch.nn as nn
import torch.optim as optim

# 작은 데이터셋
X = torch.randn(100, 4)
y = (X.sum(dim=1) > 0).long()       # 이진 분류

model = nn.Sequential(nn.Linear(4, 16), nn.ReLU(), nn.Linear(16, 2))
optimizer = optim.Adam(model.parameters(), lr=0.01)
loss_fn = nn.CrossEntropyLoss()

# 5줄 학습 루프
for epoch in range(50):
    optimizer.zero_grad()
    pred = model(X)
    loss = loss_fn(pred, y)
    loss.backward()
    optimizer.step()
    if epoch % 10 == 0:
        print(f"epoch {epoch}: loss = {loss.item():.4f}")
MLX flavor — value_and_grad + optimizer.update + mx.eval·python
import mlx.core as mx
import mlx.nn as nn
import mlx.optimizers as optim

# 작은 데이터셋 — PyTorch 버전과 같은 모양
mx.random.seed(0)
X = mx.random.normal(shape=(100, 4))
y = (X.sum(axis=1) > 0).astype(mx.int32)

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(4, 16)
        self.fc2 = nn.Linear(16, 2)
    def __call__(self, x):
        return self.fc2(nn.relu(self.fc1(x)))

net = Net()
optimizer = optim.Adam(learning_rate=0.01)

# 함수형 loss — 모델을 인자로 받음
def loss_fn(model, X, y):
    return nn.losses.cross_entropy(model(X), y, reduction="mean")

# nn.value_and_grad 가 loss_fn 을 (loss, grads) 반환 함수로 wrap
loss_and_grad = nn.value_and_grad(net, loss_fn)

for epoch in range(50):
    loss, grads = loss_and_grad(net, X, y)
    optimizer.update(net, grads)
    mx.eval(net.parameters(), optimizer.state)   # lazy op 강제 materialize
    if epoch % 10 == 0:
        print(f"epoch {epoch}: loss = {loss.item():.4f}")

External links

Exercise

위 학습 루프 실행. lr=0.01lr=10.0 (너무 높음), lr=0.0001 (너무 낮음) 으로 변경. 발산 vs 기어감 관찰. 학습률 = 가장 중요한 하이퍼파라미터.
Hint
높은 lr: loss 폭발 또는 진동. 낮은 lr: loss 거의 안 움직임. Adam 의 default 0.001-0.01 범위가 보통 좋은 시작점.

Progress

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

댓글 0

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

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