\[ \begin{align}\begin{aligned}\newcommand{\ba}{\boldsymbol{a}} \newcommand{\bb}{\boldsymbol{b}} \newcommand{\be}{\boldsymbol{e}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bw}{\boldsymbol{w}} \newcommand{\bx}{\boldsymbol{x}} \newcommand{\by}{\boldsymbol{y}} \newcommand{\bz}{\boldsymbol{z}} \newcommand{\bd}{\boldsymbol{d}} \newcommand{\bv}{\boldsymbol{v}} \newcommand{\bs}{\boldsymbol{s}}\\\newcommand{\btheta}{\boldsymbol{\theta}} \newcommand{\bbeta}{\boldsymbol{\beta}} \newcommand{\bgamma}{\boldsymbol{\gamma}} \newcommand{\bsigma}{\boldsymbol{\sigma}} \newcommand{\md}{\mbox{d}} \newcommand{\bmu}{\boldsymbol{\mu}} \newcommand{\bone}{\boldsymbol{1}} \newcommand{\bzero}{\boldsymbol{0}} \newcommand{\bepsilon}{\boldsymbol{\epsilon}} \newcommand{\bphi}{\boldsymbol{\phi}} \newcommand{\bh}{\boldsymbol{h}} \newcommand{\bc}{\boldsymbol{c}} \newcommand{\br}{\boldsymbol{r}} \newcommand{\bQ}{\boldsymbol{Q}} \newcommand{\bK}{\boldsymbol{K}} \newcommand{\bV}{\boldsymbol{V}} \newcommand{\bSigma}{\boldsymbol{\Sigma}} \newcommand{\bg}{\boldsymbol{g}} \newcommand{\bxi}{\boldsymbol{\xi}} \newcommand{\bvarepsilon}{\boldsymbol{\varepsilon}} \newcommand{\bdelta}{\boldsymbol{\delta}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bJ}{\boldsymbol{J}} \newcommand{\bp}{\boldsymbol{p}} \newcommand{\bi}{\boldsymbol{i}} \newcommand{\bo}{\boldsymbol{o}} \newcommand{\bE}{\boldsymbol{E}} \newcommand{\bH}{\boldsymbol{H}} \newcommand{\bL}{\boldsymbol{L}} \newcommand{\bu}{\boldsymbol{u}} \newcommand{\bLambda}{\boldsymbol{\Lambda}} \newcommand{\trans}{^{\rm\scriptsize T}} \newcommand{\var}{\mathrm{var}}\\\newcommand{\bA}{\boldsymbol{A}} \newcommand{\bB}{\boldsymbol{B}} \newcommand{\bC}{\boldsymbol{C}} \newcommand{\bD}{\boldsymbol{D}} \newcommand{\bG}{\boldsymbol{G}} \newcommand{\bI}{\boldsymbol{I}} \newcommand{\bM}{\boldsymbol{M}} \newcommand{\bP}{\boldsymbol{P}} \newcommand{\bS}{\boldsymbol{S}} \newcommand{\bU}{\boldsymbol{U}} \newcommand{\bW}{\boldsymbol{W}} \newcommand{\bX}{\boldsymbol{X}} \newcommand{\bY}{\boldsymbol{Y}} \newcommand{\bZ}{\boldsymbol{Z}} \newcommand{\cotp}{\textcolor[RGB]{48,209,88}{TP}} \newcommand{\cotn}{\textcolor[RGB]{100,210,255}{TN}} \newcommand{\cofp}{\textcolor[RGB]{94,92,230}{FP}} \newcommand{\cofn}{\textcolor[RGB]{191,90,242}{FN}}\\\newcommand{\numcotp}{\textcolor[RGB]{48,209,88}{50}} \newcommand{\numcotn}{\textcolor[RGB]{100,210,255}{30}} \newcommand{\numcofp}{\textcolor[RGB]{94,92,230}{10}} \newcommand{\numcofn}{\textcolor[RGB]{191,90,242}{10}} \DeclareMathOperator*{\argmin}{arg\,min}\end{aligned}\end{align} \]

正则化#

学习目标与记号#

  1. 区分显式正则化、隐式正则化、噪声注入与集成学习,并说明四类方法之间可能存在的联系;

  2. 推导 \(\ell_1\)⁠、\(\ell_2\) 惩罚与普通梯度下降中权重衰减的关系,说明 AdamW 为什么采用解耦权重衰减;

  3. 解释优化过程和提前停止如何影响模型最终得到的解,并说明它们与 双下降现象 的联系;

  4. 说明 Dropout、输入噪声和标签平滑在训练阶段与推断阶段的区别;

  5. 解释 Bagging、Boosting 和 Stacking 的基本思想,分析模型差异程度、预测效果与计算成本之间的关系。

  本节沿用统一记号:普通小写字母表示标量,粗体小写字母表示向量,粗体大写字母表示矩阵或高阶张量;层编号写作上标 \([l]\)⁠,样本或时间编号写作下标;转置写作 \(\trans\)⁠。除非另有说明,批量样本按行存放。正文与练习中的程序都应同时检查数值结果和数组维度。本节练习的参考答案见 正则化与泛化控制答案⁠。

  正则化是一组改善模型泛化能力的方法,而不是某一个固定公式。模型在训练数据上表现很好、在新数据上表现较差时,可能记住了训练样本中的偶然波动,这种现象称为 过拟合 (overfitting)。正则化通过限制参数、改变优化过程、扰动训练样本或综合多个模型,使预测较少依赖这些偶然模式。正则化强度与训练方案应在 验证集 上选择;若训练失败主要源于 初始化 或优化过程,则不能仅靠增大正则化强度解决。

