역전파

편집 역사 토론
수치해석 소프트웨어 최적설계 마지막 수정: 2026-08-17 04:12:18

1. 개요[편집]

역전파
Backpropagation
정체역방향 자동 미분의 신경망 방언
최초 정식화Linnainmaa (1970) — 석사논문, 누적 반올림오차 표현
대중화Rumelhart · Hinton · Williams (1986), Nature 323
기본 연산벡터-야코비 곱(VJP)
시간 비용순전파의 약 2배 (합계 약 3배)
메모리 비용순전파 중간 활성값 전량 — 진짜 병목
완화책체크포인팅 · 혼합 정밀도 · 활성값 재계산

역전파(backpropagation)는 손실을 계산하는 계산 그래프를 출력에서 입력 방향으로 거슬러 훑으며, 연쇄법칙을 국소적으로 적용해 모든 파라미터에 대한 손실의 기울기를 한 번의 역방향 패스로 구하는 절차다. 신경망 학습의 대명사처럼 쓰이지만, 수치해석적으로는 새로운 것이 없다 — 자동 미분의 역방향 모드를 신경망이라는 특정 계산 그래프에 적용한 것이 전부다. 딥러닝 바닥에서만 통용되는 이름이 붙어 있을 뿐, CFD 하는 사람이 아는 민감도 해석의 수반법(adjoint)과 정확히 같은 대상이다.1

이름 때문에 자주 생기는 오해 두 가지를 먼저 정리하고 가자.

  • 역전파는 학습 알고리즘이 아니다. 기울기를 계산할 뿐이고, 그 기울기로 가중치를 갱신하는 것은 확률적 경사하강법이나 Adam이다. “역전파로 학습한다”는 말은 “미분으로 최적화한다”는 말만큼 뭉뚱그린 표현이다.
  • 역전파는 근사가 아니다. 유한차분과 달리 스텝 크기가 없고, 얻은 기울기는 반올림오차를 빼면 정확하다. 그래서 수치미분으로 검증할 때 기준이 되는 쪽은 역전파다.

이 문서는 신경망 문맥에서의 구체적 재귀식·비용 회계·메모리 전략을 다룬다. 전방/역방향 모드의 일반론과 구현 방식(연산자 오버로딩 대 소스 변환)은 자동 미분에, “어느 파라미터에 얼마의 책임이 있는가”라는 상위 문제 틀은 신용 할당에 있으니 여기서 반복하지 않는다.

2. 다층 퍼셉트론에서의 재귀식[편집]

l=1,,Ll = 1,\dots,L 에 대해 순전파가

z(l)=W(l)a(l1)+b(l),a(l)=σ(z(l))\mathbf{z}^{(l)} = W^{(l)}\mathbf{a}^{(l-1)} + \mathbf{b}^{(l)}, \qquad \mathbf{a}^{(l)} = \sigma\bigl(\mathbf{z}^{(l)}\bigr)

이고 손실이 L(a(L))L(\mathbf{a}^{(L)}) 라 하자. 층 ll오차 신호δ(l)=L/z(l)\boldsymbol\delta^{(l)} = \partial L/\partial \mathbf{z}^{(l)} 로 정의하면 역전파는 딱 세 줄이다.

δ(L)=a(L)Lσ(z(L))\boldsymbol\delta^{(L)} = \nabla_{\mathbf{a}^{(L)}} L \odot \sigma'\bigl(\mathbf{z}^{(L)}\bigr) δ(l)=(W(l+1)δ(l+1))σ(z(l))\boldsymbol\delta^{(l)} = \Bigl(W^{(l+1)\top}\boldsymbol\delta^{(l+1)}\Bigr)\odot \sigma'\bigl(\mathbf{z}^{(l)}\bigr) LW(l)=δ(l)a(l1),Lb(l)=δ(l)\frac{\partial L}{\partial W^{(l)}} = \boldsymbol\delta^{(l)}\mathbf{a}^{(l-1)\top}, \qquad \frac{\partial L}{\partial \mathbf{b}^{(l)}} = \boldsymbol\delta^{(l)}

읽어야 할 지점은 두 번째 줄의 전치 W(l+1)W^{(l+1)\top} 이다. 순방향에서 정보를 퍼뜨린 바로 그 행렬이 역방향에서는 전치되어 신호를 되돌린다. 이 전치가 물리적으로 실현 가능하냐는 질문이 뇌 모형 쪽의 가중치 수송 문제이고, 무작위 행렬로 대체해도 학습이 된다는 피드백 정렬 계열의 실험이 거기서 나왔다(자세한 논쟁은 신용 할당 참고).2

