文章目录
-
- [📚 学习路线图](#📚 学习路线图)
- 本文内容一览(快速理解)
- [一、激活函数(Activation Functions):引入非线性](#一、激活函数(Activation Functions):引入非线性)
-
- [1.1 Sigmoid激活函数(Sigmoid Activation Function):历史经典但有问题](#1.1 Sigmoid激活函数(Sigmoid Activation Function):历史经典但有问题)
- [1.2 tanh激活函数(tanh Activation Function):零中心但仍有问题](#1.2 tanh激活函数(tanh Activation Function):零中心但仍有问题)
- [1.3 ReLU激活函数(ReLU Activation Function):现代标准](#1.3 ReLU激活函数(ReLU Activation Function):现代标准)
- [1.4 Leaky ReLU和PReLU(Leaky ReLU and PReLU):解决死亡ReLU](#1.4 Leaky ReLU和PReLU(Leaky ReLU and PReLU):解决死亡ReLU)
- [1.5 ELU和Maxout(ELU and Maxout):其他选择](#1.5 ELU和Maxout(ELU and Maxout):其他选择)
- [二、数据预处理(Data Preprocessing):归一化数据](#二、数据预处理(Data Preprocessing):归一化数据)
-
- [2.1 数据归一化(Data Normalization):使优化更容易](#2.1 数据归一化(Data Normalization):使优化更容易)
- [2.2 图像数据预处理(Image Data Preprocessing):常见方法](#2.2 图像数据预处理(Image Data Preprocessing):常见方法)
- [三、权重初始化(Weight Initialization):好的开始](#三、权重初始化(Weight Initialization):好的开始)
-
- [3.1 权重初始化的问题(Problems with Weight Initialization):太小或太大都不行](#3.1 权重初始化的问题(Problems with Weight Initialization):太小或太大都不行)
- [3.2 Xavier初始化(Xavier Initialization):适用于tanh](#3.2 Xavier初始化(Xavier Initialization):适用于tanh)
- [3.3 He初始化(He Initialization / Kaiming Initialization):适用于ReLU](#3.3 He初始化(He Initialization / Kaiming Initialization):适用于ReLU)
- [四、批量归一化(Batch Normalization):稳定训练](#四、批量归一化(Batch Normalization):稳定训练)
-
- [4.1 批量归一化的原理(Batch Normalization Principle):归一化激活值](#4.1 批量归一化的原理(Batch Normalization Principle):归一化激活值)
- [4.2 批量归一化的优势(Benefits of Batch Normalization):稳定训练](#4.2 批量归一化的优势(Benefits of Batch Normalization):稳定训练)
- [4.3 批量归一化的注意事项(Batch Normalization Considerations):训练vs测试](#4.3 批量归一化的注意事项(Batch Normalization Considerations):训练vs测试)
- [📚 延伸阅读](#📚 延伸阅读)
📌 适合对象 :计算机视觉初学者、深度学习入门者
⏱️ 预计阅读时间 :50-60分钟
🎯 学习目标:理解激活函数的选择、数据预处理方法、权重初始化策略和批量归一化的作用,掌握训练神经网络的基础设置
📚 学习路线图
激活函数选择
ReLU/Leaky ReLU 数据预处理
归一化 权重初始化
Xavier/He 批量归一化
Batch Normalization 模型训练
稳定收敛
本文内容一览(快速理解)
- 激活函数(Activation Functions):Sigmoid、tanh、ReLU、Leaky ReLU、Maxout、ELU的特点和选择
- 数据预处理(Data Preprocessing):归一化、PCA、白化的作用和方法
- 权重初始化(Weight Initialization):Xavier初始化和Kaiming初始化的原理
- 批量归一化(Batch Normalization):如何稳定训练深层网络
一、激活函数(Activation Functions):引入非线性
这一章要建立的基础:理解不同激活函数的特点,选择适合的激活函数
核心问题:为什么需要激活函数?如何选择激活函数?
!NOTE
📝 关键点总结:激活函数引入非线性,使神经网络能够学习复杂模式。ReLU是最常用的激活函数,因为它计算简单、不饱和、收敛快。Sigmoid和tanh在深层网络中容易导致梯度消失。
1.1 Sigmoid激活函数(Sigmoid Activation Function):历史经典但有问题
概念的本质:
Sigmoid函数将输入压缩到 [ 0 , 1 ] [0,1] [0,1]范围,公式为: f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+e−x1。历史上很流行,因为它可以解释为神经元的"饱和放电率"。但在深层网络中有三个问题:饱和神经元会"杀死"梯度、输出不是零中心的、计算 e x e^x ex较昂贵。
图解说明:
Sigmoid函数
f(x) = 1/(1+e^(-x)) 输出范围[0,1] 问题1
梯度消失 问题2
非零中心 问题3
计算昂贵
💡 说明:
- 饱和问题:当输入很大或很小时,梯度接近0,导致梯度消失
- 非零中心:输出总是正数,导致梯度更新方向受限
- 计算成本:需要计算指数函数,比简单操作慢
类比理解:
想象你在爬坡。Sigmoid就像:
- 输入很大:你已经爬到山顶,再往上走坡度很小(梯度小)
- 输入很小:你在谷底,往下走坡度也很小(梯度小)
- 非零中心:你只能往一个方向走,不能灵活调整(梯度方向受限)
实际例子:
Sigmoid的问题:
输入 x = -10:
- Sigmoid输出 ≈ 0.000045
- 梯度 ≈ 0(几乎为0)
- 结果:梯度消失,无法学习
输入 x = 0:
- Sigmoid输出 = 0.5
- 梯度 = 0.25(最大)
- 结果:可以学习
输入 x = 10:
- Sigmoid输出 ≈ 0.999955
- 梯度 ≈ 0(几乎为0)
- 结果:梯度消失,无法学习
深层网络中的问题:
- 如果多个Sigmoid层叠加,梯度会指数级衰减
- 前面的层几乎无法更新(梯度太小)
- 导致训练失败
1.2 tanh激活函数(tanh Activation Function):零中心但仍有问题
概念的本质:
tanh函数将输入压缩到 [ − 1 , 1 ] [-1,1] [−1,1]范围,公式为: tanh ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=ex+e−xex−e−x。相比Sigmoid,tanh是零中心的(输出有正有负),但仍然会在饱和时"杀死"梯度。
图解说明:
tanh函数
输出范围[-1,1] 优势
零中心 问题
饱和时梯度消失
💡 说明:
- 零中心:输出有正有负,梯度更新方向更灵活
- 饱和问题:当输入很大或很小时,仍然会梯度消失
- 适用场景:比Sigmoid好,但在深层网络中仍有问题
类比理解:
想象你在爬坡。tanh就像:
- 零中心:你可以往上走,也可以往下走(梯度方向灵活)
- 饱和问题:在极端位置(山顶或谷底),坡度仍然很小(梯度小)
实际例子:
tanh的特点:
输入 x = -10:
- tanh输出 ≈ -1
- 梯度 ≈ 0(几乎为0)
输入 x = 0:
- tanh输出 = 0
- 梯度 = 1(最大)
输入 x = 10:
- tanh输出 ≈ 1
- 梯度 ≈ 0(几乎为0)
与Sigmoid对比:
- 零中心:梯度更新方向更灵活
- 但仍有饱和问题:在深层网络中梯度仍会消失
1.3 ReLU激活函数(ReLU Activation Function):现代标准
概念的本质:
ReLU(Rectified Linear Unit,修正线性单元)计算 f ( x ) = max ( 0 , x ) f(x) = \max(0, x) f(x)=max(0,x)。ReLU不会饱和(在正区域),计算非常高效,在实践中收敛速度比Sigmoid/tanh快约6倍。但它不是零中心的,且在 x < 0 x < 0 x<0时梯度为0(可能导致"死亡ReLU")。
图解说明:
ReLU函数
f(x) = max(0,x) 优势1
不饱和 优势2
计算高效 优势3
收敛快 问题
死亡ReLU
💡 说明:
- 不饱和:在正区域,梯度恒为1,不会消失
- 计算高效:只需要比较和选择,比指数函数快得多
- 收敛快:在实践中比Sigmoid/tanh快约6倍
- 死亡ReLU:如果输入总是负数,神经元永远不会激活
类比理解:
想象你在爬坡。ReLU就像:
- 正区域:坡度恒为1,一直可以往上走(梯度不消失)
- 负区域:坡度为0,无法往下走(梯度为0)
- 问题:如果一直在负区域,就"死"了(死亡ReLU)
实际例子:
ReLU的特点:
输入 x = -10:
- ReLU输出 = 0
- 梯度 = 0
- 结果:神经元"死亡",无法学习
输入 x = 0:
- ReLU输出 = 0
- 梯度 = 0(在0处不可导,通常设为0或1)
输入 x = 10:
- ReLU输出 = 10
- 梯度 = 1
- 结果:梯度不消失,可以学习
优势:
- 计算简单:只需要max(0, x)
- 不饱和:在正区域梯度恒为1
- 收敛快:比Sigmoid/tanh快约6倍
问题:
- 死亡ReLU:如果学习率太大,可能导致很多神经元"死亡"
- 非零中心:输出总是非负
1.4 Leaky ReLU和PReLU(Leaky ReLU and PReLU):解决死亡ReLU
概念的本质:
Leaky ReLU在负区域给一个小的斜率(如0.01),公式为: f ( x ) = max ( 0.01 x , x ) f(x) = \max(0.01x, x) f(x)=max(0.01x,x)。这样即使输入为负,也有小的梯度,不会"死亡"。PReLU(Parametric ReLU)将负区域的斜率作为可学习参数,让网络自己学习最优的斜率。
图解说明:
Leaky ReLU
f(x) = max(0.01x, x) 优势
不会死亡 PReLU
可学习斜率 优势
自适应
💡 说明:
- Leaky ReLU:负区域有小的斜率(如0.01),不会完全"死亡"
- PReLU:负区域的斜率是可学习参数,网络自动学习最优值
- 优势:解决了ReLU的"死亡"问题,同时保持计算高效
类比理解:
想象你在爬坡。Leaky ReLU就像:
- 正区域:坡度为1,可以往上走
- 负区域:坡度为0.01(很小但非零),也可以往下走(虽然慢)
- 结果:不会"死亡",总是可以学习
实际例子:
Leaky ReLU的例子:
输入 x = -10:
- Leaky ReLU输出 = 0.01 × (-10) = -0.1
- 梯度 = 0.01(非零!)
- 结果:可以学习,不会"死亡"
输入 x = 10:
- Leaky ReLU输出 = 10
- 梯度 = 1
- 结果:正常学习
PReLU:
- 负区域斜率α是可学习参数
- 网络自动学习最优的α值
- 通常α在0.01到0.3之间
1.5 ELU和Maxout(ELU and Maxout):其他选择
概念的本质:
ELU(Exponential Linear Unit)具有ReLU的所有优点,同时输出更接近零均值,负区域有饱和机制,对噪声更鲁棒,但需要计算指数函数。Maxout是更一般的形式,可以学习任意分段线性函数,但参数数量翻倍。
图解说明:
ELU
指数线性单元 优势
零均值/鲁棒 Maxout
分段线性 优势
灵活 问题
参数翻倍
💡 说明:
- ELU:结合ReLU的优点和零均值输出,负区域有饱和机制
- Maxout:可以学习任意分段线性函数,但参数数量翻倍
- 选择:在实践中,ReLU和Leaky ReLU最常用
实际例子:
激活函数选择建议:
推荐:
- ReLU:最常用,计算简单,收敛快
- Leaky ReLU:如果担心死亡ReLU,使用这个
- PReLU:让网络自己学习最优斜率
可以尝试:
- ELU:如果需要零均值输出
- Maxout:如果需要最大灵活性
不推荐:
- Sigmoid:在深层网络中梯度消失
- tanh:虽然比Sigmoid好,但仍有问题
实践建议:
- 默认使用ReLU
- 注意学习率,避免死亡ReLU
- 可以尝试Leaky ReLU或PReLU
二、数据预处理(Data Preprocessing):归一化数据
这一章要建立的基础:理解数据预处理的作用,掌握图像数据的预处理方法
核心问题:为什么需要数据预处理?如何预处理图像数据?
!NOTE
📝 关键点总结:数据预处理通过归一化使数据分布更均匀,使优化更容易。对于图像,通常减去均值(每通道或整图),有时除以标准差。PCA和白化较少使用。
2.1 数据归一化(Data Normalization):使优化更容易
概念的本质:
数据归一化(Normalization)将数据转换为零均值、单位方差(或接近)。归一化后,损失函数对权重矩阵的小变化不那么敏感,优化更容易。对于图像数据,通常减去均值图像或每通道均值。
图解说明:
原始数据
分布不均匀 减去均值
零中心化 除以标准差
单位方差 归一化数据
易于优化
💡 说明:
- 零中心化:减去均值,使数据分布以0为中心
- 单位方差:除以标准差,使数据分布更均匀
- 效果:损失函数对权重变化不敏感,优化更容易
类比理解:
想象你在调整天平。数据归一化就像:
- 原始数据:天平两边重量差异很大,很难平衡
- 归一化:将两边重量调整到相近范围,容易平衡
- 优化:就像调整天平,归一化后更容易找到平衡点
实际例子:
数据归一化的例子:
原始数据(像素值):
- 范围:0-255
- 均值:128
- 标准差:50
归一化后:
- 减去均值:范围变为-128到127
- 除以标准差:范围变为约-2.5到2.5
- 均值:0
- 标准差:1
效果:
- 损失函数对权重变化不敏感
- 梯度更稳定
- 优化更容易收敛
2.2 图像数据预处理(Image Data Preprocessing):常见方法
概念的本质:
对于图像数据,常见的预处理方法包括:减去均值图像(如AlexNet)、减去每通道均值(如VGGNet)、除以每通道标准差(如ResNet)。PCA和白化较少使用,因为计算成本高且效果不明显。
图解说明:
图像数据
32×32×3 方法1
减去均值图像 方法2
减去每通道均值 方法3
除以每通道标准差
💡 说明:
- 减去均值图像:计算所有训练图像的平均图像,然后减去
- 减去每通道均值:分别计算R、G、B三个通道的均值,然后减去
- 除以标准差:计算每通道的标准差,然后除以
- 实践:通常只做零中心化(减去均值),不做单位方差
类比理解:
想象你在处理彩色照片。图像预处理就像:
- 减去均值图像:将所有照片调整到相同的"平均亮度"
- 减去每通道均值:分别调整红、绿、蓝三个通道的"平均亮度"
- 效果:让所有图像在相似的"亮度范围"内,更容易学习
实际例子:
图像预处理的例子:
CIFAR-10数据集(32×32×3图像):
方法1:减去均值图像(AlexNet风格)
- 计算所有训练图像的平均图像:[32, 32, 3]
- 每个图像减去这个平均图像
- 结果:图像以0为中心
方法2:减去每通道均值(VGGNet风格)
- 计算R通道均值:例如128.5
- 计算G通道均值:例如127.8
- 计算B通道均值:例如128.2
- 每个图像减去对应的通道均值
- 结果:每个通道以0为中心
方法3:除以每通道标准差(ResNet风格)
- 在方法2的基础上,除以每通道标准差
- 例如:R通道标准差=50.2
- 结果:每个通道接近单位方差
实践建议:
- 默认:减去每通道均值
- 可选:除以每通道标准差
- 不推荐:PCA和白化(计算成本高,效果不明显)
三、权重初始化(Weight Initialization):好的开始
这一章要建立的基础:理解权重初始化的重要性,掌握Xavier和He初始化方法
核心问题:为什么权重初始化很重要?如何正确初始化权重?
!NOTE
📝 关键点总结:权重初始化对训练至关重要。太小的权重导致激活值趋向0,梯度消失;太大的权重导致激活值饱和,梯度也为0。Xavier初始化适用于tanh,He初始化适用于ReLU。
3.1 权重初始化的问题(Problems with Weight Initialization):太小或太大都不行
概念的本质:
权重初始化对训练至关重要。如果权重太小(如标准差0.01),深层网络的激活值会趋向0,梯度也会趋向0,无法学习。如果权重太大(如标准差0.05),激活值会饱和,梯度也会为0,同样无法学习。
图解说明:
权重太小
std=0.01 激活值→0
梯度→0 权重太大
std=0.05 激活值饱和
梯度→0 权重合适
Xavier/He 激活值正常
梯度正常
💡 说明:
- 太小:激活值衰减到0,梯度消失
- 太大:激活值饱和,梯度也为0
- 合适:激活值保持在合理范围,梯度正常
类比理解:
想象你在调整音量。权重初始化就像:
- 太小:音量太小,听不到声音(激活值太小)
- 太大:音量太大,声音失真(激活值饱和)
- 合适:音量适中,声音清晰(激活值正常)
实际例子:
权重初始化的问题:
6层网络,隐藏层大小4096:
权重太小(std=0.01):
- 第1层激活值:正常
- 第2层激活值:变小
- 第3层激活值:更小
- ...
- 第6层激活值:接近0
- 梯度:接近0,无法学习
权重太大(std=0.05):
- 第1层激活值:饱和
- 第2层激活值:饱和
- ...
- 所有层激活值:饱和
- 梯度:接近0,无法学习
权重合适(Xavier/He):
- 所有层激活值:保持在合理范围
- 梯度:正常,可以学习
3.2 Xavier初始化(Xavier Initialization):适用于tanh
概念的本质:
Xavier初始化(也称为Glorot初始化)使用标准差 σ = 1 D i n \sigma = \frac{1}{\sqrt{D_{in}}} σ=Din 1,其中 D i n D_{in} Din是输入维度。Xavier初始化假设激活函数是零中心的(如tanh),可以保持激活值的方差在合理范围。对于卷积层, D i n = kernel_size 2 × input_channels D_{in} = \text{kernel\_size}^2 \times \text{input\_channels} Din=kernel_size2×input_channels。
图解说明:
Xavier初始化
std = 1/sqrt(Din) 适用于
tanh激活 保持激活值
在合理范围
💡 说明:
- 公式 : σ = 1 D i n \sigma = \frac{1}{\sqrt{D_{in}}} σ=Din 1
- 假设:激活函数是零中心的(如tanh)
- 效果:所有层的激活值保持在合理范围
- 卷积层 : D i n = kernel_size 2 × input_channels D_{in} = \text{kernel\_size}^2 \times \text{input\_channels} Din=kernel_size2×input_channels
类比理解:
想象你在调整音量。Xavier初始化就像:
- 输入维度大:需要较小的音量(较小的权重)
- 输入维度小:可以使用较大的音量(较大的权重)
- 结果:无论输入维度如何,输出音量都适中
实际例子:
Xavier初始化的例子:
全连接层:
- 输入维度:3072
- 输出维度:100
- 权重初始化:std = 1/sqrt(3072) ≈ 0.018
卷积层:
- 输入通道:3
- 滤波器大小:5×5
- Din = 5×5×3 = 75
- 权重初始化:std = 1/sqrt(75) ≈ 0.115
效果:
- 所有层的激活值保持在合理范围
- 梯度正常,可以学习
- 适用于tanh激活函数
3.3 He初始化(He Initialization / Kaiming Initialization):适用于ReLU
概念的本质:
He初始化(也称为Kaiming初始化)是Xavier初始化的修正版本,适用于ReLU激活函数。由于ReLU不是零中心的,Xavier初始化会导致激活值趋向0。He初始化使用标准差 σ = 2 D i n \sigma = \sqrt{\frac{2}{D_{in}}} σ=Din2 ,可以保持ReLU网络的激活值在合理范围。
图解说明:
He初始化
std = sqrt(2/Din) 适用于
ReLU激活 保持激活值
在合理范围
💡 说明:
- 公式 : σ = 2 D i n \sigma = \sqrt{\frac{2}{D_{in}}} σ=Din2
- 修正:考虑了ReLU的非零中心特性
- 效果:ReLU网络的激活值保持在合理范围
- 实践:ReLU网络应该使用He初始化
类比理解:
想象你在调整音量。He初始化就像:
- ReLU特性:只输出非负值(类似只放大不缩小)
- Xavier问题:基于零中心假设,不适用于ReLU
- He修正:考虑ReLU特性,调整初始化策略
- 结果:ReLU网络的激活值保持在合理范围
实际例子:
He初始化的例子:
全连接层(ReLU):
- 输入维度:3072
- 输出维度:100
- 权重初始化:std = sqrt(2/3072) ≈ 0.026
卷积层(ReLU):
- 输入通道:3
- 滤波器大小:5×5
- Din = 5×5×3 = 75
- 权重初始化:std = sqrt(2/75) ≈ 0.163
对比Xavier:
- Xavier(tanh):std = 1/sqrt(75) ≈ 0.115
- He(ReLU):std = sqrt(2/75) ≈ 0.163
- He的权重稍大,补偿ReLU的非零中心特性
效果:
- ReLU网络的激活值保持在合理范围
- 梯度正常,可以学习
- 适用于ReLU激活函数
四、批量归一化(Batch Normalization):稳定训练
这一章要建立的基础:理解批量归一化的作用和原理
核心问题:为什么需要批量归一化?批量归一化如何工作?
!NOTE
📝 关键点总结:批量归一化通过归一化每层的激活值,使深层网络更容易训练。它改善梯度流动、允许更高的学习率、使网络对初始化更鲁棒,并起到正则化作用。批量归一化在训练和测试时的行为不同,需要注意。
4.1 批量归一化的原理(Batch Normalization Principle):归一化激活值
概念的本质:
批量归一化(Batch Normalization)对每个批次的激活值进行归一化,使其具有零均值和单位方差。公式为: x ^ = x − μ σ 2 + ϵ \hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} x^=σ2+ϵ x−μ,其中 μ \mu μ和 σ 2 \sigma^2 σ2是批次均值和方差, ϵ \epsilon ϵ是小的常数(防止除零)。然后通过可学习的缩放和偏移参数 γ \gamma γ和 β \beta β进行变换: y = γ x ^ + β y = \gamma \hat{x} + \beta y=γx^+β。
图解说明:
批次激活值
N×D 计算均值μ
和方差σ² 归一化
(x-μ)/sqrt(σ²+ε) 缩放和偏移
γx̂ + β 归一化输出
零均值单位方差
💡 说明:
- 归一化:使激活值具有零均值和单位方差
- 可学习参数 : γ \gamma γ(缩放)和 β \beta β(偏移)是可学习的
- 位置:通常放在全连接层或卷积层之后,激活函数之前
- 批次统计:使用当前批次的均值和方差
类比理解:
想象你在调整音量。批量归一化就像:
- 原始音量:每首歌的音量不同,有的很大,有的很小
- 归一化:将所有歌曲调整到相同的"平均音量"
- 缩放和偏移:允许网络学习最优的"音量范围"
- 结果:所有歌曲在相似的"音量范围"内,更容易处理
实际例子:
批量归一化的例子:
输入:批次大小为32,特征维度100
- 形状:32×100
步骤1:计算批次统计
- 均值μ:形状100(每维的均值)
- 方差σ²:形状100(每维的方差)
步骤2:归一化
- x̂ = (x - μ) / sqrt(σ² + ε)
- 结果:零均值、单位方差
步骤3:缩放和偏移
- y = γx̂ + β
- γ和β是可学习参数(形状100)
- 允许网络学习最优的分布
位置:
- 全连接层:FC -> BN -> ReLU
- 卷积层:CONV -> BN -> ReLU
4.2 批量归一化的优势(Benefits of Batch Normalization):稳定训练
概念的本质:
批量归一化使深层网络更容易训练,因为它改善梯度流动、允许更高的学习率、使网络对初始化更鲁棒,并在训练时起到正则化作用。批量归一化在测试时使用运行平均值(而不是批次统计),可以融合到卷积操作中,零开销。
图解说明:
批量归一化 优势1
改善梯度流动 优势2
允许高学习率 优势3
对初始化鲁棒 优势4
正则化作用
💡 说明:
- 改善梯度流动:归一化使梯度更稳定,不会快速衰减或爆炸
- 高学习率:可以使用更高的学习率,加快收敛
- 初始化鲁棒:对权重初始化不那么敏感
- 正则化:在训练时起到正则化作用,可能减少过拟合
类比理解:
想象你在训练运动员。批量归一化就像:
- 改善梯度流动:训练过程更稳定,不会突然"崩溃"
- 高学习率:可以更快速地训练,不需要小心翼翼
- 初始化鲁棒:无论起点如何,都能稳定训练
- 正则化:训练时自动"约束",防止过度训练
实际例子:
批量归一化的优势:
没有批量归一化:
- 学习率:0.001(需要很小)
- 训练不稳定:容易梯度消失或爆炸
- 对初始化敏感:需要仔细初始化
- 收敛慢:需要很多轮训练
有批量归一化:
- 学习率:0.01(可以更大)
- 训练稳定:梯度流动正常
- 对初始化鲁棒:可以使用随机初始化
- 收敛快:训练轮数减少
测试时:
- 使用运行平均值(训练时累积的均值和方差)
- 可以融合到卷积操作中
- 零开销:不影响推理速度
4.3 批量归一化的注意事项(Batch Normalization Considerations):训练vs测试
概念的本质:
批量归一化在训练和测试时的行为不同。训练时使用当前批次的统计量,测试时使用运行平均值。这是一个常见的bug来源。批量归一化在训练时起到正则化作用,但在测试时没有(因为使用固定的统计量)。
图解说明:
批量归一化 训练时
使用批次统计 测试时
使用运行平均值 正则化作用 固定统计量
💡 说明:
- 训练时:使用当前批次的均值和方差,动态更新
- 测试时:使用训练时累积的运行平均值,固定不变
- 常见bug:忘记切换模式,导致测试时性能下降
- 正则化:只在训练时起作用,测试时没有
类比理解:
想象你在做实验。批量归一化就像:
- 训练时:每次实验都重新测量(使用当前批次统计)
- 测试时:使用之前实验的平均值(使用运行平均值)
- 问题:如果搞混了,结果会出错(常见bug)
实际例子:
批量归一化的注意事项:
训练时:
```python
model.train() # 设置为训练模式
# 使用当前批次的均值和方差
# 更新运行平均值
测试时:
python
model.eval() # 设置为评估模式
# 使用运行平均值(固定)
# 不更新统计量
常见bug:
- 忘记调用model.eval():测试时仍使用批次统计,性能下降
- 忘记调用model.train():训练时使用固定统计量,无法学习
解决方案:
-
训练前:model.train()
-
测试前:model.eval()
-
使用torch.no_grad():测试时不需要梯度
📝 本章总结
核心要点回顾:
-
激活函数:
- ReLU是最常用的激活函数(计算简单、不饱和、收敛快)
- Leaky ReLU和PReLU可以解决死亡ReLU问题
- Sigmoid和tanh在深层网络中容易导致梯度消失
-
数据预处理:
- 减去均值(每通道或整图)是最常用的方法
- 归一化使优化更容易
- PCA和白化较少使用
-
权重初始化:
- Xavier初始化适用于tanh
- He初始化适用于ReLU
- 正确的初始化对训练至关重要
-
批量归一化:
- 归一化激活值,使深层网络更容易训练
- 改善梯度流动、允许高学习率、对初始化鲁棒
- 注意训练和测试时的不同行为
知识地图:
flowchart TD A["训练神经网络"] --> B["激活函数
ReLU/Leaky ReLU"] A --> C["数据预处理
归一化"] A --> D["权重初始化
Xavier/He"] A --> E["批量归一化
稳定训练"] B --> F["稳定训练"] C --> F D --> F E --> F style A fill:#E8F4F8 style B fill:#90EE90 style C fill:#FFD700 style D fill:#87CEEB style E fill:#FFB6C1 style F fill:#DDA0DD -
关键决策点:
- 激活函数:默认使用ReLU,担心死亡ReLU时使用Leaky ReLU
- 数据预处理:图像数据减去每通道均值,可选除以标准差
- 权重初始化:ReLU网络使用He初始化,tanh网络使用Xavier初始化
- 批量归一化:深层网络建议使用,注意训练和测试模式切换
📚 延伸阅读
推荐资源
-
激活函数:
- ReLU论文:Krizhevsky et al., "ImageNet Classification with Deep Convolutional Neural Networks", 2012
- Leaky ReLU论文:Maas et al., "Rectifier Nonlinearities Improve Neural Network Acoustic Models", 2013
- ELU论文:Clevert et al., "Fast and Accurate Deep Network Learning by Exponential Linear Units", 2015
-
权重初始化:
- Xavier初始化:Glorot and Bengio, "Understanding the difficulty of training deep feedforward neural networks", 2010
- He初始化:He et al., "Delving Deep into Rectifiers", 2015
-
批量归一化:
- Batch Normalization论文:Ioffe and Szegedy, "Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift", 2015
-
实践项目:
- 比较不同激活函数的效果
- 比较不同权重初始化的效果
- 实现批量归一化并观察训练稳定性