四类方法并非互不相交

  本节按照主要作用机制,把常用方法组织为显式正则化、隐式正则化、噪声注入和集成学习四部分。这是一种便于学习的分类,并不是互不相交的集合。例如,Dropout 直接向网络中加入随机掩码,因此本节主要在“噪声注入”部分介绍;它也会改变优化过程,并可从近似集成的角度理解。提前停止由使用者明确设定,但它没有在目标函数中加入惩罚项,因此通常把它的正则化作用称为隐式正则化。

表 5 四类正则化方法的主要思路#

类别

主要做法

典型方法

显式正则化

直接修改目标函数、参数约束或参数更新规则

\(\ell_1\)⁠、\(\ell_2\) 惩罚、权重衰减和 AdamW

隐式正则化

通过优化路径、初始化或训练时长影响最终得到的解

梯度下降的隐式偏好和提前停止

噪声注入

在训练阶段随机扰动输入、激活或参数,或按预定规则平滑观测标签

Dropout、输入噪声、数据增强和标签平滑

集成学习

综合多个存在差异的模型,减少单个模型预测的偶然波动

Bagging、Boosting 和 Stacking

显式正则化#

  显式正则化会直接改变需要最小化的目标函数、参数可行范围或参数更新规则。优点是作用位置明确、便于控制;需要注意的是,不同公式和不同优化器中的系数含义可能不同,不能只比较系数的数值大小。

参数惩罚:\(\ell_2\) 惩罚与 \(\ell_1\) 惩罚#

  设 \(\mathcal{J}_{\mathrm{data}}(\btheta)\) 是小批量上的平均数据损失。\(\ell_2\) 正则化后的目标可写为

(67)#\[\mathcal{J}(\btheta) =\mathcal{J}_{\mathrm{data}}(\btheta) +\frac{\lambda}{2}\sum_{l=1}^{L} \left\lVert\bW^{[l]}\right\rVert_F^2, \qquad \lambda\geq 0,\]

其中,\(\lVert\bW\rVert_F^2=\sum_{i,j}w_{ij}^2\)⁠。这里采用“平均数据损失加惩罚”的写法,因此惩罚项没有再除以样本量;若教材或软件采用总损失,\(\lambda\) 的数值尺度也会随之改变。通常只惩罚权重,不惩罚偏置和归一化层的尺度参数与平移参数。

  对应的权重梯度为

(68)#\[\frac{\partial\mathcal{J}}{\partial\bW^{[l]}} =\frac{\partial\mathcal{J}_{\mathrm{data}}}{\partial\bW^{[l]}} +\lambda\bW^{[l]}.\]

  对于不含动量和逐坐标自适应缩放的普通梯度下降,把式 (68) 代入参数更新式可得

(69)#\[\bW^{(t+1)} =(1-\alpha\lambda)\bW^{(t)} -\alpha\frac{\partial\mathcal{J}_{\mathrm{data}}} {\partial\bW^{(t)}}.\]

  因此,在当前系数写法下,把 \(\ell_2\) 惩罚的梯度加入普通梯度下降,等价于先把权重乘以 \(1-\alpha\lambda\)⁠,再按照数据损失的梯度更新。当 \(0<\alpha\lambda<1\) 时,这个乘法因子会缩小权重的绝对值,因此称为权重衰减(weight decay)。较大的 \(\lambda\) 倾向于得到较小的权重,但不保证每个权重都接近 0,也不保证模型一定不过拟合。

系数写法必须前后一致

  本节把数据损失定义为样本平均值,并将惩罚写成 \(\lambda\lVert\bW\rVert_F^2/2\)⁠。有些资料把惩罚写成 \(\lambda\lVert\bW\rVert_F^2/(2n)\) 的样子,此时梯度中的系数为 \(\lambda/n\)⁠。两种写法都可以使用,但同一个数值的 \(\lambda\) 所表示的正则化强度不同,推导和程序必须采用同一种写法。

  \(\ell_1\) 惩罚把权重元素的绝对值加入目标函数:

\[\lambda_1\sum_{l=1}^{L}\left\lVert\bW^{[l]}\right\rVert_1, \qquad \lambda_1\geq 0, \qquad \lVert\bW\rVert_1=\sum_{i,j}|w_{ij}|,\]

其中,本节用 \(\lVert\bW\rVert_1\) 表示矩阵所有元素绝对值之和,而不是矩阵的诱导 1-范数。对非零元素,次梯度为 \(\lambda_1\operatorname{sign}(w_{ij})\)⁠;在 \(w_{ij}=0\) 处,次梯度集合为 \([-\lambda_1,\lambda_1]\)⁠。这里所说的 稀疏参数 是指许多权重精确等于 0,而不仅是绝对值比较小。

为什么 \(\ell_1\) 惩罚能够产生稀疏参数?

  关键在于绝对值函数 \(|w|\)\(w=0\) 处存在尖点。在某个候选参数点暂时固定其余参数,记数据损失关于权重 \(w_{ij}\) 的偏导数为 \(g_{ij}\)⁠。要使 \(w_{ij}=0\) 满足该坐标的一阶条件,需要有

\[0\in g_{ij}+\lambda_1\partial|w_{ij}|,\]

其中,\(\partial|w_{ij}|\) 表示绝对值函数的次梯度集合。当 \(w_{ij}=0\) 时,该集合为 \([-1,1]\)⁠。因此,只要 \(|g_{ij}|\leq\lambda_1\)⁠,就能从这个区间中找到一个值抵消 \(g_{ij}\)⁠,从而使 \(w_{ij}=0\) 满足该坐标的一阶条件。直观地说,如果某个权重对降低数据损失的作用不够大,无法抵消 \(\ell_1\) 惩罚带来的代价,目标函数就倾向于把它保留在 0。需要注意,这个条件只涉及当前坐标;对于凸问题,全部参数同时满足相应条件时才可以据此判断全局最优,而在神经网络等非凸问题中,满足一阶条件也不能保证得到全局最优解。

  这一点与 \(\ell_2\) 惩罚不同。\(\ell_2\) 惩罚关于 \(w_{ij}\) 的导数为 \(\lambda w_{ij}\)⁠,其绝对值会随着 \(w_{ij}\) 接近 0 而不断减小。因此,数据损失的梯度通常会与一个较小但非零的权重取得平衡;\(\ell_2\) 惩罚往往能缩小权重,却不容易使大量权重精确等于 0。

  近端梯度法(proximal gradient method) 中的软阈值操作可以更清楚地展示稀疏参数是怎样产生的。先只按照数据损失进行一步更新,再执行

