BioPlayground

🧬
목록으로

역전파는 어떻게 작동하는가 — 신호 캐스케이드의 역방향 원인 추적

3,362만 개 파라미터의 편미분을 어떻게 효율적으로 계산하는가. 세포 신호 캐스케이드 역추적으로 이해하는 역전파와 연쇄 법칙, 그리고 PyTorch autograd의 원리.

입문
|
20
|
검증 완료 (2026-07)
진행률0/15 (0%)

역전파는 어떻게 작동하는가 — 신호 캐스케이드의 역방향 원인 추적

이 토픽을 마치면

편 #3에서 "기울기가 어떻게 계산되는지는 나중에 다룬다"고 미뤘던 질문의 답을 얻습니다. 3,362만 개의 파라미터 각각에 대한 편미분을 실용적인 시간 안에 어떻게 계산하는가. 여기서 등장하는 알고리즘이 역전파(backpropagation) 이고, 그 밑에 깔린 수학이 연쇄 법칙(chain rule) 입니다.

이 편은 편 #3의 짝을 이룹니다. 편 #3이 "얼마나 이동할까"를 다뤘다면 이 편은 "어느 방향인지 어떻게 아는가"를 다룹니다. 편 #5 트랜스포머와 편 #12 PyTorch 실전이 이 편을 밑판으로 씁니다.


순진한 방법의 처참한 실패

편 #3에서 우리는 파라미터 θ_i의 편미분을 이렇게 정의했습니다.

text
∂L/∂θ_i = lim_{ε → 0} [L(θ_1, ..., θ_i + ε, ..., θ_P) - L(θ)] / ε

교과서적으로 이걸 그대로 실행해봅시다. 파라미터를 하나씩 잡고, ε만큼 살짝 늘려서 손실이 얼마나 변하는지 관찰하고, ε로 나눠 편미분을 얻습니다. 이걸 유한 차분법(finite difference) 이라 합니다.

문제: 파라미터가 3,362만 개면, 편미분 하나를 얻기 위해 신경망을 완전히 한 번 순전파(전방 전파)해야 합니다. 3,362만 개 편미분을 다 얻으려면 신경망을 3,362만 번 순전파해야 합니다.

병리학 신경망 예시로 규모 감을 잡읍시다. 한 번의 순전파가 GPU 위에서 1밀리초라고 하면, 한 스텝의 기울기 계산에만 3,362만 밀리초 = 약 9.3시간. 그런데 훈련은 이런 스텝을 수십만~수백만 번 반복해야 합니다. 이 방식으로는 훈련이 수백 년 걸립니다.

그렇다고 유한 차분법이 완전히 쓸모없는 건 아닙니다. 나중에 이야기하겠지만 역전파 구현의 검증 도구로 쓰입니다. "우리가 짠 역전파 코드가 실제로 정확한가?"를 확인할 때 유한 차분법으로 몇 개 파라미터의 편미분을 참값처럼 계산해 비교합니다. 이걸 gradient check 라 하며, 신경망 라이브러리 개발자가 필수로 하는 검증입니다.

훈련 자체에는 훨씬 빠른 방법이 필요합니다. 그 방법이 역전파.


신호 캐스케이드의 이상 반응 — 원인은 어디에 있나

역전파의 직관을 잡기 위해 실험실 시나리오 하나를 봅시다.

여러분이 세포 신호 전달 실험을 하고 있다고 해봅시다. 세포에 특정 리간드를 처리하면 하류에서 유전자 발현이 유도되어야 합니다. 신호 경로는 대략 이렇습니다.

text
리간드 (외부 자극)
   ↓
수용체 활성화
   ↓
2차 신호 (예: cAMP)
   ↓
Kinase 캐스케이드 (RAF → MEK → ERK 등)
   ↓
전사인자 인산화
   ↓
유전자 발현 유도 (측정 결과)

