正则化与泛化控制:参考答案#
说明#
以下答案与正文 9 道题逐题对应。推导题给出主要步骤;编程和实验题给出参考程序、检查方法与公平比较要求。实验结果会随数据和模型而变化,因此应根据实际结果作出结论,不能把参考答案中的一般趋势当作固定结论。
记 \(\bU\) 为先对数据损失和 \(\ell_2\) 项执行一步梯度更新后得到的临时参数。由于
\[\nabla_{\bW} \frac{\lambda_2}{2}\lVert\bW\rVert_F^2 =\lambda_2\bW,\]普通梯度下降的更新式为
\[\bW^{+} =(1-\alpha\lambda_2)\bW -\alpha\nabla_{\bW}\mathcal{J}_{\mathrm{data}} -\alpha\lambda_1\bS =\bU-\alpha\lambda_1\bS,\]其中,矩阵 \(\bS\) 的每个元素都是相应权重绝对值的次梯度:
\[\begin{split}S_{ij}\in \begin{cases} \{1\}, & w_{ij}>0,\\ [-1,1], & w_{ij}=0,\\ \{-1\}, & w_{ij}<0. \end{cases}.\end{split}\]普通次梯度更新每次减去一个有限步长,权重可能从正数跨到负数而没有恰好落在 0。近端梯度法先用数据损失和 \(\ell_2\) 项得到 \(\bU\),再逐元素执行软阈值
\[W_{ij}^{+} =\operatorname{sign}(U_{ij}) \max\!\left(|U_{ij}|-\alpha\lambda_1,0\right).\]当 \(|U_{ij}|\leq\alpha\lambda_1\) 时,结果精确等于 0,因此软阈值能够直接产生稀疏解。若偏置不参与正则化,应把它从以上范数和更新中排除。
Adam 加耦合 \(\ell_2\) 惩罚时,进入一阶矩和二阶原点矩估计的梯度为
\[\bG_{\mathrm{reg}}^{(t)} =\bG^{(t)}+\lambda_{\ell_2}\bW^{(t)}.\]AdamW 只用 \(\bG^{(t)}\) 计算两个矩估计,并在自适应更新之外执行
\[\bW^{(t+1)} =(1-\alpha\lambda_{\mathrm{wd}})\bW^{(t)} -\alpha \frac{\widehat{\bv}_W^{(t+1)}} {\sqrt{\widehat{\bs}_W^{(t+1)}}+\epsilon}.\]对普通梯度下降,有
\[\bW^{(t+1)} =\bW^{(t)} -\alpha\left(\bG^{(t)}+\lambda\bW^{(t)}\right) =(1-\alpha\lambda)\bW^{(t)}-\alpha\bG^{(t)}.\]因而耦合 \(\ell_2\) 惩罚与乘法式权重衰减在这个条件下等价。Adam 会把惩罚梯度一起送入两个矩估计,并对不同坐标进行不同的缩放;AdamW 的统一收缩不进入矩估计,所以这个等价关系不能直接推广到 Adam。实践中通常把权重矩阵放入衰减参数组,把偏置和归一化层的尺度参数、平移参数放入不衰减参数组;最终仍应按模型名称和结构核对分组。
由于 \(\mathbb{E}(M)=q\),所以
\[\mathbb{E}(\widetilde a\mid a) =\frac{a}{q}\mathbb{E}(M)=a.\]又因为 \(M^2=M\),所以
\[\operatorname{Var}(\widetilde a\mid a) =\frac{a^2}{q^2}\operatorname{Var}(m) =\frac{a^2(1-q)}{q}.\]保留数量服从 \(\operatorname{Binomial}(100,0.8)\),其期望为 80;每个被保留的激活变为 \(2/0.8=2.5\);所有激活之和的期望为 \(80(2.5)=200\),与原来的总和相同。训练阶段已经用 \(1/q\) 对齐了期望,因此推断时关闭随机掩码并使用完整激活,不再除以 \(q\)。
记第 \(k\) 个模型的预测误差为 \(e_k\),则平均误差为 \(\overline e=K^{-1}\sum_{k=1}^{K}e_k\)。利用 \(\operatorname{Var}(e_k)=\sigma^2\) 和 \(\operatorname{Cov}(e_j,e_k)=\rho\sigma^2\),可得
\[\begin{split}\begin{aligned} \operatorname{Var}(\overline e) &=\frac{1}{K^2} \left[ K\sigma^2+K(K-1)\rho\sigma^2 \right]\\ &=\sigma^2\left[ \rho+\frac{1-\rho}{K} \right]. \end{aligned}\end{split}\]当 \(\rho=0\) 时,方差为 \(\sigma^2/K\);当 \(\rho=1\) 时,方差仍为 \(\sigma^2\);当 \(K\to\infty\) 时,方差趋于 \(\rho\sigma^2\)。因此,增加成员只能减小误差中彼此不同的部分,不能消除所有成员共同具有的误差。成员数量很多但误差高度相关时,集成收益仍然有限。
一种参考实现如下。
state可以是模型的状态字典;深复制可以防止后续训练原地修改已经保存的最佳参数。import copy import numpy as np class EarlyStopper: def __init__(self, patience, min_delta=0.0): if patience < 1: raise ValueError("patience 必须为正整数") if min_delta < 0: raise ValueError("min_delta 不能为负数") self.patience = int(patience) self.min_delta = float(min_delta) self.best_loss = np.inf self.best_epoch = None self.best_state = None self.bad_epochs = 0 def update(self, val_loss, state, epoch): if not np.isfinite(val_loss): raise ValueError("验证损失必须是有限数") improved = val_loss < self.best_loss - self.min_delta if improved: self.best_loss = float(val_loss) self.best_epoch = int(epoch) self.best_state = copy.deepcopy(state) self.bad_epochs = 0 else: self.bad_epochs += 1 return self.bad_epochs >= self.patience def restore(self): if self.best_state is None: raise RuntimeError("尚未保存最佳状态") return copy.deepcopy(self.best_state)
例如,令验证损失依次为 \(0.8,0.5,0.5,0.6\),取
patience=2和min_delta=0。第二轮是最佳轮,相同损失不算改进,第四轮结束后停止,restore()应返回第二轮的状态而不是第四轮状态。还应测试最小改进量恰好位于边界时的行为。停止器只接收验证损失,不接收测试指标;所有训练方案确定以后,才在测试集上评价一次。倒置 Dropout 和高斯输入噪声可以写成两个只在训练阶段工作的函数:
import numpy as np def inverted_dropout(x, keep_prob, training, rng): x = np.asarray(x) if not 0 < keep_prob <= 1: raise ValueError("keep_prob 必须位于 (0, 1]") if not training or keep_prob == 1: return x.copy(), np.ones_like(x, dtype=bool) mask = rng.random(x.shape) < keep_prob return x * mask / keep_prob, mask def gaussian_input_noise(x, sigma, training, rng): x = np.asarray(x) if sigma < 0: raise ValueError("sigma 不能为负数") if not training or sigma == 0: return x.copy() noise = rng.normal(loc=0.0, scale=sigma, size=x.shape) return x + noise
两个由相同种子建立的生成器应产生相同结果;
keep_prob=1、sigma=0或training=False时,输出应逐元素等于输入。对固定标量 \(a\) 重复采样 Dropout,经验均值应接近 \(a\),经验方差应接近 \(a^2(1-q)/q\);对固定输入重复加入高斯噪声,输出均值应接近原输入,逐元素方差应接近 \(\sigma^2\)。还应测试概率越界、负噪声标准差、输出维度和有限性。与框架实现比较时,要分别切换训练模式和评估模式。公平比较可以采用如下流程:先确定相同的数据划分、初始参数、批次顺序、Adam 设置和最大训练量;对 \(\ell_1\)、\(\ell_2\) 与 AdamW 分别设置包含 0 在内且数量相同的候选强度,并只根据验证集选择。三种方法应作用于同一参数集合,例如都排除偏置和归一化参数。\(\ell_1\) 与 \(\ell_2\) 组把惩罚加入损失,AdamW 组只计算数据损失并执行解耦衰减。
报告时应区分数据损失与含惩罚项的训练目标,因为不同惩罚下的总目标不能直接比较。权重统计至少包括 \(\lVert\bW\rVert_1\)、\(\lVert\bW\rVert_F\),以及按预先确定阈值计算的近零权重比例;阈值不能在看到结果后为某个方法单独调整。还应报告多个固定随机种子下的任务指标均值与标准差、训练—验证差距、训练秒数、固定批量预测时间、参数量和峰值内存。适度正则化可能减小训练—验证差距,过强正则化可能造成欠拟合,最终结论应以实际验证与测试结果为准。
采用固定训练轮数的实验组在实验前确定轮数,并在该轮结束后保存参数;提前停止组设定相同的最大轮数,但根据验证损失、耐心轮数和最小改进量决定何时停止,并恢复最佳检查点。两组应共享数据划分、初始参数、批次顺序、优化器、学习率和验证频率。若希望只研究停止规则,不能同时改变数据增强、模型结构或正则化系数。
需要记录提前停止组的最佳轮、实际停止轮和恢复后的指标,并分别报告两组的训练时间和测试表现。限制训练时长会阻止参数继续拟合训练数据中的细微波动,因此可能产生隐式正则化作用;但停止太早也可能造成欠拟合。测试集不能用于选择固定轮数、耐心轮数或最小改进量,只能在所有方案确定后用于最终评价。
第一种比较方式让每个成员使用相同结构和相同训练量,因而 \(K=3,5\) 的总训练量高于 \(K=1\);它回答“增加完整训练的成员能带来多少收益”。第二种方式固定所有成员共享的总训练预算,例如把总更新次数分配给 \(K\) 个成员;它回答“在相同计算预算下,训练多个较弱成员是否值得”。两种方式不能混在同一结论中。
对每个 \(K\),应使用预先确定的随机种子集合独立训练成员,并平均分类概率。报告单个成员和集成的任务指标、成员误差之间的平均相关系数、总训练时间、运行全部成员后的固定批量预测时间、参数存储总量和峰值内存。随着 \(K\) 增大,若误差相关性较低,集成方差和测试误差可能下降;若误差相关性很高,收益会很快达到上限。部署结论还应说明成员能否并行运行,因为并行可以降低等待时间,却不会消除总计算量与存储量的增加。