\[u_{ij}^{(t)} =w_{ij}^{(t)}-\alpha g_{ij}^{(t)}, \qquad w_{ij}^{(t+1)} =\operatorname{sign}\!\left(u_{ij}^{(t)}\right) \max\!\left\{\left|u_{ij}^{(t)}\right|-\alpha\lambda_1,0\right\},\]

其中,\(\alpha>0\) 是学习率。当 \(|u_{ij}^{(t)}|\leq\alpha\lambda_1\) 时,更新后的权重恰好等于 0;当 \(|u_{ij}^{(t)}|>\alpha\lambda_1\) 时,权重的绝对值减小 \(\alpha\lambda_1\)⁠。这就是软阈值操作能够直接产生精确零值的原因。该式表示近端梯度法的一步更新,不是所有优化器通用的更新公式,也不表示只进行一步就能求出原问题的最优解。本节不展开近端算子、步长选择和收敛条件等一般理论;对近端梯度法感兴趣的同学,可以通过上述链接阅读 Parikh 与 Boyd(2014)的 Proximal Algorithms⁠,并自行学习。

  从二维凸问题的几何示意图看,两个参数构成的 \(\ell_1\) 约束区域是带有尖角的菱形,尖角位于坐标轴上。数据损失的等值线与约束区域首次接触时,较容易落在这些尖角处;落在坐标轴上意味着至少有一个参数等于 0。在更高维空间中,类似的尖角和棱对应多个参数同时等于 0,因此 \(\ell_1\) 惩罚常用于变量选择和模型压缩。

  \(\ell_1\) 惩罚只是促使参数稀疏,并不保证任意模型和任意优化算法都会得到大量精确的 0。普通次梯度法可能使参数在 0 附近来回变化,而不是停在 0;在神经网络等非凸模型中,结果还会受到初始化、学习率和训练过程的影响。若确实需要得到精确的 0,可以使用近端梯度法;比较不同特征所对应的权重时,还应先让输入特征具有相近的数值尺度,避免同一个惩罚系数对不同尺度的特征产生不公平的影响。

先区分惩罚项与更新规则

  \(\ell_2\) 惩罚是对目标函数的修改,权重衰减是对参数更新规则的修改。它们在式 (69) 所描述的普通梯度下降中可以等价,但在 Adam 等逐坐标自适应优化器中通常不等价。

AdamW:解耦权重衰减#

  AdamW(Adam with Decoupled Weight Decay,采用解耦权重衰减的 Adam)保留 Adam 的一阶矩、二阶原点矩和偏差修正,但把权重衰减从自适应梯度计算中分离出来。为了区分两种强度,下面用 \(\lambda_{\ell_2}\) 表示加入目标函数的 \(\ell_2\) 惩罚系数,用 \(\lambda_{\mathrm{wd}}\) 表示 AdamW 的权重衰减系数。

  记第 \(t\) 步的数据损失梯度为

\[\bG^{(t)} =\frac{\partial\mathcal{J}_{\mathrm{data}}} {\partial\bW^{(t)}}.\]

  若把 \(\ell_2\) 惩罚直接加入 Adam 使用的目标函数,则实际送入 Adam 的梯度为

(70)#\[\bG_{\mathrm{reg}}^{(t)} =\bG^{(t)}+\lambda_{\ell_2}\bW^{(t)}.\]

  这个合并后的梯度会同时进入 Adam 的两个移动平均:

\[\begin{split}\begin{aligned} \bv_W^{(t+1)} &=\beta_1\bv_W^{(t)} +(1-\beta_1)\bG_{\mathrm{reg}}^{(t)},\\ \bs_W^{(t+1)} &=\beta_2\bs_W^{(t)} +(1-\beta_2) \bG_{\mathrm{reg}}^{(t)} \odot\bG_{\mathrm{reg}}^{(t)}. \end{aligned}\end{split}\]

  经过偏差修正后,Adam 再按对应位置除以 \(\sqrt{\widehat{\bs}_W^{(t+1)}}+\epsilon\)⁠。因此,惩罚梯度不仅改变一阶矩和二阶原点矩,还会受到各坐标不同的自适应缩放,参数更新不再呈现式 (69) 所示的统一乘法收缩。

  AdamW 的矩估计只使用数据损失梯度 \(\bG^{(t)}\)⁠,随后在自适应梯度更新之外单独收缩权重:

(71)#\[\bW^{(t+1)} =(1-\alpha\lambda_{\mathrm{wd}})\bW^{(t)} -\alpha \frac{\widehat{\bv}_W^{(t+1)}} {\sqrt{\widehat{\bs}_W^{(t+1)}}+\epsilon},\]

其中,\(\widehat{\bv}_W^{(t+1)}\)\(\widehat{\bs}_W^{(t+1)}\) 只由数据损失梯度计算,分式、平方、开方和除法都按对应位置逐元素进行。当 \(\lambda_{\mathrm{wd}}=0\) 时,式 (71) 退化为 Adam 的更新式。

  实践中通常只衰减权重矩阵,不衰减偏置,也常把归一化层的尺度参数和平移参数排除在权重衰减之外。下面的代码假定 modelweight_decaylearning_rate 已经定义:它读取模型中所有可训练参数,按照参数的名称与维度分成“衰减”和“不衰减”两组,再据此创建一个 AdamW 优化器。该代码只完成优化器配置,不会立即更新参数或打印结果。

