Activation & Initialization —— 激活函数与权重初始化
一、引言:激活函数与初始化的「共生关系」
在上一篇文章中,我们推导了多层感知机的反向传播过程。细心的读者可能已经注意到一个关键问题:反向传播时,梯度在每一层都会乘以激活函数的导数。如果这个导数很小,多层累积之后梯度就会指数级衰减——这就是著名的梯度消失(Vanishing Gradient) 问题。
梯度消失几乎让深度学习在2010年前后陷入绝境。直到ReLU激活函数和Kaiming初始化的出现,才真正让训练数十层甚至上百层的深度网络成为可能。
本文将从梯度饱和这一核心问题出发,系统梳理激活函数的演进历程,并深入推导Xavier和Kaiming两种初始化方法的数学原理。
二、饱和激活函数:Sigmoid与Tanh的「甜蜜陷阱」
2.1 Sigmoid:优雅但致命
Sigmoid函数的定义为:
σ(x)=1+e−x1值域为 (0,1),在零点处取最大值 σ(0)=0.5。
Sigmoid有一个非常优美的导数公式:
σ′(x)=σ(x)(1−σ(x))证明:用商法则,
σ′(x)=(1+e−x)2e−x而
σ(x)(1−σ(x))=1+e−x1⋅1+e−xe−x=(1+e−x)2e−x因此 σ′(x)=σ(x)(1−σ(x))。这个公式的优雅之处在于:只要知道函数值,就能直接算出导数值。
然而,致命的缺陷隐藏在这个导数公式中:
当 x→+∞ 时,σ(x)→1,σ′(x)→0; 当 x→−∞ 时,σ(x)→0,σ′(x)→0。
在 x=0 处导数取最大值:
σ′(0)=σ(0)(1−σ(0))=21⋅21=41也就是说,Sigmoid的导数最大也只有0.25。
这意味着什么?假设一个10层的网络,每层都使用Sigmoid激活函数,在最优情况下(每层输入都在0附近),反向传播的梯度每经过一层就乘以0.25。10层之后:
0.2510≈9.5×10−7梯度衰减了一百万倍!这就是梯度消失的数学根源。
📌 实验数据:当输入绝对值大于5时,Sigmoid输出已接近饱和区,梯度接近零。在10层以上的网络中,反向传播时梯度会以指数级衰减。
2.2 Tanh:零中心的改进,但饱和依旧
Tanh函数的定义为:
tanh(x)=ex+e−xex−e−x它与Sigmoid的关系为:tanh(x)=2σ(2x)−1。
Tanh的导数公式为:
tanh′(x)=1−tanh2(x)Tanh相比Sigmoid的改进:输出是零中心(zero-centered) 的,值域为 (−1,1)。这缓解了Sigmoid非零中心导致的”锯齿形”(zigzag)梯度更新问题。
但Tanh仍然存在梯度饱和问题:当输入绝对值较大时,tanh(x)→±1,导数 tanh′(x)→0。虽然Tanh在零点处的导数最大值为1(比Sigmoid的0.25大),但在饱和区的梯度同样趋近于零。
2.3 饱和激活函数的三大缺陷总结
| 缺陷 | Sigmoid | Tanh |
|---|---|---|
| 梯度饱和 | 最大导数仅0.25,极易梯度消失 | 仍存在饱和区,梯度趋近于零 |
| 非零中心 | 输出恒为正,导致zigzag更新 | ✅ 已解决,输出零中心 |
| 计算开销 | 需要exp运算,较慢 | 需要exp运算,较慢 |
三、ReLU及其变体:非饱和时代的开启
3.1 ReLU:简单粗暴的解决方案
ReLU(Rectified Linear Unit)的定义极为简单:
ReLU(x)=max(0,x)其导数为:
ReLU′(x)={1,0,x>0x≤0ReLU的革命性优势:
-
正区间无梯度饱和:当 x>0 时,导数为1,梯度可以完整地向前传播。这意味着在正区间,梯度不会衰减!
-
计算简单:不需要指数运算,只是简单的比较和取零。
-
稀疏激活:负值被置零,产生稀疏表示,有助于特征选择。
3.2 死亡ReLU(Dying ReLU):ReLU的「阿喀琉斯之踵」
然而,ReLU并非完美。当神经元的输入持续为负时,该神经元的输出恒为0,梯度也为0,权重再也无法更新——这个神经元就”死”了。
数学上,若对于某神经元,在训练过程中 w⊤x+b<0 始终成立,则:
∂w∂L=∂ReLU∂L⋅ReLU′(w⊤x+b)=0权重永远无法更新。
死亡ReLU的严重后果:在深度超过20层的网络中,未经特殊处理的ReLU可能导致30%-50%的神经元死亡,显著降低模型的有效容量。
3.3 ReLU变体:给负区间留一条「活路」
LeakyReLU
LeakyReLU在负区间引入一个小的斜率 α(通常取0.01):
LeakyReLU(x)={x,αx,x>0x≤0导数为:
LeakyReLU′(x)={1,α,x>0x≤0负区间梯度不再是0,神经元不会”死亡”。实验表明,α=0.01 时神经元死亡率可降低至5%以下。
PReLU(Parametric ReLU)
PReLU将负区间的斜率 α 变为可学习的参数:
f(x)=max(x,αx)其中 α 通过反向传播与权重一起更新。在ImageNet分类任务中,PReLU较ReLU可提升约1.2%的Top-1准确率。
ELU(Exponential Linear Unit)
ELU在负区间使用指数函数:
ELU(x)={x,α(ex−1),x>0x≤0ELU具有ReLU的优势,且输出均值接近零,同时对噪声有一定鲁棒性。但需要计算exp,计算量稍大。
GELU(Gaussian Error Linear Unit)
GELU是Transformer等现代架构的首选激活函数。其定义为:
GELU(x)=x⋅Φ(x)其中 Φ(x) 是标准正态分布的累积分布函数。
实际计算中常用近似公式:
GELU(x)≈0.5x(1+tanh(π2(x+0.044715x3)))GELU的核心思想是:根据输入的大小”软性”地决定激活程度——输入值大时接近完全激活,输入值小时部分激活,负值大时接近零但不完全为零。
GELU的平滑性和非零曲率提供了更丰富的梯度信息,使深度网络的训练更加稳定。
Swish
Swish由Google Brain团队通过自动搜索发现,定义为:
Swish(x)=x⋅σ(βx)=1+e−βxx其中 β 可以是常数(通常为1)或可训练参数。
Swish被称为**“自门控”(self-gated)激活函数**:输入 x 乘以其自身的Sigmoid函数 σ(x),Sigmoid充当一个”门”,控制有多少输入能够通过。
当 x 很大时,σ(x)≈1,Swish ≈x(近似线性); 当 x 很小时,σ(x)≈0,Swish ≈0(但梯度非零)。
Swish在负区间保持非零梯度,同时保留正区间的线性特性,避免了死亡ReLU问题。
3.4 激活函数对比总结
| 激活函数 | 梯度饱和 | 零中心 | 计算开销 | 死亡神经元 | 适用场景 |
|---|---|---|---|---|---|
| Sigmoid | ✅ 严重 | ❌ | 高 | - | 二分类输出层 |
| Tanh | ✅ 存在 | ✅ | 高 | - | 传统RNN |
| ReLU | ❌ 正区间无 | ❌ | 低 | ✅ 有 | CNN通用 |
| LeakyReLU | ❌ | ❌ | 低 | ⚠️ 极少 | 防止死亡ReLU |
| PReLU | ❌ | ❌ | 低 | ⚠️ 极少 | 可学习负斜率 |
| ELU | ❌ | ✅ | 中 | ❌ | 需零中心输出 |
| GELU | ❌ | ❌ | 中 | ❌ | Transformer |
| Swish | ❌ | ❌ | 中 | ❌ | 深层网络 |
四、权重初始化:让网络赢在「起跑线」
选择合适的激活函数只是解决梯度问题的一半。即使使用了ReLU,如果权重初始化不当,梯度仍然可能爆炸或消失。
4.1 为什么初始化如此重要?
考虑一个全连接层:z=∑i=1nwixi。
如果权重 wi 初始值太大,z 会很大,可能将激活函数推入饱和区(对Sigmoid/Tanh而言)。
如果权重 wi 初始值太小,z 会很小,梯度在反向传播时会逐层衰减。
理想情况是:每一层输出的方差保持稳定,既不放大也不衰减。
4.2 Xavier初始化(Glorot初始化)
Xavier初始化由Glorot & Bengio在2010年提出,主要适用于 Sigmoid和Tanh 等饱和激活函数。
核心假设
- 权重 wi 独立同分布,均值为0,方差为 Var(w)
- 输入 xi 独立同分布,均值为0,方差为 Var(x)
- 激活函数在0附近近似线性(即 f(z)≈z)
前向传播的方差约束
对于线性层 z=∑i=1ninwixi,根据方差的性质(独立变量和的方差等于方差之和):
Var(z)=i=1∑ninVar(wixi)=nin⋅Var(w)⋅Var(x)为了保持方差一致(Var(z)=Var(x)),需要:
nin⋅Var(w)=1⟹Var(w)=nin1反向传播的方差约束
反向传播时,梯度 ∂xi∂L 与权重的转置相关:
∂xi∂L=j=1∑noutwij⋅∂zj∂L同理,为保持梯度方差一致,需要:
nout⋅Var(w)=1⟹Var(w)=nout1最终的方差选择
前向和反向传播对方差的要求不同(1/nin vs 1/nout),Xavier取两者的调和平均:
Var(w)=nin+nout2实现方式
正态分布:w∼N(0,nin+nout2)
均匀分布:若 w∼U(−a,a),则 Var(w)=3a2。令其等于 nin+nout2,得:
a=nin+nout6即 w∼U(−nin+nout6,nin+nout6)
4.3 Kaiming初始化(He初始化)
Xavier初始化在ReLU上表现不佳,因为ReLU会将大约一半的神经元输出置为零,相当于砍掉了一半的信号。
何恺明在2015年的论文《Delving Deep into Rectifiers》中提出了专门针对ReLU的Kaiming初始化。
核心洞察
ReLU的负值全部被截断为零,导致输出的方差大约只有输入方差的一半。为了补偿这个损失,权重的方差需要翻倍。
前向传播的推导
设第 l 层的输入为 x(已经过ReLU激活),输出为 y=∑i=1nwixi(线性变换后,尚未激活)。
由于 x 是ReLU的输出,x≥0 且均值为0(假设权重均值为0,输入在0附近对称分布)。
关键步骤:ReLU将输入方差减半
对于零均值的对称分布 u,经过ReLU后:
E[x2]=E[(ReLU(u))2]=21E[u2]即 Var(x)=21Var(u)。
因此:
Var(y)=n⋅Var(w)⋅Var(x)=n⋅Var(w)⋅21Var(u)为了保持方差一致(Var(y)=Var(u)):
n⋅Var(w)⋅21=1⟹Var(w)=n2最终结果
Kaiming初始化的权重方差为:
Var(w)=nin2正态分布:w∼N(0,nin2)
均匀分布:w∼U(−nin6,nin6)
💡 关键区别:Xavier用的是 nin+nout2,Kaiming用的是 nin2。对于ReLU,Kaiming初始化保证每层方差守恒。
4.4 Python实现
1import numpy as np2
3def xavier_uniform(input_dim, output_dim):4 """Xavier均匀初始化,适用于Sigmoid/Tanh"""5 limit = np.sqrt(6 / (input_dim + output_dim))6 return np.random.uniform(-limit, limit, (output_dim, input_dim))7
8def xavier_normal(input_dim, output_dim):9 """Xavier正态初始化,适用于Sigmoid/Tanh"""10 std = np.sqrt(2 / (input_dim + output_dim))11 return np.random.normal(0, std, (output_dim, input_dim))12
13def kaiming_uniform(input_dim, output_dim):14 """Kaiming均匀初始化,适用于ReLU"""15 limit = np.sqrt(6 / input_dim)16 return np.random.uniform(-limit, limit, (output_dim, input_dim))17
18def kaiming_normal(input_dim, output_dim):19 """Kaiming正态初始化,适用于ReLU"""20 std = np.sqrt(2 / input_dim)21 return np.random.normal(0, std, (output_dim, input_dim))22
23# 示例:创建一个3层MLP的权重24d, h1, h2, q = 784, 256, 128, 1025
26# 使用Kaiming初始化(ReLU网络)27W1 = kaiming_normal(d, h1) # 方差 = 2/784 ≈ 0.0025528W2 = kaiming_normal(h1, h2) # 方差 = 2/256 ≈ 0.0078129W3 = kaiming_normal(h2, q) # 方差 = 2/128 ≈ 0.015634.5 初始化方法选择指南
| 激活函数 | 推荐初始化 | 方差公式 |
|---|---|---|
| Sigmoid | Xavier | 2/(nin+nout) |
| Tanh | Xavier | 2/(nin+nout) |
| ReLU | Kaiming | 2/nin |
| LeakyReLU | Kaiming(Leaky版) | 2/(1+α2)nin |
| GELU | 近似Kaiming | 2/nin |
| Swish | 近似Kaiming | 2/nin |
五、总结:激活函数与初始化的「协同进化」
回顾整个发展历程,我们可以看到一条清晰的脉络:
第一代(Sigmoid) :提出了可微的非线性激活,但梯度饱和严重,最大导数仅0.25,深层网络几乎无法训练。
第二代(Tanh) :解决了零中心问题,但饱和问题依然存在。
第三代(ReLU) :正区间导数为1,彻底解决了正区间的梯度消失问题,使训练深层网络成为可能。但引入了死亡ReLU的新问题。
第四代(LeakyReLU/PReLU/ELU/GELU/Swish) :在保留ReLU优势的同时,通过给负区间赋予非零梯度来解决死亡ReLU问题。
而权重初始化与激活函数相辅相成:
- Xavier初始化为Sigmoid/Tanh提供了方差守恒的保障
- Kaiming初始化为ReLU家族补偿了”砍掉一半信号”的损失
一个经验法则:
使用ReLU及其变体 → 用Kaiming初始化 使用Sigmoid或Tanh → 用Xavier初始化
理解这些原理,你就掌握了深度学习训练稳定性的两个关键杠杆。下一篇文章,我们将深入探讨卷积神经网络(CNN) 的数学原理与反向传播。
延伸阅读:
Some information may be outdated