Vanishing/Exploding Gradients (C2W1L10)
딥러닝 모델, 특히 심층 신경망(Deep Neural Network)을 훈련하는 과정에서 경사 소실(Vanishing Gradient) 및 경사 폭발(Exploding Gradient) 문제는 흔히 발생한다. 이 두 가지 문제는 모델의 깊이가 깊어질수록 더욱 심각해지며, 훈련을 어렵게 만드는 주요 요인으로 작용한다.
경사 소실 및 폭발 문제란 무엇인가?
경사 소실 및 폭발 문제는 역전파(Backpropagation) 과정에서 계산되는 미분값, 즉 기울기가 너무 작아지거나 너무 커지는 현상을 의미한다.
- 경사 소실: 기울기가 너무 작아지면 가중치 업데이트가 제대로 이루어지지 않아 학습이 매우 느려지거나 멈춰버리는 문제가 발생한다.
- 경사 폭발: 기울기가 너무 커지면 가중치가 과도하게 업데이트되어 학습이 불안정해지고 발산하는 문제가 발생한다.
이러한 문제는 모델의 깊이가 깊어질수록 더욱 심각해지는데, 이는 역전파 과정에서 여러 개의 가중치를 거치면서 기울기가 계속해서 곱해지기 때문이다.
선형 활성화 함수를 사용한 경우
간단한 이해를 돕기 위해 선형 활성화 함수를 사용하는 경우를 가정해 보자. 이 경우 출력 y는 각 가중치 행렬의 곱으로 표현된다.
$$ y = W^{[L]} W^{[L-1]} \cdots W^{[3]} W^{[2]} W^{[1]} x $$
만약 각 가중치 행렬의 값이 1.5라면, 깊은 신경망에서는 y 값이 기하급수적으로 커질 수 있다. 반대로 0.5와 같이 1보다 작은 값이라면 y 값은 기하급수적으로 작아질 수 있다. 즉, 가중치 값에 따라 출력이 폭발하거나 소실되는 현상이 발생할 수 있다.
왜 문제가 되는가?
최근의 딥러닝 모델은 150개 이상의 층을 가지는 경우가 많으며, Microsoft에서는 852개의 층을 가진 모델을 발표하기도 했다. 이렇게 깊은 신경망에서 활성값이나 경사가 기하급수적으로 증가하거나 감소한다면 학습이 매우 어려워진다. 특히 경사가 너무 작아지는 경우, 경사 하강법 알고리즘이 제대로 작동하지 않아 학습이 거의 불가능하게 된다.
가중치 초기화의 중요성
이러한 문제를 해결하기 위한 방법 중 하나는 가중치 초기화(Weight Initialization)를 신중하게 선택하는 것이다. 적절한 가중치 초기화는 경사 소실 및 폭발 문제를 완화하고, 학습을 안정화시키는 데 큰 도움을 줄 수 있다. 다음 포스팅에서는 가중치 초기화 방법에 대해 자세히 알아보도록 하겠다.
Weight Initialization in a Deep Network (C2W1L11)
신경망 훈련, 특히 심층 신경망(Deep Neural Network) 훈련 과정에서 경사 소실(Vanishing Gradient) 및 경사 폭발(Exploding Gradient) 문제는 매우 중요한 난제이다. 미분값, 즉 기울기가 너무 작아지거나 커져서 훈련이 제대로 이루어지지 않기 때문이다. 이 문제를 완벽하게 해결할 수는 없지만, 가중치 초기화(Weight Initialization)를 신중하게 선택하는 것으로 상당 부분 완화할 수 있다.
가중치 초기화, 왜 중요할까?
깊은 신경망에서 각 층을 거칠 때마다 가중치 행렬이 곱해지면서 값이 증폭되거나 소실될 수 있다. 이는 경사 하강법(Gradient Descent)을 사용하여 네트워크를 훈련할 때, 경사가 너무 작아지면 학습이 매우 느려지거나 멈춰버리고, 너무 커지면 학습이 불안정해지는 결과를 초래한다.
단일 뉴런 예시를 통해 이해하기
단일 뉴런을 예로 들어 가중치 초기화의 중요성을 살펴보겠자. 4개의 입력 특성(\( (x_1) ~ (x_4) \))을 받아 출력 (\( a \) )를 계산하는 뉴런이 있다. (\( z \))는 입력과 가중치의 곱의 합으로 계산되며, bias 항 (\( b \))는 0이라고 가정한다.
$$ z = w_1x_1 + w_2x_2 + ... + w_nx_n $$
\( z \) 값이 너무 크거나 작아지지 않도록 조절해야 하는데, 입력 특성 개수 (\( n \)) 가 클수록 가중치 ( \( w_i \) ) 값은 작아져야 한다. \( z \)는 \( w_i * w_i \) 의 합이므로, 항들이 작아지도록 하는 것이 합리적이다.
합리적인 접근법
\( w_i \) 의 분산을 \( 1/n \)으로 설정하는 것이 한 가지 방법이다. (\( n \)) 은 뉴런에 들어가는 입력 특성 개수이다. 실제 가중치 행렬 \( w^{[l]} \) 을 초기화할 때, `np.random.randn` 함수를 사용하여 무작위 값을 생성하고, 여기에 \( \sqrt{1/n^{[l-1]}} \)을 곱해준다. (n^{[l-1]})은 \( l \)층의 유닛에 들어가는 유닛 개수이다.
w[l] = np.random.randn(shape) * np.sqrt(1/n[l-1])
ReLU 활성화 함수를 사용하는 경우에는 분산을 (1/n) 대신 (2/n)으로 설정하는 것이 더 효과적이다. 가우시안 랜덤 변수를 사용하여 (2/n) 분산을 설정하고, 이 값의 제곱근을 곱해준다.
다양한 가중치 초기화 방법
- tanh 활성화 함수를 사용하는 경우에는 \( \sqrt{1/n^{[l-1]}} \) 을 곱해준다 (Xavier 초기화, 세이비어 초기화).
- 다른 버전의 초기화 방법도 있지만, ReLU 활성화 함수를 사용하는 경우에는 위에 언급한 방법을 사용하는 것이 일반적이다.
마무리
가중치 초기화는 경사 소실 및 폭발 문제를 완화하고, 안정적인 학습을 돕는 중요한 과정이다. 적절한 가중치 초기화를 통해 깊은 신경망을 효과적으로 훈련시킬 수 있다.
Numerical Approximations of Gradients (C2W1L12)
역전파(Backpropagation)는 딥러닝 모델 학습의 핵심 알고리즘이지만, 그 구현 과정은 복잡하고 오류가 발생하기 쉽다. 특히 복잡한 모델의 경우, 수많은 수식을 작성하고 코드를 구현하는 과정에서 예상치 못한 오류가 발생할 수 있다. 이러한 오류를 효과적으로 찾아내고 수정하기 위해 경사 검사(Gradient Checking)라는 유용한 도구가 활용된다.
경사 검사란 무엇인가?
경사 검사는 역전파를 통해 계산된 기울기(gradient) 값이 수치적으로 근사된 기울기와 유사한지 비교하여 역전파 구현의 정확성을 확인하는 방법이다. 만약 두 값이 다르다면 역전파 과정에 오류가 있다는 의미이며, 이를 통해 오류를 수정할 수 있다.
수치적 기울기 근사 방법
경사 검사를 위해 먼저 수치적 기울기를 근사하는 방법을 알아야 한다. 함수 \( f(\theta) = \theta^3 \)을 예로 들어 설명한다.
- 양쪽 차분 (Two-sided Difference)
\( \theta \) 주변의 아주 작은 값 \( \epsilon \)을 사용하여 \( \theta + \epsilon \)과 \( \theta - \epsilon \)에서의 함수 값을 계산한다. 그런 다음 두 점을 잇는 직선의 기울기를 계산한다.
$$ g(\theta) \approx \frac{f(\theta + \epsilon) - f(\theta - \epsilon)}{2\epsilon} $$
이 방법은 중심 차분법이라고도 불리며, \( \theta \)에서의 도함수를 더 정확하게 근사한다. - 편도함수 (Partial Derivative)
\( \theta \)가 벡터인 경우, 각 요소별로 편도함수를 계산한다. 즉, \( \theta_i \)에 대해서만 미분하고, 나머지 \( \theta_j (j \ne i) \)는 상수로 취급한다.
Gradient Checking (C2W1L13)
경사 검사에 대한 이론은 위에 설명되어 있다.
경사 검사 과정, A부터 Z까지
- 매개변수 벡터화: 신경망의 모든 매개변수 \( W^{[1]}, b^{[1]}, ..., W^{[L]}, b^{[L]} \)를 하나의 긴 벡터 \( \theta \)로 변환한다. 각 가중치 행렬 \( W^{[l]} \)은 벡터로 펼쳐지고, 모든 벡터는 연결된다.
- 비용 함수 재정의: 원래 비용 함수 \( J(W, b) \)를 \( \theta \)에 대한 함수 \( J(\theta) \)로 재정의한다.
- 기울기 벡터 계산: 역전파를 통해 각 매개변수에 대한 기울기를 계산하고, 이들을 긴 벡터 \( d \theta \)로 변환한다. \( d \theta \)는 \( \theta \)와 동일한 차원을 갖는다.
- 수치적 기울기 근사: 각 \( \theta_i \) 에 대해 양쪽 차분법을 사용하여 수치적 기울기 \(d \theta_{approx}[i] \)를 계산한다.
$$ d \theta_{approx}[i] = \frac{J(\theta_1, ..., \theta_i + \epsilon, ...) - J(\theta_1, ..., \theta_i - \epsilon, ...)}{2 \epsilon} $$
이때 \( \epsilon \)은 아주 작은 값 (일반적으로 \( 10^{-7} \) 정도)이다. - 두 벡터 비교: \( d \theta_{approx} \)와 \( d \theta \) 두 벡터를 비교하여 유사성을 측정한다. 일반적으로 다음과 같은 정규화된 유클리드 거리를 사용한다.
$$ \frac{||d \theta_{approx} - d \theta||}{||d \theta_{approx}|| + ||d \theta||} $$
경사 검사, 언제 어떻게 활용할까?
- 경사 검사는 계산 비용이 크므로, 훈련 전에만 사용하여 역전파 구현의 정확성을 확인하는 것이 좋다.
- 비교 결과 값이 \( 10^{-7} \) 정도면 매우 좋은 근사이며, \( 10^{-5} \) 정도면 괜찮은 수준이다. 하지만 \( 10^{-3} \)보다 크다면 역전파 과정에 오류가 있을 가능성이 높다.
- 오류가 발견되면 개별 \( \theta_i \)에 대한 \( d \theta_{approx}[i] \)와 \( d \theta[i] \) 값을 비교하여 어떤 부분에서 문제가 발생했는지 추적해야 한다.
마무리
경사 검사는 역전파 구현의 정확성을 확인하는 필수적인 과정이다. 수치적 기울기 근사 방법과 비교 방법을 정확하게 이해해야 한다. 비교 결과 값이 너무 크다면 오류를 의심하고 꼼꼼하게 디버깅해야 한다.
Gradient Checking Implementation Notes (C2W1L14)
위에서 경사 검사의 기본 원리를 알아보았습니다. 이번 포스팅에서는 경사 검사를 실제로 신경망에 적용하는 방법과 유용한 팁들을 공유하고자 합니다.
- 훈련 중에는 경사 검사 Off 디버깅 시에만 On|
경사 검사는 모든 \( i \) 값에 대해 \( d \theta_{approx}[i] \)를 계산하는 데 상당한 시간이 소요된다. 따라서 훈련 과정에서 경사 검사를 계속 실행하면 훈련 속도가 매우 느려질 수 있다. 경사 검사는 디버깅 시에만 활용하고, 훈련 시에는 역전파를 통해 계산된 기울기 \( d \theta \)만 사용하는 것이 효율적이다. - 경사 검사 실패 시, 개별 요소 분석
만약 경사 검사 알고리즘이 실패하여 \( d \theta_{approx} \)와 \( d \theta \)의 차이가 크다면, 개별 요소들을 자세히 살펴봐야 한다. 어떤 \( d \theta_{approx}[i] \) 값이 \( d \theta[i] \) 값과 유독 큰 차이를 보이는지 확인하고, 해당 요소와 관련된 \( W \) 또는 \( b \) 값을 추적하여 버그의 위치를 좁혀나갈 수 있다. - 정규화 항(Regularization Term)도 포함
비용 함수 \( J(\theta) \)에 정규화 항이 포함되어 있다면, 경사 검사 시에도 정규화 항을 고려해야 한다. 즉, \( d \theta \)는 정규화 항에 대한 기울기까지 포함해야 한다. - 드롭아웃(Dropout) 사용 시 주의사항
드롭아웃은 매 반복마다 무작위로 일부 유닛을 제거하기 때문에 비용 함수 \( J(\theta) \) 를 명확하게 정의하기 어렵다. 따라서 드롭아웃을 사용한 상태에서는 경사 검사가 제대로 작동하지 않을 수 있다. 드롭아웃을 사용하는 경우, 드롭아웃을 끈 상태에서 경사 검사를 수행하고, 드롭아웃 구현에 오류가 없는지 확인하는 것이 좋다. - 가중치 초기화 값에 따른 문제 발생 가능성
드물지만, 무작위 초기화된 \( W \) 와 \( b \) 값이 0에 가까울 때만 경사 하강법 구현이 정확하고, 값이 커질수록 부정확해지는 경우가 발생할 수 있다. 이 경우, 작은 무작위 값으로 초기화한 후 잠시 훈련하여 \( W \) 와 \( b \) 값이 0에서 멀어지도록 한 후 경사 검사를 다시 수행하는 것이 좋다.
References
https://www.youtube.com/watch?v=4Ct3Yujl1dk&list=PLkDaE6sCZn6Hn0vK8co82zjQtt3T2Nkqc&index=14
'AI > DL' 카테고리의 다른 글
2nd course: Hyperparameter Tuning, Batch Normalization and Programming Frameworks (C2W3L01 ~ C2W3L10) (0) | 2025.02.01 |
---|---|
2nd course: Optimization algorithms (C2W2L01 ~ C2W2L09) (0) | 2025.01.30 |
Normalizing Inputs (C2W1L09) (0) | 2025.01.30 |
Other Regularization Methods (C2W1L08) (0) | 2025.01.28 |
Understanding Dropout (C2W1L07) (0) | 2025.01.28 |