import torch

decay_parameters = []
no_decay_parameters = []

for name, parameter in model.named_parameters():
    if not parameter.requires_grad:
        continue
    if parameter.ndim == 1 or name.endswith(".bias"):
        no_decay_parameters.append(parameter)
    else:
        decay_parameters.append(parameter)

optimizer = torch.optim.AdamW(
    [
        {"params": decay_parameters, "weight_decay": weight_decay},
        {"params": no_decay_parameters, "weight_decay": 0.0},
    ],
    lr=learning_rate,
)

  循环先跳过不需要梯度的参数,再把一维参数和名称以 .bias 结尾的参数放入 no_decay_parameters其余参数进入 decay_parameters两个字典作为独立参数组传给 AdamW因此前一组使用给定的 weight_decay后一组使用 0。创建完成后,训练循环仍需依次执行计算损失、backwardoptimizer.step()优化器才会真正更新参数。

  将一维参数排除在权重衰减之外是一种常见规则,通常能够排除偏置和归一化参数,但它并不是适用于所有模型的数学定理。例如,有些模型含有应当衰减的一维权重,或含有维度大于 1、却不希望衰减的特殊参数。实际程序应根据参数名称、维度和模型结构核对分组结果,并确认每个可训练参数恰好进入一组。

表 6 \(\ell_2\) 惩罚与 AdamW 的关键区别#

更新方法

矩估计使用的梯度

权重收缩方式

普通梯度下降加 \(\ell_2\) 惩罚

不涉及 Adam 的矩估计

与统一乘法衰减等价,见式 (69)

Adam 加 \(\ell_2\) 惩罚

数据梯度与惩罚梯度之和

惩罚梯度进入矩估计并受到逐坐标缩放

AdamW

仅使用数据损失梯度

在自适应更新之外统一收缩权重,见式 (71)

使用 AdamW 时需要注意

  1. \(\lambda_{\ell_2}\)\(\lambda_{\mathrm{wd}}\) 的数值不能直接视为等价,应分别在验证集上选择。

  2. 不同优化器或软件实现中的 weight_decay 配置未必具有相同含义,使用前应核对它表示耦合惩罚还是解耦权重衰减。

  3. AdamW 与 Adam 保存相同数量的矩状态,不增加模型参数量,也不改变推断阶段的计算;训练时只增加一次逐元素权重收缩。

  4. AdamW 并不保证一定优于 Adam 或普通梯度下降。学习率、权重衰减系数、参数分组和训练预算仍应通过验证实验确定。

隐式正则化#

  隐式正则化不在目标函数中直接加入惩罚项,而是由优化算法、初始化、批量抽样方式或训练时长对最终解产生偏好。它说明即使两个训练方案最小化同一个数据损失,也可能得到不同参数和不同的泛化表现。“隐式”描述的是正则化作用的来源,并不表示使用者完全无法控制这些训练选择。

离散梯度下降与优化路径#

  普通梯度下降按照离散步长更新参数,而梯度流用微分方程描述连续时间下的理想变化:

(72)#\[\begin{split}\begin{aligned} \btheta^{(t+1)} &=\btheta^{(t)}-\alpha\nabla_{\btheta} \mathcal{J}\!\left(\btheta^{(t)}\right),\\ \frac{\mathrm{d}\btheta(\tau)}{\mathrm{d}\tau} &=-\nabla_{\btheta}\mathcal{J}\!\left(\btheta(\tau)\right), \end{aligned}\end{split}\]

其中,\(\alpha\) 是学习率,\(t\) 是离散更新次数,\(\tau\) 是连续时间。离散更新不是连续轨迹的完全复制;步长、初始化和训练次数都会影响算法经过哪些区域以及最终到达哪个解。

  在目标函数足够光滑且学习率较小时,后向误差分析可以用一个修正目标函数的梯度流,对离散梯度下降的局部轨迹作低阶近似。忽略关于学习率的高阶项后,这个修正目标函数为

(73)#\[\widetilde{\mathcal{J}}(\btheta) =\mathcal{J}(\btheta) +\lambda_{\mathrm{IG}} \mathcal{R}_{\mathrm{IG}}(\btheta), \qquad \lambda_{\mathrm{IG}}=\frac{\alpha P}{4}, \qquad \mathcal{R}_{\mathrm{IG}}(\btheta) =\frac{1}{P} \left\lVert\nabla_{\btheta}\mathcal{J}(\btheta)\right\rVert_2^2,\]

其中,\(P\) 是参数个数,\(\mathcal{R}_{\mathrm{IG}}\) 是所有参数方向上的损失梯度平方的平均值,\(\lambda_{\mathrm{IG}}\) 表示相应的隐式正则化强度。按照这里的定义,二者的乘积为 \(\lambda_{\mathrm{IG}}\mathcal{R}_{\mathrm{IG}}=\alpha\lVert\nabla_{\btheta}\mathcal{J}\rVert_2^2/4\)⁠。因此,\(\mathcal{R}_{\mathrm{IG}}\) 衡量的不是参数本身的大小,而是当前参数位置处训练损失曲面的局部斜率。