세 번째 줄도 중요하다. 가중치 기울기는 역방향 오차와 순방향 활성값의 외적이다. 즉 a(l1)\mathbf{a}^{(l-1)} 를 어딘가 들고 있어야 한다 — 역전파의 메모리 비용이 여기서 발생한다.

3. JVP와 VJP — 프레임워크가 실제로 파는 것[편집]

일반 계산 그래프에서는 층 개념 대신 야코비 곱의 언어로 쓰는 편이 정확하다. 어떤 원시연산 y=f(x)\mathbf{y} = f(\mathbf{x}) 의 야코비를 JJ 라 할 때,

  • 야코비-벡터 곱(JVP) JuJ\mathbf{u} — 입력 방향 u\mathbf{u} 를 밀어 보낸다. 전방 모드의 원시 연산.
  • 벡터-야코비 곱(VJP) vJ\mathbf{v}^\top J — 출력 쪽 여벡터 v\mathbf{v} 를 끌어당긴다. 역방향 모드의 원시 연산.

핵심은 둘 다 JJ 를 실제로 만들지 않는다는 것이다. m×nm\times n 행렬을 메모리에 올리는 순간 게임이 끝나는데, JVP·VJP는 원시연산 하나당 O(연산 비용)O(\text{연산 비용}) 으로 계산된다. 역전파는 결국

xL=J1J2JLyL\nabla_{\mathbf{x}} L = J_1^\top J_2^\top \cdots J_L^\top \,\nabla_{\mathbf{y}} L

오른쪽에서 왼쪽으로 곱하는 것이고, 왼쪽부터 곱하면 행렬-행렬 곱이 되어 비용이 폭발한다. 곱셈 순서가 전부라는 점에서 이건 사실상 행렬 연쇄 곱셈 문제와 같은 이야기다.

실무적 함의: PyTorch의 backward, JAX의 vjp/grad 는 VJP 조립기이고, jvp/jacfwd 는 JVP 조립기다. 출력이 스칼라(손실)면 VJP 한 번, 입력이 하나뿐이면 JVP 한 번이 이긴다. 야코비안 행렬 전체가 정말 필요하면 어느 쪽이든 min(m,n)\min(m,n) 번 돌려야 한다.

4. 비용 회계 — 시간은 3배, 메모리는 전부[편집]

시간. 완전연결층 y=Wx\mathbf{y} = W\mathbf{x} (WRm×nW \in \mathbb{R}^{m\times n})의 순전파는 mnmn 번의 곱셈-누산이다. 역전파는 L/x=Wδ\partial L/\partial\mathbf{x} = W^\top\boldsymbol\deltamnmn 번, L/W=δx\partial L/\partial W = \boldsymbol\delta\mathbf{x}^\top 로 다시 mnmn 번 — 역방향이 순방향의 두 배다. 합쳐서 3배. 트랜스포머 학습 비용을 어림할 때 흔히 쓰는 “파라미터 NN, 토큰 DD 에 대해 6ND6ND FLOPs” 규칙이 정확히 이 2+42 + 4 의 분해에서 나온다.

이론적으로도 이 상수배는 보장된다. 바우어-슈트라센 정리(1983)는 유리함수를 계산하는 산술회로에 대해 모든 편미분을 함수값 계산 비용의 상수배(정리 판본에 따라 3~5배)로 얻을 수 있다고 말한다. 파라미터가 몇 개든 상수배라는 것 — 그리바인크는 이를 값싼 기울기 원리(cheap gradient principle)라 불렀다. 유한차분이라면 파라미터 수 PP 에 비례해 O(P)O(P) 번의 함수 평가가 필요하고, PP 가 억 단위인 모형에서 이 차이는 배수가 아니라 가능/불가능의 경계다.

메모리. 여기가 진짜 문제다. 역방향 패스가 a(l1)\mathbf{a}^{(l-1)}σ(z(l))\sigma'(\mathbf{z}^{(l)}) 를 요구하므로, 순전파의 중간 활성값을 전부 살려 둔 채로 끝까지 가야 한다. 배치 BB, 깊이 LL, 층 폭 HH 면 활성값 메모리가 O(BLH)O(BLH) 로 붙는데, 요즘 대형 모형에서는 파라미터·옵티마이저 상태보다 이쪽이 먼저 GPU를 터뜨린다. 순전파만 하는 추론에서는 층 하나 지나면 이전 활성값을 버려도 되니 메모리가 O(BH)O(BH) 로 끝난다 — 추론은 되는데 학습이 안 되는 흔한 상황의 정체가 이것이다.

5. 그래디언트 체크포인팅[편집]

