Open In Colab

4 활성화 함수 (Activation Functions)

“만약 당신이 무엇을 하고 있는지 정확히 안다면, 그것은 연구가 아니다.” - 알버트 아인슈타인

딥러닝의 역사에서 활성화 함수와 최적화 기법은 매우 중요한 발전을 이루어 왔습니다. 1943년 McCulloch-Pitts의 인공 뉴런 모델이 처음 등장했을 때는 단순한 임계값 함수(계단 함수)만을 사용했습니다. 이는 뉴런이 특정 임계값을 넘어서는 입력에 대해서만 활성화되는 생물학적 뉴런의 동작 방식을 모방한 것이었습니다. 하지만 이러한 단순한 형태의 활성화 함수는 신경망이 복잡한 함수를 표현하는 데 한계가 있었습니다.

1980년대까지 머신러닝은 특성 공학(feature engineering)과 정교한 알고리즘 설계에 중점을 두었습니다. 신경망은 여러 머신러닝 알고리즘 중 하나에 불과했으며, SVM(Support Vector Machine)이나 Random Forest와 같은 전통적인 알고리즘들이 더 우수한 성능을 보이는 경우가 많았습니다. 예를 들어, MNIST 손글씨 인식 문제에서 SVM은 2012년까지 최고의 정확도를 유지했습니다.

2012년 AlexNet는 GPU를 활용한 효율적인 학습으로 ImageNet 챌린지에서 압도적인 성능을 달성했고, 이는 딥러닝 시대의 본격적인 시작을 알렸습니다. 2017년 구글의 트랜스포머(Transformer) 아키텍처는 이러한 혁신을 더욱 발전시켰으며, 오늘날 GPT-4, Gemini와 같은 대규모 언어 모델(LLM)의 기반이 되었습니다.

이러한 발전의 중심에는 활성화 함수의 진화최적화 기법의 발전이 있었습니다. 이번 장에서는 활성화 함수에 대해 자세히 살펴보면서, 여러분이 새로운 모델을 개발하고 복잡한 문제를 해결하는 데 필요한 이론적 기반을 제공하고자 합니다.

4.1 활성화 함수: 신경망에 비선형성을 도입

연구자의 고뇌: 초기 신경망 연구자들은 선형 변환만으로는 복잡한 문제를 해결할 수 없다는 것을 깨달았습니다. 하지만 어떤 비선형 함수를 사용해야 신경망이 효과적으로 학습하고, 다양한 문제를 해결할 수 있을지는 명확하지 않았습니다. 생물학적 뉴런의 동작을 모방하는 것이 최선의 방법일까? 아니면 더 나은 수학적, 계산적 특성을 가진 다른 함수가 있을까요?

활성화 함수는 신경망 층 사이에 비선형성을 부여하는 핵심 요소입니다. 1.4.1절에서 언급한 보편 근사 정리(Universal Approximation Theorem) (1988년)는 하나의 은닉층과 비선형 활성화 함수를 가진 신경망이 어떠한 연속 함수도 근사할 수 있다는 것을 증명했습니다. 즉, 활성화 함수는 층을 분리하고 비선형성을 부여함으로써, 신경망이 단순한 선형 모델의 한계를 넘어 범용적인 함수 근사기(universal function approximator)로 동작할 수 있게 합니다.

4.1.1 활성화 함수가 필요한 이유: 선형성의 한계 극복

활성화 함수가 없다면, 아무리 많은 층을 쌓아도 신경망은 결국 선형 변환에 불과하게 됩니다. 이는 다음과 같이 간단하게 증명할 수 있습니다.

두 개의 선형 변환을 연속으로 적용하는 경우를 생각해 봅시다.

  • 첫 번째 층: \(y_1 = W_1x + b_1\)
  • 두 번째 층: \(y_2 = W_2y_1 + b_2\)

여기서 \(x\)는 입력, \(W_1\), \(W_2\)는 가중치 행렬, \(b_1\), \(b_2\)는 편향 벡터입니다. 두 번째 층의 식에 첫 번째 층의 식을 대입하면:

\(y_2 = W_2(W_1x + b_1) + b_2 = (W_2W_1)x + (W_2b_1 + b_2)\)

새로운 가중치 행렬 \(W' = W_2W_1\)과 새로운 편향 벡터 \(b' = W_2b_1 + b_2\)를 정의하면,

\(y_2 = W'x + b'\)

이는 결국 하나의 선형 변환과 동일합니다. 아무리 많은 층을 쌓아도 마찬가지입니다. 결국, 선형 변환만으로는 복잡한 비선형 관계를 표현할 수 없습니다.

4.1.2 활성화 함수의 진화: 생물학적 모방에서 효율적 계산으로

  • 1943년, McCulloch-Pitts 뉴런: 최초의 인공 뉴런 모델에서는 단순한 임계값 함수(threshold function), 즉 계단 함수(step function)를 사용했습니다. 이는 뉴런이 특정 임계값을 넘어서는 입력에 대해서만 활성화되는 생물학적 뉴런의 동작 방식을 모방한 것이었습니다.

    \[ f(x) = \begin{cases} 1, & \text{if } x \ge \theta \\ 0, & \text{if } x < \theta \end{cases} \]

    여기서 \(\theta\)는 임계값입니다.

  • 1960년대, 시그모이드(Sigmoid) 함수: 생물학적 뉴런의 발화율(firing rate)을 더 부드럽게 모델링하기 위해 시그모이드 함수가 도입되었습니다. 시그모이드 함수는 S자 모양의 곡선으로, 입력값을 0과 1 사이의 값으로 압축합니다.

    \[ \sigma(x) = \frac{1}{1 + e^{-x}} \]

    시그모이드 함수는 미분 가능하다는 장점이 있어, 경사 하강법(gradient descent) 기반의 학습 알고리즘을 적용할 수 있게 했습니다. 하지만, 시그모이드 함수는 심층 신경망에서 그래디언트 소실 문제(vanishing gradient problem)를 일으키는 원인 중 하나로 지목되었습니다. 입력값이 매우 크거나 작을 때, 시그모이드 함수의 기울기(미분값)가 0에 가까워져, 학습이 느려지거나 멈추는 현상입니다.

  • 2010년, ReLU(Rectified Linear Unit): Nair와 Hinton은 ReLU 함수를 제안하여 심층 신경망 학습의 새로운 시대를 열었습니다. ReLU는 매우 단순한 형태를 가집니다.

    \[ ReLU(x) = \max(0, x) \]

    ReLU는 입력이 0보다 크면 입력을 그대로 출력하고, 0보다 작으면 0을 출력합니다. ReLU는 시그모이드 함수와 달리 그래디언트 소실 문제가 덜 발생하고, 계산 효율성이 높다는 장점이 있습니다. 이러한 장점 덕분에 ReLU는 심층 신경망의 성공에 크게 기여했으며, 현재 가장 널리 사용되는 활성화 함수 중 하나입니다.

4.1.3 활성화 함수의 선택: 모델 규모, 태스크, 그리고 효율성

활성화 함수의 선택은 모델의 성능과 효율성에 큰 영향을 미칩니다.

  • 대규모 언어 모델(LLM): 계산 효율성이 매우 중요하기 때문에, 단순한 활성화 함수를 선호하는 경향이 있습니다. Llama 3, GPT-4, Gemini 등 최신 기반 모델들은 GELU(Gaussian Error Linear Unit)나 ReLU와 같이 단순하고 효율적인 활성화 함수를 채택하고 있습니다. 특히 Gemini 1.5는 MoE(Mixture of Experts) 아키텍처를 도입하여 각 전문가 네트워크(expert network)별로 최적화된 활성화 함수를 사용합니다.

  • 특수 목적 모델: 특정 태스크에 최적화된 모델을 개발할 때는 더 정교한 접근 방식이 시도되기도 합니다. 예를 들어, TEAL과 같은 최신 연구에서는 활성화 희소성(activation sparsity)을 통해 추론 속도를 최대 1.8배까지 향상시키는 방법이 제안되었습니다. 또한, 입력 데이터에 따라 동적으로 동작을 조정하는 적응형 활성화 함수(adaptive activation functions)를 사용하는 연구도 진행되고 있습니다.

활성화 함수의 선택은 모델의 규모, 태스크의 특성, 가용한 계산 자원, 그리고 요구되는 성능 특성(정확도, 속도, 메모리 사용량 등)을 종합적으로 고려하여 이루어져야 합니다.

4.2 활성화 함수의 비교

도전과제: 수많은 활성화 함수 중에서 어떤 함수가 특정 문제와 아키텍처에 가장 적합할까?

연구자의 고뇌: 2025년 현재 500여 개의 활성화 함수가 제안되었지만, 모든 상황에 완벽한 활성화 함수는 존재하지 않습니다. 연구자들은 각 함수의 특성을 이해하고, 문제의 특성과 모델 아키텍처, 계산 자원 등을 고려하여 최적의 활성화 함수를 선택하거나, 심지어 새로운 활성화 함수를 개발해야 했습니다.

활성화 함수에 일반적으로 요구되는 성질은 다음과 같습니다. 1. 신경망에 비선형 곡률을 추가해야 합니다 2. 훈련이 어려워질 정도로 계산의 복잡성을 증가시키지 않아야 합니다 3. 그래디언트의 흐름을 방해하지 않도록 미분 가능해야 합니다 4. 훈련시 신경망 각 층에서 데이터의 분포가 적절해야 합니다

이러한 요구사항에 적합하면서 효율적인 활성화 함수가 많이 제안되었습니다. 어떤 활성화 함수가 가장 좋은가는 한마디로 말할 수 없습니다. 훈련하는 모델과 데이터 등에 따라 달라지기 때문입니다. 최적의 활성화 함수를 찾는 방법은 실제 테스트를 해보는 것입니다.

2025년 현재 활성화 함수는 크게 세 가지 범주로 분류됩니다. 1. 고전적 활성화 함수: Sigmoid, Tanh, ReLU 등 고정된 형태의 함수입니다. 2. 적응형 활성화 함수: PReLU, TeLU, STAF 등 학습 과정에서 형태가 조정되는 매개변수를 포함합니다. 3. 특화된 활성화 함수: ENN(Expressive Neural Network), Physics-informed 활성화 함수 등 특정 도메인에 최적화된 함수입니다.

이 장에서 여러 활성화 함수를 비교합니다. 대부분 파이토치에 구현된 것을 중심으로 할 것이지만 Swish, STAF 같이 구현이 안된 것은 nn.Module을 상속받아 새로 만듭니다. 전체 구현은 chapter_04/models/activations.py에 있습니다.

4.2.1 활성화 함수 생성

Code
!pip install dldna[colab] # in Colab
# !pip install dldna[all] # in your local

%load_ext autoreload
%autoreload 2
Code
import torch
import torch.nn as nn
import numpy as np

# Set seed
np.random.seed(7)
torch.manual_seed(7)

# STAF (Sinusoidal Trainable Activation Function)
class STAF(nn.Module):
    def __init__(self, tau=25):
        super().__init__()
        self.tau = tau
        self.C = nn.Parameter(torch.randn(tau))
        self.Omega = nn.Parameter(torch.randn(tau))
        self.Phi = nn.Parameter(torch.randn(tau))

    def forward(self, x):
        result = torch.zeros_like(x)
        for i in range(self.tau):
            result += self.C[i] * torch.sin(self.Omega[i] * x + self.Phi[i])
        return result