\(\mathcal{R}_{\mathrm{IG}}\) 项的作用

  Barrett 与 Dherin(2021)的原始论文《Implicit Gradient Regularization》\(\mathcal{R}_{\mathrm{IG}}\) 称为隐式梯度正则项(implicit gradient regularizer,IGR)。该项是经过参数个数归一化的局部斜率平方。按照论文采用的几何定义,损失曲面的局部斜率满足 \(\operatorname{slope}(\btheta)=\lVert\nabla_{\btheta}\mathcal{J}(\btheta)\rVert_2=\sqrt{P\mathcal{R}_{\mathrm{IG}}(\btheta)}\)⁠。因此,该项较大,表示当前参数位置处的训练损失曲面较陡;该项较小,则表示当前位置处的斜率较小。这里的“斜率较小”只描述当前位置附近的一阶变化,不能直接理解为曲率较小,也不能仅凭该项判断某个极小值所在区域是否宽阔。

  改变参数经过的路径。 在修正目标 \(\widetilde{\mathcal{J}}\) 中,梯度较大的区域会带来额外代价。原论文的后向误差分析表明,在目标函数足够光滑且学习率较小时,离散梯度下降的更新轨迹更接近修正目标的梯度流,而不是原始目标 \(\mathcal{J}\) 的梯度流。因此,离散步长会使优化过程倾向于避开斜率很大的路径,并优先经过梯度较小、变化较平缓的区域。

  影响最终到达的区域。 每一步产生的局部偏好可以在训练过程中逐渐累积,使参数更可能沿斜率较小的路线到达周围也较平缓的低损失区域。需要注意,在任何精确的驻点处都有 \(\nabla_{\btheta}\mathcal{J}=\bzero\)⁠,因而 \(\mathcal{R}_{\mathrm{IG}}=0\)⁠;无论该驻点是尖锐极小值、平坦极小值还是鞍点,仅看这个终点数值都无法区分。因此,该项的主要作用不是在训练结束后给不同驻点排序,而是在训练过程中改变参数经过的路径。在论文所讨论的小步长近似适用范围内,它也不会帮助梯度下降跳出局部极小值;论文强调的是,在具有许多全局最优解的模型中,不同路径可能到达其中不同的解。

  与平坦区域和泛化的联系。 原论文先用一个含两个参数的线性模型展示学习率如何改变优化路径;在 MNIST 多层感知机实验中,较强的隐式梯度正则化与较小的 \(\mathcal{R}_{\mathrm{IG}}\)⁠、较平缓的损失区域、对参数扰动更强的稳定性以及较小的测试误差相关;在 CIFAR-10 的 ResNet-18 实验中,论文也观察到学习率、\(\mathcal{R}_{\mathrm{IG}}\) 和测试准确率之间存在相应联系。这里的“相关”是论文在特定模型和实验设置下得到的结果,不能理解为 \(\mathcal{R}_{\mathrm{IG}}\) 较小就必然具有更好的泛化能力。

  上述近似只保留了关于 \(\alpha\) 的一阶修正,省略了更高阶项。原论文的理论推导针对足够光滑的目标函数和全批量梯度下降;论文虽然通过实验观察到类似作用在小批量随机梯度下降中仍可能存在,但没有把同一结论证明为对随机梯度下降、动量法、Adam 或任意学习率都成立。因此,式 (73) 不能理解为某一次梯度下降更新与修正目标更新之间的严格等式,也不能据此断言学习率越大,隐式正则化效果或模型的泛化能力就一定越好。

  小批量随机梯度下降还会受到批量抽样噪声的影响,不同初始化也可能使非凸模型到达不同解。这些因素可能形成隐式偏好,但其结果依赖数据、模型和优化设置,必须通过验证实验判断,不能把某一种优化器笼统地称为“必然更好的正则化器”。

提前停止#

  提前停止(early stopping)在训练过程中监控验证指标,并保留验证表现最好的检查点。常见实现设置耐心轮数(patience)和最小改进量:如果验证指标连续若干轮没有达到规定的改进幅度,就终止训练。测试指标不能作为停止条件,否则测试集参与了训练方案的选择,最终评价会失去独立性。

  提前停止没有修改数据损失,却限制了参数沿训练目标继续移动的时间,因此具有隐式正则化作用。训练指标存在随机波动时,应恢复验证表现最好的检查点,而不是简单返回停止时的最后一次参数。耐心轮数、最小改进量和验证频率都属于需要事先确定或在验证集上选择的训练设置。

提前停止与训练轮次增加时的双下降

  Nakkiran 等(2019) 在固定网络结构并延长训练时间时观察到一种训练时间双下降(epoch-wise double descent)现象:测试误差可能先下降,在训练误差接近 0、模型刚好能够近乎完全拟合训练数据的阶段附近上升,随后又随着训练继续进行而下降。因此,训练前期出现的第一个测试误差低点,不一定是整个训练过程中的最低点。一种直观理解是,随着训练继续,模型逐渐能够拟合训练数据中更细微的变化;在刚好能够近乎完全拟合训练数据的阶段,模型可能对观测标签噪声和训练集的细小变化比较敏感,测试误差因而升高。对于容量足够大的模型,继续训练有时会使优化过程到达另一个在训练集上同样拟合良好、但在新样本上表现更好的解,于是测试误差再次下降。这是论文根据实验提出的解释思路,并不是适用于所有模型的定理。关于插值阈值和双下降三个区间的完整介绍,见 双下降现象⁠。

  这个现象与提前停止看起来有些矛盾:如果耐心轮数太少,验证指标刚开始变差时训练就会结束,确实可能看不到后面可能出现的第二次下降。但是二者描述的内容不同。训练时间双下降是某些数据、模型和训练设置下可能出现的误差变化现象;提前停止则是根据验证集表现选择训练轮数和参数检查点的方法。提前停止往往会在训练误差接近 0 之前结束训练,此时模型尚未进入双下降可能出现的临界阶段,所以不少实验中不会观察到完整的双下降曲线。原论文也指出,采用合适的提前停止后,论文研究的许多双下降现象不再出现,但这不是对所有任务都成立的保证。

  实际训练时不能根据测试误差决定是否等待第二次下降。如果预先的验证实验表明后期改善可能出现,并且计算条件允许,可以适当增加最大训练轮数和耐心轮数,同时保存整个训练过程中验证表现最好的参数;如果验证表现没有再次改善,就仍然使用较早保存的参数。训练时间双下降并非必然发生,在观测标签含有噪声时通常更明显,因此不能因为它可能出现就认定训练时间越长越好。

