신경망이 학습을 멈출 때: 기울기 소실 이해

발행: (2025년 12월 29일 오전 03:36 GMT+9)
5 min read
원문: Dev.to

Source: Dev.to

소실되는 그래디언트 문제란?

신경망에서 그래디언트는 오류를 줄이기 위해 각 가중치를 얼마나 변경해야 하는지를 네트워크에 알려줍니다.
그래디언트가 너무 작으면, 네트워크는 극도로 느리게 학습하거나 때로는 완전히 학습을 멈추게 됩니다. 이것이 소실되는 그래디언트 문제입니다.

왜 이런 현상이 발생할까요?

Vanishing gradients usually happen in deep networks, especially with activation functions like sigmoid.

Sigmoid는 입력을 작은 범위인 0~1로 압축합니다. 여러 층을 거쳐 gradient를 계산하면 초기 층의 gradient는 다음과 같이 계산됩니다:

Gradient of layer 1 = Gradient at output × product of gradients of all subsequent layers

각 gradient가 1보다 작기 때문에, 많은 작은 수를 곱하면 매우 작은 gradient가 되어 초기 층에서는 거의 0에 가깝게 됩니다.

Vanishing Gradients 시각화

import numpy as np
import matplotlib.pyplot as plt

# Sigmoid activation
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# Sigmoid gradient
def sigmoid_grad(x):
    s = sigmoid(x)
    return s * (1 - s)

x = np.linspace(-10, 10, 1000)
grad = sigmoid_grad(x)

plt.figure(figsize=(8, 4))
plt.plot(x, grad, label="Sigmoid Gradient")
plt.title("Sigmoid Gradient (Vanishing at Extremes)")
plt.xlabel("Input")
plt.ylabel("Gradient")
plt.grid(True)
plt.legend()
plt.show()

시그모이드 기울기 (극단에서 소멸)

관찰: 큰 양수 또는 음수 입력에 대해 기울기가 매우 작습니다. 이것이 깊은 신경망에서 vanishing gradient 현상을 일으키는 원인입니다.

간단한 딥 네트워크 시뮬레이션

# Simulate deep network gradient
layers = 10
x = 5  # extreme input
grad = 1.0

for i in range(layers):
    grad *= sigmoid_grad(x)  # multiply by each layer's gradient
    print(f"Layer {i+1}, Gradient: {grad:.8f}")

출력

Layer 1, Gradient: 0.00665
Layer 2, Gradient: 0.00004
Layer 3, Gradient: 0.00000
Layer 4, Gradient: 0.00000
Layer 5, Gradient: 0.00000
Layer 6, Gradient: 0.00000
Layer 7, Gradient: 0.00000
Layer 8, Gradient: 0.00000
Layer 9, Gradient: 0.00000
Layer 10, Gradient: 0.00000

관찰: 그래디언트가 빠르게 매우 작아집니다. 초기 레이어는 효과적으로 학습할 수 없습니다.

Mitigation with ReLU

ReLU는 양의 값을 압축하지 않기 때문에, 그래디언트가 쉽게 사라지지 않습니다.

비슷한 깊은 네트워크에서 sigmoidReLU를 비교해 봅시다:

# ReLU activation and gradient
def relu(x):
    return np.maximum(0, x)

def relu_grad(x):
    return np.where(x > 0, 1, 0)

layers = 10
x = 5  # extreme input

# Sigmoid deep gradient
grad_sigmoid = 1.0
grad_relu = 1.0

for i in range(layers):
    grad_sigmoid *= sigmoid_grad(x)
    grad_relu *= relu_grad(x)
    print(f"Layer {i+1}, Sigmoid Grad: {grad_sigmoid:.8f}, ReLU Grad: {grad_relu}")

Output

Layer 1, Sigmoid Grad: 0.00664806, ReLU Grad: 1.0
Layer 2, Sigmoid Grad: 0.00004420, ReLU Grad: 1.0
Layer 3, Sigmoid Grad: 0.00000029, ReLU Grad: 1.0
Layer 4, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0
Layer 5, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0
Layer 6, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0
Layer 7, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0
Layer 8, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0
Layer 9, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0
Layer 10, Sigmoid Grad: 0.00000000, ReLU Grad: 1.0

Observation

  • Sigmoid 그래디언트는 빠르게 사라집니다.
  • 입력이 양수인 한 ReLU 그래디언트는 1을 유지하므로, 더 빠르고 안정적인 학습이 가능합니다.

마무리

이제 소실되는 그래디언트 문제에 대해 명확히 이해하셨길 바랍니다. 활성화 함수와 그래디언트와 함께, 이 개념은 신경망을 이해하기 위한 핵심 구성 요소 중 하나입니다. 앞으로의 기사에서는 이러한 기초를 바탕으로 다음에 무엇이 오는지 탐구할 것입니다.

예제는 Colab notebook에서 직접 실행해 볼 수 있습니다.

Back to Blog

관련 글

더 보기 »