여러분이 리간드를 처리하고 하류 유전자 발현을 측정했더니 예상보다 50% 낮게 나왔다고 합시다. 여러분의 질문. "어느 단계에서 문제가 생겼는가?"

수용체가 덜 활성화된 것일 수도, 2차 신호가 덜 만들어졌을 수도, 특정 kinase의 활성이 낮을 수도, 전사인자의 인산화가 안 됐을 수도 있습니다. 하류의 오차 50%가 각 상류 노드에 얼마씩 "책임"이 있는지 정량화해야 원인을 찾을 수 있습니다.

여러분이 이 문제를 어떻게 접근할까요. 각 단계를 정량적으로 측정해 상하류 관계로 되짚어 갑니다.

  • 유전자 발현이 50% 낮음 → 전사인자 인산화 수준은 어땠나? 30% 낮음 → 전사인자 단계에서 30% 기여, 그 아래(전사인자→발현) 매핑 단계에서 20% 기여
  • 전사인자 인산화가 30% 낮음 → 상류 ERK 활성은? 15% 낮음 → ERK 단계는 15% 기여
  • ERK 활성이 15% 낮음 → MEK는? 8% 낮음 → MEK는 8% 기여
  • ... 계속 상류로

각 단계에서 "이 단계가 하류 이상에 얼마나 기여했는가"를 계산합니다. 방식은 이렇습니다.

하류에 이미 알려진 기여도 × 이 단계에서 하류로 전달되는 민감도 = 이 단계의 기여도

이 두 요소를 곱하면서 상류로 전파하는 것이 바로 역전파. 이걸 수학적으로 정식화한 것이 연쇄 법칙(chain rule) 입니다.

중요한 관찰. 이 역방향 추적을 하기 전에, 여러분은 이미 순방향(리간드→발현)을 한 번 통과해야 각 단계의 정상적 값(baseline)을 알 수 있습니다. 즉 순방향 측정 한 번 + 역방향 추적 한 번 이면 각 상류 노드의 기여도를 다 얻습니다. 이것이 역전파가 유한 차분법(각 파라미터마다 순방향 반복)보다 압도적으로 빠른 이유입니다.


연쇄 법칙 — 미적분의 되짚어가기 원리

역전파의 뼈대인 연쇄 법칙을 최소한의 수학으로 이해합시다.

함수가 조합되어 있다고 해봅시다. x를 입력하면 먼저 y = f(x)가 되고, 다시 z = g(y)가 됩니다. 최종적으로 z = g(f(x))입니다.

x가 아주 살짝 변하면 z가 얼마나 변하는가를 알고 싶습니다. 즉 dz/dx를 구하고 싶다.

직접 계산할 수도 있지만, 연쇄 법칙은 이걸 두 단계로 쪼갭니다.

text
dz/dx = (dz/dy) × (dy/dx)

말로 풀면: "x가 y를 얼마나 변화시키는가""y가 z를 얼마나 변화시키는가" 를 곱하면 "x가 z를 얼마나 변화시키는가" 가 나옵니다.

바이오 캐스케이드 비유로 다시. "리간드 농도가 살짝 변하면 유전자 발현이 얼마나 변하는가"는 여러 단계의 곱입니다.

text
Δ(발현)/Δ(리간드) =
   Δ(발현)/Δ(전사인자) × Δ(전사인자)/Δ(ERK) × Δ(ERK)/Δ(MEK) × ... × Δ(수용체)/Δ(리간드)

각 화살표마다 "이 단계에서 다음 단계로의 민감도"가 곱해지고, 최종적으로 리간드에서 발현까지의 전체 민감도가 나옵니다.

신경망도 정확히 같습니다. 손실 함수 L은 마지막 층 출력의 함수이고, 마지막 층 출력은 그 이전 층 출력의 함수이고... 결국 첫 층의 파라미터까지 함수의 함수의 함수... 로 조합되어 있습니다.