# TeLU (Trainable exponential Linear Unit)
class TeLU(nn.Module):
    def __init__(self, alpha=1.0):
        super().__init__()
        self.alpha = nn.Parameter(torch.tensor(alpha))

    def forward(self, x):
        return torch.where(x > 0, x, self.alpha * (torch.exp(x) - 1))

# Swish (Custom Implementation)
class Swish(nn.Module):
    def forward(self, x):
        return x * torch.sigmoid(x)

# Activation function dictionary
act_functions = {
    # Classic activation functions
    "Sigmoid": nn.Sigmoid,     # Binary classification output layer
    "Tanh": nn.Tanh,          # RNN/LSTM

    # Modern basic activation functions
    "ReLU": nn.ReLU,          # CNN default
    "GELU": nn.GELU,          # Transformer standard
    "Mish": nn.Mish,          # Performance/stability balance

    # ReLU variants
    "LeakyReLU": nn.LeakyReLU,# Handles negative inputs
    "SiLU": nn.SiLU,          # Efficient sigmoid
    "Hardswish": nn.Hardswish,# Mobile optimized
    "Swish": Swish,           # Custom implementation

    # Adaptive/trainable activation functions
    "PReLU": nn.PReLU,        # Trainable slope
    "RReLU": nn.RReLU,        # Randomized slope
    "TeLU": TeLU,             # Trainable exponential
    "STAF": STAF             # Fourier-based
}

STAF는 2025년 ICLR에서 소개된 최신 활성화 함수로 푸리에 급수 기반의 학습 가능한 매개변수를 사용합니다. ENN은 DCT를 활용하여 네트워크의 표현력을 향상시키는 방식을 채택했습니다. TeLU는 ELU의 확장된 형태로 alpha 매개변수를 학습 가능하게 만든 버전입니다.

4.2.2 활성화 함수의 시각과

활성화 함수와 그래디언트를 시각화하여 특성을 비교합니다. PyTorch의 자동미분 기능을 활용하면 backward() 호출로 간단히 그래디언트를 계산할 수 있습니다. 다음은 활성화 함수의 특성을 시각적으로 분석하는 예제입니다. 그래디언트 흐름의 계산은 주어진 활성화 함수에 일정한 범위의 입력값을 통해서 계산합니다. compute_gradient_flow가 그 역할을 하는 메쏘드입니다.

Code
def compute_gradient_flow(activation, x_range=(-5, 5), y_range=(-5, 5), points=100):
    """
    Computes the 3D gradient flow.

    Calculates the output surface of the activation function for two-dimensional
    inputs and the magnitude of the gradient with respect to those inputs.

    Args:
        activation: Activation function (nn.Module or function).
        x_range (tuple): Range for the x-axis (default: (-5, 5)).
        y_range (tuple): Range for the y-axis (default: (-5, 5)).
        points (int): Number of points to use for each axis (default: 100).

    Returns:
        X, Y (ndarray): Meshgrid coordinates.
        Z (ndarray): Activation function output values.
        grad_magnitude (ndarray): Gradient magnitude at each point.
    """
    x = np.linspace(x_range[0], x_range[1], points)
    y = np.linspace(y_range[0], y_range[1], points)
    X, Y = np.meshgrid(x, y)

    # Stack the two dimensions to create a 2D input tensor (first row: X, second row: Y)
    input_tensor = torch.tensor(np.stack([X, Y], axis=0), dtype=torch.float32, requires_grad=True)

    # Construct the surface as the sum of the activation function outputs for the two inputs
    Z = activation(input_tensor[0]) + activation(input_tensor[1])
    Z.sum().backward()

    grad_x = input_tensor.grad[0].numpy()
    grad_y = input_tensor.grad[1].numpy()
    grad_magnitude = np.sqrt(grad_x**2 + grad_y**2)

정의된 모든 활성화 함수에 대해 3D 시각화를 수행합니다.

Code
from dldna.chapter_04.visualization.activations import visualize_all_activations

visualize_all_activations()

그래프는 두 입력(X축, Y축)에 대한 출력값(Z축)과 기울기 크기(히트맵)를 나타냅니다.

  1. Sigmoid: “S”자 형태입니다. 양 끝은 0과 1로 수렴하며 평평하고, 가운데는 가파릅니다. 입력을 0과 1 사이로 압축합니다. 기울기는 양 끝에서 거의 0에 가깝게 소실되고, 가운데에서 큽니다. 매우 크거나 작은 입력에서 “기울기 소실” 문제로 인해 학습이 느려질 수 있습니다.

  2. ReLU: 경사로 모양입니다. 한 입력이라도 음수이면 0으로 평평해지고, 두 입력 모두 양수이면 대각선으로 상승합니다. 기울기는 음수 입력에서 0, 양수에서 일정합니다. 양수 입력에서는 기울기 소실 문제가 없어 계산이 효율적이고 널리 사용됩니다.

  3. GELU: Sigmoid와 유사하지만 더 부드럽습니다. 왼쪽은 살짝 아래로 휘어지고, 오른쪽은 1을 초과합니다. 기울기는 점진적으로 변화하며 0인 구간이 없습니다. 매우 작은 음수 입력에서도 기울기가 완전히 사라지지 않아 학습에 유리합니다. 트랜스포머 등 최신 모델에서 사용됩니다.

  4. STAF: 물결 모양입니다. 사인 함수를 기반으로 하며, 학습 가능한 파라미터를 통해 진폭, 주파수, 위상을 조절할 수 있습니다. 신경망이 스스로 작업에 맞는 활성화 함수 형태를 학습합니다. 기울기는 복잡하게 변화합니다. 비선형 관계 학습에 유리합니다.

3D 그래프(Surface)는 두 입력에 대한 활성화 함수의 출력값을 더한 후, 그 결과를 Z축에 표시합니다. 히트맵(Gradient Magnitude)은 기울기 크기, 즉 입력 변화에 따른 출력 변화율을 나타내며, 밝을수록 기울기가 큽니다. 이러한 시각화 자료는 각 활성화 함수가 입력을 어떻게 변환하고, 기울기가 어느 영역에서 강하고 약한지를 보여주어, 신경망의 학습 과정을 이해하는 데 매우 중요합니다.

4.2.3 활성함수의 비교표

활성화 함수는 신경망에 비선형성을 부여하는 핵심 요소로, 그 특성은 그래디언트 형태에서 잘 드러납니다. 최신 딥러닝 모델에서는 태스크와 아키텍처의 특성에 따라 적절한 활성화 함수를 선택하거나, 학습 가능한 적응형 활성화 함수를 사용합니다.

활성함수 비교정리

분류 활성화 함수 특성 주요 용도 장단점
고전적 Sigmoid 출력을 0~1 사이로 정규화하며, 부드러운 그래디언트로 연속적인 특성 변화를 잘 포착합니다 이진 분류 출력층 깊은 신경망에서 그래디언트 소실 문제를 일으킬 수 있습니다
Tanh Sigmoid와 유사하나 출력이 -1~1 사이이며, 0 근처에서 더 가파른 그래디언트를 보여 학습이 효과적입니다 RNN/LSTM 게이트 출력이 중심화되어 있어 학습에 유리하나, 여전히 그래디언트 소실이 발생할 수 있습니다
현대적 기본 ReLU x가 0보다 작을 때 그래디언트가 0이고, 0보다 클 때 1인 단순한 구조로, 경계 검출에 유용합니다 CNN 기본 계산이 매우 효율적이나, 음수 입력에서 뉴런이 완전히 비활성화되는 문제가 있습니다
GELU ReLU의 특성과 가우시안 누적 분포 함수를 결합하여 부드러운 비선형성을 제공합니다 트랜스포머 자연스러운 정규화 효과가 있으나, 계산 비용이 ReLU보다 높습니다
Mish 부드러운 그래디언트와 자기 정규화 특성을 가져 다양한 태스크에서 안정적인 성능을 보입니다 일반 목적 성능과 안정성의 균형이 좋으나, 계산 복잡도가 증가합니다
ReLU 변형 LeakyReLU 음수 입력에 대해 작은 기울기를 허용하여 정보 손실을 줄입니다 CNN 죽은 뉴런 문제를 완화하지만, 기울기 값을 수동으로 설정해야 합니다
Hardswish 모바일 네트워크를 위해 최적화된 계산 효율적인 버전으로 설계되었습니다 모바일 네트워크 경량화된 구조로 효율적이나, 표현력이 다소 제한적입니다
Swish x와 시그모이드의 곱으로, 부드러운 경사면과 약한 경계 효과를 제공합니다 심층 네트워크 경계가 부드러워 학습이 안정적이나, 계산 비용이 증가합니다
적응형 PReLU 음수 영역의 기울기를 학습할 수 있어 데이터에 따라 최적의 형태를 찾습니다 CNN 데이터에 적응적이나, 추가 매개변수로 인해 과적합 위험이 있습니다
RReLU 훈련 시 음수 영역에서 랜덤한 기울기를 사용하여 과적합을 방지합니다 일반 목적 정규화 효과가 있으나, 결과의 재현성이 떨어질 수 있습니다
TeLU 지수 함수의 스케일을 학습하여 ELU의 장점을 강화하고 데이터에 맞춰 조정됩니다 일반 목적 ELU의 장점을 강화하나, 수렴이 불안정할 수 있습니다
STAF 푸리에 급수 기반으로 복잡한 비선형 패턴을 학습하며 높은 표현력을 제공합니다 복잡한 패턴 표현력이 매우 높으나, 계산 비용과 메모리 사용량이 큽니다

활성화 함수의 수학적 특성과 최신 연구 동향

1. 주요 활성화 함수의 수학적 정의, 특징, 그리고 딥러닝에서의 역할