메모리와 시간을 맞바꾸는 표준 처방이 그래디언트 체크포인팅(activation checkpointing)이다. 발상은 단순하다 — 활성값을 다 저장하지 말고, 몇 군데만 저장한 뒤 역방향에서 필요할 때 그 지점부터 다시 순전파해 복원한다.

LL 개 층을 L\sqrt{L} 개 구간으로 나눠 구간 경계만 저장하면 메모리가 O(L)O(\sqrt{L}) 로 줄고, 추가 계산은 순전파 한 번 분량(전체의 약 33% 증가)이다. 더 공격적으로는 그리바인크-발터의 revolve 스케줄이 있는데, 체크포인트 cc 개와 재계산 스윕 rr 회로 처리 가능한 스텝 수가 이항계수 (c+rc)\binom{c+r}{c} 까지 늘어난다. 즉 로그 수준의 메모리로 로그 수준의 재계산을 사면 된다.

이 기법이 원래 어디서 왔는지 알면 좀 재밌다. 시간 적분되는 편미분방정식 수반해석 — 예컨대 비정상 전산유체역학 해석의 형상 민감도 — 에서는 수천 스텝의 유동장을 전부 저장할 수 없어서 1990년대부터 이 스케줄링이 연구됐다. 딥러닝이 20년 뒤에 같은 벽에 부딪혀 같은 답을 다시 찾은 셈이다.

체크포인팅은 속도를 내주고 메모리를 사는 거래로 알려져 있지만, 실측하면 그렇게 단순하지 않다.3

메모리를 줄이는 다른 축으로 혼합 정밀도(활성값을 FP16/BF16으로 저장)와 활성값 오프로딩(CPU 메모리로 밀어내기)이 있고, 셋을 조합하는 것이 대형 학습의 기본기다.

6. 기울기가 죽거나 터질 때[편집]

δ\boldsymbol\delta 의 재귀식을 풀어 쓰면 야코비의 곱이다.

