3.6 기울기 소실과 폭주

유명곤·2026년 9월 27일

층을 깊게 쌓아도 앞쪽 층까지 학습에 필요한 기울기가 전달되지 않으면 가중치를 제대로 조정하기 어렵다. 기울기 소실(Gradient vanishing)은 역전파 과정에서 기울기가 매우 작아지는 현상이고, 기울기 폭주(Gradient exploding)는 기울기가 지나치게 커지는 현상이다. 전자는 학습을 느리게 하거나 정체시키고, 후자는 가중치 갱신을 불안정하게 만들 수 있다.

역전파에서는 각 연산의 미분값을 연결해 손실에 대한 가중치의 기울기를 구했다. 이번에는 이 계산이 깊은 신경망에서 어려워지는 이유와, 기울기가 전달되기 좋은 조건을 만드는 방법을 정리한다.

미분값이 반복해서 곱해질 때

역전파는 연쇄 법칙(Chain rule)을 사용한다. 앞쪽 층의 기울기를 구하려면 그 뒤에 이어지는 여러 연산의 미분값을 곱해야 한다. 따라서 각 단계의 변화율이 조금씩 작거나 커도, 여러 층을 거치면 차이가 크게 벌어질 수 있다.

단순히 같은 수를 열 번 곱하는 상황을 생각하면 0.510≈0.000980.5^{10}\approx0.00098이지만 210=10242^{10}=1024이다. 실제 신경망의 기울기는 가중치 행렬과 활성화 함수의 미분값 등이 함께 결정하므로 이 계산과 같지는 않다. 다만 곱셈이 반복될 때 크기가 급격히 달라질 수 있다는 점을 보여 준다.

기울기 크기와 학습률도 구분해야 한다. 학습률을 높이면 작은 기울기의 갱신 폭을 키울 수 있지만, 층마다 기울기 크기가 다르면 다른 층의 갱신이 지나치게 커질 수 있다. 소실을 학습률 하나로 해결하기 어려운 이유이다.

활성화 함수가 기울기 전달에 미치는 영향

시그모이드(Sigmoid)의 미분은 다음과 같다.

σ′(z)=σ(z)(1−σ(z))\sigma'(z)=\sigma(z)\bigl(1-\sigma(z)\bigr)

출력이 0과 1 사이이므로 미분값의 최댓값은 0.25이다. 입력의 절댓값이 커져 출력이 0이나 1에 가까워지면 미분값은 더 작아진다. 이처럼 입력이 변해도 출력이 거의 변하지 않는 구간을 포화(Saturation) 구간이라고 한다. 깊은 은닉층에서 이런 작은 미분값이 반복되면 기울기 소실에 영향을 준다.

렐루(ReLU)는 양수 입력을 그대로 전달하므로 양수 구간의 미분값이 1이다. 이 구간에서는 활성화 함수 자체가 기울기를 줄이지 않는다. 다만 음수 구간에서는 출력과 미분값이 0이므로, 어떤 뉴런에 음수 입력만 계속 들어오면 그 뉴런의 학습이 멈출 수 있다.

리키 렐루(Leaky ReLU)는 음수 구간에도 작은 양의 기울기를 남긴다. 예를 들어 음수 구간의 기울기를 0.01로 두면 그 구간에서도 기울기가 전달된다. 그러나 작은 값이 반복해서 곱해지거나 가중치의 영향이 크면 전체 기울기는 여전히 작아지거나 커질 수 있다. 활성화 함수를 바꾸는 것만으로 모든 소실과 폭주가 사라지는 것은 아니다.

층의 크기와 활성화 함수에 맞춰 초기화하기

가중치 초기화(Weight initialization)는 학습을 시작할 가중치 값을 정하는 과정이다. 가중치가 지나치게 작거나 크면 여러 층을 통과하는 값과 기울기의 크기가 불안정해질 수 있다. 그래서 층의 입력·출력 수와 활성화 함수를 고려해 초기 분포의 크기를 정한다.

자비에 초기화(Xavier initialization)는 입력 수와 출력 수를 함께 고려한다. 히 초기화(He initialization)는 ReLU처럼 입력의 일부 구간을 0으로 만드는 활성화 함수의 특성을 고려한다.

입력 수를 ninn_{\text{in}}, 출력 수를 noutn_{\text{out}}이라 하자. 평균이 0인 정규분포로 가중치를 뽑을 때, Xavier의 기본 배율을 1로 둔 표준편차와 ReLU용 He 초기화에서 입력 수를 기준으로 한 표준편차는 다음과 같다.

Xavier: 2nin+nout,He: 2nin\text{Xavier: }\sqrt{\frac{2}{n_{\text{in}}+n_{\text{out}}}},\qquad \text{He: }\sqrt{\frac{2}{n_{\text{in}}}}

PyTorch에서는 각각 nn.init.xavier_normal_과 nn.init.kaiming_normal_을 사용할 수 있다. He 식에 맞추려면 mode='fan_in', nonlinearity='relu'로 설정한다. 이 식들은 초기 분포를 정하는 기준이며, 학습 내내 같은 분포가 유지된다는 뜻은 아니다.

배치 정규화와 층 정규화의 차이

배치 정규화(Batch normalization)와 층 정규화(Layer normalization)는 중간값을 평균과 분산으로 조정하는 방법이다. 선택한 값들의 묶음에서 평균을 빼고 표준편차에 가까운 값으로 나눈 뒤, 학습 가능한 배율과 이동량을 적용한다.

y=γx−μv+ϵ+βy=\gamma\frac{x-\mu}{\sqrt{v+\epsilon}}+\beta

여기서 μ\mu와 vv는 해당 묶음의 평균과 분산이다. ϵ\epsilon은 분모가 너무 작아지는 것을 막는 작은 양수이고, γ\gamma와 β\beta는 학습하는 배율과 이동량이다. 따라서 최종 출력의 평균이 반드시 0이고 분산이 반드시 1인 것은 아니다.

두 방법의 핵심 차이는 어떤 값들을 한 묶음으로 계산하는가이다. 입력이 배치 크기 B, 특성 수 D인 (B, D) 행렬일 때 비교하면 다음과 같다.

구분BatchNorm1d(D)LayerNorm(D)
훈련 때 평균·분산을 구하는 범위같은 특성의 값을 여러 샘플에 걸쳐 계산한 샘플 안의 D개 특성으로 계산
다른 샘플의 영향같은 배치의 다른 샘플에 영향을 받음다른 샘플과 독립적으로 계산
평가 때 사용하는 통계기본 설정에서는 훈련 중 누적한 이동 통계현재 입력에서 다시 계산한 통계

배치 정규화는 배치가 작으면 통계가 불안정해질 수 있다. 층 정규화는 각 샘플 안에서 계산하므로 이런 배치 구성의 영향을 받지 않는다. 위 비교는 (B, D) 입력에 대한 것이며, 이미지처럼 공간 축이 있는 입력에서는 정규화에 포함되는 축도 확인해야 한다.

배치 정규화를 사용하는 모델은 평가 전에 model.eval()로 전환해야 한다. PyTorch의 기본 설정에서는 이때 현재 배치의 통계 대신 누적한 통계를 사용한다. 반면 층 정규화는 훈련과 평가 모두 현재 입력의 통계를 사용한다.

정규화는 중간값의 크기를 조절해 학습을 안정시키는 데 도움을 준다. 적절한 활성화 함수와 초기화도 함께 고려해야 하며, 정규화 하나가 모든 기울기 문제를 해결한다고 볼 수는 없다.

참고자료

profile
Werde, der du bist!

0개의 댓글