这篇博文通过解释 Dropout 和 Batch Normalization 的核心原理、实现细节和主要作用,旨在帮助读者理解这两种在深度学习训练中常用的正则化与优化技术。
Dropout
Dropout 是神经网络训练过程中的一种常用技术,其核心思想是,在每次训练迭代的时候按照一定的给定概率 $p$," 丢弃 " 全连接层中的部分神经元。这意味着,在每次前向传播的过程中,模型使用的网络是全连接网络的一个子集。从另一个角度上看,这就像在训练不同神经元排列组合的无数模型,再从中进行选取。这正是模型集成 (model ensemble) 的方法。
这从本质上讲,是在网络训练过程中,添加噪声以维持模型对于微小噪声的稳定性 1。
实现细节
在实际计算中,有两个关键细节需要注意:
训练时的缩放处理 - Inverted Dropout
- 当按照概率 $p$ 舍去一部分节点时(即给这些节点赋值 0),为了维持该层输出的总期望在训练和测试时保持一致,要对未被丢弃的节点进行放缩
- 具体操作:将原输出值除以 $(1-p)$
- 举例:当 $p=0.5$ 时,随机将一半节点赋值为 0,同时对另一半节点的数值翻倍,以保持期望不变 1
测试时的处理
- 测试时不使用 dropout,直接使用完整网络
- 现代深度学习框架会自动处理这个切换,无需手动干预
- 原理:训练时的噪声扰动已经增强了模型的鲁棒性,测试时使用完整模型可获得最佳性能
Batch Normalization
名词辨析
在深入了解 Batch Normalization 之前,我们先厘清三个容易混淆的概念:
- 正则化 (Regularization):这是一个目标。其目的是防止模型过拟合,提高其在未见过数据上的泛化能力。通常的手段是在训练过程中加入微小噪声,实现手段包括 L1/L2 惩罚项、Dropout,以及我们后面会看到的,Batch Normalization 带来的 " 副作用 “。
- 归一化 (Normalization):这是一个宽泛的数据预处理过程,指将数据映射到特定范围。最常见的 " 归一化 " 特指 Min-Max Scaling,将数据缩放到 [0, 1] 或 [-1, 1] 区间。
- 标准化 (Standardization):这是归一化的一种特定方法,即 Z-score Normalization。它将数据处理成均值为 0,标准差为 1 的分布。Batch Normalization 和 Layer Normalization 本质上做的就是标准化,只是应用的维度和数据范围不同。
批量归一化
这个方法的主要目的,是把大的深的网络 train 起来,在比较少的迭代中收敛 2。正则化是偶然的收获。
feature normalization - 可以改变 error surface 的形状,把崎岖变得平坦,方便优化搜索。这与自适应学习率、选用不同优化器 - 改变损失函数和优化方法,是两个优化方向 3。
z 值归一化 - z score normalization 其中一种。计算同一维度分量的均值和标准差,也就是计算对应同一 feature 的不同样本表现的均值和标准差,利用它们对每个特征的数值进行归一化。我们得到的最终结果,在同一维度上变量的数值,符合均值 0 方差 1。
每次通过一层网络 - 线性回归之后,变量的分布和范围都可能发生变化,所以都要进行归一化。其放置的具体位置,目前的主流实现和推荐都是放在线性变换之后,激活函数之前。
主要原因是,BN 的目的之一是解决 " 内部协变量偏移 “(Internal Covariate Shift),即网络深层节点输入分布不稳定的问题。将 BN 放在激活函数(如 ReLU 或 Sigmoid)之前,可以直接控制送入激活函数的数据分布,使其保持在梯度较明显的区域(例如,对于 Sigmoid 函数,是 0 附近导数大),从而避免梯度消失,加速训练。
特征归一化 - 指的是,对全体训练集数据进行归一化。而批量归一化,是对整个批量里面的数据,计算特定维度对应的均值和标准差,然后对这个批量的数据进行归一化。所以,要批量数量较大才可以,最好批量具有足够代表性,这样进行批量归一化就近似于进行全体数据的特征归一化。
批量归一化之后,要接一个线性回归层仿射变换,引入两个需要学习的参数 $\beta$ (偏移) 和 $\gamma$ (缩放),目的是改变批量归一化强行改变的分布。如果是均值 0 方差 1 的分布,很可能会对后续造成不良影响,所以需要使用线性层调整一下分布。在使用主流框架的时候,无需关心,都已经实现并封装。
数学表达式: $y = \gamma \hat{x} + \beta$,其中 $\hat{x}$ 是归一化后的值。
测试时候,对训练过程中批量归一化得到的均值和标准差进行移动平均:$\bar{\mu} = (1-\alpha)\bar{\mu} + \alpha\mu^{(t)}$,其中 $\alpha$ 是动量参数(通常设为 0.1),$\mu^{(t)}$ 是当前批次的均值。这样得到的移动平均值作为测试时进行归一化的参数。
最后,实验可以证明,batch norm 得到平坦的 error surface ,可以使用更大的 lr 进而快速的收敛。
最后用来自 LLM 的神奇比喻收尾,如果说 Dropout 像是在训练时让每个神经元 " 轮流休假 " 以增强团队合作能力,那么 Batch Normalization 就像是在每一层网络前都设置了一个 " 纪律委员 “,确保传递给下一层的数据 " 行为规范 “(分布稳定),让整个学习过程更加高效有序。
二者关于引入噪声的区别
二者在提高模型泛化能力的角度来看,都是通过引入噪声来实现的。
Dropout 的噪声是结构性的,通过随机“关闭”神经元(可以看作是乘上0或1的随机掩码),直接改变了网络的结构,是一种乘性噪声。
这种做法,强制模型在训练时不依赖于特定的神经元,不得不学会和利用不同的、冗余的神经元组合做出决策,从而增强了模型的鲁棒性。
Batch Normalization 的噪声是数据驱动的。它来自于使用当前小批量(mini-batch)的统计数据(均值和方差)来标准化数据,而不是使用整个训练集的精确统计数据。因为每个批次的数据都有随机性,所以计算出的均值和方差会轻微波动,这种波动就为训练过程带来了噪声。
即使是相同的样本,由于在不同批次中被送入训练,其经过BN层之后的结果也会不同,这种噪声波动,正是由于不同批次引入。
在这里,我们关注的是数据的“行为”,至于他是什么分布,是不是在BN之后符合某种漂亮的分布,这不重要。很大程度上,这是“工程化思维”,经验主义的胜利。