역전파는 신경망의 예측 오차를 출력층에서 입력층 쪽으로 거꾸로 전달하며 각 가중치가 오차에 얼마나 책임이 있는지(기울기)를 계산하는 방법이다. 딥러닝 모델을 학습시킬 때 매 단계 실행되며, 직접 구현할 일 없이 PyTorch에서는 loss.backward() 한 줄로 프레임워크가 자동 처리한다.
| 단계 | 방향 | 하는 일 |
|---|---|---|
| 순전파 | 입력 → 출력 | 예측값과 손실 계산 |
| 역전파 | 출력 → 입력 | 가중치마다 기울기 계산 |
| 업데이트 | - | 기울기를 보고 가중치 조정 |
신경망은 층이 여러 겹 이어진 함수다. 연쇄법칙(chain rule)을 쓰면 뒤쪽 층에서 구한 기울기를 다시 써서 앞쪽 층의 기울기를 차례로 구할 수 있다. 그래서 가중치가 수백만 개여도 모든 기울기를 한 번의 역방향 계산으로 얻는다.
이 계산에는 순전파 때 나온 중간값이 필요하다. 학습할 때 추론보다 메모리를 훨씬 많이 쓰는 이유가 이 중간값을 저장해 두기 때문이다.
PyTorch의 자동 미분(Autograd)은 계산 과정을 기록해 두었다가 loss.backward()를 부르면 역전파를 실행한다. 학습 루프는 한 바퀴마다 보통 아래 순서로 돈다.
| 순서 | 코드 | 의미 |
|---|---|---|
| 1 | optimizer.zero_grad() | 이전 기울기 지우기 |
| 2 | loss = loss_fn(model(x), y) | 순전파, 손실 계산 |
| 3 | loss.backward() | 역전파 |
| 4 | optimizer.step() | 가중치 업데이트 |
기울기는 지우지 않으면 계속 쌓이기 때문에 1번을 빼먹으면 학습이 엉뚱하게 흘러간다. 학습 없이 추론만 할 때는 torch.no_grad() 안에서 실행해 기록을 끄면 메모리와 시간을 아낄 수 있다.
층이 많으면 기울기를 계속 곱하는 과정에서 값이 0에 가까워지거나(그래디언트 소실) 지나치게 커진다(그래디언트 폭주). 기울기가 소실되면 앞쪽 층이 거의 학습되지 않고, 폭주하면 손실이 NaN으로 튄다.
| 증상 | 흔한 대처 |
|---|---|
| 기울기 소실 | ReLU 활성화, 잔차 연결, 정규화 레이어(Batch Norm 등) |
| 기울기 폭주 | 그래디언트 클리핑, 학습률 낮추기, 알맞은 가중치 초기화 |
둘을 같은 것으로 착각하기 쉽다. 역전파는 기울기를 구하는 방법이고, 경사하강법은 그 기울기로 가중치를 고치는 방법이다. 옵티마이저를 SGD에서 Adam으로 바꿔도 역전파 과정은 그대로다.
| 구분 | 역전파 | 경사하강법(옵티마이저) |
|---|---|---|
| 역할 | 기울기 계산 | 가중치 갱신 |
| PyTorch 코드 | loss.backward() | optimizer.step() |
역전파를 따로 골라 쓰는 일은 드물고, 신경망의 가중치를 바꾸는 작업이면 거의 언제나 안에서 돌아간다. 사용자 입장에서는 학습 루프에서 loss.backward()를 부르는 순간이 곧 역전파를 쓰는 순간이다.
| 어디서 | 어떻게 쓰나 |
|---|---|
| 모델 처음부터 학습 | 매 배치마다 순전파 → loss.backward() → optimizer.step() 반복 |
| 파인튜닝 | 사전학습 모델을 내 데이터로 조금 더 학습. 고정할 층은 기울기 계산을 꺼서 메모리 절약 |
| 학습 문제 진단 | 층별 기울기 크기를 찍어 보고 소실·폭주 여부를 확인, 필요하면 클리핑 적용 |
| 모델 해석 | 입력에 대한 기울기를 구해 예측에 크게 영향을 준 부분(예: 이미지 영역)을 표시 |