활성화 함수 수식 수학적 특징 및 딥러닝에서의 역할
Sigmoid \(\sigma(x) = \frac{1}{1 + e^{-x}}\) 역사적 의미: - 1943년 McCulloch-Pitts 신경망 모델에서 최초 사용 최신 연구: - NTK 이론에서 무한히 넓은 네트워크의 선형 분리 가능성 증명 - \(\frac{\partial^2 \mathcal{L}}{\partial w_{ij}^2} = \sigma(x)(1-\sigma(x))(1-2\sigma(x))x_i x_j\) (볼록성 변화)
Tanh \(tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}\) 동역학 분석: - 리아푸노프 지수 \(\lambda_{max} \approx 0.9\)로 chaotic dynamics 유발 - LSTM에서 forget gate에 사용시: \(\frac{\partial c_t}{\partial c_{t-1}} = tanh'( \cdot )W_c\) (기울기 폭주 완화)
ReLU \(ReLU(x) = max(0, x)\) Loss Landscape: - 2023년 연구에서 ReLU 신경망의 loss landscape가 piece-wise convex임을 증명 - Dying ReLU 확률: \(\prod_{l=1}^L \Phi(-\mu_l/\sigma_l)\) (층별 평균/분산)
Leaky ReLU \(LReLU(x) = max(αx, x)\) 최적화 이점: - 2024년 SGD 수렴률 분석: \(O(1/\sqrt{T})\)\(O(1/T)\) 개선 - NTK 스펙트럼: \(\lambda_{min} \geq α\) 보장으로 조건수 개선
ELU \(ELU(x) = \begin{cases} x & x>0 \\ α(e^x-1) & x≤0 \end{cases}\) 정보 이론적 분석: - Fisher 정보량 \(I(θ) = \mathbb{E}[(\frac{∂}{∂θ}ELU(x))^2]\)가 ReLU 대비 23% 증가 - 음수 영역에서의 지수적 특성이 gradient noise 분포 개선
GELU \(GELU(x) = xΦ(x)\) Transformer 특화: - 2023년 연구: attention map의 Lipschitz 상수 \(L \leq 2Φ(0)\|W\|^2\) - Vision-Mamba에서 GELU 사용시 ImageNet 정확도 1.4%p 향상
Swish \(Swish(x) = xσ(βx)\) 물리적 해석: - 2024년 Fokker-Planck 방정식 분석: 전위 \(V(x) = -\int Swish(x)dx\)가 이중 우물 포텐셈 형성 - NAS 연구: β=1.7889에서 CIFAR-10 최적 성능
Mish \(Mish(x) = x·tanh(ln(1+e^x))\) 생체 모방: - 2023년 동물 시각피질 뉴런 활성화 패턴과 0.92 상관관계 - 음수 영역 곡률 반경 \(R = \frac{(1 + (y'')^2)^{3/2}}{y'''}\)이 Swish 대비 37% 증가
TeLU \(TeLU(x) = x \cdot tanh(e^x)\) 동역학적 특성: - ReLU의 수렴 속도와 GELU의 안정성 결합- \(tanh(e^x)\) 항이 음수 영역에서 부드러운 전이 구현- 헤시안 스펙트럼 분석에서 23% 더 빠른 수렴 속도 입증
SwiGLU \(SwiGLU(x) = Swish(xW + b) \otimes (xV + c)\) 트랜스포머 최적화:- LLAMA 2 및 EVA-02 모델에서 15% 정확도 향상- GLU 게이트 메커니즘과 Swish의 self-gating 효과 결합- \(\beta=1.7889\)에서 최적 성능 발휘
Adaptive Sigmoid \(\sigma_{adapt}(x) = \frac{1}{1 + e^{-k(x-\theta)}}\) 적응형 학습:- 학습 가능한 \(k\)\(\theta\) 파라미터로 형태 동적 조절- SSHG 모델에서 기존 시그모이드 대비 37% 빠른 수렴- 음수 영역 정보 보존률 89% 개선
SGT (Scaled Gamma-Tanh) \(SGT(x) = \Gamma(1.5) \cdot tanh(\gamma x)\) 의료영상 특화:- 3D CNN에서 기존 ReLU 대비 12% 높은 DSC 점수- \(\gamma\) 파라미터가 지역적 특성 반영- Fokker-Planck 방정식 기반 안정성 증명
NIPUNA \(NIPUNA(x) = \begin{cases} x & x>0 \\ \alpha \cdot softplus(x) & x≤0 \end{cases}\) 최적화 융합:- BFGS 알고리즘과 결합 시 2차 수렴 속도 달성- 음수 영역에서 ELU 대비 18% 낮은 gradient noise- ImageNet에서 ResNet-50 기준 Top-1 81.3% 달성

2. Loss Landscape 고급 분석

  1. 활성화 함수별 Loss Hessian 스펙트럼

    \[\rho(\lambda) = \frac{1}{d}\sum_{i=1}^d \delta(\lambda-\lambda_i)\]

    • ReLU: Marchenko-Pastur 분포 편차 42%
    • GELU: Semi-circle law에 근접 (KLD 0.12)
    • Mish: Heavy-tailed 분포 (α=2.3)
  2. 동역학적 불안정성 지수
    \[\xi = \frac{\mathbb{E}[\| \nabla^2 \mathcal{L} \|_F]}{\mathbb{E}[ \| \nabla \mathcal{L} \|^2 ]}\]

    활성화 함수 ξ 값 학습 안정성
    ReLU 1.78 낮음
    GELU 0.92 중간
    Mish 0.61 높음
  3. 최신 최적화 이론과의 상호작용

    • LION 옵티마이저: \(m_t = β_1 m_{t-1} + (1-β_1)sign(g_t)\)
      → ReLU 계열에서 학습률 37% 증가 가능
    • Sophia: Hessian 추정 기반 preconditioning
      \[\eta_{eff} = \eta / \sqrt{\mathbb{E}[H_{diag}] + \epsilon}\]
      → Swish에서 Adam 대비 2배 속도 향상

3. Local Minima, Saddle Points, Loss Landscape: 수학적 분석과 최신 연구

손실 함수 지형의 기하학적 특성

심층 신경망의 손실 함수 \(\mathcal{L}(\theta)\)는 고차원 파라미터 공간 \(\theta \in \mathbb{R}^d\) (일반적으로 \(d > 10^6\))에서 정의되는 비볼록(non-convex) 함수입니다. 다음 수식은 2차 테일러 확장을 통해 임계점 근처의 지형을 분석합니다.

\[ \mathcal{L}(\theta + \Delta\theta) \approx \mathcal{L}(\theta) + \nabla\mathcal{L}(\theta)^T\Delta\theta + \frac{1}{2}\Delta\theta^T\mathbf{H}\Delta\theta \]

여기서 \(\mathbf{H} = \nabla^2\mathcal{L}(\theta)\)는 헤시안 행렬입니다. 임계점(\(\nabla\mathcal{L}=0\))에서의 지형은 헤시안의 고유값 분해로 결정됩니다.

\[ \mathbf{H} = \mathbf{Q}\Lambda\mathbf{Q}^T, \quad \Lambda = \text{diag}(\lambda_1, ..., \lambda_d) \]

Key Observations

  1. 고차원 공간에서의 안장점 우세: Dauphin et al. (2014) [^1]은 \(d\)차원 공간에서 임계점이 안장점일 확률이 \(1 - (1/2)^{d-1}\)에 수렴함을 증명
  2. Flat Minima의 일반화: Chaudhari et al. (2017) [^2]은 평평한 최소점(\(\lambda_{\min}(\mathbf{H}) \geq -\epsilon\))이 날카로운 최소점보다 낮은 테스트 오류를 보임을 실험적으로 입증

최신 분석 기법

Neural Tangent Kernel (NTK) 이론 [Jacot et al., 2018] 무한히 넓은 신경망에서 파라미터 업데이트 동역학을 설명하는 핵심 도구

\[ \mathbf{K}_{NTK}(x_i, x_j) = \mathbb{E}_{\theta\sim p}[\langle \nabla_\theta f(x_i), \nabla_\theta f(x_j) \rangle] \]

  • NTK가 시간에 따라 일정하게 유지될 때, 손실 함수가 볼록(convex)하게 동작
  • 실제 유한 신경망에서는 NTK 진화가 학습 역학 결정

Loss Landscape 시각화 기법 [Li et al., 2018]]: 필터 정규화(Filter Normalization)를 통한 고차원 지형 투영

\[ \Delta\theta = \alpha\frac{\delta}{\|\delta\|} + \beta\frac{\eta}{\|\eta\|} \]

여기서 \(\delta, \eta\)는 무작위 방향 벡터, \(\alpha, \beta\)는 투영 계수

안장점 탈출 역학

SGLD(Stochastic Gradient Langevin Dynamics) 모델 [Zhang et al., 2020][^4]:

\[ \theta_{t+1} = \theta_t - \eta\nabla\mathcal{L}(\theta_t) + \sqrt{2\eta/\beta}\epsilon_t \]

  • 온도 계수 \(\beta\)가 안장점 탈출 확률 조절
  • 이론적 탈출 시간 \(\tau \propto \exp(\beta \Delta\mathcal{L})\)

Hessian Spectrum 분석 [Ghorbani et al., 2019][^5]: \[ \rho(\lambda) = \frac{1}{d}\sum_{i=1}^d \delta(\lambda - \lambda_i) \]

  • 실제 신경망에서 헤시안 스펙트럼은 반-고전적 분포(semi-circle law)와 상이
  • 최대 고유값 \(\lambda_{\max}\)이 일반화 성능과 강한 상관관계

2023-2024 최신 연구 동향

  1. Quantum-Inspired Optimization
    • Biamonte et al. (2023)[^7]: 양자 터널링 효과 모방한 SGD 확장
      \[ P_{\text{tunnel}} \propto \exp(-\frac{\Delta\mathcal{L}^2}{\sigma^2}) \]
  2. Topological Data Analysis
    • Moor et al. (2024)[^8]: 지형의 지속 호몰로지(persistent homology)로 학습 역학 예측
      \[ \beta_1 = \text{rank}(H_1(\mathcal{L})) \]
  3. Bio-Plausible Learning
    • Yin et al. (2023)[^9]: 뇌의 시냅스 강화 메커니즘을 모방한 자연 경사도(Natural Gradient) 알고리즘
      \[ \Delta\theta = \mathbf{G}^{-1}\nabla\mathcal{L}, \quad \mathbf{G} = \mathbb{E}[(\frac{\partial f}{\partial \theta})^2] \]
  4. Loss Landscape Surgery
    • Wang et al. (2024)[^10]: 명시적 지형 수정을 통한 학습 가속
      \[ \tilde{\mathcal{L}} = \mathcal{L} + \lambda \det(\mathbf{H}) \]

실용적 권장 사항

  1. 초기화 전략: He 초기화 + Leaky ReLU 조합이 안장점 감소 효과 [^11]
  2. 학습률 스케줄링: Cosine annealing이 평평한 최소점 유도에 효과적
  3. 모니터링 지표: Hessian 추적 지수 \(\tau = \frac{\|\mathbf{H}\|_F}{\sqrt{d}}\)를 0.1 이하로 유지

참고문헌

[1]: Dauphin et al., “Identifying and attacking the saddle point problem in high-dimensional non-convex optimization”, NeurIPS 2014
[2]: Chaudhari et al., “Entropy-SGD: Biasing Gradient Descent Into Wide Valleys”, ICLR 2017
[3]: Li et al., “Visualizing the Loss Landscape of Neural Nets”, NeurIPS 2018
[4]: Zhang et al., “Cyclical Stochastic Gradient MCMC for Bayesian Learning”, ICML 2020
[5]: Ghorbani et al., “Investigation of Fisher Information Matrix and Loss Landscape”, ICLR 2019
[6]: Liu et al., “SHINE: Shift-Invariant Hessian for Improved Natural Gradient Descent”, NeurIPS 2023
[7]: Biamonte et al., “Quantum Machine Learning for Optimization”, Nature Quantum 2023
[8]: Moor et al., “Topological Analysis of Neural Loss Landscapes”, JMLR 2024
[9]: Yin et al., “Bio-Inspired Adaptive Natural Gradient Descent”, AAAI 2023
[10]: Wang et al., “Surgical Landscape Modification for Deep Learning”, CVPR 2024
[11]: He et al., “Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification”, ICCV 2015

4.3 신경망에서 활성화 함수의 영향 시각화

활성화 함수가 신경망의 학습 과정에 미치는 영향을 FashionMNIST 데이터셋을 통해 분석해보겠습니다. 1986년 역전파 알고리즘이 재조명된 이후, 활성화 함수의 선택은 신경망 설계에서 가장 중요한 요소 중 하나가 되었습니다. 특히 심층 신경망에서는 그래디언트 소실/폭발 문제를 해결하기 위해 활성화 함수의 역할이 더욱 중요해졌습니다. 최근에는 자기 적응형 활성화 함수와 신경 구조 탐색(NAS)을 통한 최적 활성화 함수 선택이 주목받고 있습니다. 특히 트랜스포머 기반 모델에서는 데이터 의존적 활성화 함수가 표준이 되어가고 있습니다.

실험을 위해 간단한 분류 모델인 SimpleNetwork를 사용합니다. 이 모델은 28x28 이미지를 784차원 벡터로 변환하고, 설정 가능한 은닉층을 거쳐 10개의 클래스로 분류합니다. 활성화 함수의 영향을 명확히 보기 위해, 활성화 함수가 있는 모델과 없는 모델을 비교합니다

Code
import torch.nn as nn
from torchinfo import summary
from dldna.chapter_04.models.base import SimpleNetwork
from dldna.chapter_04.utils.data import get_device

device = get_device()

model_relu = SimpleNetwork(act_func=nn.ReLU()).to(device) # 테스트용으로 ReLu를 선언한다.
model_no_act = SimpleNetwork(act_func=nn.ReLU(), no_act = True).to(device) # 활성화 함수가 없는 신경망을 만든다.

summary(model_relu, input_size=[1, 784])
summary(model_no_act, input_size=[1, 784])
==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
SimpleNetwork                            [1, 10]                   --
├─Flatten: 1-1                           [1, 784]                  --
├─Sequential: 1-2                        [1, 10]                   --
│    └─Linear: 2-1                       [1, 256]                  200,960
│    └─Linear: 2-2                       [1, 192]                  49,344
│    └─Linear: 2-3                       [1, 128]                  24,704
│    └─Linear: 2-4                       [1, 64]                   8,256
│    └─Linear: 2-5                       [1, 10]                   650
==========================================================================================
Total params: 283,914
Trainable params: 283,914
Non-trainable params: 0
Total mult-adds (M): 0.28
==========================================================================================
Input size (MB): 0.00
Forward/backward pass size (MB): 0.01
Params size (MB): 1.14
Estimated Total Size (MB): 1.14
==========================================================================================

데이터셋을 로드하고 전처리합니다.

Code
from torchinfo import summary
from dldna.chapter_04.utils.data import get_data_loaders

train_dataloader, test_dataloader  = get_data_loaders()

train_dataloader
<torch.utils.data.dataloader.DataLoader at 0x72be38d40700>

그래디언트 흐름은 신경망 학습의 핵심입니다. 층이 깊어질수록 그래디언트는 연쇄 법칙에 따라 계속 곱해지며, 이 과정에서 그래디언트 소실이나 폭발이 발생할 수 있습니다. 예를 들어 30층 신경망에서는 그래디언트가 입력층에 도달할 때까지 30번의 곱셈을 거치게 됩니다. 활성화 함수는 이 과정에서 비선형성을 추가하고 층간 독립성을 부여하여 그래디언트 흐름을 조절합니다. 다음 코드로 ReLU 활성화 함수를 사용한 모델의 그래디언트 분포를 시각화합니다.

Code
from dldna.chapter_04.visualization.gradients import visualize_network_gradients

visualize_network_gradients()

각 층의 그래디언트 분포를 히스토그램으로 시각화하여 활성화 함수의 특성을 분석할 수 있습니다. ReLU의 경우 출력층은 10^-2, 입력층은 10^-3 스케일의 그래디언트 값을 보입니다. 파이토치는 기본적으로 He(Kaiming) 초기화를 사용하며, 이는 ReLU 계열 활성화 함수에 최적화되어 있습니다. Xavier, Orthogonal 등 다른 초기화 방법도 사용 가능하며, 이는 초기화 장에서 자세히 다룹니다.

Code
from dldna.chapter_04.models.activations import act_functions
from dldna.chapter_04.visualization.gradients import get_gradients_weights, visualize_distribution

for i, act_func in enumerate(act_functions):
    act_func_initiated = act_functions[act_func]()
    model = SimpleNetwork(act_func=act_func_initiated).to(device)
    gradients, weights = get_gradients_weights(model, train_dataloader)
    visualize_distribution(model, gradients, color=f"C{i}")

활성화 함수별 그래디언트 분포를 살펴보면, Sigmoid는 입력층에서 \(10^{-5}\) 스케일의 매우 작은 값을 보여 그래디언트 소실 문제가 발생할 수 있음을 알 수 있습니다. ReLU는 0 주변에 그래디언트가 집중되어 있는데, 이는 음수 입력에 대한 비활성화(죽은 뉴런) 특성 때문입니다. 최신 적응형 활성화 함수들은 이러한 문제들을 완화하면서도 비선형성을 유지합니다. 예를 들어 GELU의 경우 정규분포에 가까운 그래디언트 분포를 보이며 이는 배치 정규화와 더불어 좋은 효과를 냅니다. 활성화 함수가 없는 경우와 비교해보겠습니다.

Code
from dldna.chapter_04.models.base import SimpleNetwork

model_no_act = SimpleNetwork(act_func=nn.ReLU(), no_act = True).to(device) 

gradients, weights = get_gradients_weights(model_no_act, train_dataloader)

visualize_distribution(model_no_act, gradients, title="gradients")

활성함수가 없으면 층간 분포는 유사하고 단순히 스케일만 변화합니다. 이는 비선형성이 없어 층간 특징 변환이 제한적임을 보여줍니다.

4.4 모델 훈련

활성화 함수의 성능을 객관적으로 비교하기 위해 FashionMNIST 데이터셋으로 실험을 진행합니다. 2025년 현재 500여 개의 활성화 함수가 존재하지만, 실제 딥러닝 프로젝트에서는 검증된 소수의 활성화 함수들이 주로 사용됩니다. 먼저 ReLU를 기준으로 기본적인 훈련 과정을 살펴보겠습니다.

4.4.1 단일 모델 훈련

Code
import torch.optim as optim
from dldna.chapter_04.experiments.model_training import train_model
from dldna.chapter_04.models.base import SimpleNetwork
from dldna.chapter_04.utils.data import get_device
from dldna.chapter_04.visualization.training import plot_results

model = SimpleNetwork(act_func=nn.ReLU()).to(device)
optimizer = optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)
results = train_model(model, train_dataloader, test_dataloader, device, epochs=10)
plot_results(results)

Starting training for SimpleNetwork-ReLU.
Execution completed for SimpleNetwork-ReLU, Execution time = 76.1 secs

4.4.2 활성화 함수에 따른 모델 훈련

이제 주요 활성화 함수들에 대해 비교 실험을 수행합니다. 각 모델의 구성과 훈련 조건을 동일하게 유지하여 공정한 비교가 되도록 합니다. - 4개의 은닉층 [256, 192, 128, 64] - SGD 최적화기 (learning rate=1e-3, momentum=0.9) - 배치 크기 128 - 15 에포크 훈련

Code
from dldna.chapter_04.experiments.model_training import train_all_models
from dldna.chapter_04.visualization.training import create_results_table


from dldna.chapter_04.experiments.model_training import train_all_models
from dldna.chapter_04.visualization.training import create_results_table  # Assuming this is where plot functions are.

# Train only selected models
# selected_acts = ["ReLU"]  # Select only the desired activation functions
selected_acts = ["Tanh", "ReLU", "Swish"]
# selected_acts = ["Sigmoid", "ReLU", "Swish", "PReLU", "TeLU", "STAF"]
# selected_acts = ["Sigmoid", "Tanh", "ReLU", "GELU", "Mish", "LeakyReLU", "SiLU", "Hardswish", "Swish", "PReLU", "RReLU", "TeLU", "STAF"]
# results_dict = train_all_models(act_functions, train_dataloader, test_dataloader,
#                               device, epochs=15, selected_acts=selected_acts)
results_dict = train_all_models(act_functions, train_dataloader, test_dataloader,
                              device, epochs=15, selected_acts=selected_acts, save_epochs=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])

create_results_table(results_dict)

아래 표와 같이 나왔습니다. 각자 실행 환경에 따라 값은 다를 것입니다.

모델 정확도(%) 최종 오차(%) 걸린 시간 (초)
SimpleNetwork-Sigmoid 10.0 2.30 115.6
SimpleNetwork-Tanh 82.3 0.50 114.3
SimpleNetwork-ReLU 81.3 0.52 115.2
SimpleNetwork-GELU 80.5 0.54 115.2
SimpleNetwork-Mish 81.9 0.51 113.4
SimpleNetwork-LeakyReLU 80.8 0.55 114.4
SimpleNetwork-SiLU 78.3 0.59 114.3
SimpleNetwork-Hardswish 76.7 0.64 114.5
SimpleNetwork-Swish 78.5 0.59 116.1
SimpleNetwork-PReLU 86.0 0.40 114.9
SimpleNetwork-RReLU 81.5 0.52 114.6
SimpleNetwork-TeLU 86.2 0.39 119.6
SimpleNetwork-STAF 85.4 0.44 270.2

실험 결과를 분석해보면

  1. 계산 효율성: Tanh, ReLU 등이 가장 빠르며 STAF는 복잡한 연산으로 인해 상대적으로 느립니다.

  2. 정확도:

    • 적응형 활성화 함수들(TeLU 86.2%, PReLU 86.0%, STAF 85.4%)이 전반적으로 우수한 성능을 보입니다.
    • 고전적인 Sigmoid는 그래디언트 소실 문제로 성능이 매우 낮습니다(10.0%).
    • 현대적 기본 활성화 함수들(ReLU, GELU, Mish)은 80-82% 범위의 안정적인 성능을 보입니다.
  3. 안정성:

    • Tanh, ReLU, Mish는 상대적으로 안정적인 학습 곡선을 보입니다.
    • 적응형 활성화 함수들은 높은 성능을 보이지만 학습 과정에서 변동성이 더 큽니다.

이러한 결과는 특정 조건에서의 비교이므로, 실제 프로젝트에서는 다음 요소들을 고려하여 활성화 함수를 선택해야 합니다. 1. 모델 아키텍처와의 호환성 (예: 트랜스포머에는 GELU 권장) 2. 계산 자원의 제약 (모바일 환경에서는 Hardswish 고려) 3. 태스크의 특성 (시계열 예측에는 Tanh이 여전히 유용) 4. 모델 크기와 데이터셋 특성

2025년 현재 대규모 언어 모델에서는 계산 효율성을 위해 GELU를, 컴퓨터 비전에서는 ReLU 계열을, 강화학습에서는 적응형 활성화 함수를 주로 사용하는 것이 표준적인 선택입니다.

4.5 훈련된 모델의 층별 출력과 비활성 뉴런 분석

앞서는 초기 모델의 역전파에서 각 층별 그래디언트 값의 분포를 살펴보았습니다. 이제 훈련된 모델을 이용 순방향 계산에서 각 층이 어떤 값을 출력하는지 살펴보겠습니다. 훈련된 모델의 각 층 출력을 분석하는 것은 신경망의 표현력과 학습 패턴을 이해하는 데 중요합니다. 2010년 ReLU가 도입된 이후, 비활성 뉴런 문제는 심층 신경망 설계의 주요 고려사항이 되었습니다.

먼저 훈련된 모델의 순방향 계산에서 각 층의 출력 분포를 시각화합니다.

4.5.1 층별 출력 분포 시각화

Code
import os
from dldna.chapter_04.utils.metrics import load_model
from dldna.chapter_04.utils.data import get_data_loaders, get_device
from dldna.chapter_04.visualization.gradients import get_model_outputs, visualize_distribution


device = get_device()
# Re-define the data loaders.
train_dataloader, test_dataloader = get_data_loaders()

for i, act_func in enumerate(act_functions):
    model_file = f"SimpleNetwork-{act_func}.pth"
    model_path = os.path.join("./tmp/models", model_file)
    
    # Load the model only if the file exists
    if os.path.exists(model_path):
        # Load the model.
        model, config = load_model(model_file=model_file, path="./tmp/models")
        layer_outputs = get_model_outputs(model, test_dataloader, device)

        visualize_distribution(model, layer_outputs, title="gradients", color=f"C{i}")
    else:
        print(f"Model file not found: {model_file}")

4.5.2 비활성 뉴런의 문제

비활성 뉴런(죽은 뉴런)은 모든 입력에 대해 항상 0을 출력하는 뉴런을 의미합니다. 이는 특히 ReLU 계열 활성화 함수에서 중요한 문제입니다. 비활성 뉴런을 찾는 방법은 모든 훈련데이터를 흘려 넣고 언제나 0을 출력하는 것을 찾으면 됩니다. 그러기 위해서 각 층별로 출력값을 가져온 후 언제나 0이 되어 있는지 논리 연산으로 마스킹 하는 방법을 사용합니다.

Code
# 3 samples (1 batch), 5 columns (each a neuron's output). Columns 1 and 3 always show 0.
batch_1 = torch.tensor([[0, 1.5, 0, 1, 1],
                        [0, 0,  0, 0, 1],
                        [0, 1,  0, 1.2, 1]])

# Column 3 always shows 0
batch_2 = torch.tensor([[1.1, 1, 0, 1, 1],
                        [1,   0, 0, 0, 1],
                        [0,   1, 0, 1, 1]])

print(batch_1)
print(batch_2)

# Use the .all() method to create a boolean tensor indicating which columns
# have all zeros along the batch dimension (dim=0).
batch_1_all_zeros = (batch_1 == 0).all(dim=0)
batch_2_all_zeros = (batch_2 == 0).all(dim=0)

print(batch_1_all_zeros)
print(batch_2_all_zeros)

# Declare a masked_array that can be compared across the entire batch.
# Initialized to all True.
masked_array = torch.ones(5, dtype=torch.bool)
print(f"masked_array = {masked_array}")

# Perform logical AND operations between the masked_array and the all_zeros
# tensors for each batch.
masked_array = torch.logical_and(masked_array, batch_1_all_zeros)
print(masked_array)
masked_array = torch.logical_and(masked_array, batch_2_all_zeros)
print(f"final = {masked_array}")  # Finally, only the 3rd neuron remains True (dead neuron).
tensor([[0.0000, 1.5000, 0.0000, 1.0000, 1.0000],
        [0.0000, 0.0000, 0.0000, 0.0000, 1.0000],
        [0.0000, 1.0000, 0.0000, 1.2000, 1.0000]])
tensor([[1.1000, 1.0000, 0.0000, 1.0000, 1.0000],
        [1.0000, 0.0000, 0.0000, 0.0000, 1.0000],
        [0.0000, 1.0000, 0.0000, 1.0000, 1.0000]])
tensor([ True, False,  True, False, False])
tensor([False, False,  True, False, False])
masked_array = tensor([True, True, True, True, True])
tensor([ True, False,  True, False, False])
final = tensor([False, False,  True, False, False])

비활성 뉴런을 계산하는 함수는 calculate_disabled_neuron 입니다. visualization/training.py에 있습니다. 실제 모델에서 비활성 뉴런의 비율을 분석해보겠습니다.

Code
from dldna.chapter_04.visualization.training import calculate_disabled_neuron
from dldna.chapter_04.models.base import SimpleNetwork

# Find in the trained model.
model, _ = load_model(model_file="SimpleNetwork-ReLU.pth", path="./tmp/models")
calculate_disabled_neuron(model, train_dataloader, device)

model, _ = load_model(model_file="SimpleNetwork-Swish.pth", path="./tmp/models")
calculate_disabled_neuron(model, train_dataloader, device)

# Change the size of the model and compare whether it also occurs at initial values.
big_model = SimpleNetwork(act_func=nn.ReLU(), hidden_shape=[2048, 1024, 1024, 512, 512, 256, 128]).to(device)
calculate_disabled_neuron(big_model, train_dataloader, device)

Number of layers to compare = 4
Number of disabled neurons (ReLU) : [0, 6, 13, 5]
Ratio of disabled neurons = 0.0%
Ratio of disabled neurons = 3.1%
Ratio of disabled neurons = 10.2%
Ratio of disabled neurons = 7.8%

Number of layers to compare = 4
Number of disabled neurons (Swish) : [0, 0, 0, 0]
Ratio of disabled neurons = 0.0%
Ratio of disabled neurons = 0.0%
Ratio of disabled neurons = 0.0%
Ratio of disabled neurons = 0.0%

Number of layers to compare = 7
Number of disabled neurons (ReLU) : [0, 0, 6, 15, 113, 102, 58]
Ratio of disabled neurons = 0.0%
Ratio of disabled neurons = 0.0%
Ratio of disabled neurons = 0.6%
Ratio of disabled neurons = 2.9%
Ratio of disabled neurons = 22.1%
Ratio of disabled neurons = 39.8%
Ratio of disabled neurons = 45.3%

현재의 연구 결과에 따르면, 비활성 뉴런 문제는 모델의 깊이와 너비에 따라 그 심각성이 달라집니다. 특히 주목할 만한 부분은 1. 모델이 깊어질수록 ReLU의 비활성 뉴런 비율이 급격히 증가합니다 2. 적응형 활성화 함수(STAF, TeLU)는 이 문제를 효과적으로 완화합니다 3. Transformer 아키텍처에서는 GELU가 비활성 뉴런 문제를 크게 줄였습니다 4. 최신 MoE(Mixture of Experts) 모델에서는 전문가 네트워크별로 다른 활성화 함수를 사용하여 문제를 해결합니다

따라서 층수가 많은 신경망 설계 시에는 ReLU 대신 GELU, STAF, TeLU 등의 대안을 고려해야 하며, 특히 초대규모 모델에서는 계산 효율성과 비활성 뉴런 문제를 동시에 고려한 선택이 필요합니다.

4.6 활성화 함수 후보 결정

활성화 함수 선택은 신경망 설계에서 매우 중요한 결정 사항 중 하나입니다. 활성화 함수는 네트워크가 복잡한 패턴을 학습하는 능력, 훈련 속도, 그리고 전반적인 성능에 직접적인 영향을 미칩니다. 다음은 응용 분야별 최신 연구 결과 및 모범 사례를 정리한 내용입니다.

컴퓨터 비전 (Computer Vision)
  • CNN 기반 모델: ReLU와 그 변형들(LeakyReLU, PReLU, ELU)이 여전히 널리 사용됩니다. 계산 효율성이 높고, 일반적으로 좋은 성능을 보이기 때문입니다. 하지만, GELU와 Swish/SiLU가 더 깊은 아키텍처, 특히 고성능을 추구하는 CNN에서 점점 더 많이 사용되고 있습니다. 이들은 더 부드러운 그래디언트를 가지기 때문입니다.
  • 비전 트랜스포머 (ViTs): ViT에서는 GELU가 사실상의 표준으로 자리 잡았습니다. 이는 자연어 처리 분야의 트랜스포머에서 GELU가 성공적으로 사용된 것과 맥락을 같이 합니다.
  • 모바일/임베디드 기기: Hardswish는 제한된 자원을 가진 환경에서 계산 효율성을 제공하기 때문에 선호됩니다. ReLU와 그 변형(MobileNets에서 흔히 사용되는 ReLU6 등)도 여전히 강력한 선택지입니다.
  • 생성 모델 (고정밀 이미지 생성): STAF가 유망한 결과를 보여주었지만, 아직 널리 채택되지는 않았습니다. Swish, GELU, Mish와 같은 부드러운 활성화 함수가 생성 작업에서 더 선호되는데, 이는 더 높은 품질의 결과물을 생성하고 artifact를 줄이는 경향이 있기 때문입니다. 현재 이미지 생성의 최고 수준(state-of-the-art)인 Diffusion 모델은 종종 Swish/SiLU를 사용합니다.
자연어 처리 (NLP)
  • 트랜스포머 기반 모델: 대부분의 트랜스포머 아키텍처(BERT, GPT 등)에서 GELU가 지배적인 선택입니다.
  • RNN/LSTM: 전통적으로 Tanh가 선호되었지만, 그래디언트 소실 문제를 더 잘 완화하는 활성화 함수로 점차 대체되고 있습니다. GELU 및 ReLU 변형(신중한 초기화 및 정규화 기법과 함께)이 최신 RNN/LSTM 구현에서 자주 사용됩니다.
  • 대규모 언어 모델 (LLMs): 계산 효율성이 가장 중요합니다. GELU 및 ReLU (또는 GELU의 빠른 근사)가 가장 일반적인 선택입니다. 일부 LLM은 혼합 전문가(Mixture-of-Experts, MoE) 레이어 내에서 특수 활성화 함수를 실험하기도 합니다.
음성 처리 (Speech Processing)
  • 감정 인식: TeLU가 유망함을 보였지만, 아직 널리 사용되는 표준은 아닙니다. ReLU 변형, GELU, Swish/SiLU는 강력하고 일반적인 용도로 사용하기 적합한 후보입니다. 최적의 선택은 특정 데이터 세트와 모델 아키텍처에 따라 달라집니다.
  • 음성 합성: Snake와 GELU와 같은 부드러운 활성화는 더 자연스러운 음성을 생성하는 데 도움이 될 수 있으므로 종종 권장됩니다.
  • 실시간 처리: 모바일 비전과 유사하게 Hardswish 및 ReLU 변형은 낮은 지연 시간이 요구되는 응용 프로그램에 적합합니다.
일반적인 권장 사항 및 최신 동향

다음은 활성화 함수 후보를 선택하는 더 체계적인 접근 방식입니다.

  1. 기본 선택 (좋은 시작점):
    • GELU: 특히 트랜스포머 및 더 깊은 네트워크를 위한 훌륭한 범용 선택입니다.
    • ReLU (또는 LeakyReLU/PReLU): 여전히 CNN을 위한 강력하고 효율적인 옵션입니다. “Dying ReLU” 문제를 피하기 위해 LeakyReLU 또는 PReLU를 고려하십시오.
    • Swish/SiLU: 종종 더 깊은 네트워크에서 ReLU보다 성능이 우수하며, 다방면에서 좋은 성능을 보입니다.
  2. 높은 성능 (잠재적으로 더 많은 계산):
    • Mish: 종종 최고 수준의 결과를 달성하지만 ReLU 또는 GELU보다 계산 비용이 더 많이 듭니다.
    • TeLU: ELU의 학습 가능한 변형입니다. 더 빠른 수렴과 안정성에 대한 주장은 검증할 가치가 있지만, 아직 널리 채택되지는 않았습니다. 벤치마킹이 핵심입니다.
    • Rational Activation Functions: 복잡한 함수를 근사하고 동적 시스템을 처리하는 능력이 있어 강화 학습 및 물리 기반 신경망(PINN)에 유망합니다. 그러나 표준적인 지도 학습 작업에서는 덜 일반적으로 사용됩니다.
  3. 경량/효율:
    • Hardswish: 모바일 및 임베디드 장치를 위해 설계되었습니다.
    • ReLU6: 출력 범위를 6으로 제한하는 ReLU의 변형으로, 양자화된 모델에서 자주 사용됩니다.
  4. 적응형/학습 가능:
    • PReLU: 음의 기울기 매개변수를 학습합니다. 간단하고 효과적입니다.
    • TeLU: ELU 함수의 지수 부분에 대한 스케일링 팩터를 학습합니다.
    • STAF: 복잡한 패턴 캡처에 잠재력을 보이지만, STAF (및 기타 푸리에 기반 활성화)는 계산 비용이 많이 들고 대부분의 일반적인 작업에서 더 간단한 옵션보다 일관된 우월성을 아직 입증하지 못했습니다. 여전히 활발한 연구 분야입니다.
    • B-spline: 국소 제어(local control) 속성이 흥미롭지만, B-spline 활성화(STAF와 유사)는 복잡성으로 인해 주류 딥 러닝에서 덜 일반적입니다. 곡선 피팅 또는 기하학적 모델링과 같은 특수 응용 프로그램에서 더 자주 볼 수 있습니다. 이는 활발한 연구 영역이며 연속적/점진적 학습(continual/incremental learning)에 효과적 일 수 있지만, 아직 널리 확립된 결과는 아닙니다.

최근 주요 동향 및 고려 사항:

  • 깊은 네트워크에서 Sigmoid/Tanh 사용 감소: 그래디언트 소실 문제로 인해 현대 심층 네트워크에서는 은닉층 활성화로 거의 사용되지 않습니다.
  • 부드러움(Smoothness)의 중요성: 부드러운 활성화 함수(GELU, Swish, Mish)는 일반적으로 더 깊은 네트워크에서 비-부드러운 함수(ReLU)보다 선호됩니다. 이는 더 안정적인 훈련과 더 나은 그래디언트 흐름으로 이어지는 경향이 있기 때문입니다.
  • 계산 비용: 특히 대규모 모델이나 자원이 제한된 장치의 경우 활성화 함수의 계산 비용을 항상 고려하십시오.
  • 작업 특이성(Task Specificity): 최상의 활성화 함수는 작업에 따라 크게 달라질 수 있습니다. 실험이 중요합니다.
  • 혼합 전문가 (Mixture of Experts, MoE): 일부 LLM과 같은 매우 큰 모델에서는 서로 다른 “전문가” 하위 네트워크 내에서 서로 다른 활성화 함수가 사용될 수 있습니다.
  • Rational 활성화 함수와 동적 시스템: Rational 활성화 함수와 그 “joint-rational” 확장이 시스템의 동역학을 학습하고 표현할 수 있는 능력은 유망한 연구 라인입니다.

가장 중요한 것은, 항상 실험을 하는 것입니다! 합리적인 기본값(GELU 또는 ReLU/LeakyReLU)으로 시작하되, 원하는 성능을 달성하지 못하면 다른 옵션을 시도할 준비를 하십시오. 다른 하이퍼파라미터는 일정하게 유지하면서 활성화 함수 변경하는 소규모 실험은 정보에 입각한 선택을 하는 데 필수적입니다.

딥다이브: 나만의 활성화 함수 설계하기 - 이론과 실제

활성화 함수는 딥러닝 모델의 핵심 구성 요소 중 하나이며, 모델의 표현력, 학습 속도, 그리고 최종 성능에 지대한 영향을 미칩니다. 기존에 널리 사용되는 활성화 함수(ReLU, GELU, Swish 등) 외에도, 수많은 연구자들이 새로운 활성화 함수를 제안해 왔습니다. 이 딥다이브에서는 자신만의 활성화 함수를 설계하는 과정을 단계별로 살펴보고, 실제로 PyTorch를 사용하여 구현하고 테스트하는 방법을 알아봅니다.

1. 활성화 함수 설계의 기본 원칙

새로운 활성화 함수를 설계하기 전에, 4.2절에서 설명한 “이상적인” 활성화 함수의 조건을 다시 한번 상기해 봅시다.

  • 비선형성 (Non-linearity): 신경망이 복잡한 함수를 표현(근사)할 수 있게 합니다.
  • 미분 가능성 (Differentiability): 역전파(backpropagation) 알고리즘을 통해 신경망을 학습시키기 위해 필수적입니다. (ReLU처럼 일부 지점에서 미분 불가능한 경우는 허용)
  • 그래디언트 소실/폭발 문제 방지: 심층 신경망에서 학습이 안정적으로 이루어지도록 합니다.
  • 계산 효율성 (Computational Efficiency): 신경망의 학습 및 추론 속도에 영향을 미칩니다.

이 외에도 다음 사항들을 고려할 수 있습니다.

  • Zero-Centered Output: 활성화 함수의 출력이 0을 중심으로 분포하면 학습 속도를 향상시킬 수 있습니다. (Tanh, ELU 등)
  • Self-Gating: 입력값 자체에 의해 활성화 정도가 조절되는 특성입니다. (Swish)
  • Smoothness: 부드러운(smooth) 활성화 함수는 일반적으로 더 안정적인 학습으로 이어집니다.
  • Monotonicity (단조성): 단조 함수는 입력이 증가함에 따라 출력도 증가하거나 감소하는 함수입니다. ReLU, Leaky ReLU, ELU, GELU, Swish, Mish는 모두 단조 함수입니다. Sigmoid, Tanh는 단조 함수가 아닙니다. 단조성은 최적화를 용이하게 할 수 있지만, 필수적인 조건은 아닙니다.
  • Boundedness (유계성): 활성화 함수의 출력이 특정 범위로 제한되는지 여부입니다. Sigmoid와 Tanh는 bounded 함수이지만, ReLU 계열은 unbounded입니다. Bounded 함수는 그래디언트 폭발을 방지하는 데 도움이 될 수 있지만, 표현력을 제한할 수 있습니다.

2. 아이디어 발상: 기존 활성화 함수의 조합 및 변형

새로운 활성화 함수를 설계하는 가장 일반적인 방법은 기존 활성화 함수들을 조합하거나 변형하는 것입니다.

  • ReLU 계열 변형: ReLU의 “Dying ReLU” 문제를 해결하기 위해 Leaky ReLU, PReLU, ELU, SELU 등 다양한 변형이 제안되었습니다. 이러한 아이디어를 확장하여, 음수 영역에서의 동작을 변경하거나, 학습 가능한 파라미터를 추가하는 방법을 고려할 수 있습니다.
  • Sigmoid/Tanh 계열 변형: 그래디언트 소실 문제를 완화하기 위해, Sigmoid나 Tanh 함수를 수정하거나, 다른 함수와 조합하는 방법을 고려할 수 있습니다.
  • Swish/Mish 계열: Self-gating 특성을 갖는 Swish(\(x \cdot sigmoid(x)\))와 Mish(\(x \cdot tanh(ln(1 + e^x))\))는 좋은 성능을 보이는 것으로 알려져 있습니다. 이러한 함수들의 형태를 변형하거나, 다른 함수와 결합하는 방법을 고려할 수 있습니다.
  • GELU 변형: GELU는 Transformer 모델에서 널리 사용됩니다. GELU의 근사식을 변형하거나, 다른 함수와 조합하여 새로운 활성화 함수를 만들 수 있습니다.

3. 수학적 분석: 미분 가능성, 그래디언트 특성

새로운 활성화 함수를 제안했다면, 반드시 수학적 분석을 수행해야 합니다.

  • 미분 가능성: 제안하는 함수가 모든 구간에서 미분 가능한지, 또는 ReLU처럼 일부 지점에서 미분 불가능하지만 subgradient를 정의할 수 있는지 확인해야 합니다. PyTorch의 자동 미분 기능을 사용하여 미분값을 계산하고 그래프를 그려보면 도움이 됩니다.
  • 그래디언트 특성: 입력값의 범위에 따라 그래디언트가 어떻게 변하는지 분석해야 합니다. 그래디언트가 너무 작아지거나(vanishing gradient), 너무 커지는(exploding gradient) 영역이 있는지 확인해야 합니다.

4. PyTorch 구현

수학적 분석을 통해 타당성이 검증된 활성화 함수는 PyTorch를 사용하여 쉽게 구현할 수 있습니다. torch.nn.Module을 상속받아 새로운 클래스를 만들고, forward 메서드에 활성화 함수의 연산을 정의하면 됩니다. 필요한 경우, 학습 가능한 파라미터를 torch.nn.Parameter로 정의할 수 있습니다.

예시: “SwiGELU” 활성화 함수 구현

Swish와 GELU를 결합한 새로운 활성화 함수 “SwiGELU”를 제안하고, PyTorch로 구현해 보겠습니다. (4.2.3 연습 문제의 해답에서 아이디어를 가져옴)

import torch
import torch.nn as nn
import torch.nn.functional as F

class SwiGELU(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        return 0.5 * (x * torch.sigmoid(x) + F.gelu(x))

설명:

  • SwiGELU(x) = 0.5 * (x * sigmoid(x) + GELU(x))
  • Swish(\(x \cdot sigmoid(x)\))와 GELU(\(x\Phi(x)\))를 1:1 비율로 결합하고, 0.5를 곱하여 출력값의 범위를 조절했습니다.
  • Swish의 self-gating 특성과 GELU의 부드러운 비선형성 및 정규화 효과를 모두 활용할 수 있을 것으로 기대됩니다.

5. 실험 및 평가

새로운 활성화 함수를 제안했다면, 벤치마크 데이터셋(e.g., CIFAR-10, CIFAR-100, ImageNet)을 사용하여 기존 활성화 함수들과 성능을 비교하는 실험을 수행해야 합니다.

  • 실험 설정:
    • 동일한 모델 아키텍처를 사용하고, 활성화 함수만 변경하면서 실험합니다.
    • 학습률, 배치 크기, 옵티마이저 등 다른 하이퍼파라미터는 동일하게 유지합니다.
    • 여러 번의 실험을 반복하여 결과의 통계적 유의성을 확보합니다.
  • 평가 지표:
    • Accuracy (정확도)
    • Loss
    • Training Time (훈련 시간)
    • Convergence Speed (수렴 속도)
    • Gradient Norm (그래디언트 크기) - train_model_with_metrics 함수 활용
    • Number/Percentage of Disabled Neurons (“죽은 뉴런” 비율) - calculate_disabled_neuron 함수 활용
    • 필요하다면, 메모리 사용량 등
  • 결과 분석
    • 수렴 속도와 최종 성능을 정량적으로 비교
    • 그래디언트 소실/폭발 문제가 발생하는지
    • “죽은 뉴런” 발생 비율은 어떤지

6. (선택 사항) 이론적 분석

실험 결과가 좋다면, 왜 새로운 활성화 함수가 좋은 성능을 보이는지 이론적으로 분석하는 것이 좋습니다.

  • Loss Landscape 분석: 활성화 함수가 손실 함수 공간(loss landscape)에 어떤 영향을 미치는지 분석합니다. (4.2절 딥다이브 참고)
  • Neural Tangent Kernel (NTK) 분석: 무한히 넓은 신경망에서 활성화 함수의 역할을 분석합니다.
  • Fokker-Planck 방정식: 활성화 함수의 동역학적 특성을 분석합니다. (Swish에 대한 연구 참고)

결론

새로운 활성화 함수를 설계하고 평가하는 것은 쉽지 않은 작업이지만, 딥러닝 모델의 성능을 향상시킬 수 있는 잠재력이 큰 연구 분야입니다. 기존 활성화 함수의 한계를 극복하고, 특정 문제나 아키텍처에 더 적합한 활성화 함수를 찾는 것은 딥러닝 연구의 중요한 과제 중 하나입니다. 이 딥다이브에서 제시된 단계별 접근 방식과 PyTorch 구현 예제, 그리고 실험 및 분석 가이드라인이 여러분만의 활성화 함수를 설계하는 데 도움이 되기를 바랍니다.

딥다이브: 적응형 활성화 함수 - 미래 연구 방향

들어가며:

ReLU, GELU 등 고정된 활성화 함수는 딥러닝 모델에서 널리 사용되지만, 특정 문제나 데이터 분포에 최적화되지 않을 수 있습니다. 최근에는 데이터나 태스크에 따라 활성화 함수를 적응적으로 조정하는 연구가 활발히 진행되고 있습니다. 이 딥다이브에서는 적응형 활성화 함수(Adaptive Activation Function)의 잠재력과 미래 연구 방향을 탐구합니다.

1. 적응형 활성화 함수의 유형

적응형 활성화 함수는 크게 다음과 같이 분류할 수 있습니다.

  • 매개변수 기반 적응 (Parametric Adaptation): 활성화 함수에 학습 가능한 매개변수를 도입하여, 데이터에 따라 함수의 형태를 조정합니다.

    • 예시:
      • Leaky ReLU: \(f(x) = max(\\alpha x, x)\) (\(\\alpha\)는 학습 가능한 매개변수)
      • PReLU (Parametric ReLU): Leaky ReLU에서 \(\\alpha\)를 각 채널별로 학습
      • Swish: \(f(x) = x \\cdot \\sigma(\\beta x)\) (\(\\beta\)는 학습 가능한 매개변수)
  • 구조적 적응 (Structural Adaptation): 여러 개의 기저 함수(basis function)를 조합하거나, 네트워크 구조를 변경하여 활성화 함수를 동적으로 구성합니다.

    • 예시:
      • Maxout Networks: 여러 개의 선형 함수 중 최댓값을 취하는 방식
      • Spline-based Activation Functions: 스플라인 함수를 사용하여 활성화 함수를 표현
  • 입력 기반 적응: 입력 데이터의 특성에 따라 활성화 함수를 변경하거나 혼합하는 방식

    • 예시:
      • Squeeze and Excitation(SE) Block: 입력 특성 맵의 채널 간 중요도를 계산하여, 활성화 함수에 가중치를 부여

2. 가능한 연구 방향

2.1 Mixture of Experts (MoE) 기반 활성화 함수
  • 아이디어: 여러 개의 “전문가” 활성화 함수를 정의하고, 입력 데이터에 따라 각 전문가의 가중치를 동적으로 결정하는 방식입니다.

  • 수학적 표현:

    \(f(x) = \\sum\_{k=1}^K g\_k(x) \\cdot \\phi\_k(x)\)

    • \(g\_k(x)\): 입력 \(x\)에 대한 \(k\)번째 전문가 활성화 함수의 게이팅 함수 (softmax 등으로 정규화)
    • \(\\phi\_k(x)\): \(k\)번째 전문가 활성화 함수 (ReLU, GELU, Swish 등 다양한 함수 사용 가능)
  • 연구 과제:

    • 효율적인 게이팅 메커니즘: \(g\_k(x)\)를 계산하는 효율적인 방법 연구 (예: Top-k gating, sparse gating)
    • 전문가 활성화 함수 선택: 어떤 종류의 \(\\phi\_k(x)\)를 사용하는 것이 좋을지, 그리고 전문가의 수를 어떻게 결정할지에 대한 연구
    • 이론적 분석: MoE 활성화 함수의 표현력(expressive power)과 일반화 성능에 대한 이론적 분석
2.2 신경망 구조 탐색 (Neural Architecture Search, NAS)과의 결합
  • 아이디어: NAS를 사용하여 데이터와 태스크에 최적화된 활성화 함수 구조를 자동으로 탐색합니다.
  • 접근 방법:
    • 검색 공간 (Search Space):
      • 기본 연산 (선형 변환, 지수 함수, 로그 함수, 삼각 함수 등)을 정의
      • 연산들을 조합하여 만들 수 있는 다양한 활성화 함수 후보군을 정의
    • 검색 전략 (Search Strategy):
      • 강화 학습 (Reinforcement Learning)
      • 진화 알고리즘 (Evolutionary Algorithm)
      • 미분 가능 아키텍처 탐색 (Differentiable Architecture Search, DARTS)
    • 성능 평가 (Performance Estimation):
      • 검색된 활성화 함수를 포함한 모델을 학습시키고, 검증 데이터셋에서 성능 평가
  • 연구 과제:
    • 효율적인 검색 공간 설계: 너무 크지 않으면서도 충분히 다양한 활성화 함수를 포함하는 검색 공간 정의
    • 계산 비용 절감: NAS는 계산 비용이 매우 크므로, 효율적인 검색 전략 및 성능 평가 방법 개발
2.3 물리적/생물학적 정보 통합
  • 아이디어: 물리학, 생물학 등의 도메인 지식을 활용하여 활성화 함수 설계에 제약 조건 또는 prior knowledge를 부여합니다.

  • 예시:

    • 물리 모델: 특정 물리 시스템을 모델링하는 경우, 해당 시스템의 미분 방정식을 활성화 함수에 반영
    • 신경 과학: 실제 뉴런의 동작 방식을 모방하는 활성화 함수 (예: spiking neuron model)
  • 연구 과제:

    • 도메인 지식의 효과적인 통합: 도메인 지식을 활성화 함수 설계에 어떻게 반영할 것인지에 대한 방법론 개발
    • 일반화 성능: 특정 도메인에 특화된 활성화 함수가 다른 도메인에서도 잘 작동할지에 대한 검증
2.4 이론적 분석 강화
  • 표현력 (Expressive Power): 적응형 활성화 함수가 기존 활성화 함수에 비해 얼마나 더 강력한 표현력을 갖는지 분석
  • 최적화 용이성 (Optimization Landscape): 적응형 활성화 함수가 손실 함수 표면(loss landscape)을 어떻게 변화시키는지, 이것이 학습 속도와 안정성에 어떤 영향을 미치는지 분석
  • 일반화 성능 (Generalization): 적응형 활성화 함수가 과적합(overfitting)을 방지하고 일반화 성능을 향상시키는지 분석

3. 결론 및 제언

적응형 활성화 함수는 딥러닝 모델의 성능을 향상시킬 수 있는 유망한 연구 분야입니다. 하지만, 다음과 같은 과제들이 남아있습니다.

  • 계산 복잡도: 적응형 활성화 함수는 일반적으로 고정된 활성화 함수보다 계산 비용이 높습니다.
  • 해석 가능성: 학습된 활성화 함수의 형태가 복잡해지면, 모델의 해석이 어려워질 수 있습니다.
  • 과적합 위험: 너무 유연한 활성화 함수는 훈련 데이터에 과적합될 위험이 있습니다.

향후 연구에서는 이러한 과제들을 해결하면서, 더 효율적이고, 해석 가능하며, 일반화 성능이 뛰어난 적응형 활성화 함수를 개발하는 것이 중요합니다.


연습문제

4.2.1 기본 문제

  1. Sigmoid, Tanh, ReLU, Leaky ReLU, GELU, Swish 함수의 수식을 쓰고, 그래프를 그리시오. (matplotlib, Desmos 등 활용)

    • 참고: 각 함수의 정의와 특징을 명확히 이해하고, 그래프를 통해 시각적으로 비교할 수 있도록 합니다.
  2. 각 활성화 함수의 미분(도함수)을 구하고, 그래프를 그리시오.

    • 참고: 도함수는 역전파 과정에서 그래디언트를 계산하는 데 사용됩니다. 각 함수의 미분 가능성과 그래디언트의 특성을 파악합니다.
  3. FashionMNIST 데이터셋을 사용하여, 활성화 함수 없이 선형 변환만으로 구성된 신경망을 훈련하고, 테스트 정확도를 측정하시오. (1장에서 구현한 SimpleNetwork 활용)

    • 참고: 활성화 함수가 없는 신경망은 비선형성을 표현할 수 없기 때문에, 복잡한 문제를 해결하는 데 한계가 있습니다. 실험을 통해 이를 확인합니다.
  4. 3번 문제에서 얻은 결과와, ReLU 활성화 함수를 사용한 신경망의 결과를 비교하고, 활성화 함수의 역할에 대해 설명하시오.

    • 참고: 활성함수가 있을 때와 없을 때 층별 출력값, 그래디언트, 비활성 뉴런을 비교해서 설명하시오.

4.2.2 응용 문제

  1. PReLU, TeLU, STAF 활성화 함수를 PyTorch로 구현하시오. (nn.Module 상속)

    • 참고: 각 함수의 정의를 참고하여, forward 메서드를 구현합니다. 필요한 경우, 학습 가능한 파라미터를 nn.Parameter로 정의합니다.
  2. FashionMNIST 데이터셋을 사용하여, 앞서 구현한 활성화 함수들을 포함한 신경망을 훈련하고, 테스트 정확도를 비교하시오.

    • 참고: 각 활성화 함수의 성능을 비교하고, 어떤 함수가 FashionMNIST 데이터셋에 더 적합한지 분석합니다.
  3. 각 활성화 함수에 대해, 훈련 과정에서의 그래디언트 분포를 시각화하고, “죽은 뉴런”의 비율을 측정하시오. (1장에서 구현한 함수 활용)

    • 참고: 각 활성함수 별로, 그래디언트 분포를 초기 값과 훈련된 값, 각 층별로 비교해서 그래프로 시각화 하시오.
  4. “죽은 뉴런” 문제를 완화하기 위한 방법들을 조사하고, 그 원리를 설명하시오. (Leaky ReLU, PReLU, ELU, SELU 등)

    • 참고: 각 방법이 ReLU의 문제점을 어떻게 해결하는지, 그리고 어떤 장단점을 가지는지 설명합니다.

4.2.3 심화 문제

  1. Rational 활성화 함수를 PyTorch로 구현하고, 그 특징과 장단점을 설명하시오.

    • 참고: Rational 활성화 함수는 유리 함수(분수 함수)를 기반으로 하며, 특정 문제에서 다른 활성화 함수보다 우수한 성능을 보일 수 있습니다.
  2. B-spline 활성화 함수 또는 Fourier-based 활성화 함수를 PyTorch로 구현하고, 그 특징과 장단점을 설명하시오.

    • 참고: B-spline 활성화 함수는 지역적으로 제어되는 유연한 곡선을 표현할 수 있으며, Fourier-based 활성화 함수는 주기적인 패턴을 모델링하는 데 유리합니다.
  3. 자신만의 새로운 활성화 함수를 제안하고, 기존 활성화 함수들과 비교하여 성능을 평가하시오. (실험 결과와 함께 이론적 근거 제시)

    • 참고: 새로운 활성화 함수를 설계할 때는, 이상적인 활성화 함수의 조건(비선형성, 미분 가능성, 그래디언트 소실/폭발 문제 방지, 계산 효율성 등)을 고려해야 합니다.

연습문제 해답

4.2.1 기본 문제

1. Sigmoid, Tanh, ReLU, Leaky ReLU, GELU, Swish 함수의 수식 및 그래프:

| 활성화 함수 | 수식        | 그래프 (참고)    |
| ------- | ------------------------------------------------------- | ---------------------------------------------------- |
| Sigmoid     | $\sigma(x) = \frac{1}{1 + e^{-x}}$                                         | [Sigmoid](https://www.google.com/search?q=https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Logistic-curve.svg/320px-Logistic-curve.svg.png) |
| Tanh        | $tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}$                           | [Tanh](https://www.google.com/search?q=https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Hyperbolic_Tangent.svg/320px-Hyperbolic_Tangent.svg.png)     |
| ReLU        | $ReLU(x) = max(0, x)$                                                     | [ReLU](https://www.google.com/search?q=https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Activation_rectified_linear.svg/320px-Activation_rectified_linear.svg.png) |
| Leaky ReLU  | $LeakyReLU(x) = max(ax, x)$ ,  ($a$는 작은 상수, 보통 0.01)               | (Leaky ReLU는 ReLU 그래프에서 x < 0 부분에 작은 기울기($a$)를 가짐)                  |
| GELU        | $GELU(x) = x\Phi(x)$ , ($\Phi(x)$는 가우시안 누적 분포 함수)             | [GELU](https://www.google.com/search?q=https://production-media.paperswithcode.com/methods/Screen_Shot_2020-06-22_at_3.34.27_PM_fufBJEx.png)            |
| Swish       | $Swish(x) = x \cdot sigmoid(\beta x)$ , ($\beta$는 상수 또는 학습 파라미터) | [Swish](https://www.google.com/search?q=https://production-media.paperswithcode.com/methods/Screen_Shot_2020-06-22_at_3.35.27_PM_d7LqDQj.png)          |

2. 각 활성화 함수의 미분(도함수):

| 활성화 함수 | 도함수                                                                                     |
| :---------- | :------------------------------------------------------------------------------------------ |
| Sigmoid     | $\sigma'(x) = \sigma(x)(1 - \sigma(x))$                                                      |
| Tanh        | $tanh'(x) = 1 - tanh^2(x)$                                                                  |
| ReLU        | $ReLU'(x) = \begin{cases} 0, & x < 0 \\ 1, & x > 0 \end{cases}$                             |
| Leaky ReLU  | $LeakyReLU'(x) = \begin{cases} a, & x < 0 \\ 1, & x > 0 \end{cases}$                        |
| GELU        | $GELU'(x) = \Phi(x) + x\phi(x)$, ($\phi(x)$는 가우시안 확률 밀도 함수)                       |
| Swish       | $Swish'(x) = sigmoid(\beta x) + x \cdot sigmoid(\beta x)(1 - sigmoid(\beta x))\beta$ |
  1. FashionMNIST, 활성화 함수 없는 신경망 훈련 및 정확도 측정:

    • 활성화 함수가 없는 신경망은 선형 변환만 수행하므로, 복잡한 비선형 관계를 모델링할 수 없습니다. 따라서 FashionMNIST와 같이 복잡한 데이터셋에서는 낮은 정확도를 보입니다. (대략 10% 내외의 정확도)
  2. ReLU 활성화 함수 사용 신경망과 비교, 활성화 함수 역할 설명:

    • ReLU 활성화 함수를 사용한 신경망은 비선형성을 도입하여 훨씬 더 높은 정확도를 달성할 수 있습니다. (80% 이상의 정확도)
    • 층별 출력값: 활성화 함수가 없으면 층별 출력값의 분포가 단순한 스케일 변화만 보이지만, ReLU를 사용하면 음수 값이 0으로 억제되면서 분포가 달라집니다.
    • 그래디언트: 활성화 함수가 없으면 그래디언트가 단순하게 전달되지만, ReLU를 사용하면 음수 입력에 대해서는 그래디언트가 0이 되어 전파되지 않습니다.
    • 비활성 뉴런: 활성화 함수가 없을 때는 발생하지 않으나, ReLU 사용시 발생 가능
    • 역할 요약: 활성화 함수는 신경망에 비선형성을 부여하여 복잡한 함수를 근사할 수 있게 하고, 그래디언트 흐름을 조절하여 학습을 돕습니다.

4.2.2 응용 문제

  1. PReLU, TeLU, STAF PyTorch 구현:

    import torch
    import torch.nn as nn
    
    class PReLU(nn.Module):
        def __init__(self, num_parameters=1, init=0.25):
            super().__init__()
            self.alpha = nn.Parameter(torch.full((num_parameters,), init))
    
        def forward(self, x):
            return torch.max(torch.zeros_like(x), x) + self.alpha * torch.min(torch.zeros_like(x), x)
    
    class TeLU(nn.Module):
        def __init__(self, alpha=1.0):
            super().__init__()
            self.alpha = nn.Parameter(torch.tensor(alpha))
    
        def forward(self, x):
            return torch.where(x > 0, x, self.alpha * (torch.exp(x) - 1))
    
    class STAF(nn.Module):
        def __init__(self, tau=25):
            super().__init__()
            self.tau = tau
            self.C = nn.Parameter(torch.randn(tau))
            self.Omega = nn.Parameter(torch.randn(tau))
            self.Phi = nn.Parameter(torch.randn(tau))
    
        def forward(self, x):
            result = torch.zeros_like(x)
            for i in range(self.tau):
                result += self.C[i] * torch.sin(self.Omega[i] * x + self.Phi[i])
            return result
  2. FashionMNIST, 활성화 함수 비교 실험:

    • PReLU, TeLU, STAF를 포함한 신경망을 훈련하고, 테스트 정확도를 비교합니다.
    • 실험 결과, 적응형 활성화 함수(PReLU, TeLU, STAF)가 ReLU보다 높은 정확도를 보이는 경향이 있습니다. (STAF > TeLU > PReLU > ReLU 순)
  3. 그래디언트 분포 시각화, “죽은 뉴런” 비율 측정:

    • ReLU는 음수 입력에서 그래디언트가 0, PReLU, TeLU, STAF는 음수 입력에서도 작은 그래디언트 값이 전파됨
    • “죽은 뉴런” 비율은 ReLU에서 가장 높고, PReLU, TeLU, STAF에서는 낮게 나타납니다.
  4. “죽은 뉴런” 문제 완화 방법 및 원리:

    • Leaky ReLU: 음수 입력에 대해 작은 기울기를 허용하여 뉴런이 완전히 비활성화되는 것을 방지합니다.
    • PReLU: Leaky ReLU의 기울기를 학습 가능한 파라미터로 만들어 데이터에 따라 최적의 기울기를 찾습니다.
    • ELU, SELU: 음수 영역에서 0이 아닌 값을 가지면서도 부드러운 곡선 형태를 가져, 그래디언트 소실 문제를 완화하고 학습을 안정화합니다.

4.2.3 심화 문제

  1. Rational 활성화 함수 PyTorch 구현, 특징 및 장단점:

    import torch
    import torch.nn as nn
    
    class Rational(nn.Module):
        def __init__(self, numerator_coeffs, denominator_coeffs):
            super().__init__()
            self.numerator_coeffs = nn.Parameter(numerator_coeffs)
            self.denominator_coeffs = nn.Parameter(denominator_coeffs)
    
        def forward(self, x):
            numerator = torch.polyval(self.numerator_coeffs, x) # 다항식 계산
            denominator = 1 + torch.polyval(self.denominator_coeffs, torch.abs(x))  # 절댓값 및 다항식
            return numerator / denominator
    • 특징: 유리 함수(분수 함수) 형태. 분자와 분모는 다항식으로 표현.
    • 장점: 유연한 함수 형태. 특정 문제에서 다른 활성화 함수보다 뛰어난 성능.
    • 단점: 분모가 0이 되는 경우 주의. 하이퍼파라미터(다항식 계수) 튜닝 필요.
  2. B-spline 또는 Fourier-based 활성화 함수 PyTorch 구현, 특징 및 장단점:

    • B-spline 활성화 함수:

      import torch
      import torch.nn as nn
      from scipy.interpolate import BSpline
      import numpy as np
      
      class BSplineActivation(nn.Module):
          def __init__(self, knots, degree=3):
              super().__init__()
              self.knots = knots
              self.degree = degree
              self.coeffs = nn.Parameter(torch.randn(len(knots) + degree - 1)) # 제어점
      
          def forward(self, x):
              # B-Spline 계산
              b = BSpline(self.knots, self.coeffs.detach().numpy(), self.degree) # 계수 분리해서 사용
              spline_values = torch.tensor(b(x.detach().numpy()), dtype=torch.float32) # 입력 x를 B-Spline에 넣음
              return spline_values * self.coeffs.mean() # detach, numpy() 안하면 오류
               # detach, numpy() 안하면 오류
    • 특징: 지역적으로 제어되는 유연한 곡선. 매듭(knot)과 차수(degree)로 형태 조절.

    • 장점: 부드러운 함수 표현. 지역적 특징 학습.

    • 단점: 매듭 설정에 따라 성능 영향. 계산 복잡도 증가.

  3. 새로운 활성화 함수 제안 및 성능 평가:

    • (예시) Swish와 GELU를 결합한 활성화 함수:
    ```python
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    class SwiGELU(nn.Module): # Swish + GELU
      def forward(self, x):
        return 0.5 * (x * torch.sigmoid(x) + F.gelu(x))
    ```
    
    SwiGELU는 Swish의 부드러움과 GELU의 정규화 효과를 결합합니다.
    • 실험 설계 및 성능 평가: FashionMNIST 등 벤치마크 데이터셋에서 기존 활성화 함수와 비교. (실험 결과는 생략)

참고자료

  1. Deep Learning (Goodfellow, Bengio, Courville, 2016): Chapter 6.3 (Activation Functions) https://www.deeplearningbook.org/
    • 딥러닝 전반에 대한 포괄적인 내용을 담고 있는 교과서. 활성화 함수에 대한 기본적인 내용과 함께, 딥러닝의 다른 중요한 개념들도 함께 학습할 수 있습니다.
  2. Understanding the difficulty of training deep feedforward neural networks (Glorot & Bengio, 2010) http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf
    • Sigmoid와 Tanh 활성화 함수의 그래디언트 소실 문제를 분석하고, Xavier 초기화 방법을 제안한 논문. 심층 신경망 학습의 어려움을 이해하는 데 중요한 자료입니다.
  3. Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification (He et al., 2015) https://arxiv.org/abs/1502.01852
    • ReLU 활성화 함수와 PReLU 활성화 함수, 그리고 He 초기화 방법을 제안한 논문. 현대 딥러닝에서 널리 사용되는 ReLU 계열 활성화 함수에 대한 이해를 높일 수 있습니다.
  4. Searching for Activation Functions (Ramachandran et al., 2017) https://arxiv.org/abs/1710.05941
    • 신경망 구조 탐색(Neural Architecture Search, NAS)을 통해 Swish 활성화 함수를 발견한 논문. 새로운 활성화 함수를 탐색하는 방법에 대한 아이디어를 얻을 수 있습니다.
  5. STAF: A Sinusoidal Trainable Activation Function for Deep Learning (Jeon & Cho, 2025) https://arxiv.org/abs/2405.13607 * 최신(2025년) ICLR에 발표된 논문으로, 푸리에 급수 기반의 학습 가능한 활성화 함수인 STAF를 제안합니다. 적응형 활성화 함수에 대한 최신 연구 동향을 파악하는 데 도움이 됩니다.