常用激活函数(深度学习、大模型)

作用

激活函数通常需满足以下条件:

  • 非线性:允许网络逼近任意函数,避免线性叠加的限制。
  • 可微性:支持梯度下降和反向传播,便于优化。
  • 输出范围有限:控制输出值域,防止梯度爆炸或数值不稳定。

主要作用包括:

  • 引入非线性变换,使多层网络具有表达能力。
  • 控制输出范围:将神经元的输出压缩在特定区间(如 [ 0 , 1 ] [0, 1] [0,1] [ − 1 , 1 ] [-1, 1] [1,1]),有利于数值稳定性和后续层的输入对齐。控制梯度流动,影响训练速度和稳定性。
  • 在输出层适应特定任务,如分类或回归。
  • 稀疏激活(Sparse Activation):通过让部分神经元输出为 0,模拟生物神经元的抑制机制,减少计算冗余并缓解过拟合。

基础经典组:

sigmod

早期神经网络(如 Logistic 回归)的标准选择。数学表达: σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+ex1

  • 优点:输出平滑,值域在 ( 0 , 1 ) (0, 1) (0,1) 之间,非常适合表示概率。
  • 缺点:
    1. 梯度消失(Gradient Vanishing):在 x x x 很大或很小时,导数趋近于 0,导致反向传播时参数无法更新。
    2. 非零中心(Non-zero centered):输出均大于 0,会导致后一层神经元的梯度方向出现“锯齿协同”变化,减缓收敛。(所有参数的更新(梯度)方向相同,要么同为正,要么同为负)

softmax

Softmax 是神经网络中常用的多分类激活函数,将实数向量转换为概率分布。数学表达: σ ( x ) i = e x i ∑ j = 1 k e x j \sigma(x)_{i}=\frac{e^{x_{i}}}{\sum_{j=1}^{k}e^{x_{j}}} σ(x)i=j=1kexjexi

  • 优点:输出平滑,每个输出可解释为类别概率,且所有类别概率之和为 1。
  • 缺点:
    1. 梯度消失(Gradient Vanishing):当某个类别的 logit 值远大于其他类别时,主导类别和其他类别的梯度都趋近于 0,导致反向传播时参数无法更新。
    2. 非零中心(Non-zero centered):输出均大于 0

tanh

数学表达: tanh ⁡ ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=ex+exexex

  • 优点:输出范围在 ( − 1 , 1 ) (-1, 1) (1,1),解决了零中心化问题,收敛速度通常快于 Sigmoid。
  • 缺点:依然无法逃脱梯度消失的困境。

ReLU 变体与平滑组:

ReLu

由 AlexNet 推向主流,彻底改变了深层网络的训练难度。数学表达: f ( x ) = max ⁡ ( 0 , x ) f(x) = \max(0, x) f(x)=max(0,x)

  • 优点:
    1. 计算极其简单:只需一个阈值判断。
    2. 缓解梯度消失:在 x > 0 x > 0 x>0 区域,导数恒为 1,支持训练极深的网络。
    3. 稀疏性:使部分神经元失活,模型更具鲁棒性。
  • 缺点:Dead ReLU 问题:如果一个很大的梯度流过,导致权重更新到让 x x x 始终小于 0,该神经元将永久“死亡”,不再更新。

LeakyRelu&PRelu

旨在修复“Dead ReLU”问题。数学表达: f ( x ) = max ⁡ ( α x , x ) f(x) = \max(\alpha x, x) f(x)=max(αx,x)(其中 α \alpha α 是一个很小的常数,如 0.01)。

  • 优点:在 x < 0 x < 0 x<0 时保留了一个微小的梯度,保证所有神经元都能持续学习。
  • PReLU (Parametric ReLU):将 α \alpha α 设为可学习参数,让模型自适应调整负半轴斜率。

RRelu