첫 층 파라미터에 대한 L의 편미분은 연쇄 법칙에 의해 각 층에서의 민감도의 곱이 됩니다. 이 곱을 역방향으로 계산해 나가는 게 역전파.


역전파 알고리즘의 뼈대

이제 알고리즘을 정리합시다. 신경망을 L개 층으로 구성된 것으로 봅시다.

1단계 — 순전파(Forward Pass)

입력에서 출력까지 신경망을 통과시켜 각 층의 활성값을 계산하고 저장합니다.

text
a^(0) = 입력
a^(1) = σ(W^(1) · a^(0) + b^(1))
a^(2) = σ(W^(2) · a^(1) + b^(2))
...
a^(L) = σ(W^(L) · a^(L-1) + b^(L))

a^(l)는 층 l의 활성값 벡터, W^(l)·b^(l)은 층 l의 가중치 행렬·편향 벡터, σ는 활성 함수. 편 #2에서 다룬 그림.

여기서 중요: 각 층의 a^(l)값을 메모리에 저장해둡니다. 역전파 시에 필요하기 때문. 이것이 훈련이 추론보다 훨씬 많은 GPU 메모리를 쓰는 이유. 추론(inference)은 순전파만 하면 되지만, 훈련은 모든 층의 활성값을 역전파 때까지 붙들고 있어야 합니다.

2단계 — 손실 계산

마지막 층 출력 a^(L)와 정답 y로 손실을 계산합니다.

text
L = CrossEntropy(a^(L), y)

여기서 얻는 것: 마지막 층 활성값에 대한 손실의 편미분 δ^(L) = ∂L/∂a^(L).

Softmax + Cross-Entropy 조합의 경우 이 편미분은 놀랍도록 우아합니다.

text
δ^(L) = a^(L) - y

즉 "예측 확률 분포 마이너스 정답 원-핫 벡터". 이 우아함이 SoftMax + CE가 짝지어 쓰이는 이유입니다. 부록 A.4에서 유도.

3단계 — 역전파(Backward Pass)

δ^(L)에서 시작해 층을 하나씩 거꾸로 내려가며 각 층의 δ^(l)를 계산합니다.

text
δ^(l) = (W^(l+1))^T · δ^(l+1) ⊙ σ'(z^(l))

는 원소별 곱, z^(l) = W^(l) · a^(l-1) + b^(l)은 활성 함수 통과 전의 값. σ'는 활성 함수의 미분.

이 식이 무엇을 하는가:

  • (W^(l+1))^T · δ^(l+1) : 다음 층의 오차 신호를 이번 층 활성값 공간으로 되돌린다. 다음 층으로 신호를 보낼 때 사용된 가중치를 역방향으로 통과.
  • ⊙ σ'(z^(l)) : 이번 층 활성 함수의 국소 기울기를 곱한다. 활성 함수가 죽어 있는(예: ReLU에서 z < 0인 뉴런) 지점은 σ'가 0이라 오차가 여기서 차단됨.

이걸 층 L부터 층 1까지 반복해서 모든 층의 δ^(l)를 얻습니다.

4단계 — 파라미터 편미분 계산

각 층의 δ^(l)가 얻어지면 그 층의 가중치·편향에 대한 편미분은 즉시 나옵니다.

text
∂L/∂W^(l) = δ^(l) · (a^(l-1))^T
∂L/∂b^(l) = δ^(l)

이렇게 얻은 편미분들이 편 #3에서 이야기한 기울기의 실제 값입니다. 이제 편 #3의 옵티마이저(Adam 등)가 이 기울기로 파라미터를 업데이트.


왜 이렇게 빠른가

역전파의 놀라운 점. 한 번의 순전파와 한 번의 역전파로 모든 파라미터의 편미분이 얻어집니다. 유한 차분법이 파라미터 개수만큼 순전파를 반복해야 하는 것과 대조적.