δ(l)=(k=l+1LD(k)W(k))δ(L),D(k)=diag(σ(z(k)))\boldsymbol\delta^{(l)} = \left(\prod_{k=l+1}^{L} D^{(k)}W^{(k)\top}\right)\boldsymbol\delta^{(L)}, \qquad D^{(k)} = \mathrm{diag}\bigl(\sigma'(\mathbf{z}^{(k)})\bigr)

행렬 곱이 길게 이어지면 결과는 지수적으로 커지거나 작아진다. 시그모이드는 σ1/4\sigma' \le 1/4 이므로 층마다 최소 4분의 1로 깎이고, 20층이면 42010124^{-20}\approx 10^{-12} — 앞쪽 층은 기울기를 사실상 못 받는다. 반대로 야코비 곱의 스펙트럼 반지름이 1보다 크면 폭발한다. 순환 신경망에서는 같은 WW 가 시퀀스 길이만큼 곱해지므로 이 문제가 훨씬 극단적으로 나타난다(호흐라이터 1991, 벤지오 외 1994).

현대 아키텍처의 상당 부분은 이 곱을 1 근처로 붙들어 두려는 배관 공사로 읽힌다.

  • 활성함수 교체 — ReLU 계열은 활성 영역에서 σ=1\sigma' = 1 이라 곱을 깎지 않는다.
  • 초기화 — Xavier/He 초기화는 층을 지날 때 분산이 유지되도록 WW 의 스케일을 잡는다.
  • 잔차 연결a(l)=a(l1)+F(a(l1))\mathbf{a}^{(l)} = \mathbf{a}^{(l-1)} + F(\mathbf{a}^{(l-1)}) 이면 야코비가 I+FI + \partial F 라 항등 성분이 항상 남는다. 100층 넘는 망이 학습되기 시작한 결정적 이유.
  • 정규화 계층배치 정규화·층 정규화가 각 층의 스케일을 재설정해 곱의 폭주를 막는다.
  • 게이팅 — LSTM의 셀 상태는 곱셈 대신 덧셈으로 정보를 나르도록 설계됐다.
  • 기울기 클리핑 — 폭발 쪽은 노름을 잘라 버리는 게 가장 싸고 확실한 처방이다.

7. 구현에서 사람이 실제로 틀리는 것[편집]

  • 기울기 검증은 중심차분으로. [f(x+h)f(xh)]/2h[f(x+h)-f(x-h)]/2h 와 비교하고, 상대오차 gfdgad/(gfd+gad)\lVert g_{\text{fd}} - g_{\text{ad}}\rVert / (\lVert g_{\text{fd}}\rVert + \lVert g_{\text{ad}}\rVert) 를 본다. 배정밀도에서 10710^{-7} 이하면 통과. ReLU 꺾임점 근처에서 검증하면 당연히 틀리니 그 점은 피하거나 매끄러운 활성함수로 바꿔서 확인한다.
  • 제자리 연산(in-place)이 역방향에 필요한 값을 덮어쓴다. 프레임워크가 “version counter” 에러를 뱉는 것이 이 경우다. 성능 욕심에 += 를 남발하다 걸린다.
  • 그래프를 끊는 위치를 틀린다. detach/stop_gradient 를 잘못 두면 기울기가 조용히 0이 되고, 손실은 줄지 않는데 에러도 안 난다. 타깃 네트워크·GAN·강화학습 구현의 단골 버그.
  • 이중 역전파. 기울기 자체를 미분해야 하는 경우(기울기 페널티, MAML 같은 메타학습)에는 역전파 그래프를 다시 미분한다. 이때 메모리가 한 번 더 곱해지고, create_graph=True 를 잊으면 그냥 상수로 취급되어 조용히 틀린 학습이 된다.
  • 시퀀스는 잘라서. 긴 시퀀스의 시간 역전파(BPTT)를 끝까지 펼치면 메모리가 길이에 비례한다. 실무에서는 절단 BPTT로 kk 스텝만 되돌린다 — 이건 근사이며, 그 사실을 잊으면 장기 의존성이 왜 안 잡히는지 영원히 모른다.

8. 역사 — 몇 번이나 다시 발명됐나[편집]

역전파는 1986년에 발명되지 않았다. 계보를 시대순으로 적으면 이렇다.

  • 1960~62년 — 켈리, 브라이슨, 드레이퍼스가 최적제어 문제에서 수반 방정식으로 기울기를 구하는 절차를 제시한다. 다단 결정 문제의 연쇄법칙 역방향 적용이라는 점에서 내용은 이미 같다.
  • 1970년 — 세포 린나인마의 헬싱키대 석사논문. 프로그램의 누적 반올림오차를 표현하려다 역방향 모드 AD의 일반적 형태에 도달했다. 오늘날 역전파의 최초 정식화로 인정되는 문헌.4
  • 1974년 — 폴 워보스의 하버드 박사논문이 이를 신경망 형태의 모형에 적용한다.
  • 1986년 — 러멜하트·힌턴·윌리엄스의 Nature 논문. 알고리즘 자체는 새롭지 않았으나, 은닉층의 내부 표현이 학습으로 저절로 생겨난다는 것을 설득력 있게 보여 신경망 연구를 되살렸다. 대중화의 공은 온전히 이 논문 몫이다.
  • 1989년 — 르쿤이 우편번호 숫자 인식에 적용해 합성곱 신경망과 결합시킨다. 실용화의 출발점.

교훈은 뻔하지만 매번 반복된다 — 알고리즘의 발명과 알고리즘의 성공은 다른 사건이다. 1970년의 린나인마에게는 GPU도, 데이터도, 그걸로 뭘 하고 싶다는 문제의식도 없었다.

9. 관련 문서[편집]

10. Footnotes[편집]

  1. 유체 하던 사람이 딥러닝 세미나에 갔다가 “역전파라는 게 있는데요”라는 설명을 듣고 “그거 이산 수반 아닌가요”라고 물었다가 어색해지는 장면은 실제로 여러 번 목격된다. 물론 정말 같은 것이 맞다. 분야가 다르면 같은 알고리즘에 다른 이름이 붙고, 그 이름 때문에 20년쯤 서로를 못 알아본다.

  2. “역전파는 뇌가 하는 일이 아니다”라는 지적은 옳지만, 그래서 역전파를 안 쓰겠다는 결론으로 가면 곤란하다. 비행기도 날개를 퍼덕이지 않는다. 다만 뇌가 어떻게 하는지는 여전히 흥미로운 질문이고, 그 질문이 신용 할당 연구를 계속 살려 두고 있다.

  3. 체크포인팅 옵션을 켜면 학습이 30% 느려지는 대신 배치를 2~4배 키울 수 있다. 그런데 배치를 키우면 스텝당 처리량이 올라가서, 실측해 보면 전체 학습 시간이 오히려 줄어드는 경우가 흔하다. “메모리를 아끼려고 켰는데 속도까지 빨라졌다”는 보고가 나오는 이유이며, 그래서 이건 켜 보기 전엔 모른다.

  4. Linnainmaa, S. (1970). Algoritmin kumulatiivinen pyöristysvirhe…, 헬싱키대 석사논문(핀란드어). 1976년 BIT 에 영어 요약이 실렸다. 제목을 번역하면 “테일러 전개된 국소 반올림오차의 알고리즘적 누적”쯤 되는데, 신경망은 한 글자도 안 나온다. 딥러닝의 심장을 만든 논문이 사실은 오차 해석 논문이었다는 것.