在训练过程中随机化负半轴的斜率,以增强模型的鲁棒性和泛化能力。其数学表达式为: f ( x ) = max ⁡ ( α x , x ) f(x) = \max(\alpha x, x) f(x)=max(αx,x) 其中 α \alpha α 是一个随机变量,服从特定分布(如均匀分布或高斯分布),而非固定值或可学习参数。例如:
f ( x ) = { x if  x ≥ 0   α x if  x < 0 , α ∼ U ( a , b ) f(x) = \begin{cases} x & \text{if } x \geq 0 \ \alpha x & \text{if } x < 0 \end{cases}, \quad \alpha \sim \mathcal{U}(a,b) f(x)={xif x0 αxif x<0,αU(a,b) 其中 U ( a , b ) \mathcal{U}(a,b) U(a,b) 表示均匀分布, a a a b b b 为超参数(例如 a = 0.1 a=0.1 a=0.1, b = 0.3 b=0.3 b=0.3)。

  • 优点:引入随机性,RRELU能够动态调整负半轴的梯度传递强度,既避免了Dead ReLU问题,又增强了模型对噪声和输入变化的适应能力

Dice

Dice 是在阿里巴巴的 DIN (Deep Interest Network) 模型中提出的,专门为推荐系统设计。

  • 设计目的:ReLU 的硬截断(在 0 处断开)忽略了数据分布。Dice 认为,激活的“开关”不应固定在 0,而应根据输入数据的均值和方差动态调整。数学表达: f ( s ) = p ( s ) ⋅ s + ( 1 − p ( s ) ) ⋅ α s f(s) = p(s) \cdot s + (1 - p(s)) \cdot \alpha s f(s)=p(s)s+(1p(s))αs其中 p ( s ) = 1 1 + e − s − E [ s ] V a r [ s ] + ϵ p(s) = \frac{1}{1 + e^{-\frac{s - E[s]}{\sqrt{Var[s] + \epsilon}}}} p(s)=1+eVar[s]+ϵ sE[s]1
  • 优点:
    1. 平滑性:在分布中心附近平滑过渡。
    2. 数据自适应:根据当前 Batch 的数据分布自动调整校正点。
  • 缺点:计算开销比 ReLU 大,且高度依赖 Batch 统计信息(受 Batch Size 影响)。

GELU

GeLU (Gaussian Error Linear Unit):Transformer 的标配当前 GPT、BERT 等大语言模型最常用的激活函数。数学表达: G E L U ( x ) = x ⋅ Φ ( x ) GELU(x) = x \cdot \Phi(x) GELU(x)=xΦ(x)其中 Φ ( x ) \Phi(x) Φ(x) 是标准正态分布的累积分布函数。

  • 设计逻辑:它结合了 ReLU 的非线性和 Dropout 的随机性思想。在 x x x 较小时,以更高概率被“丢弃(归零)”。
  • 优点:在 0 附近更加平滑,实验证明其在高性能 NLP 模型中表现优于 ReLU。

GeLU近似实现: GeLU ( x ) ≈ x σ ( 1.702 x ) \text{GeLU}(x) \approx x\sigma(1.702x) GeLU(x)xσ(1.702x) 通过调整sigmoid系数平衡线性与非线性特性。

Swish

由 Google 团队通过自动搜索发现,目前广泛应用于 EfficientNet 和 Llama 2/3。数学表达: f ( x ) = x ⋅ σ ( β x ) = x 1 + e − β x f(x) = x \cdot \sigma(\beta x) = \frac{x}{1 + e^{-\beta x}} f(x)=xσ(βx)=1+eβxx(当 β = 1 \beta=1 β=1 时,常被称为 SiLU)。

  • 优点:
    1. 无上界但有下界:有助于防止梯度饱和。
    2. 非单调性(Non-monotonic):在 x < 0 x < 0 x<0 附近有一个小的“凹陷”,这被认为有助于捕捉更复杂的底层特征。
    3. 平滑性:导数连续,比 ReLU 更容易通过梯度下降优化。

门控组

GLU

GLU(Gated Linear Unit)是一种门控激活函数,通过线性变换和门控机制结合,增强模型对信息的筛选能力。

  • 核心思想是使用sigmoid门控控制信息流动,保留重要特征,抑制无关信息。数学表达: GLU ( x ) = ( x W + b ) ⊗ σ ( x V + c ) \text{GLU}(x) = (xW + b) \otimes \sigma(xV + c) GLU(x)=(xW+b)σ(xV+c)
    其中: x x x 是输入向量, W , V W, V W,V是可学习的权重矩阵, b , c b, c b,c是偏置项, σ \sigma σ 是sigmoid函数, ⊗ \otimes 表示逐元素乘法
  • 工作原理:输入向量通过两条并行路径处理:
    1. 线性变换路径: x W + b xW + b xW+b 对输入做线性投影
    2. 门控路径: σ ( x V + c ) \sigma(xV + c) σ(xV+c) 生成0到1之间的门控值
  • 优点:
    1. 门控机制实现动态特征选择
    2. 缓解梯度消失问题(线性变换允许梯度部分传播)

变体:(替换门控sigmoid函数)

  1. ReGLU:用ReLU替换sigmoid门控 ReGLU ( x ) = ( x W + b ) ⊗ max ⁡ ( 0 , x V + c ) \text{ReGLU}(x) = (xW + b) \otimes \max(0, xV + c) ReGLU(x)=(xW+b)max(0,xV+c)
  2. GEGLU:采用GELU作为门控函数 GEGLU ( x ) = ( x W + b ) ⊗ GELU ( x V + c ) \text{GEGLU}(x) = (xW + b) \otimes \text{GELU}(xV + c) GEGLU(x)=(xW+b)GELU(xV+c)

SwiGLU

Llama 系列、PaLM 等主流大模型的核心组件。数学表达: S w i G L U ( x , W , V , b , c ) = S w i s h β ( x W + b ) ⊗ ( x V + c ) SwiGLU(x, W, V, b, c) = Swish_{\beta}(xW + b) \otimes (xV + c) SwiGLU(x,W,V,b,c)=Swishβ(xW+b)(xV+c)其中 ⊗ \otimes 是逐元素相乘(Hadamard product)。

  • 设计目的:利用“门控机制”。一个分支负责提取特征 ( x V xV xV),另一个分支通过 Swish 产生权重控制信息流。
  • 为什么 LLM 都用它?计算效率与表达力的平衡:虽然参数量增加了(需要两个权重矩阵 W W W V V V),但它显著提升了模型在处理复杂逻辑推理时的收敛速度和最终精度。

GeGLU

PaLM 和部分 BERT 变体中使用,是 GeLU 的门控版本。数学表达: G e G L U ( x , W , V ) = G e L U ( x W ) ⊗ ( x V ) GeGLU(x, W, V) = GeLU(xW) \otimes (xV) GeGLU(x,W,V)=GeLU(xW)(xV)

  • 特点:与 SwiGLU 类似,但将门控分支替换为 GeLU。在处理多模态数据时表现出极强的稳定性。

总结对比表

函数核心应用场景关键特性建议
ReLUCNN / 工业级baseline,简单、快、易死掉适合快速实验
GeLUBERT / Transformer平滑、考虑随机性NLP 任务的首选单函数
Dice推荐系统 (CTR)数据自适应偏移仅推荐在 DS 场景尝试
SwiGLULlama / 大模型 FFN门控机制、推理能力强当前 SOTA 模型的最强选择

激活函数可视化:

在这里插入图片描述

1. 组 1:基础经典组

  • Sigmoid vs Tanh:直观地看到 Tanh 是零中心的(过原点),而 Sigmoid 全部在 y > 0 y > 0 y>0 区域。这解释了为什么 Tanh 在深层网络中通常比 Sigmoid 收敛更快。
  • ReLU 的硬截断:注意 ReLU 在 x = 0 x=0 x=0 处的突变,这导致了“Dead ReLU”问题。

2. 组 2:ReLU 变体与平滑组(最重要的一组)

  • SiLU (Swish) vs GeLU:两者非常相似,但在 0 附近,GeLU 的负向凹陷比 SiLU 更深一些,且在正负轴过渡时更加平滑。这微小的差别在超大规模参数的 Transformer 训练中可能会产生累积的影响。
  • 局部放大图:清晰地展示了“非单调性”——当输入 x x x − 2 -2 2 0 0 0 之间变大时,输出 y y y 反而变小。这种特性被认为有助于模型在优化初期跳出局部最优。

3. 组 3:数据自适应组 (Dice)

  • 核心区别:ReLU 坚决地将负数全部归零。而 Dice 函数的“开关点”随着数据分布的均值(E[s])移动。在我们的模拟中,数据中心在 1.0,Dice 在 1.0 附近平滑地实现了从“抑制(斜率为 α \alpha α)”到“激活(斜率为 1)”的转换。

4. 组 4:大模型门控组

  • 表达力对比:SiLU (Swish) 只是一个简单的非线性映射。而 SwiGLU(我们这里做了一维的抽象表示)通过门控机制,在正轴方向产生了一个更复杂的、具有更强非线性截断特征的曲线。这种结构赋予了大模型更强的逻辑推理和参数拟合能力。

Python 代码实现

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

#设置中文字体 (根据你的系统调整,常用有 SimHei, Arial Unicode MS)
plt.rcParams['font.sans-serif'] = ['SimHei'] 
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题

# --- 1. 定义激活函数 ---

# 经典组
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def tanh(x):
    return np.tanh(x)

def relu(x):
    return np.maximum(0, x)

# 平滑与变体组
def leaky_relu(x, alpha=0.1): # 稍微增大 alpha 以便观察
    return np.where(x > 0, x, alpha * x)

def silu(x): # 即 Swish with beta=1
    return x * sigmoid(x)

from scipy.stats import norm
def gelu(x):
    # 使用标准正态分布的累积分布函数
    return x * norm.cdf(x)

# 数据自适应组 (Dice)
def dice_simulation(s, alpha=0.2):
    """
    模拟 Dice 函数。
    在真实场景中,E[s] 和 Var[s] 来自 Batch 统计。
    这里我们模拟一个均值为 1.0,方差为 0.5 的分布。
    """
    E_s = 1.0
    Var_s = 0.5
    epsilon = 1e-8
    # 计算 p(s)
    p_s = 1 / (1 + np.exp(-(s - E_s) / np.sqrt(Var_s + epsilon)))
    return p_s * s + (1 - p_s) * (alpha * s)

# 大模型门控组 (抽象展示 Swish vs SwiGLU 的门控效果)
def swiglu_abstract_show(x):
    """
    SwiGLU 是一个双分支结构:Swish(xW) * (xV)。
    为了在一维图像中展示其非线性特性,我们抽象地假设 W=1, V=0.5 (简化表示)。
    这仅用于展示其相比 SiLU 更加复杂的非线性截断特征。
    """
    gate_branch = silu(x * 1.0)
    linear_branch = x * 0.5
    return gate_branch * linear_branch

# --- 2. 准备数据 ---
x = np.linspace(-5, 5, 500) # 生成 -5 到 5 的 500 个点

# --- 3. 开始绘图 ---
fig = plt.figure(figsize=(16, 12), dpi=100)
gs = gridspec.GridSpec(2, 2, height_ratios=[1, 1], width_ratios=[1, 1])

# --- 子图 1: 基础经典组 ---
ax1 = fig.add_subplot(gs[0, 0])
ax1.plot(x, sigmoid(x), label='Sigmoid', color='#1f77b4', lw=2.5)
ax1.plot(x, tanh(x), label='Tanh', color='#ff7f0e', lw=2.5)
ax1.plot(x, relu(x), label='ReLU', color='#2ca02c', lw=2.5, linestyle='--')
ax1.set_title('组 1: 基础经典激活函数', fontsize=14)
ax1.set_ylim(-1.2, 1.2) # Tanh 范围
ax1.axhline(0, color='black',linewidth=0.5)
ax1.axvline(0, color='black',linewidth=0.5)
ax1.grid(True, linestyle='--', alpha=0.5)
ax1.legend(fontsize=12)

# --- 子图 2: ReLU 变体与平滑组 (最常用) ---
ax2 = fig.add_subplot(gs[0, 1])
ax2.plot(x, relu(x), label='ReLU (硬截断)', color='#2ca02c', lw=3, alpha=0.6)
ax2.plot(x, leaky_relu(x), label='Leaky ReLU ($\\alpha=0.1$)', color='#d62728', lw=2)
ax2.plot(x, silu(x), label='SiLU/Swish (Llama/EfficientNet)', color='#9467bd', lw=2.5)
ax2.plot(x, gelu(x), label='GeLU (Transformer/GPT)', color='#8c564b', lw=2.5, linestyle=':')
ax2.set_title('组 2: ReLU 变体与平滑非单调函数', fontsize=14)
ax2.set_ylim(-1.0, 5.0) # 聚焦负半轴死区
ax2.set_xlim(-4, 4)
ax2.axhline(0, color='black',linewidth=0.5)
ax2.axvline(0, color='black',linewidth=0.5)
ax2.grid(True, linestyle='--', alpha=0.5)
ax2.legend(fontsize=12)

# 在负半轴放大局部,展示 SiLU/GeLU 的非单调性 (凹陷)
ax2_ins = ax2.inset_axes([0.1, 0.5, 0.35, 0.35])
ax2_ins.plot(x, silu(x), color='#9467bd', lw=2)
ax2_ins.plot(x, gelu(x), color='#8c564b', lw=2, linestyle=':')
ax2_ins.set_xlim(-2.5, 0.5)
ax2_ins.set_ylim(-0.3, 0.1)
ax2_ins.grid(True, linestyle='--', alpha=0.3)
ax2_ins.set_title('负半轴非单调性放大', fontsize=10)

# --- 子图 3: 数据自适应组 (Dice) ---
ax3 = fig.add_subplot(gs[1, 0])
s = np.linspace(-3, 6, 500) # 扩大范围以容纳模拟分布
# 模拟的数据分布直方图 (辅助理解)
data_dist = np.random.normal(1.0, np.sqrt(0.5), 10000)
ax3.hist(data_dist, bins=50, density=True, alpha=0.15, color='gray', label='模拟数据分布 ($\\mu=1, \\sigma^2=0.5$)')

ax3.plot(s, relu(s), label='ReLU (固定 0 点截断)', color='#2ca02c', lw=2, alpha=0.5)
ax3.plot(s, dice_simulation(s), label='Dice (自适应分布中心)', color='#e377c2', lw=3)

# 标出数据分布中心 E[s]
ax3.axvline(1.0, color='#e377c2', linestyle=':', label='数据均值 E[s]')

ax3.set_title('组 3: 数据自适应激活函数 (推荐系统)', fontsize=14)
ax3.set_xlabel('神经元输入 $s$', fontsize=12)
ax3.set_ylim(-0.5, 4.0)
ax3.grid(True, linestyle='--', alpha=0.5)
ax3.legend(fontsize=11, loc='upper left')

# --- 子图 4: 大模型门控组 (SiLU vs SwiGLU 抽象效果) ---
ax4 = fig.add_subplot(gs[1, 1])
ax4.plot(x, silu(x), label='SiLU (单分支非线性)', color='#9467bd', lw=2.5)
# 抽象展示 SwiGLU 的门控效果
ax4.plot(x, swiglu_abstract_show(x), label='SwiGLU (门控线性单元 - 抽象展示)', color='#17becf', lw=3, linestyle='-.')

ax4.set_title('组 4: 大模型前馈网络 (FFN) 演进', fontsize=14)
ax4.set_xlabel('输入 $x$', fontsize=12)
ax4.set_ylim(-1.0, 5.0)
ax4.axhline(0, color='black',linewidth=0.5)
ax4.axvline(0, color='black',linewidth=0.5)
ax4.grid(True, linestyle='--', alpha=0.5)
ax4.legend(fontsize=12)

plt.tight_layout()
plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值