계산량 감. 역전파의 계산량은 대략 순전파의 2~3배 정도입니다. 즉 3,362만 파라미터 신경망의 훈련 한 스텝은 대략 순전파 3~4번 하는 시간. 유한 차분법의 3,362만 번과 비교하면 약 800만 배 빠름.

이 알고리즘이 없었다면 오늘날의 딥러닝은 존재하지 않았을 것입니다. 실제로 역전파의 현대적 형태가 정착된 1986년 Rumelhart-Hinton-Williams 논문 이후에야 다층 신경망 훈련이 실용화되었고, 오늘의 AI 붐이 시작되었습니다.

바이오 시나리오 다시. 신호 캐스케이드의 원인 분석에서도 우리는 각 상류 노드마다 별도 실험을 하지 않습니다. 한 번의 정상적 자극 + 한 번의 이상 상황 관찰 + 역방향 추적으로 각 노드의 기여도를 얻습니다. 유한 차분법에 해당하는 것은 각 노드를 개별적으로 knockout·knockdown하는 실험인데, 이건 노드 수만큼 실험이 필요합니다. 역전파식 원인 추적이 실험 경제성 면에서도 훨씬 우수한 이유가 같은 논리로 설명됩니다.


계산 그래프 — PyTorch가 실제로 하는 일

지금까지의 설명은 층 단위 신경망에 국한되었지만, 실제 딥러닝 프레임워크(PyTorch·JAX)는 훨씬 일반적인 형태로 역전파를 처리합니다. 그 형태가 계산 그래프(computational graph) 입니다.

원리는 이렇습니다. 프레임워크가 순전파 코드를 실행할 때 각 연산(더하기·곱하기·행렬곱·softmax 등)을 그래프의 노드로 기록합니다. 그래프의 간선은 데이터 흐름.

text
x → (곱하기 W_1) → z_1 → (ReLU) → a_1 → (곱하기 W_2) → z_2 → ...

각 연산 노드는 자신이 어떤 연산인지, 어떤 입력을 받았는지 저장. 이 그래프가 완성되면 손실 L에서 시작해 그래프를 역방향으로 순회하면서, 각 노드의 국소 기울기를 곱해가며 모든 파라미터의 편미분을 얻습니다.

이 자동화된 역전파를 자동 미분(automatic differentiation, autograd) 이라 부릅니다. 오늘날 신경망 개발자는 자기 손으로 역전파 코드를 짤 필요가 없습니다. 순전파 코드만 짜면 프레임워크가 자동으로 계산 그래프를 만들고 역전파를 처리합니다.

PyTorch에서는 이렇게 생겼습니다.

python
import torch
x = torch.randn(32, 100) # 배치 크기 32, 특성 100
W1 = torch.randn(100, 50, requires_grad=True)
W2 = torch.randn(50, 3, requires_grad=True)
y_true = torch.randint(0, 3, (32,))
# 순전파 - PyTorch가 자동으로 계산 그래프 구축
z1 = x @ W1
a1 = torch.relu(z1)
logits = a1 @ W2
loss = torch.nn.functional.cross_entropy(logits, y_true)
# 역전파 - 이 한 줄이 모든 편미분을 계산
loss.backward()
# W1.grad, W2.grad에 각 파라미터의 편미분이 저장됨
print(W1.grad.shape, W2.grad.shape)

loss.backward() 한 줄에 우리가 위에서 설명한 4단계가 모두 들어 있습니다. 이 자동화 덕에 개발자는 새 아키텍처를 실험할 때 순전파만 신경 쓰면 됩니다.

바이오 관점. 이 계산 그래프는 시스템 생물학의 조절 네트워크(regulatory network) 표현과 개념이 정확히 같습니다. 각 노드가 반응·조절 관계, 간선이 인과 흐름. 시스템 생물학자가 조절 네트워크에서 특정 하류 표현형에 대한 각 유전자의 기여도를 분석하는 방법이 사실상 계산 그래프에서의 자동 미분과 같은 논리입니다.


