89. 기울기 폭발 (Exploding Gradient)
⚠️ 이 문서는 딥러닝의 역전파(Backpropagation) 과정에서 에러 신호가 뒤로 갈수록 0으로 소멸해 버리는 '기울기 소실'과 정반대로, **1보다 큰 가중치가 연속으로 곱해지면서 미분값(기울기)이 기하급수적으로 커져 컴퓨터의 표현 한계(NaN)를 뚫고 결괏값이 펑 터져버림으로써 학습 궤도를 이탈해 버리는 치명적 현상인 '기울기 폭발'**을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 고등학교 수학의 연쇄 법칙(Chain Rule)에 의해 발생하는 부작용이다. 1.5, 2.0 같은 1보다 큰 숫자를 은닉층을 거스르며 수십~수백 번 곱하다 보니 신호가 수백만, 수십억으로 눈덩이처럼 불어나 가중치를 갱신하는 폭(보폭)이 미쳐 날뛰는 현상이다.
- 가치: 기울기가 터져버리면 모델의 가중치 값이
NaN(Not a Number)텍스트로 찍히면서 시스템이 완전히 고장 나게 되며, 주로 순환 신경망(RNN)처럼 동일한 가중치 덩어리가 반복해서 곱해지는 구조에서 가장 끔찍하게 발생한다.- 기술 체계: 이를 막기 위해 임곗값을 넘는 순간 기울기를 가위로 싹둑 잘라버리는 무식하지만 확실한 가중치 클리핑(Gradient Clipping) 기법을 사용하거나, LSTM, 가중치 정규화(L2 Penalty), 올바른 가중치 초기화(He 등)를 처방으로 사용한다.
Ⅰ. 1보다 큰 수의 무한 곱셈이 낳은 재앙
0.5를 10번 곱하면 0이 되지만, 1.5를 100번 곱하면 우주가 터진다.
- 연쇄 법칙(Chain Rule)의 쌍둥이 악마:
- 100개의 층을 가진 딥러닝 모델에서 정답과 예측의 오차(Loss)를 줄이려면 역전파 미분을 통해 맨 뒤 100번 층부터 1번 층까지 기울기를 거꾸로 곱해가며 전달해야 한다.
- 이때 이전 층으로 전달하는 신호 값(미분값 $\times$ 가중치)이 평균적으로
0.9라면, 100번을 곱하면 $0.9^{100} \approx 0.00002$로 증발해 버린다. 이것이 **기울기 소실(Vanishing)**이다. - 반대로 이 신호 값이 평균
1.1이라면? 100번을 곱하면 $1.1^{100} \approx 13780$이 되고, 500층이면 상상을 초월하는 숫자로 커진다. 이것이 **기울기 폭발(Exploding)**이다.
- RNN(순환 신경망)에서의 취약성:
- 특히 번역이나 주가 예측에 쓰이는 RNN은 문장 길이가 50 단어라면 같은 가중치 행렬 $W$를 50번 연속해서 곱한다. (예: $W \times W \times W ...$)
- 1보다 조금만 큰 가중치가 우연히 걸려도 50번의 루프를 타면서 숫자가 어마어마하게 팽창해 학습 데이터가 컴퓨터의 64비트 메모리 한계를 뚫어버려
NaN(숫자 아님)오류를 뿜고 뻗어버린다.
📢 섹션 요약 비유: 복리 이자의 마법과 같습니다. 은행 이자율이 10% 일 때 복리로 돈이 굴러가면 수십 년 뒤에 우주를 살 돈이 되는 것처럼, 역전파 과정에서 신호가 1배보다 조금이라도 큰 상태로 수백 개의 층(복리)을 통과하면 그 신호 값이 폭주하여 기계의 두뇌를 태워버리는 현상입니다.
Ⅱ. 응급처치: 가중치 클리핑 (Gradient Clipping)
숫자가 터질 것 같으면 가위로 강제로 잘라버린다.
- 클리핑(Clipping)의 직관적 원리:
- 해결책은 의외로 무식하고 심플하다. "기울기(보폭)의 최대 한계선(Threshold)을 정해놓고, 그 선을 넘으면 그냥 그 선에 맞춰 잘라버리자!"
- 예: 최대 한계치=5.0으로 설정. 역전파로 계산된 기울기가
1.2면 그대로1.2만큼 걷는다. 계산된 기울기가15,000으로 미쳐 날뛰면? 그냥 가위로 싹둑 잘라서5.0으로 깎아 내린 뒤 걷는다.
- L2 Norm 클리핑 (방향성 유지):
- 그냥 숫자를 자르면 x, y, z 여러 차원의 기울기 비율이 깨져 엉뚱한 방향으로 걷게 된다.
- 그래서 딥러닝 프레임워크(PyTorch 등)는 기울기 벡터의 전체 덩치(L2 Norm 길이)가 5.0을 넘으면, 벡터가 가리키는 화살표의 '방향'은 그대로 유지한 채 화살표의 '길이'만 5.0으로 쪼그라뜨리는 수학적 보정(
clip_grad_norm_)을 수행한다.
- RNN 생태계의 구원자:
- 이 가중치 클리핑 기법은 RNN 모델이 폭주해서 죽는 것을 막아주는 산소호흡기 같은 국룰 기법으로 정착했다.
📢 섹션 요약 비유: 길을 내려가야 하는데 기울기 폭발이 일어나 1보 앞으로 가야 할 발걸음이 실수로 100km짜리 보폭이 되어버렸습니다. 그대로 발을 내디디면 우주 밖으로 튕겨 나갑니다. 그래서 신발에 강력한 사슬(클리핑)을 묶어두어, 아무리 힘껏 뛰려 해도 한 번에 최대 1미터(한계치)까지만 발이 나가도록 물리적으로 다리를 묶어버리는 안전장치입니다.
Ⅲ. 근본적 해결책 3선 (구조적 접근)
가위로 자르는 건 땜질이다. 애초에 숫자가 커지지 않는 체질을 만들어야 한다.
- 가중치 초기화 (Weight Initialization):
- 처음에 가중치 $W$에 난수를 잘못 넣어서 시작된 일이다. He 초기화나 Xavier 초기화를 쓰면 $W$의 분산이 1로 예쁘게 유지되어, 100번을 곱해도 값이 0이나 무한대로 터지지 않는 '황금 비율'의 시작점을 잡아준다.
- 배치 정규화 (Batch Normalization):
- 층과 층 사이를 지날 때마다 신호가 커지려고 하면, 다음 층으로 넘기기 전에 데이터 뭉치(Batch)의 평균을 0, 분산을 1로 강제로 꾹꾹 눌러 깎아(정규화) 넘겨주는 밸브를 설치한다.
- RNN의 포기, LSTM/GRU 및 ResNet 도입:
- 똑같은 가중치를 계속 곱하는 구조인 RNN 자체가 결함 덩어리다. 그래서 덧셈(+) 기반의 우회 도로(컨베이어 벨트)를 파서 신호를 흘려보내는 LSTM이나 GRU 딥러닝 아키텍처가 발명되었다. (덧셈은 100번 더해도 곱셈처럼 미친 듯이 폭주하지 않는다.)
📢 섹션 요약 비유: 폭주하는 자동차를 멈추기 위해 매번 밧줄로 잡아채는 것(클리핑)은 한계가 있습니다. 아예 엑셀을 너무 세게 밟지 못하도록 엔진 튜닝(초기화)을 하고, 중간중간 과속 방지턱(배치 정규화)을 깔며, 폭주하기 쉬운 스포츠카(RNN) 대신 안전한 궤도를 달리는 모노레일(LSTM, ResNet)로 구조 자체를 뜯어고친 것이 현대 딥러닝의 해결책입니다.