type: source status: seedling title: Neural Networks: Forward Pass and Backpropagation tags: [“deep-learning”, “neural-networks”, “forward-pass”, “backpropagation”, “activation-functions”, “pytorch”] created: 2026-04-26 url: https://towardsdatascience.com/neural-networks-forward-pass-and-backpropagation-be3b75a1cfcc harvested: 2026-04-26 site: Towards Data Science source_count: 1 source_type: article updated: 2026-04-26 valid_as_of: 2026-04-26

Neural Networks: Forward Pass and Backpropagation

학습 목표 매핑

SKALA 3기 Module 3 — ML/Deep Learning (Learning Objective 3-3)

  • Objective: 신경망의 순전파(Forward Pass)와 역전파(Backpropagation)를 수식으로 설명하고, PyTorch 구현으로 검증할 수 있다 (Bloom L2-L3)
  • Evaluation: 다양한 활성화 함수에 대해 미분 공식을 적용 가능 + 자동 미분 vs 수동 계산 비교 가능

순전파 (Forward Pass) — 데이터 흐름

개념

정의: 입력 데이터가 입력층에서 출력층으로 흐르며 각 층에서 선형 변환과 비선형 활성화를 거치는 과정

단계별 흐름:

입력 데이터 (x)
    ↓
선형 변환: z = W·x + b
    ↓
활성화 함수: a = σ(z)
    ↓
다음 층으로 입력 (a → x)
    ↓
... (반복)
    ↓
출력층: 최종 예측값 (ŷ)

수식

각 뉴런에서:

여기서:

  • : 층의 가중치
  • : 층의 번째 바이어스
  • : 활성화 함수
  • : 층의 번째 활성화값

역전파 (Backpropagation) — 체인 룰 기반

핵심 원리: 체인 룰 (Chain Rule)

손실함수 에 대한 가중치 의 편미분:

또는 층 표기로:

그래디언트 계산 흐름

출력층 오차 (∂L/∂a_out)
    ↓
∂L/∂z_out = (∂L/∂a) × σ'(z)
    ↓
∂L/∂w = (∂L/∂z) × a_prev (이전 층 입력)
    ↓
이전 층으로 역전파: ∂L/∂a_prev = (∂L/∂z) × W
    ↓
... (반복 - 입력층까지)

활성화 함수와 미분

1. Sigmoid

미분:

범위: → 확률 해석에 유용 문제: 깊은 네트워크에서 그래디언트 소실 (Vanishing Gradient)

2. Tanh

미분:

범위: → 중심화된 출력 장점: Sigmoid보다 그래디언트 큼 (수렴 빠름)

3. ReLU (Rectified Linear Unit)

미분:

장점:

  • 계산 빠름 (미분이 단순)
  • 깊은 네트워크에서 그래디언트 소실 완화
  • 현대 신경망의 표준

주의: Dead ReLU (음수 입력은 영구적으로 비활성화)

4. Softmax

미분 (크로스엔트로피 손실과 함께):

단일 뉴런 에 대한 편미분:

또는 행렬 형태:

범위: 합 = 1 → 다중 클래스 확률
특징: 모든 출력의 합이 1이므로 다중 클래스 분류 출력층에 최적
주의: PyTorch의 CrossEntropyLoss는 내부에서 log-softmax를 포함하므로 안정적 (수치 오버플로우 방지)

활성화 함수 비교표

함수범위미분 복잡도그래디언트특징
Sigmoid(0,1)중간소실 위험이진 분류 출력층
Tanh(-1,1)중간중간은닉층 (ReLU 전)
ReLU[0,∞)간단우수은닉층 (표준)
Softmax(0,1) 합=1복잡중간다중 클래스 출력층

PyTorch 구현 예시

Forward Pass (수동 + 자동 비교)

import torch
import torch.nn as nn
 
# 데이터 정의
x = torch.tensor(, requires_grad=True)
y_true = torch.tensor()
 
