기울기 소실(Gradient Vanishing ) 문제는 딥러닝이 "깊게(Deep)" 쌓일 수 없었던 가장 큰 기술적 장벽 중 하나였습니다.
Gradient Vanishing: 현상과 정의
딥러닝은 역전파(Backpropagation)를 통해 출력층의 오차를 입력층 방향으로 전달하며 가중치를 업데이트합니다. 이때 기울기 소실 이란, 층이 깊어질수록 전달되는 기울기(Gradient) 값이 점점 작아져서 입력층에 가까운 앞쪽 레이어의 가중치들이 거의 업데이트되지 않는 현상 을 말합니다.
결과: 모델의 앞부분이 '학습'을 멈춰버립니다. 뇌로 치면 감각기관은 살아있는데 판단을 내리는 깊은 사고 회로가 굳어버리는 것과 같죠.
체인 룰(Chain Rule) 과 특정 활성화 함수 의 특성이 맞물려 발생하는 현상입니다.
왜 발생하는가? (The Root Cause)
이 문제는 'Sigmoid' 계열의 활성화 함수 와 '체인 룰' 의 합작입니다.
① 깊이(Depth)의 문제: Sigmoid + Chain Rule (곱셈의 저주)
층이 아래로 깊게 쌓일 때 발생하는 전통적인 기울기 소실 원인입니다.
1-a) 활성화 함수의 한계 (Sigmoid의 덫)
시그모이드(Sigmoid \text{Sigmoid} Sigmoid ) 와 하이퍼볼릭 탄젠트(tanh \tanh tanh ) 처럼 출력을 특정 범위로 '압축'하는 함수들에서 주로 발생합니다.
시그모이드: 시그모이드 함수는 입력을 0~1 사이로 압축합니다. 이 함수의 미분값을 구해보면 최댓값이 0.25 밖에 되지 않습니다. 층을 거칠 때마다 신호가 1/4토막 납니다.
Tanh: 출력이 -1 ~ 1 사이라 시그모이드보다 낫지만, 미분 최댓값이 1.0입니다. 하지만 0에서 멀어질수록 미분값이 급격히 0으로 수렴하는 '포화(Saturation)' 현상은 여전해서 깊은 층에서는 여전히 소실 문제가 생깁니다.
반면 ReLU 계열은 x > 0 x > 0 x > 0 일 때 미분이 항상 1이라서, 이론적으로 수천 층을 쌓아도 신호가 그대로 전달됩니다.
1-b) 체인 룰의 누적 효과
역전파는 각 층의 미분값을 계속 곱하며 진행됩니다. 10층짜리 모델이라면?
0.25 × 0.25 × ⋯ × 0.25 ≈ 0.00000095 0.25 \times 0.25 \times \dots \times 0.25 \approx 0.00000095 0 . 2 5 × 0 . 2 5 × ⋯ × 0 . 2 5 ≈ 0 . 0 0 0 0 0 0 9 5
신호가 거의 0에 수렴하게 됩니다. 앞쪽 가중치 입장에서는 "오차가 발생했으니 수정해!"라는 메시지가 너무 작게 들려(0에 가까운 값) 아무런 변화를 일으키지 못하게 됩니다.
② 넓이(Width)의 문제: 분산 제어 실패 (합산의 포화)
한 층의 노드(채널) 개수가 옆으로 아주 넓을 때(Wide Layer) 발생하는 기울기 소실 원인입니다.
1. 수식으로 보는 노드 합산 과정
한 레이어의 특정 노드 출력값 z z z 는 이전 레이어의 모든 노드(n n n 개)로부터 오는 입력값 x x x 와 가중치 w w w 의 선형 결합으로 결정됩니다. (편의상 편향 b = 0 b=0 b = 0 으로 가정)
z = ∑ i = 1 n w i x i z = \sum_{i=1}^{n} w_i x_i z = ∑ i = 1 n w i x i
이때, 입력을 받는 노드의 개수 n n n 이 수만 개로 매우 크다고 가정해 봅시다.
2. 분산 제어 실패의 수학적 근거
입력 x x x 와 가중치 w w w 가 서로 독립이고, 각각 평균이 0이라고 가정할 때, 합산 결과인 z z z 의 분산(V a r Var V a r ) 은 다음과 같이 계산됩니다.
V a r ( z ) = V a r ( ∑ i = 1 n w i x i ) = ∑ i = 1 n V a r ( w i x i ) = n ⋅ V a r ( w ) ⋅ V a r ( x ) Var(z) = Var\left(\sum_{i=1}^{n} w_i x_i\right) = \sum_{i=1}^{n} Var(w_i x_i)= n \cdot Var(w) \cdot Var(x) V a r ( z ) = V a r ( ∑ i = 1 n w i x i ) = ∑ i = 1 n V a r ( w i x i ) = n ⋅ V a r ( w ) ⋅ V a r ( x )
여기서 발생하는 문제 (The n n n Factor)
분산의 폭주: 만약 가중치 초기화 시 분산(V a r ( w ) Var(w) V a r ( w ) )을 적절히 조절하지 못하면, 노드 개수 n n n 이 커질수록 V a r ( z ) Var(z) V a r ( z ) 는 기하급수적으로 커집니다.
신호의 극단화: V a r ( z ) Var(z) V a r ( z ) 가 크다는 것은 합산 결과인 z z z 값이 0 근처에 머물지 않고, 매우 큰 양수나 매우 작은 음수(± ∞ \pm \infty ± ∞ ) 로 퍼져버릴 확률이 높다는 뜻입니다.
3. 결과: 활성화 함수의 포화(Saturation)와 기울기 소실
이제 이 z z z 값이 활성화 함수(예: Sigmoid)를 통과한다고 생각해 봅시다. 시그모이드 함수 σ ( z ) \sigma(z) σ ( z ) 와 그 미분값 σ ′ ( z ) \sigma'(z) σ ′ ( z ) 의 관계는 다음과 같습니다.
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1 + e^{-z}} σ ( z ) = 1 + e − z 1
σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z)(1 - \sigma(z)) σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) )
수학적 연쇄 반응
입력의 비대화: 레이어가 너무 넓어 n n n 이 크면, z z z 값은 분산 법칙에 의해 매우 큰 값(예: z = 10 z=10 z = 1 0 ) 혹은 매우 작은 값(예: z = − 10 z=-10 z = − 1 0 )이 될 가능성이 높습니다.
포화 영역(Saturation Region) 진입: 시그모이드 그래프를 보면 z z z 가 커질수록 출력은 1에 가깝게, z z z 가 작아질수록 0에 가깝게 평평해집니다.
미분값의 소멸:
z = 10 ⟹ σ ( 10 ) ≈ 0.999 ⟹ σ ′ ( 10 ) = 0.999 × ( 1 − 0.999 ) ≈ 0.001 z=10 \implies \sigma(10) \approx 0.999 \implies \sigma'(10) = 0.999 \times (1 - 0.999) \approx 0.001 z = 1 0 ⟹ σ ( 1 0 ) ≈ 0 . 9 9 9 ⟹ σ ′ ( 1 0 ) = 0 . 9 9 9 × ( 1 − 0 . 9 9 9 ) ≈ 0 . 0 0 1
z = 100 ⟹ σ ( 100 ) = 0.99999... ⟹ σ ′ ( 100 ) = 0.99999 × ( 1 − 0.99999... ) ≈ 0 z=100 \implies \sigma(100) = 0.99999... \implies \sigma'(100) = 0.99999\times (1 - 0.99999...) \approx 0 z = 1 0 0 ⟹ σ ( 1 0 0 ) = 0 . 9 9 9 9 9 . . . ⟹ σ ′ ( 1 0 0 ) = 0 . 9 9 9 9 9 × ( 1 − 0 . 9 9 9 9 9 . . . ) ≈ 0
최종 결과: 활성화 함수의 미분값이 0에 수렴하므로, 역전파 시 곱해지는 기울기가 사라지는 Gradient Vanishing 이 발생합니다.
따라서 레이어를 넓게 설계할 때는 단순히 파라미터를 늘리는 것이 아니라, 노드 개수 n n n 에 반비례하도록 가중치의 분산을 조정하는 Xavier 초기화 나 He 초기화 (V a r ( w ) = 2 n Var(w) = \frac{2}{n} V a r ( w ) = n 2 ) 같은 정교한 수학적 장치가 반드시 필요합니다.
깊은 모델: 체인 룰에 의한 '곱셈' 의 누적으로 기울기가 0이 됨.
넓은 모델: 수많은 노드의 '합산' 과정에서 분산이 통제 불능이 되어, 활성화 함수를 '0인 구간(포화 영역)' 으로 밀어버리기 때문에 기울기가 0이 됨.
왜 심각한 문제인가?
딥러닝의 핵심인 계층적 학습(Hierarchical Learning) 이 무너지는 과정을 순서대로 살펴보면, 왜 깊은 모델이 얕은 모델보다 못하게 되는지 명확히 알 수 있습니다.
Step 1: 신호의 단절 (Gradient Vanishing)
현상: 역전파 과정에서 뒤쪽 레이어에서 계산된 오차(Error) 신호가 앞쪽으로 전달되다가 0이 되어 사라집니다.
원인: 활성화 함수의 미분값과 체인 룰의 반복적인 곱셈이 신호를 갉아먹기 때문입니다.
결과: 모델의 '입구'에 해당하는 앞쪽 레이어들은 "무엇을 고쳐야 할지" 에 대한 명령을 전혀 받지 못하는 고립 상태가 됩니다.
Step 2: 앞쪽 레이어의 학습 불능 (Learning Failure)
현상: 명령을 받지 못한 앞쪽 레이어들의 가중치(W W W )가 업데이트되지 않고 초기 랜덤 상태 에 머뭅니다.
구조적 타격: * 원래 앞쪽 레이어는 이미지의 '선, 면, 질감' 같은 기초적인 특징 을 잡아내야 합니다.
하지만 기초 공사가 안 되니, 뒤쪽 레이어들이 아무리 '눈, 코, 입'을 조합하려 해도 재료(기초 특징)가 없어 학습이 불가능해집니다.
결론: 모델 전체가 데이터의 핵심 패턴을 보지 못하는 '눈먼 상태' 가 됩니다.
Step 3: 학습 정체와 언더피팅 (Flat Plateau & Underfitting)
현상: 아무리 학습(Epoch)을 반복해도 L o s s Loss L o s s 그래프가 내려가지 않고 평평하게 유지됩니다.
수학적 이유: 가중치 업데이트 공식 W n e w = W o l d − η × 0 W_{new} = W_{old} - \eta \times \mathbf{0} W n e w = W o l d − η × 0 에 의해 가중치가 변하지 않기 때문입니다.
상태: 이는 공부를 너무 많이 해서 생긴 부작용(Overfitting)이 아니라, 공부하는 방법 자체를 몰라 아예 시작도 못한 상태(Underfitting) 입니다.
Step 4: 최종 결과 - 성능 저하 (Degradation Problem)
역설: 이론적으로 56층 모델은 20층 모델의 기능을 포함해야 하지만, 현실은 20층 모델보다 성능이 낮게 나옵니다.
원인: 깊게 쌓을수록 학습의 통로가 막혀 지능의 활용은커녕 기초 지식조차 습득하지 못하기 때문 입니다.
결론: 결국 Vanishing(원인) 이 쌓여 Learning Failure(과정) 를 만들고, 이것이 Degradation(결과) 이라는 비극으로 완성됩니다.
통로가 막힘: Gradient Vanishing으로 앞쪽 층에 신호 전달 안 됨.
기초가 무너짐: 앞쪽 층이 학습을 못 하니 데이터의 기본 특징 추출 실패.
성장이 멈춤: 가중치 업데이트가 안 되어 L o s s Loss L o s s 가 줄어들지 않는 정체기 발생.
퇴보함 (Degradation): 깊은 모델이 얕은 모델보다 멍청해지는 성능 저하 발생.
어떻게 해결하는가? (The Solutions)
데이터 과학자들이 이 절망적인 상황을 해결하기 위해 내놓은 3가지 핵심 전략입니다.
① 활성화 함수의 교체: ReLU의 등장
가장 확실한 해결책은 미분해도 값이 작아지지 않는 함수를 쓰는 것입니다. ReLU 는 x > 0 x > 0 x > 0 일 때 미분값이 항상 1 입니다. 1은 아무리 곱해도 1이기 때문에 신호가 소실되지 않고 입력층까지 끝까지 전달됩니다.
선형적 미분값: Sigmoid는 미분값의 최댓값이 0.25에 불과해 층이 깊어지면 금방 0이 되지만, ReLU는 입력이 0보다 크기만 하면 미분값이 항상 1입니다.
기울기 유지: 1 × 1 × 1 … 1 \times 1 \times 1 \dots 1 × 1 × 1 … 을 아무리 많이 해도 값은 1로 유지되죠. 덕분에 수십, 수백 개의 층을 쌓아도 기울기가 소실되지 않고 그대로 보존됩니다.
단점: 다만, 입력이 0보다 작으면 미분값이 0이 되어 뉴런이 죽어버리는 Dying ReLU 현상이 생길 수 있는데, 이를 보완하기 위해 배치 정규화나 Leaky ReLU 등을 함께 사용합니다.
② 가중치 초기화 (Weight Initialization)
처음 가중치를 정할 때 너무 크거나 작지 않게 적절히 분산을 맞춰주는 기법입니다. Xavier 초기화 나 He 초기화 가 대표적이며, 이를 통해 신호가 전달되는 통로를 매끄럽게 닦아줍니다.
과거에는 가중치를 단순히 표준정규분포(평균 0, 표준편차 1)로 초기화했습니다. 하지만 이 경우 층이 깊어질수록 활성화 값들이 0이나 1로 쏠리면서 기울기가 사라지는 문제가 생겼죠.
Xavier (Glorot) 초기화: Sigmoid나 Tanh 함수에 최적화되어 있습니다. 앞뒤 층의 노드 수에 맞춰 가중치 범위를 조절하여, 출력값의 분산이 일정하게 유지되도록 돕습니다.
He 초기화: ReLU 함수를 쓸 때 필수입니다. ReLU는 음수 영역을 버리기 때문에 분산이 절반으로 줄어드는데, He 초기화는 이를 보완하기 위해 가중치를 더 넓게(2 / n \sqrt{2/n} 2 / n ) 퍼뜨려 초기화합니다.
효과: 층이 깊어져도 데이터의 흐름(Variance)이 죽지 않고 마지막까지 전달됩니다.
③ 배치 정규화 (Batch Normalization)
각 층을 통과할 때마다 데이터의 분포를 강제로 정규화하여, 활성화 함수의 미분값이 급격히 작아지는 구간(Saturation region)에 빠지지 않도록 잡아주는 역할을 합니다.
Sigmoid나 Tanh 같은 함수는 입력값이 커지거나 작아지면 미분값이 0에 가까워지는 포화 영역(Saturation Region) 이 존재합니다.
분포의 고정: 배치 정규화는 활성화 함수를 통과하기 전 데이터의 분포를 평균 0, 표준편차 1로 강제 조정합니다.
활성화 함수의 중심부 활용: 데이터를 정규화하면 값이 대부분 미분값이 살아있는(기울기가 큰) 함수의 중심부에 위치하게 됩니다.
결과: 미분값이 급격히 작아지는 구간에 빠지지 않으니, 역전파 시 기울기가 죽지 않고 하위 층까지 잘 전달됩니다.
④ 잔차 연결 (Residual Connection - ResNet)
층을 거칠수록 정보가 손실된다면, 이전 층의 정보를 그대로 다음 층에 더해주는 방법입니다.
지름길 (Skip Connection): 입력값 x x x 를 단순히 쌓인 층(F(x))에 통과시키는 게 아니라, 나중에 원래의 x x x 를 다시 더해줍니다 (H ( x ) = F ( x ) + x H(x) = F(x) + x H ( x ) = F ( x ) + x ).
미분의 마법: 역전파(Backpropagation) 시, 미분 기호가 더하기(+)를 만나면 기울기가 최소 '1'은 확보됩니다.
공식: ∂ ( F ( x ) + x ) ∂ x = ∂ F ( x ) ∂ x + 1 \frac{\partial (F(x) + x)}{\partial x} = \frac{\partial F(x)}{\partial x} + 1 ∂ x ∂ ( F ( x ) + x ) = ∂ x ∂ F ( x ) + 1
결과: 아무리 층이 깊어져도 이 '+1' 덕분에 기울기가 0이 되지 않고 입력층까지 안전하게 배달됩니다. 덕분에 152층 같은 초거대 모델도 학습이 가능해진 것이죠.
번외) 그럼에도 sigmoid function을 쓰는 이유 (3가지)
시그모이드는 "데이터를 특징으로 변환하는 과정"에는 부적합하지만, "최종 판단을 내리는 과정" 에는 최고의 도구입니다.
① 확률로 해석하기 (Probability Mapping)
딥러닝의 결과값이 15.7이나 -3.2처럼 제각각이면 해석하기 어렵습니다.
시그모이드는 어떤 값이 들어와도 0과 1 사이로 매핑해줍니다."이 사진이 고양이일 확률이 0.92(92%) 다"라고 말하고 싶을 때, 시그모이드만큼 직관적인 함수가 없습니다.
② 이진 분류(Binary Classification)의 제왕
"스팸인가 아닌가?", "암인가 아닌가?"처럼 답이 두 개인 문제에서 마지막 출력층은 반드시 0~1 사이의 값을 내뱉어야 합니다.
이때 시그모이드는 결정 경계(Decision Boundary) 를 만드는 핵심 역할을 합니다.
③ 게이트(Gate) 컨트롤 (LSTM, GRU 등)
RNN이나 LSTM 같은 모델 들어보셨죠? 여기서 시그모이드는 '정보를 얼마나 통과시킬지' 결정하는 문지기 역할을 합니다.
시그모이드 값이 0.9면 "정보의 90%를 기억해!", 0.1이면 "10%만 남기고 다 버려!"라는 식으로 스위치 역할을 수행합니다.
Activation Function의 전략적 배치: "중간은 ReLU, 끝은 Sigmoid"
현대 딥러닝 블로그에서 권장하는 표준 공식은 이렇습니다.
Input → \to → Hidden Layers: ReLU 사용 (기울기 소실 방지, 빠른 학습)
Hidden → \to → Output Layer: Sigmoid 혹은 Softmax 사용 (결과를 확률로 해석)