噪声注入#

  本节把训练阶段的随机扰动,以及按预定规则平滑观测标签的方法,一起放在“噪声注入”部分介绍。它们的共同点是改变模型训练时接收到的输入、计算路径、参数或目标信号,使模型不能只依赖某个样本或某条计算路径中的微小细节。用 \(\bxi\) 表示随机扰动或变换编号,可以把一般训练目标写为

(74)#\[\mathcal{J}_{\mathrm{noise}}(\btheta) =\mathbb{E}_{(\bx,y)} \mathbb{E}_{\bxi} \left[ \ell\!\left( f_{\btheta,\bxi} (T_{\bxi}(\bx)), \widetilde y_{\bxi} \right) \right],\]

其中,\(T_{\bxi}\) 表示输入变换,\(f_{\btheta,\bxi}\) 表示加入激活噪声或参数噪声后的网络,\(\widetilde y_{\bxi}\) 表示扰动或平滑后的观测标签;没有使用某类扰动时,相应部分保持不变。标准标签平滑是确定性变换,此时 \(\widetilde y_{\bxi}\) 不随 \(\bxi\) 变化。所有变换都必须与任务相符:强度过弱可能没有明显作用,强度过大则可能破坏与观测标签有关的信息并造成欠拟合。除非任务本身要求随机预测,推断阶段通常关闭训练期噪声或改用确定性的期望近似。

Dropout:对激活加入乘性噪声#

  Dropout 在训练阶段随机屏蔽一部分激活值,使网络不能长期依赖少数几个单元。设第 \(l\) 个隐藏层的激活为 \(\bA^{[l]}=[(\ba_1^{[l]})\trans;\ldots;(\ba_m^{[l]})\trans]\in\mathbb{R}^{m\times d^{[l]}}\)⁠,丢弃概率为 \(p^{[l]}\)⁠,保留概率为 \(q^{[l]}=1-p^{[l]}\)⁠。对当前小批量采样

\[M_{ij}^{[l]}\overset{\mathrm{i.i.d.}}{\sim} \operatorname{Bernoulli}\!\left(q^{[l]}\right).\]

  倒置 Dropout(inverted Dropout)在训练阶段把保留的激活除以保留概率:

(75)#\[\widetilde{\bA}^{[l]} =\frac{\bA^{[l]}\odot\bM^{[l]}}{q^{[l]}}, \qquad \mathbb{E}\!\left(\widetilde{\bA}^{[l]}\mid\bA^{[l]}\right) =\bA^{[l]}.\]

  训练时已经通过 \(1/q^{[l]}\) 对条件期望进行调整,因此推断阶段只需关闭 Dropout,直接使用完整激活,不再缩放。后向传播必须复用同一次前向传播生成的掩码:

\[\frac{\partial\mathcal{J}}{\partial\bA^{[l]}} =\frac{\partial\mathcal{J}}{\partial\widetilde{\bA}^{[l]}} \odot\frac{\bM^{[l]}}{q^{[l]}}.\]

  掩码为 0 的位置,其梯度也为 0。通常对隐藏层使用 Dropout,不对最终输出层使用;某些模型也会对输入或注意力权重使用专门的 Dropout,因此“输入层绝不使用”并不是普遍规则。

Dropout 的三种理解

  从操作上看,Dropout 是对激活加入伯努利乘性噪声;从优化过程看,随机掩码会改变每次更新使用的计算路径,因此具有隐式正则化作用;从模型组合看,不同掩码对应许多共享参数的子网络,可以提供近似集成的理解。不过,标准 Dropout 在推断时关闭掩码,只运行一个确定性网络,并不等同于保存和平均多个独立训练的模型。

使用 Dropout 时需要注意

  丢弃概率应在验证集上选择,过大的丢弃概率会造成欠拟合和训练不稳定。Batch Normalization 与 Dropout 同时使用时还要注意:训练阶段的随机屏蔽会改变 BatchNorm 看到的批次统计量,推断阶段关闭 Dropout 后可能产生统计差异。是否组合使用应由网络结构和验证实验决定。下一节将对 批量归一化 进行详细介绍。

输入、激活与参数噪声#

  最简单的输入噪声是在训练阶段向特征加入高斯扰动:

(76)#\[\widetilde{\bx} =\bx+\sigma_x\bepsilon, \qquad \bepsilon\sim \mathcal{N}(\bzero,\bI),\]

其中,\(\sigma_x\geq 0\) 控制噪声强度。特征应先采用一致的预处理方法,否则同一个 \(\sigma_x\) 对不同尺度的特征具有完全不同的影响。推断时通常令 \(\sigma_x=0\)⁠。

  还可以扰动隐藏层激活、权重或梯度。不同位置的噪声具有不同含义:输入噪声要求模型对测量误差保持稳定,激活噪声改变中间表示,权重噪声使模型在附近参数下仍需给出合理预测。噪声分布、加入位置与强度都应明确记录,并通过验证集选择。

数据增强与标签平滑#

  数据增强对训练样本施加不会改变观测标签含义的结构化变换,例如图像的适度裁剪与翻转、音频的时移,或不会改变语义的文本扰动。它把任务中希望模型学习的不变性加入训练过程。并非所有增强都等同于简单的加性噪声;若变换改变了标签含义,反而会向训练数据引入系统性错误。增强参数只能根据训练集和验证集确定,不能根据测试结果反复调整。

  对含 \(K\) 个类别的分类问题,标签平滑(label smoothing)把独热观测标签 \(\by\) 改为

(77)#\[\widetilde{\by} =(1-\varepsilon)\by +\frac{\varepsilon}{K}\bone, \qquad 0\leq\varepsilon<1,\]

