Skip to main content

활성화 함수

학습 목표

  • 활성화 함수(Activation Function)가 왜 필요한지 설명할 수 있다
  • 주요 활성화 함수(Sigmoid, Tanh, ReLU, GELU, SiLU)의 수학적 특성을 비교할 수 있다
  • 기울기 소실(Gradient Vanishing) 문제와 활성화 함수의 관계를 이해한다
  • 상황에 맞는 활성화 함수를 선택할 수 있다

왜 중요한가

활성화 함수가 없으면 여러 층을 쌓아도 결과는 하나의 선형 변환과 동일합니다. f(W2(W1x))=Wxf(\mathbf{W}_2(\mathbf{W}_1 \mathbf{x})) = \mathbf{W}' \mathbf{x}. 활성화 함수는 **비선형성(Nonlinearity)**을 도입하여 신경망이 복잡한 함수를 학습할 수 있게 만드는 핵심 요소입니다.

Sigmoid

σ(x)=11+ex\sigma(x) = \frac{1}{1 + e^{-x}} 출력 범위가 (0,1)(0, 1)이므로 확률로 해석할 수 있어, 이진 분류의 출력층에서 사용됩니다.
import torch
import torch.nn as nn

sigmoid = nn.Sigmoid()
x = torch.linspace(-5, 5, 100)
y = sigmoid(x)

# 기울기 확인
x_grad = torch.tensor([0.0, 2.0, -2.0, 5.0], requires_grad=True)
output = sigmoid(x_grad)
output.sum().backward()
print(f"기울기: {x_grad.grad}")
# x=0에서 최대 0.25, |x|가 크면 거의 0 (기울기 소실)
한계:
  • 기울기 소실: x|x|가 크면 기울기가 거의 0이 되어 학습이 멈춤
  • 비대칭 출력: 출력이 항상 양수(0~1)이므로 가중치 업데이트가 비효율적
  • 지수 연산: exp() 계산 비용이 상대적으로 높음

Tanh

tanh(x)=exexex+ex=2σ(2x)1\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} = 2\sigma(2x) - 1 출력 범위가 (1,1)(-1, 1)로 원점 대칭이어서 Sigmoid보다 학습이 안정적입니다. RNN 계열에서 자주 사용됩니다.
tanh = nn.Tanh()
x = torch.tensor([-3.0, -1.0, 0.0, 1.0, 3.0])
print(f"tanh 출력: {tanh(x)}")
# 원점 대칭: 음수 입력 → 음수 출력
특성: Sigmoid와 동일한 기울기 소실 문제를 가지지만, 출력이 원점 대칭이라 Sigmoid보다 은닉층에서 선호됩니다.

ReLU (Rectified Linear Unit)

ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x) 2012년 AlexNet 이후 딥러닝의 기본 활성화 함수로 자리 잡았습니다. 양수 영역에서 기울기가 항상 1이므로 기울기 소실 문제를 크게 완화합니다.
relu = nn.ReLU()
x = torch.tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
print(f"ReLU 출력: {relu(x)}")
# 출력: [0., 0., 0., 1., 2.]
장점:
  • 양수 영역에서 기울기 = 1 → 기울기 소실 완화
  • 계산이 매우 빠름 (단순 비교 연산)
  • 희소 활성화(Sparse Activation): 일부 뉴런만 활성화
한계 — Dead ReLU 문제: 음수 입력에서 기울기가 0이므로, 한번 비활성화된 뉴런은 영구적으로 학습이 중단될 수 있습니다.

ReLU 변형들

Leaky ReLU

LeakyReLU(x)={xif x>0αxif x0\text{LeakyReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha x & \text{if } x \leq 0 \end{cases} 음수 영역에 작은 기울기(α=0.01\alpha = 0.01)를 부여하여 Dead ReLU 문제를 완화합니다.
leaky_relu = nn.LeakyReLU(negative_slope=0.01)
x = torch.tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
print(f"Leaky ReLU: {leaky_relu(x)}")
# 출력: [-0.02, -0.01, 0., 1., 2.]

PReLU (Parametric ReLU)

Leaky ReLU에서 α\alpha를 학습 가능한 파라미터로 만든 버전입니다.
prelu = nn.PReLU(num_parameters=1)  # α가 학습됨

GELU (Gaussian Error Linear Unit)

GELU(x)=xΦ(x)xσ(1.702x)\text{GELU}(x) = x \cdot \Phi(x) \approx x \cdot \sigma(1.702x) 여기서 Φ(x)\Phi(x)는 표준 정규 분포의 누적 분포 함수(CDF)입니다. 입력값에 확률적 가중치를 부여하여, 입력이 클수록 그대로 통과하고 작을수록 억제됩니다.
gelu = nn.GELU()
x = torch.tensor([-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0])
print(f"GELU 출력: {gelu(x)}")
# 음수 영역에서 부드럽게 억제, 양수 영역에서 거의 항등
Transformer 계열 모델(BERT, GPT 등)의 표준 활성화 함수입니다. ReLU와 달리 미분이 연속이어서 최적화가 안정적입니다.

SiLU / Swish

SiLU(x)=xσ(x)=x1+ex\text{SiLU}(x) = x \cdot \sigma(x) = \frac{x}{1 + e^{-x}} Google Brain이 자동 탐색(AutoML)으로 발견한 활성화 함수입니다. GELU와 유사한 형태이며, EfficientNet 등에서 사용됩니다.
silu = nn.SiLU()
x = torch.tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
print(f"SiLU 출력: {silu(x)}")

활성화 함수 비교

함수수식출력 범위기울기 소실주 사용처
Sigmoid11+ex\frac{1}{1+e^{-x}}(0, 1)심각이진 분류 출력층
Tanhexexex+ex\frac{e^x-e^{-x}}{e^x+e^{-x}}(-1, 1)있음RNN 은닉층
ReLUmax(0,x)\max(0,x)[0, ∞)완화CNN, MLP 기본
Leaky ReLUmax(αx,x)\max(\alpha x, x)(-∞, ∞)완화Dead ReLU 방지
GELUxΦ(x)x\Phi(x)≈(-0.17, ∞)완화Transformer
SiLUxσ(x)x\sigma(x)≈(-0.28, ∞)완화EfficientNet

선택 기준

Softmax는 다중 클래스 분류의 출력층에서 사용되며, 여러 값을 확률 분포로 변환합니다. 엄밀히는 정규화 함수이지만, 출력층의 활성화 함수 역할을 합니다. PyTorch에서는 nn.CrossEntropyLoss가 내부적으로 Softmax를 포함하므로 별도로 적용하지 않는 것이 일반적입니다.
실험적으로 Transformer에서는 GELU가 ReLU보다 좋은 성능을 보이지만, CNN에서는 ReLU가 여전히 효과적입니다. GELU는 계산 비용이 약간 더 높으므로, 모델 크기와 태스크에 따라 선택해야 합니다.

체크리스트

  • 활성화 함수 없이 다층 네트워크를 쌓으면 왜 의미가 없는지 설명할 수 있다
  • Sigmoid의 기울기 소실 문제를 ReLU가 어떻게 완화하는지 이해한다
  • GELU가 Transformer에서 선호되는 이유를 설명할 수 있다
  • 출력층과 은닉층에서 적절한 활성화 함수를 선택할 수 있다

다음 문서