🤖 AI/ML

백프로파게이션

Backpropagation

역전파. 출력 오차를 역방향으로 전파하며 가중치를 업데이트하는 신경망 학습 알고리즘.

📖 상세 설명

백프로파게이션(Backpropagation, 역전파)은 신경망 학습의 핵심 알고리즘으로, 출력 오차를 네트워크의 역방향으로 전파하여 각 가중치의 기울기(gradient)를 계산합니다. 이 기울기를 사용해 가중치를 업데이트함으로써 손실을 최소화하는 방향으로 모델을 학습시킵니다.

1986년 Rumelhart, Hinton, Williams가 발표한 이 알고리즘은 연쇄 법칙(Chain Rule)을 기반으로 합니다. 복합 함수의 미분을 각 구성 함수의 미분 곱으로 분해하는 원리를 활용하여, 수백 개 레이어를 가진 깊은 네트워크에서도 효율적으로 기울기를 계산할 수 있습니다.

계산 과정은 두 단계로 나뉩니다. Forward Pass에서는 입력 데이터가 레이어를 통과하며 예측값을 생성하고, Backward Pass에서는 손실 함수로부터 시작해 각 파라미터에 대한 기울기를 역방향으로 계산합니다. PyTorch의 autograd, TensorFlow의 GradientTape가 이 과정을 자동화합니다.

2024년 현재 백프로파게이션은 GPT-4, Claude, Gemini 등 수천억 파라미터 모델 학습의 기반입니다. Gradient Checkpointing, Mixed Precision Training 등의 최적화 기법과 결합되어 대규모 모델의 효율적인 학습을 가능하게 합니다.

💻 코드 예제

# PyTorch에서 백프로파게이션 이해하기
import torch
import torch.nn as nn

# 간단한 신경망 정의
class SimpleNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer1 = nn.Linear(10, 20)
        self.relu = nn.ReLU()
        self.layer2 = nn.Linear(20, 1)

    def forward(self, x):
        x = self.layer1(x)
        x = self.relu(x)
        x = self.layer2(x)
        return x

# 모델, 손실 함수, 옵티마이저 설정
model = SimpleNetwork()
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 데이터 준비
x = torch.randn(32, 10)  # 배치 크기 32, 특성 10개
y_true = torch.randn(32, 1)

# === Forward Pass ===
# 입력이 네트워크를 통과하며 예측값 생성
y_pred = model(x)
loss = criterion(y_pred, y_true)
print(f"Loss: {loss.item():.4f}")

# === Backward Pass (역전파) ===
# 손실로부터 각 파라미터의 기울기 계산
optimizer.zero_grad()  # 기존 기울기 초기화 (필수!)
loss.backward()        # 역전파 수행 - 모든 .grad 속성 업데이트

# 기울기 확인
print(f"layer1 weight gradient shape: {model.layer1.weight.grad.shape}")
print(f"layer1 weight gradient mean: {model.layer1.weight.grad.mean():.6f}")

# === 가중치 업데이트 ===
optimizer.step()  # w = w - lr * gradient

# 수동으로 역전파 이해하기 (교육용)
def manual_backprop_demo():
    """
    연쇄 법칙 시각화: dL/dw = dL/dy * dy/dz * dz/dw
    """
    w = torch.tensor([2.0], requires_grad=True)
    x = torch.tensor([3.0])

    # Forward: z = w*x, y = z^2, L = y
    z = w * x           # z = 6
    y = z ** 2          # y = 36
    L = y               # L = 36

    # Backward (연쇄 법칙)
    L.backward()

    # dL/dw = dL/dy * dy/dz * dz/dw
    #       = 1 * 2z * x = 2 * 6 * 3 = 36
    print(f"자동 기울기: {w.grad.item()}")
    print(f"수동 계산: {2 * (w.item() * x.item()) * x.item()}")

manual_backprop_demo()

🗣️ 실무에서 이렇게 말하세요

💬 회의에서
"모델 학습 중 Gradient가 NaN이 되는 문제가 있습니다. 역전파 과정에서 기울기 폭발이 발생한 것 같은데, Gradient Clipping을 적용하거나 학습률을 낮춰봐야 할 것 같습니다. max_grad_norm=1.0으로 설정해보겠습니다."
💬 면접에서
"백프로파게이션은 연쇄 법칙을 사용해 손실 함수의 기울기를 각 파라미터에 대해 계산합니다. Forward pass에서 중간 활성화 값을 저장하고, Backward pass에서 이를 사용해 역방향으로 기울기를 전파합니다. 딥러닝 프레임워크의 autograd가 이를 자동화합니다."
💬 기술 토론에서
"대형 모델에서는 역전파 시 메모리가 부족해지는데요, Gradient Checkpointing을 쓰면 중간 활성화 값을 저장하지 않고 필요할 때 다시 계산해서 메모리를 크게 절약할 수 있어요. 계산량은 30% 정도 증가하지만 메모리는 절반 이하로 줄어듭니다."

⚠️ 흔한 실수 & 주의사항

optimizer.zero_grad() 누락

PyTorch에서 zero_grad()를 호출하지 않으면 기울기가 누적됩니다. 의도적으로 기울기 누적을 사용하는 경우가 아니라면, 매 반복마다 반드시 호출해야 합니다. 이를 빠뜨리면 학습이 발산합니다.

Vanishing/Exploding Gradient 무시

깊은 네트워크에서 기울기가 0에 수렴(vanishing)하거나 무한대로 발산(exploding)할 수 있습니다. ReLU 활성화 함수, BatchNorm, Residual Connection을 사용하지 않으면 50개 이상의 레이어에서 학습이 실패합니다.

올바른 방법: 기울기 모니터링 + 안정화 기법

TensorBoard로 기울기 분포를 모니터링하고, Gradient Clipping (max_norm=1.0), 적절한 가중치 초기화 (He/Xavier), 잔차 연결(ResNet)을 적용하세요. 학습률 스케줄러도 안정적인 학습에 중요합니다.

🔗 관련 용어

📚 더 배우기