其中,\(\varepsilon\) 是平滑强度。这个确定性写法没有在每一步随机采样噪声,但它会有计划地扰动训练目标,因此常与噪声注入方法一起介绍。适度平滑可减少模型对某个类别给出过度极端的训练信号;平滑过强会削弱类别之间的区分。若资料采用把 \(\varepsilon\) 只分配给其余 \(K-1\) 类的写法,应注意两种系数定义不同。

集成学习#

  集成学习(ensemble learning)综合多个模型的预测,减少结果对某一次数据抽样、初始化或训练过程的依赖。它不一定修改单个模型的目标函数,因此更准确地说,它是一种泛化控制策略。集成能否带来明显收益,不仅取决于成员数量,还取决于各成员是否准确以及它们所犯的错误是否存在差异。

预测平均与误差相关性#

  对回归问题,最简单的集成把 \(K\) 个模型的预测取平均:

(78)#\[\overline f(\bx) =\frac{1}{K}\sum_{k=1}^{K}f_k(\bx),\]

其中,\(f_k\) 是第 \(k\) 个成员模型。分类问题通常先平均各类别的预测概率,再选择概率最大的类别;不能直接对类别编号取算术平均。

  为说明成员差异的重要性,设每个模型的预测误差均值为 0、方差为 \(\sigma^2\)⁠,任意两个不同模型误差的相关系数均为 \(\rho\)⁠;为便于讨论,设 \(0\leq\rho\leq1\)⁠。平均预测误差的方差为

(79)#\[\operatorname{Var}(\overline e) =\sigma^2\left[ \rho+\frac{1-\rho}{K} \right].\]

  当成员误差接近独立,即 \(\rho\) 接近 0 时,增加成员数量可以明显降低方差;当 \(\rho\) 接近 1 时,各模型几乎犯同样的错误,集成收益很小。因此,集成需要在单个成员的预测能力与成员之间的差异之间取得平衡。

Bagging、Boosting 与 Stacking#

  Bagging。 Bagging(bootstrap aggregating)从训练集进行有放回抽样,在不同自助样本上并行训练多个模型,再对预测进行平均或投票。随机森林在不同自助样本和特征子集上训练决策树,是典型的 Bagging 方法。Bagging 主要通过降低预测方差发挥作用,适合对训练数据变化较敏感的模型。

  Boosting。 Boosting 按顺序训练多个较弱的学习器,后续学习器重点修正已有集成尚未处理好的部分。AdaBoost、梯度提升决策树(GBDT)和 XGBoost 都属于这一类。Boosting 经常能够同时降低偏差并改善预测,但训练通常不能完全并行,学习器数量过多或设置不当也可能造成过拟合。

  Stacking。 Stacking 先训练若干类型不同的基础模型,再训练一个组合模型,根据基础模型的预测学习如何加权。为了避免信息泄漏,组合模型的训练输入应来自基础模型对折外样本的预测,而不能直接使用基础模型在其训练样本上的拟合结果。最终评价时,测试集仍然只能在所有模型和组合规则确定后使用。

预测效果与计算成本要同时报告

  显式集成通常需要训练、保存并运行多个模型。若每个成员的结构相同,成员数从 1 增加到 \(K\) 时,总训练量、参数存储量和顺序推断量通常也会明显增加。比较集成规模时,应分别说明“每个成员使用相同训练量”还是“所有成员共享相同总训练预算”,并同时报告任务指标、训练时间、固定批量预测时间或吞吐量、参数总量和峰值内存。

Shiny 交互演示:正则化方法

  下面三个交互页面分别比较无参数惩罚、\(\ell_1\) 惩罚、\(\ell_2\) 惩罚和 AdamW,展示不同隐藏层丢弃概率下的 Dropout,并演示提前停止。页面使用验证集比较训练设置,测试集只用于最终评价;Dropout 在评价时关闭随机屏蔽,提前停止则保存并恢复验证损失最低时的模型参数。

核心推导与实现核验#

核心关系

\[\begin{split}\begin{aligned} \text{显式:}\quad \mathcal{J}_{\mathrm{reg}} &=\mathcal{J}_{\mathrm{data}}+\lambda\mathcal{R}(\btheta),\\ \text{隐式:}\quad \btheta^{(t+1)} &=\btheta^{(t)}-\alpha\nabla_{\btheta}\mathcal{J},\\ \text{噪声:}\quad \mathcal{J}_{\mathrm{noise}} &=\mathbb{E}_{\bxi} \left[ \ell\!\left( f_{\btheta,\bxi} (T_{\bxi}(\bx)), \widetilde y_{\bxi} \right) \right],\\ \text{集成:}\quad \overline f(\bx) &=\frac{1}{K}\sum_{k=1}^{K}f_k(\bx). \end{aligned}\end{split}\]

  推导路径。 显式方法直接改变目标或更新规则,具体见式 (67) 与式 (71)⁠;隐式方法通过式 (72) 所示的优化路径和训练时长影响最终解;噪声注入及相关方法在随机扰动或预定平滑规则下计算损失,Dropout 的具体形式见式 (75)⁠;集成学习按照式 (78) 综合多个成员,其收益取决于式 (79) 中的误差相关性。

关键条件

  式 (69) 的等价关系要求使用不含动量和逐坐标自适应缩放的普通梯度下降;在式 (71) 中,一阶矩和二阶原点矩必须只由数据损失梯度计算。式 (73) 只是在目标函数光滑且学习率较小时的局部低阶解释。对于式 (75)⁠,掩码均值必须等于保留概率;对于式 (79)⁠,各成员需要具有题设中的相同误差方差与共同相关系数。

数据规模

  AdamW 与 Adam 保存相同的一阶矩和二阶原点矩状态;若共有 \(P\) 个需要优化的参数,这两组状态也各包含 \(P\) 个数。Dropout 通常为每个被处理的激活值生成一个 0 或 1 标记。显式集成若包含 \(K\) 个独立成员,则需要分别记录各成员的参数和预测;计算成本不能只按单个成员报告。