사라지는 기울기와 폭발하는 기울기 — 역전파의 재앙

역전파의 곱셈 구조가 예상치 못한 문제를 만들 수 있습니다.

사라지는 기울기(Vanishing Gradient). 각 층에서의 국소 기울기가 1보다 작으면(예: Sigmoid 활성 함수의 미분은 최대 0.25), 여러 층을 통과하면서 곱해질 때마다 기울기가 지수적으로 작아집니다. 20층 신경망에서 첫 층에 도달할 때는 기울기가 사실상 0. 첫 층 파라미터가 훈련되지 않는 문제.

폭발하는 기울기(Exploding Gradient). 반대로 국소 기울기가 1보다 크면 지수적으로 커집니다. 첫 층 파라미터의 기울기가 우주적으로 큰 값이 되고, 파라미터가 미쳐 날뛰며 훈련이 발산합니다.

해결책 (편 #2 A.8 초기화, 편 #12에서 더 자세히):

  • ReLU 계열 활성 함수: 활성값이 양수인 영역에서 미분이 정확히 1이라 곱해도 사라지지 않음
  • Xavier·He 초기화: 층의 크기에 맞춰 초기 가중치 분산을 조정해서 초기부터 기울기가 사라지지 않게
  • Batch Normalization·Layer Normalization: 층 활성값 분포를 조정해서 기울기 스케일 유지
  • Residual Connection (편 #5): 층을 뛰어넘는 지름길을 만들어 기울기가 여러 층을 곱하지 않아도 되게. ResNet·트랜스포머의 핵심.
  • Gradient Clipping: 폭발하는 기울기를 강제로 특정 값 이하로 자름

바이오 비유. 신호 캐스케이드에서 각 단계의 증폭·감쇠 계수가 곱해지는 것과 같은 구조. 자연에서도 세포는 이 문제를 진화적으로 해결해 왔습니다. 각 단계에 음성 피드백·양성 피드백 루프, MAPK 스캐폴드 단백질(신호 강도 조절), 인산화 탈인산화 균형 등이 있습니다. 신경망의 초기화·정규화·residual 기법들이 하는 일이 바로 세포 신호 시스템의 이 조절 장치들과 개념적으로 대응됩니다.


바이오 응용 시나리오

시나리오 1 — 세포 유형 분류기 훈련의 실제

편 #3에서 언급한 scRNA-seq 세포 유형 분류기 훈련. 여러분이 PyTorch로 이걸 구현할 때, 순전파만 짜면 됩니다.

python
class CellTypeClassifier(torch.nn.Module):
def __init__(self, n_genes, n_types, hidden=512):
super().__init__()
self.encoder = torch.nn.Sequential(
torch.nn.Linear(n_genes, hidden),
torch.nn.ReLU(),
torch.nn.Dropout(0.3),
torch.nn.Linear(hidden, hidden // 2),
torch.nn.ReLU(),
torch.nn.Linear(hidden // 2, n_types),
)
def forward(self, expr_matrix):
return self.encoder(expr_matrix)
model = CellTypeClassifier(n_genes=20000, n_types=25)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)
for cells, labels in train_loader:
logits = model(cells) # 순전파
loss = torch.nn.functional.cross_entropy(logits, labels)
optimizer.zero_grad()
loss.backward() # 역전파 자동
optimizer.step() # Adam 업데이트

loss.backward()가 이 편의 4단계 알고리즘을 자동으로 수행합니다. 개발자는 세포 유형 분류에 필요한 순전파 구조와 손실 함수 선택에만 집중.

시나리오 2 — 단백질 서열 임베딩 훈련 (ESM)

Meta AI의 ESM(Evolutionary Scale Modeling)은 단백질 서열의 임베딩을 학습한 모델. UniProt에 있는 수억 개의 단백질 서열을 훈련 데이터로 씀. 이 훈련도 역전파의 힘입니다. 파라미터 수가 편 #2에서 본 규모의 수천 배(150억 파라미터급). 이 크기 신경망을 훈련하는 게 물리적으로 가능한 이유가 역전파의 계산 효율성.

ESM이 훈련되고 나면, 각 단백질 서열을 벡터로 표현할 수 있게 되고, 이 벡터가 AlphaFold·단백질 기능 예측·약물 발굴에 두루 쓰입니다.

시나리오 3 — 시스템 생물학 모델의 파라미터 추정

일부 시스템 생물학 연구실은 세포 신호 캐스케이드의 미분방정식(ODE) 모델의 파라미터를 데이터에 맞추기 위해 자동 미분을 씁니다. 각 파라미터에 대한 손실의 기울기를 자동 미분으로 얻고, 경사하강법으로 파라미터를 최적화. 신경망 훈련과 개념이 완전히 같은 절차. 이걸 differentiable programming 또는 Scientific ML이라 부르며, JAX·PyTorch 같은 프레임워크의 새로운 응용 영역.


핵심 정리

  • 역전파는 모든 파라미터의 편미분을 한 번의 순전파 + 한 번의 역전파로 얻는 효율적 알고리즘입니다.
  • 밑에 깔린 수학은 연쇄 법칙. 여러 단계 함수 조합의 미분은 각 단계의 국소 미분의 곱.
  • 알고리즘은 4단계: 순전파(활성값 저장) → 손실 계산 → 역방향으로 오차 신호 전파(δ 계산) → 각 층 파라미터 편미분 계산.
  • 오늘날의 프레임워크(PyTorch·JAX)는 계산 그래프 + 자동 미분으로 이 과정을 완전 자동화. 개발자는 순전파만 짜면 됨.
  • 사라지는·폭발하는 기울기 문제는 활성 함수·초기화·정규화·residual connection·gradient clipping 조합으로 완화.
  • 시스템 생물학·과학 계산에서 자동 미분이 신경망 밖에서도 파라미터 최적화 도구로 활용 중.

다음 개념

  • 편 #5 transformer-and-embedding — 트랜스포머의 임베딩·위치 인코딩·잔차 연결이 왜 학습을 안정화하는가.
  • 편 #6 attention-mechanism — 어텐션 스코어의 기울기가 왜 문맥 이해의 열쇠인가.
  • 편 #12 pytorch-basics — 이 편의 이론을 코드로 실습.

📐 부록 — 전문가를 위한 수학 공식

난이도: 매우 어려움 (Very Hard) 대상: 대학원 수준의 선형대수·다변수 미적분·최적화 이론을 아는 독자

A.1 스칼라 연쇄 법칙

가장 단순한 형태. z = g(y), y = f(x), 스칼라 함수라면:

text
dz/dx = (dz/dy) · (dy/dx)

여러 단계 조합:

text
dz/dx = (dz/dy_k) · (dy_k/dy_{k-1}) · ... · (dy_2/dy_1) · (dy_1/dx)

A.2 다변수 연쇄 법칙 (Multivariate Chain Rule)

z = g(y_1, y_2, ..., y_m)이고 각 y_i = f_i(x_1, ..., x_n)일 때:

text
∂z/∂x_j = Σ_{i=1}^{m} (∂z/∂y_i) · (∂y_i/∂x_j)

벡터·행렬 형태로 다시 쓰면 자코비안(Jacobian) 행렬의 곱이 됩니다.

y = f(x)이고 x ∈ ℝ^n, y ∈ ℝ^m이라 하면 자코비안:

text
J_f = ∂y/∂x = [ ∂y_i/∂x_j ]_{i,j}    (m × n 행렬)

z = g(f(x))의 자코비안:

text
J_{g∘f} = J_g · J_f

역전파는 이 행렬 곱을 오른쪽에서 왼쪽으로(입력 방향으로) 계산하는 것과 정확히 같습니다. 왼쪽에서 오른쪽으로 계산하면 전방 모드 자동 미분이 되는데, 신경망처럼 입력 차원이 크고 출력이 스칼라(손실)인 경우 역방향 모드가 압도적으로 효율적입니다.

A.3 역전파의 층별 공식 (완전 형태)

L층 완전 연결 신경망:

순전파:

text
z^(l) = W^(l) a^(l-1) + b^(l)
a^(l) = σ(z^(l))

손실:

text
L = ℓ(a^(L), y)

역전파 — 마지막 층의 오차 신호:

text
δ^(L) = ∂L/∂z^(L) = (∂ℓ/∂a^(L)) ⊙ σ'(z^(L))

역전파 — 층 l의 오차 신호 (l = L-1, L-2, ..., 1):

text
δ^(l) = ((W^(l+1))^T δ^(l+1)) ⊙ σ'(z^(l))

각 층의 파라미터 편미분:

text
∂L/∂W^(l) = δ^(l) (a^(l-1))^T
∂L/∂b^(l) = δ^(l)

미니배치의 경우 이 편미분들을 배치 안 예시에 대해 평균 냅니다.

A.4 Softmax + Cross-Entropy의 우아한 편미분

Softmax:

text
p_i = exp(z_i) / Σ_k exp(z_k)

Cross-entropy (정답이 클래스 c일 때):

text
L = -log(p_c)

∂L/∂z_i 계산.

Case 1: i = c (정답 클래스):

text
∂L/∂z_c = -1 + p_c = p_c - 1

Case 2: i ≠ c (오답 클래스):

text
∂L/∂z_i = p_i

정답을 원-핫 벡터 y로 표현하면 두 경우가 한 식으로 통합:

text
∂L/∂z = p - y

예측 확률 분포 마이너스 정답 원-핫. 놀랍도록 우아하고, Softmax + Cross-Entropy가 짝지어 쓰이는 이유.

A.5 활성 함수의 미분

Sigmoid: σ(z) = 1/(1+e^{-z})

text
σ'(z) = σ(z)(1 - σ(z))

최댓값 0.25 (z=0에서). 여러 층 곱하면 지수적 감쇠 → 사라지는 기울기의 원인.

Tanh: tanh(z) = (e^z - e^{-z})/(e^z + e^{-z})

text
tanh'(z) = 1 - tanh^2(z)

최댓값 1. Sigmoid보다 낫지만 역시 극단에서 미분 0.

ReLU: ReLU(z) = max(0, z)

text
ReLU'(z) = 1 if z > 0 else 0

양수 영역에서 정확히 1. 사라지는 기울기 문제 크게 완화. 단 dying ReLU 문제 (음수 영역 뉴런은 기울기 0으로 훈련 정지).

Leaky ReLU: LeakyReLU(z) = z if z > 0 else αz (α=0.01)

text
LeakyReLU'(z) = 1 if z > 0 else α

음수 영역에서도 작은 기울기 유지.

GELU: GELU(z) = z · Φ(z) (Φ: 표준정규 CDF)

text
GELU'(z) ≈ Φ(z) + z · φ(z)

트랜스포머 표준. 자연스러운 스무딩.

A.6 계산 그래프와 역방향 모드 자동 미분

계산 그래프 G = (V, E):

  • 노드 V: 각 원자 연산 (더하기·곱하기·행렬곱·활성 함수 등)
  • 간선 E: 데이터 흐름

각 노드 v에 대해:

  • 국소 편미분 ∂v/∂parent_i를 계산할 수 있는 함수를 미리 정의 (프레임워크 내장)

역방향 모드 자동 미분:

  1. 출력 노드에서 ∂L/∂L = 1로 시작.
  2. 그래프의 역방향 위상 정렬로 노드 순회.
  3. 각 노드에서 상류 노드로 자기 편미분과 국소 편미분의 곱을 전파.
  4. 파라미터 노드에 도달하면 그것이 최종 파라미터 편미분.

시간 복잡도: 순전파와 같은 차수 (계산량은 2~3배 상수배). 공간 복잡도: 활성값을 다 저장해야 하므로 순전파와 같은 차수의 메모리 필요.

A.7 Gradient Checkpointing

훈련 메모리를 줄이는 트릭. 순전파에서 모든 활성값을 저장하지 않고 일부만 저장하고, 역전파 때 필요하면 다시 순전파해서 재계산.

  • 시간: 순전파 두 번, 역전파 한 번 → 약 1.5배 느려짐
  • 공간: √L 수준으로 활성값 저장 (L층 신경망의 경우)

편 #14 (LLM 훈련 실전)에서 언급될 대형 모델 훈련의 필수 기법.

A.8 Gradient Clipping

폭발하는 기울기 대응. 기울기의 L2 노름이 임계값 c를 초과하면 스케일 다운:

text
if ||∇||_2 > c:
    ∇ ← ∇ · (c / ||∇||_2)

c는 일반적으로 1.0. Transformer 훈련에서 사실상 표준.

A.9 Gradient Check (구현 검증)

역전파 코드가 정확한지 유한 차분과 비교:

text
∂L/∂θ_i ≈ [L(θ + ε · e_i) - L(θ - ε · e_i)] / (2ε)

e_i는 i번째 단위 벡터, ε ≈ 1e-5.

상대 오차 지표:

text
relative_error = |grad_analytic - grad_numeric| / max(|grad_analytic|, |grad_numeric|)

일반적으로 1e-7 이하이면 정확, 1e-5 이하이면 수치 오차 허용 범위, 1e-3 초과이면 버그 의심.

A.10 역전파의 시간 복잡도 정리

  • 순전파 시간: O(F) — 신경망의 총 연산량 (FLOPs)
  • 역전파 시간: O(F) — 순전파와 같은 차수 (상수배 2~3)
  • 유한 차분 전체 기울기 시간: O(P · F) — 파라미터 수 × 순전파

역전파는 파라미터 수에 무관한 시간에 전체 기울기를 얻습니다. 이것이 대형 신경망 훈련이 가능해진 결정적 이유.

이 시간 복잡도의 우아함은 Baur–Strassen 정리 (1983)로 알려져 있으며, 자동 미분의 계산 이론 기반.


참고 자료

본 편의 콘텐츠·시나리오·비유·수치는 모두 BioPlayground 자체 개발이며, 아래는 개념 학습에 도움이 되는 외부 참고 자료입니다.

  • 역전파 원 논문: Rumelhart, Hinton, Williams, "Learning representations by back-propagating errors" (Nature 1986)
  • 자동 미분 계산 이론: Baur & Strassen, "The complexity of partial derivatives" (Theoretical Computer Science 1983)
  • 딥러닝 표준 교재: Goodfellow et al., "Deep Learning" Chapter 6 (역전파)
  • 자동 미분 실용 가이드: Baydin et al., "Automatic Differentiation in Machine Learning: a Survey" (JMLR 2018)
  • PyTorch autograd 문서: pytorch.org autograd tutorial
  • JAX 자동 미분: jax.readthedocs.io — 함수형 자동 미분의 현대적 구현
  • 딥러닝 시각화 교육: 3Blue1Brown "Deep Learning" Ch 3·4 (YouTube) — 페다고지 참고
  • ESM 논문: Rives et al., "Biological structure and function emerge from scaling unsupervised learning to 250 million protein sequences" (PNAS 2021)

이 편으로 신경망 훈련의 두 축(비용 지형의 탐색 방법·기울기의 계산 방법)이 모두 이야기되었습니다. 편 #5부터는 이 훈련 기계를 어떻게 언어에 맞게 재조립해 트랜스포머가 되었는지 다룹니다.