# 모델 정의
model = nn.Sequential(
    nn.Linear(3, 4),     # 입력 3 → 은닉 4
    nn.ReLU(),
    nn.Linear(4, 2)      # 은닉 4 → 출력 2
)
 
# Forward Pass
y_pred = model(x)
print(f"예측: {y_pred}")  # 형태: [1, 2]
 
# 손실
loss_fn = nn.CrossEntropyLoss()
loss = loss_fn(y_pred, torch.argmax(y_true, dim=1))
print(f"손실: {loss.item()}")

Backpropagation (자동 미분)

# Backward Pass (자동 미분)
loss.backward()
 
# 그래디언트 확인
for name, param in model.named_parameters():
    if param.grad is not None:
        print(f"{name} 그래디언트:\n{param.grad}")
 
# 경사 하강법으로 가중치 업데이트
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
optimizer.step()

수동 vs PyTorch 검증

# 수동 계산 예시 (1층만)
W1, b1 = model[0].weight, model[0].bias
 
# Forward: z = x @ W.T + b
z1_manual = x @ W1.t() + b1
a1_manual = torch.relu(z1_manual)
 
# Backward (체인 룰): ∂L/∂W = ∂L/∂a × σ'(z) × x^T
# (실제로는 다층 계산이므로 복잡함 — PyTorch 자동 미분 권장)
 
# PyTorch 그래디언트와 수동 계산 비교
print(f"PyTorch ∂L/∂W1: {W1.grad}")
# print(f"수동 계산: {gradient_manual}")  # 일치 검증

Activation Function 선택 가이드

# 은닉층: ReLU (기본값)
nn.Linear(10, 20)
nn.ReLU()
 
# 은닉층: 변형 ReLU (Dead ReLU 해결)
nn.Linear(10, 20)
nn.LeakyReLU(negative_slope=0.01)  # x < 0일 때도 약한 그래디언트
 
# 출력층: 다중 클래스 분류
nn.Linear(20, 10)  # softmax는 손실함수에 포함됨 (CrossEntropyLoss)
 
# 출력층: 이진 분류
nn.Linear(20, 1)
nn.Sigmoid()
 
# 출력층: 회귀
nn.Linear(20, 1)  # 활성화 없음

학습 설계 포인트

Cognitive Level (Bloom)

  • L1 (Remember): 활성화 함수 이름 + 범위
  • L2 (Understand): Forward/Backward 원리, 체인 룰 이해
  • L3 (Apply): PyTorch로 커스텀 활성화 함수 구현
  • L4 (Analyze): 활성화 함수 선택 근거 분석

권장 실습

  1. 그래디언트 계산: 2층 네트워크에서 수동으로 ∂L/∂W 계산
  2. 코드 검증: 수동 계산값과 PyTorch grad 비교
  3. 활성화 함수 실험: Sigmoid vs ReLU vs Tanh 비교 (수렴 속도)
  4. 그래디언트 소실 관찰: 깊은 네트워크에서 layer별 그래디언트 크기 비교

코드: 그래디언트 추적

import torch
import torch.nn as nn
 
# 모델 정의
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.Linear(4, 2)
)
 
# 입력 + 목표
x = torch.tensor()
y = torch.tensor(, dtype=torch.long)
 
# Forward + Backward
output = model(x)
loss = nn.CrossEntropyLoss()(output, y)
loss.backward()
 
# 각 층의 그래디언트 확인 (소실 여부)
for i, layer in enumerate(model):
    if isinstance(layer, nn.Linear):
        grad_norm = layer.weight.grad.norm()
        print(f"Layer {i} 그래디언트 norm: {grad_norm:.6f}")
        
# 깊은 네트워크에서: 이전 층의 그래디언트 가장 작음 (소실)

타 소스와의 연계

backpropagation-step-by-step-mazur (구체적 수치 예시) tensorflow-keras-quickstart (실제 모델 훈련 코드) decision-tree-gini-entropy-tds (트리 기반 vs 신경망 비교)

참고 자료