常见误区

  将式 (70) 送入 Adam 后,却把所得更新称为式 (71)⁠,会混淆耦合 \(\ell_2\) 惩罚与解耦权重衰减。把式 (73) 当作任意学习率下的严格全局等价式、在推断阶段继续使用式 (75) 的随机掩码、对类别编号直接应用式 (78)⁠,也会得到错误的解释或实现。

动手检查

  对固定激活重复采样 Dropout 掩码,验证式 (75) 的经验均值接近原激活;用同一数据梯度分别计算式 (70) 和式 (71) 的一步结果;最后逐渐增加集成成员数,核对误差相关性较低时的方差下降是否与式 (79) 一致。

数值稳定性与规模

  Dropout 的保留概率不得为 0;输入噪声强度必须与特征尺度匹配。AdamW 应分别记录自适应梯度更新量和权重衰减量,并检查 \(1-\alpha\lambda_{\mathrm{wd}}\) 的数值范围。平均分类概率前还应检查各成员类别顺序一致、概率有限且每行概率和接近 1。

本节小结#

  1. 显式正则化直接改变目标函数、参数约束或更新规则;普通梯度下降中的 \(\ell_2\) 惩罚可与权重衰减等价,但 AdamW 需要把衰减与自适应梯度更新分开。

  2. 隐式正则化来自优化路径、初始化或训练时长对最终解的影响;提前停止是常用方法,双下降 则是相关的误差变化现象而不是正则化方法。

  3. 噪声注入在训练阶段扰动输入、激活或观测标签;Dropout、输入噪声、数据增强与标签平滑都必须根据任务选择适当强度。

  4. 集成学习通过平均、投票或学习组合规则综合多个模型;只有成员预测具有足够差异时,增加成员数量才更可能带来明显收益,同时还应考虑训练、存储和推断成本。

综合练习#

  程序题应固定随机种子、写出维度断言并报告运行环境;比较题还应固定数据划分、随机种子集合和训练预算。全部参考答案见 正则化与泛化控制答案⁠。

  1. ℓ₁ 与 ℓ₂ 惩罚。\(\mathcal{J}_{\mathrm{reg}}(\bW)=\mathcal{J}_{\mathrm{data}}(\bW)+\lambda_1\lVert\bW\rVert_1+(\lambda_2/2)\lVert\bW\rVert_F^2\)⁠。推导 \(\ell_2\) 项的梯度和普通梯度下降更新式;写出 \(\ell_1\) 项在非零元素处的次梯度以及零点处的次梯度集合,并解释普通次梯度更新为什么未必产生精确的 0,而软阈值操作可以产生稀疏解。

  2. 耦合 ℓ₂ 惩罚与 AdamW。 根据正文公式写出 Adam 加耦合 \(\ell_2\) 惩罚时进入两个矩估计的梯度,以及 AdamW 的解耦更新式。证明普通梯度下降下两种写法可以等价,并说明该结论为什么不能直接推广到 Adam;再说明偏置和归一化参数通常如何分组。

  3. Dropout 作为乘性噪声。\(\widetilde a=Ma/q\)⁠、\(M\sim\operatorname{Bernoulli}(q)\)⁠,推导条件期望和条件方差。再计算 100 个激活均为 2、\(q=0.8\) 时的保留数量期望、被保留激活的数值和总和期望,并说明推断阶段为什么关闭 Dropout。

  4. 集成平均与误差方差。\(K\) 个模型的预测误差均值为 0、方差为 \(\sigma^2\)⁠,任意两个不同模型误差的相关系数均为 \(\rho\)⁠,且 \(0\leq\rho\leq1\)⁠。推导式 (79)⁠,并讨论 \(\rho=0\)⁠、\(\rho=1\) 以及 \(K\to\infty\) 时的结果。说明为什么成员数量很多但误差高度相似时,集成收益仍然有限。

  5. 提前停止实现。Python 实现一个提前停止器,支持耐心轮数、最小改进量、最佳参数深复制和最佳状态恢复。测试最佳轮不是最后一轮、连续未改善次数、相同验证损失的处理方式,并确认测试集不参与停止判断。

  6. 噪声注入实现与核验。Python 实现倒置 Dropout 和仅在训练阶段启用的高斯输入噪声 \(\widetilde{\bx}=\bx+\sigma_x\bepsilon\)⁠。显式传入随机数生成器,并核验随机种子可复现、\(q=1\)⁠、\(\sigma_x=0\)⁠、评估模式、非法参数、经验均值与理论方差。可再与框架 Dropout 及训练阶段的数据变换进行比较。

  7. 显式正则化方法比较。 使用同一 Adam 基线比较无正则化、\(\ell_1\) 惩罚、\(\ell_2\) 惩罚和 AdamW。各方法分别用相同数量的候选强度进行验证集选择,并统一被正则化参数集合。报告任务性能、训练—验证差距、权重范数、近零权重比例、训练时间、固定批量预测时间、参数量和峰值内存。

  8. 提前停止与固定训练轮数比较。 在相同数据划分、初始参数、批次顺序、优化器、最大训练轮数和验证频率下,比较预先确定训练轮数与提前停止。报告最佳轮、实际停止轮、训练时间和测试表现,并解释限制优化过程为什么可能产生隐式正则化作用。测试集只能在方案确定后使用。

  9. 集成规模、预测效果与计算代价。 比较 \(K=1,3,5\) 个独立训练成员的分类概率平均。确定单个成员的结构、训练流程和随机种子集合,报告任务性能、成员误差相关性、训练总时间、固定批量预测时间、存储参数总量和峰值内存;分别讨论“每个成员训练量相同”和“所有成员共享相同总训练预算”两种比较方式。