본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 신경망(ANN) 활성화 함수 ReLU vs Sigmoid 2가지 핵심 역할과 성능 해결 방법

by Papa Martino V 2026. 4. 9.
728x90

ReLU vs Sigmoid
ReLU vs Sigmoid

 

 

딥러닝 모델이 단순히 거대한 선형 회귀 모델에 그치지 않고 복잡한 패턴을 학습할 수 있는 이유는 무엇일까요? 그 핵심은 바로 활성화 함수(Activation Function)에 있습니다. 활성화 함수는 입력 신호의 총합을 출력 신호로 변환하는 '문지기' 역할을 하며, 신경망에 비선형성(Non-linearity)을 부여합니다. 만약 활성화 함수가 없다면 아무리 층을 깊게 쌓아도 결국 하나의 선형 함수로 환원되어 복잡한 데이터를 처리할 수 없게 됩니다. 본 포스팅에서는 실무에서 가장 많이 사용되는 ReLUSigmoid의 원리와 차이점을 심층 분석하고, 기울기 소실(Vanishing Gradient) 문제를 해결하기 위한 파이썬 기반의 7가지 실무 구현 예제를 제공합니다.


1. 활성화 함수의 본질적 역할: 왜 비선형이어야 하는가?

신경망의 각 층은 $y = Wx + b$라는 선형 연산을 수행합니다. 활성화 함수 $f(y)$가 없다면 여러 층의 연산은 $y = W_n(...(W_1x + b_1)...) + b_n$이 되어 결국 하나의 행렬 곱으로 요약됩니다. 활성화 함수의 역할은 다음과 같습니다.

  • 비선형성 주입: 현실 세계의 복잡하고 구부러진 데이터 경계선을 학습하게 합니다.
  • 희소 활성화(Sparse Activation): 특정 뉴런만 활성화하여 연산 효율성을 높입니다.
  • 신호 강도 조절: 입력 신호의 크기에 따라 다음 층으로 전달할 에너지의 양을 결정합니다.

2. ReLU vs Sigmoid: 주요 특성 및 결정적 차이

과거에는 Sigmoid가 주류였으나, 현대 딥러닝에서는 ReLU가 표준으로 자리 잡았습니다. 두 함수의 차이를 표로 정리했습니다.

항목 시그모이드 (Sigmoid) 렐루 (ReLU)
수식 $\sigma(x) = \frac{1}{1 + e^{-x}}$ $f(x) = \max(0, x)$
출력 범위 0.0 ~ 1.0 (확률 해석 용이) 0.0 ~ $\infty$
장점 부드러운 미분, 이진 분류에 최적 연산 속도가 빠르고 기울기 소실 해결
단점 기울기 소실(Vanishing Gradient) 죽은 렐루(Dying ReLU) 현상 발생 가능
주요 용도 이진 분류의 출력층 심층 신경망의 은닉층(Hidden Layers)

3. [Practical Examples] 파이썬 실무 적용을 위한 활성화 함수 코드 7선

개발자가 모델 설계 시 즉시 활용할 수 있는 파이썬(NumPy, PyTorch, TensorFlow) 기반의 구현 예제입니다.

Example 1: NumPy를 이용한 Sigmoid와 미분 값 구현

import numpy as np

def sigmoid(x):
    # 시그모이드는 0~1 사이로 값을 압축합니다.
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    # 미분값이 최대 0.25로 작아져 기울기 소실의 원인이 됩니다.
    s = sigmoid(x)
    return s * (1 - s)

data = np.array([-2, 0, 2])
print(f"Sigmoid: {sigmoid(data)}")
    

Example 2: 딥러닝의 표준, ReLU 구현 및 특징

def relu(x):
    # 0보다 작으면 0, 크면 그대로 반환하여 연산이 매우 빠릅니다.
    return np.maximum(0, x)

# 음수 영역은 기울기가 0이 되어 뉴런이 죽는 현상을 주의해야 합니다.
    

Example 3: '죽은 렐루' 문제를 해결하는 Leaky ReLU

def leaky_relu(x, alpha=0.01):
    # 음수 영역에도 아주 작은 기울기를 주어 학습을 유지합니다.
    return np.where(x > 0, x, x * alpha)
    

Example 4: PyTorch 신경망에서의 활성화 함수 적용 방법

import torch.nn as nn

class SimpleANN(nn.Module):
    def __init__(self):
        super(SimpleANN, self).__init__()
        self.fc1 = nn.Linear(784, 128)
        self.relu = nn.ReLU() # 은닉층은 ReLU 권장
        self.fc2 = nn.Linear(128, 1)
        self.sigmoid = nn.Sigmoid() # 이진 분류 출력층

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.sigmoid(self.fc2(x))
        return x
    

Example 5: TensorFlow/Keras에서의 원라인(One-line) 적용

from tensorflow.keras import layers

model = layers.Dense(64, activation='relu') # 레이어 생성과 동시에 지정
    

Example 6: 부드러운 전이를 위한 Softplus 함수

def softplus(x):
    # ReLU의 미분 불가능한 점(0)을 보완한 매끄러운 곡선 함수입니다.
    return np.log(1 + np.exp(x))
    

Example 7: 다중 분류를 위한 Softmax (출력층 전용)

def softmax(x):
    # 모든 출력의 합을 1로 만들어 확률 분포로 변환합니다.
    exp_x = np.exp(x - np.max(x)) # 오버플로우 방지
    return exp_x / exp_x.sum()
    

4. 활성화 함수 선택 시 발생하는 문제와 해결 전략

모델 학습이 제대로 이루어지지 않는다면 활성화 함수 선택을 재점검해야 합니다.

  1. 기울기 소실(Vanishing Gradient) 해결: 층이 깊은 모델에서 Sigmoid를 사용하면 하위 층으로 갈수록 기울기가 0에 수렴합니다. 이때는 반드시 ReLU 계열로 교체하십시오.
  2. Dying ReLU 해결: 가중치 업데이트가 너무 커서 특정 뉴런의 입력이 계속 음수가 되면 해당 뉴런은 죽습니다. 이를 방지하기 위해 Leaky ReLUELU를 대안으로 사용하세요.
  3. 출력 범위의 일치: 회귀 문제에서는 출력층에 활성화 함수를 쓰지 않거나(Linear), 확률이 필요하면 Sigmoid/Softmax를 사용하는 등 목적에 맞게 배치해야 합니다.

5. 결론 및 요약

활성화 함수는 신경망이 '사고'할 수 있는 유연성을 제공합니다. Sigmoid는 확률적 해석이 필요한 마지막 단계에서, ReLU는 빠르고 깊은 학습이 필요한 모든 중간 단계에서 그 가치를 발휘합니다. 실무자라면 각 함수의 수학적 한계를 인지하고 데이터의 특성에 따라 Leaky ReLU나 ELU 같은 변형 함수를 적재적소에 배치하는 능력이 필요합니다.

 

[내용 출처]
1. Deep Learning (Ian Goodfellow, Yoshua Bengio, Aaron Courville)
2. CS231n: Convolutional Neural Networks for Visual Recognition (Stanford University)
3. Neural Networks and Deep Learning (Michael Nielsen)

728x90