想象一支登山探险队要在浓雾弥漫的山谷里安营扎寨。下山时雾太大,大家只能靠脚下的坡度判断方向;等终于走到谷底附近,地面平坦了,但雾更浓了——每走几步都以为自己站在最低点,其实只是最低点附近某个略偏的位置。训练神经网络几乎一模一样:我们用一小批数据算出的梯度,就像向导脚下感知到的那一小段地形,天生带着噪声。大多数训练把“最后一步踩的位置”直接当作最终模型,可你不知道那是谷底正中心,还是被噪声推偏了一点的边角。 随机权重平均(Stochastic Weight Averaging,简称 SWA)提出了一个很稳的做法:与其相信单次落脚点,不如把训练后期多个时刻的权重快照收集起来取平均。多份带噪声的位置报告互相抵消,得到的“平均营地”往往更接近谷底中央,泛化能力更强,而付出的额外代价几乎为零——也就是几行代码的事情。本文就用这支雾谷探险队的故事,把 SWA 的原理、公式、实现和调参一次讲明白。

岗位关联

对 AI 从业者而言,SWA 是你工具箱里“免费泛化增益”的入场券:不用改动模型结构、不用增加推理成本,就能让交付的模型更稳更抗扰动,是训练调优面试和实战中都能加分的技巧。

目录
  1. 可视化演示
  2. 问题背景:雾谷里徘徊的脚步声
  3. 核心原理:多份报告,一个中心
  4. 数学公式:平均就是力量
  5. 实现步骤:三步搭好营地
  6. BN重设:换了帐篷,要重新测风向
  7. 调参实践:向导的节奏
  8. 对比拓展:从篝火到GPS
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示随机权重平均SWA训练优化技的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

随机权重平均SWA训练优化技:SWA随 SWA随机权重平均原理 SWA的数学原理与收敛性 核心机制可视化 随机权重平均SWA训练优化技整体架构与关键组件

问题背景:雾谷里徘徊的脚步声

想象那支登山探险队:雾浓得看不清十步之外,向导每走一步只能靠脚底的触感判断“这边似乎更低”。等大家终于下到谷底,地面变平了——恰恰因为太平坦,任何方向都“看起来像最低点”,于是队伍只能在谷底附近反复踱步,每站定一个位置都只是近似。神经网络训练就是这样:数据太多,我们不可能看全整座山,只能随机抓一小把样本估算坡度。这个过程叫随机梯度下降(SGD),“随机”二字就来自这种小批量抽样带来的噪声。

训练走到后期,模型其实已经抵达损失曲面(也就是这座雾谷)很低的区域,但因为梯度估计总是带着噪声,最后一步踩的位置并不一定是最低点正中央。如果直接把最后一个 epoch 的权重拿去部署,就好比只相信队里最后一位向导随口报的坐标——他可能刚好站在一块偏出中心的小石头上。更要命的是,模型很容易在训练集上“死记硬背”(即过拟合),对新数据反而不够稳。

用公式记录一次典型更新,能清楚地看到噪声的来源。损失函数 $L(\theta)$ 衡量当前权重 $\theta$ 在数据上犯的错,训练就是不断朝损失下降的方向迈步:

所以问题清楚了:单次落脚点不可靠。既然每个脚印都“带着噪声在谷底附近散开”,那与其赌最后一步,不如把这一圈脚印都用起来——这正是下一节要讲的核心思路。

θt+1=θt−ηg~t\displaystyle \theta_{t+1} = \theta_t - \eta \tilde{g}_t
这一步的本质是:沿着“小批量梯度估计出的下坡方向”走一小步,但由于估计有噪声,走出的脚印并不精确。
  1. 当前位置$\theta_t$ 表示第 $t$ 步时模型的全部参数,也就是探险队此刻站的位置坐标。
    θt∈Rd\displaystyle \theta_t \in \mathbb{R}^d
  2. 梯度估计$\tilde{g}_t$ 是用一小批数据算出的损失梯度近似值,相当于向导脚下感受到的那一小段地形——真实但局部。
    g~t=1m∑i∈Bt∇θℓ(xi,yi;θt)\displaystyle \tilde{g}_t = \frac{1}{m}\sum_{i \in \mathcal{B}_t}\nabla_\theta \ell(x_i, y_i; \theta_t)
  3. 步幅$\eta$ 是学习率,控制这一步迈多大,$\eta$ 越大步幅越大,后期通常调小以免跨过谷底。
    η>0\displaystyle \eta > 0
  4. 迈出一步$\theta_{t+1}$ 是更新后的权重,沿梯度的反方向(下坡方向)走了一步。
    θt+1\displaystyle \theta_{t+1}

核心原理:多份报告,一个中心

有经验的向导扎营前,绝不会只听一个人报位置。他会在谷底走几圈,拦住东南西北几个方向的探路者,把大家的坐标都记下来,然后在心里估一个“中心点”:单独每份报告都可能偏,但多数报告的中心往往非常接近谷底正中央。SWA 的直觉与此完全一致:不把最后一步权重当答案,而是把训练后期若干个 epoch 的权重快照收集起来求平均,让噪声互相抵消,还原出那个更稳的中心位置。

为什么“平均”能换来更好的泛化?关键在于损失曲面上有两种“低点”。一种是尖锐的极小值:像一根竖立的铅笔尖,恰好站在尖顶上时误差很低,可新数据带来的微小扰动就会让它滑落。另一种是平坦的极小值:像一口宽宽的大铁锅,锅底一片平缓区域误差都不高,站哪都稳。大量研究发现,平坦极小值附近的模型在没见过的新数据上表现更好——泛化能力更强。而随机梯度恰好在训练后期把快照们推到同一个“锅底”的不同位置,平均之后自然落在锅底中央。

这个直觉在数学上有个很漂亮的保证:在凸区域里取平均不会跑出区域。把损失谷底近似看作一个凸的盆地 $C$,那么:

也就是说,哪怕个别快照被噪声推到了盆地边沿,只要多数快照还集中在盆地里,平均出来的点就不会把营地扎到悬崖边。多份报告,一个中心,这就是 SWA 的全部哲学。

θ1+θ22∈C\displaystyle \frac{\theta_1 + \theta_2}{2} \in C
意思是:两个快照连线的中点仍然待在谷底里,不会因为平均而被抛到山腰上。
  1. 盆地集合$C$ 表示损失曲面上的凸盆地,例如谷底一块近似碗状的低洼区域,里面的点损失都较低。
    C⊂Rd\displaystyle C \subset \mathbb{R}^d
  2. 两个快照$\theta_1, \theta_2$ 是 $C$ 内任意两个点,可以理解为两个不同 epoch 保存下来的权重快照。
    θ1,θ2∈C\displaystyle \theta_1, \theta_2 \in C
  3. 中点仍在盆内两点连线的中点仍属于 $C$——凸性保证了“平均不跑出盆地”,这是 SWA 安全性的根基。
    θ1+θ22∈C\displaystyle \frac{\theta_1+\theta_2}{2} \in C

数学公式:平均就是力量

现在我们给“平均”一个精确的数学定义。假设训练后期一共收集了 $T$ 个权重快照 $\theta_1, \theta_2, \dots, \theta_T$,SWA 的最终权重就是它们逐参数取算术平均:

最后一个式子道出了 SWA 的威力所在:单份快照是“带噪声的估计”,方差大;把 $T$ 份平均之后,方差直接缩小到原来的 $T$ 分之一。好比量一座山的高度,一个人量会有偏差,让十个人各自测量再取平均,结果就稳得多。训练时几乎不增加计算量,却拿到了等同于“降低估计方差”的收益——平均就是力量。

θSWA=1T∑i=1Tθi\displaystyle \theta_{SWA} = \frac{1}{T}\sum_{i=1}^{T}\theta_i
这就是 SWA 的唯一核心公式:把 T 个快照的每个参数分别加起来,再除以 T,得到一个新的权重向量。
  1. 快照集合$\theta_i$ 是训练后期第 $i$ 次保存的权重快照,一共 $T$ 个,好比探险队在不同时刻报回来的 $T$ 份位置坐标。
    {θ1,θ2,…,θT}\displaystyle \{ \theta_1, \theta_2, \dots, \theta_T \}
  2. 逐参数求和对所有快照的同一个参数求和,相当于把 T 份坐标的横轴、纵轴分别相加。
    ∑i=1Tθi\displaystyle \sum_{i=1}^{T}\theta_i
  3. 取平均总权重除以 $T$,得到 SWA 的平均权重,落在谷底中心附近。
    θSWA=1T∑i=1Tθi\displaystyle \theta_{SWA} = \frac{1}{T}\sum_{i=1}^{T}\theta_i
  4. 方差缩减若各快照近似独立且同分布,平均后每个参数的方差降为原来的 $1/T$——这正是“噪声互相抵消”的数学体现。
    Var(θSWA)=1T Var(θi)\displaystyle \mathrm{Var}(\theta_{SWA}) = \frac{1}{T}\,\mathrm{Var}(\theta_i)

实现步骤:三步搭好营地

理解了原理,实现其实只有三步,探险队三下五除二就能把营地搭好。第一步叫“阶段划分”:先正常训练,让模型一路下到谷底附近。通常建议训练到总轮数的 75% 之后再启动 SWA,因为前中期模型还在快速赶路,位置彼此相距很远,硬平均只会得到一个悬在半山腰的假中心。

第二步是“快照收集”:从启动轮开始,每隔 $c$ 个 epoch 保存一次当前权重。这里有个省内存的小技巧——不需要真的存 $T$ 份完整权重,而是维护一份“平均权重副本”,每来一个新快照就做一次在线更新。第三步是“收尾替换”:训练结束后,把平均权重副本装回模型,直接用于验证和部署。

在线更新的公式长这样:假设已经平均了 $n$ 个快照,现在来了第 $n+1$ 个快照 $\theta_{n+1}$,则:

实现时还需注意两点:一是快照应使用“模型权重”而不是包含优化器状态;二是如果用了动量(momentum),动量缓冲不需要平均——它只是训练过程的行进速度,不属于营地坐标。

θSWA(n+1)=n θSWA(n)+θn+1n+1\displaystyle \theta_{SWA}^{(n+1)} = \frac{n\,\theta_{SWA}^{(n)} + \theta_{n+1}}{n+1}
这就是“滑动平均更新”:旧平均带着 n 份权重,新快照带着 1 份权重,合在一起除以 n+1,O(1) 完成平均,无需保存所有快照。
  1. 当前平均$\theta_{SWA}^{(n)}$ 表示已经平均完 $n$ 个快照后的累计结果。
    θSWA(n)\displaystyle \theta_{SWA}^{(n)}
  2. 新快照$\theta_{n+1}$ 是刚收集到的第 $n+1$ 个 epoch 权重,是待并入的新鲜报告。
    θn+1\displaystyle \theta_{n+1}
  3. 加权合并旧平均乘以 $n$,加新快照,再除以 $n+1$,完成一次不占内存的在线平均。
    θSWA(n+1)=n θSWA(n)+θn+1n+1\displaystyle \theta_{SWA}^{(n+1)} = \frac{n\,\theta_{SWA}^{(n)} + \theta_{n+1}}{n+1}

BN重设:换了帐篷,要重新测风向

探险队扎好帐篷后,还有一件容易被忽略的小事:要重新测一下营地的风向和水源。为什么?因为之前记录的风向、水流都是在旧地点测得的数据,帐篷一挪位置,这些记录就全作废了。BatchNorm(BN)层也有同样的“娇气”:它在训练中维护着一组运行统计量(running mean 和 running variance),记录的是“当前权重下各层激活值的分布中心”。

当你把 SWA 的平均权重换进模型时,权重变了,各层激活值的分布也跟着变,可 BN 里的 running mean/var 还是旧权重时代的产物——新旧不匹配,验证集上精度不升反降的情况经常就是这么来的。解决办法很直接:把平均权重装回模型后,让模型在训练集(或其子集)上跑一遍完整前向传播,重新统计 BN 的均值和方差。这就像帐篷挪到新位置后,重新测一遍风向,之后的所有判断才靠谱。

BN 统计量本质就是小批量激活的均值与方差,公式如下:

实践上,通常准备一个辅助 DataLoader(可以只取训练集的一个子集,几百到几千个样本即可),在没有梯度的前向模式下跑一遍,让 BN 层重新积累统计量,再进入评估。这一步虽然小,却是 SWA 能否真正生效的分水岭。

μB=1m∑i=1mxi,σB2=1m∑i=1m(xi−μB)2\displaystyle \mu_B = \frac{1}{m}\sum_{i=1}^{m}x_i, \qquad \sigma_B^2 = \frac{1}{m}\sum_{i=1}^{m}(x_i - \mu_B)^2
对每个 mini-batch 计算激活均值与方差,再以滑动平均方式更新全局 running mean/var;SWA 平均权重 + 重算 BN 统计量 = 正确打开方式。
  1. 小批量大小$m$ 是当前 batch 的样本数,决定统计量的估计精度,$m$ 越大估计越稳。
    m=∣B∣\displaystyle m = |\mathcal{B}|
  2. 批均值$\mu_B$ 是该 batch 内激活值的均值,作为归一化时的中心参照。
    μB=1m∑i=1mxi\displaystyle \mu_B = \frac{1}{m}\sum_{i=1}^{m}x_i
  3. 批方差$\sigma_B^2$ 表示激活值围绕均值的离散程度,决定归一化时的缩放幅度。
    σB2=1m∑i=1m(xi−μB)2\displaystyle \sigma_B^2 = \frac{1}{m}\sum_{i=1}^{m}(x_i-\mu_B)^2

调参实践:向导的节奏

一支经验丰富的探险队,节奏感是刻在骨子里的:什么时候急行军,什么时候放慢脚步,何时停下来记录位置,都有讲究。SWA 的调参同样围绕几个关键旋钮:快照周期 $c$、起始轮数 $E_{start}$、以及学习率 $\eta$ 的策略。只要节奏对了,几乎不需要额外调什么,就能稳拿收益。

先说快照周期。$c$ 太小,相邻快照高度相关,平均的“去噪”效果打折;$c$ 太大,又浪费了后期本该收集的多样性。论文与工程经验普遍建议 $c$ 取 2 到 10 个 epoch,既不增加太多训练时间,又能保证快照之间有一定独立性。起始轮数建议放在总训练轮数的 75% 之后,此时学习率已被余弦退火压得很低,模型在谷底附近做精细探索,快照质量最高。

一个常见的搭配是:先用标准的余弦学习率衰减训练到 75%,然后把学习率固定回一个较小的常数(约为初始学习率的 5%),继续跑完剩余轮数并周期性收集快照。这种“降速巡航”让模型在谷底多转几圈,收集到的位置更密集、更贴近中心。快照总数 $N_{snap}$ 的计算很简单:

优化器方面,SWA 与带动量的 SGD 是天然搭档;与 Adam 配合时收益也存在,但稍弱一些,且建议在用 Adam 训练到后期后切换低学习率再收集快照。记住向导的节奏口诀:先下山,再降速巡航,最后平均扎营。

Nsnap=⌊Eend−Estartc⌋+1\displaystyle N_{snap} = \left\lfloor \frac{E_{end} - E_{start}}{c} \right\rfloor + 1
快照数量由“起止轮数之差除以周期再取整加一”得到,一般收集 5 到 30 个快照就能看到明显收益。
  1. 起止轮$E_{start}$ 是开始收集快照的轮次,$E_{end}$ 是训练结束的轮次,两者界定收集窗口。
    Estart, Eend\displaystyle E_{start},\ E_{end}
  2. 快照周期$c$ 表示每隔 $c$ 轮收集一个快照,控制快照之间的间隔与独立性。
    c\displaystyle c
  3. 快照总数窗口长度除以周期后向下取整再加一,得到本次 SWA 收集的快照个数。
    Nsnap=⌊Eend−Estartc⌋+1\displaystyle N_{snap} = \left\lfloor \frac{E_{end} - E_{start}}{c} \right\rfloor + 1

对比拓展:从篝火到GPS

SWA 不是唯一一种“用历史信息优化最终模型”的工具,探险队的历史上有几种不同的定位技术:有人喜欢跟着最近脚印走,有人干脆撒出多支小队分开探路,还有人背上了一台笨重的 GPS。理解 SWA 与它们的关系,你才能真正选对工具。

第一种是 EMA(指数移动平均)。它同样维护一份权重副本,但每步都做平滑:

第二种是深度集成(Deep Ensemble):训练多份独立模型,推理时把所有模型的预测结果取平均。这种方法效果强劲,但推理成本随模型数量成倍上涨;相比之下,SWA 只需一份权重,推理成本与单模型完全相同,几乎白拿泛化增益。第三种是 SWA-Gaussian(SWAG):在平均权重的基础上继续估计权重的协方差,能够输出带不确定性的近似贝叶斯模型,相当于给探险队配了一台 GPS——精度更高,但计算代价也更大。

所以选型建议很清晰:日常训练调优、追求“零成本泛化提升”时,SWA 是最优解;需要应对分布漂移或不确定性估计时,再看 SWAG;追求极致精度且算力充裕时,才考虑深度集成。

---

θEMA←β θEMA+(1−β) θt\displaystyle \theta_{EMA} \leftarrow \beta\,\theta_{EMA} + (1-\beta)\,\theta_t
EMA 给越新的权重越大的权重(指数级衰减),本质是“跟随最新状态但抹平抖动”;SWA 给窗口内每个快照同样的权重,本质是“还原谷底中心”。
  1. 平滑系数$\beta$ 通常取 0.99 或 0.999,决定历史信息保留多少,$\beta$ 越大越平滑。
    β∈[0,1)\displaystyle \beta \in [0,1)
  2. 滑动更新每步把 EMA 副本向当前权重 $\theta_t$ 移动一小段,像用最细的笔迹追踪队伍轨迹。
    θEMA←β θEMA+(1−β) θt\displaystyle \theta_{EMA} \leftarrow \beta\,\theta_{EMA} + (1-\beta)\,\theta_t
  3. 与 SWA 的差别EMA 指数加权、实时更新,擅长训练过程中的稳定输出;SWA 等权平均、后期结算,更贴近最终泛化中心。
    θSWA=1T∑i=1Tθi\displaystyle \theta_{SWA} = \frac{1}{T}\sum_{i=1}^{T}\theta_i

AI 应用场景

医疗影像分割模型的稳定交付

阶段:模型训练调优与收敛阶段

解决的问题:医疗分割模型对权重非常敏感,训练后单点权重在验证集上 Dice 分数忽高忽低,传统做法靠反复训练多次挑最好模型,既费算力又难复现。

具体案例:某影像组微调 UNet 分割肺结节,训练最后 20 轮用 SWA(每 5 轮存一个快照)做权重平均,再重算 BN 统计量,验证集 Dice 提升约 1.2%,三次重复训练的分数方差明显收窄,交付模型更可信。

推荐系统 CTR 模型快速迭代

阶段:增量训练后的模型收敛与上线评估

解决的问题:线上 CTR 模型每天重训,最后一个 epoch 权重的质量不稳定,导致小流量实验 AUC 波动偏大,难以判断策略真伪。

具体案例:算法团队在每日增量训练最后 6 个 epoch 上应用 SWA,推理服务零改动,AUC 波动从 ±0.04% 收窄到 ±0.015%,实验结论更快收敛,模型回滚率显著下降。

大模型微调的防过拟合收尾

阶段:预训练模型下游微调的后处理

解决的问题:LLM 在小数据集上微调时,最后几步容易过拟合训练集,直接保存最后权重泛化差,且对随机种子敏感。

具体案例:对 LoRA 微调后的低秩增量权重在最后 10 个 epoch 收集 3 个快照做平均(LoRA 权重可逐参数直接平均),下游任务 F1 提升约 0.8%,换随机种子重跑的稳定性也明显改善。

Python 演示

python72 行
import mathimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import DataLoader, TensorDataset torch.manual_seed(7)N = 1600X = torch.randn(N, 8)w_true = torch.randn(8, 1) * 0.5y = X @ w_true + torch.sin(X[:, :1]) * 2.0 + torch.randn(N, 1) * 0.2loader = DataLoader(TensorDataset(X, y), batch_size=64, shuffle=True)  class MLP(nn.Module):    def __init__(self):        super().__init__()        self.net = nn.Sequential(            nn.Linear(8, 32), nn.ReLU(),            nn.Linear(32, 32), nn.ReLU(),            nn.Linear(32, 1),        )     def forward(self, x):        return self.net(x)  model = MLP()swa_model = MLP()optimizer = optim.SGD(model.parameters(), lr=0.05, momentum=0.9)loss_fn = nn.MSELoss() SWA_START = 30   # 第 30 轮开始收集快照SWA_PERIOD = 5   # 每 5 轮收集一个快照TOTAL_EPOCHS = 40num_averaged = 0  def collect_snapshot():    global num_averaged    if num_averaged == 0:        swa_model.load_state_dict(model.state_dict())    else:        for swa_p, p in zip(swa_model.parameters(), model.parameters()):            swa_p.data.mul_(num_averaged).add_(p.data).div_(num_averaged + 1)    num_averaged += 1  for epoch in range(1, TOTAL_EPOCHS + 1):    model.train()    for xb, yb in loader:        optimizer.zero_grad()        loss = loss_fn(model(xb), yb)        loss.backward()        optimizer.step()    if SWA_START <= epoch <= TOTAL_EPOCHS and (epoch - SWA_START) % SWA_PERIOD == 0:        collect_snapshot() last_model = MLP()last_model.load_state_dict(model.state_dict())  # 保存最后一步权重  def rmse(m):    m.eval()    with torch.no_grad():        return math.sqrt(loss_fn(m(X), y).item())  model.load_state_dict(swa_model.state_dict())print("最后一步权重 RMSE: %.4f" % rmse(last_model))print("SWA 平均权重 RMSE: %.4f" % rmse(model))print("共收集快照数:", num_averaged)
目的:用合成回归数据训练一个两层 MLP,在训练后期按周期收集权重快照做在线平均,最后对比“最后一步权重”与“SWA 平均权重”的 RMSE,直观看到 SWA 的泛化收益。
  1. swa_model = MLP()准备一份专门存平均结果的副本模型,只负责“记账”,不参与训练。
  2. optimizer = optim.SGD(model.parameters(), lr=0.05, momentum=0.9)用带动量的 SGD 训练,这是 SWA 论文默认推荐的搭配。
  3. swa_p.data.mul_(num_averaged).add_(p.data).div_(num_averaged + 1)在线平均:新平均 =(旧平均×n + 新快照)÷(n+1),O(1) 完成且不占额外显存。
  4. if SWA_START <= epoch <= TOTAL_EPOCHS and (epoch - SWA_START) % SWA_PERIOD == 0:训练后期按固定周期触发快照收集。
  5. last_model.load_state_dict(model.state_dict())记录最后一个 epoch 的权重作为对照组,用于公平比较。
  6. model.load_state_dict(swa_model.state_dict())把平均权重装回模型,之后直接评估,无需重训。

常见误区

误区SWA 不也是维护一份权重的平均副本、边训练边更新吗?跟 EMA 不就是换了个名字,用哪个都一样。

正解两者都在时间方向上平滑权重,但哲学完全不同。EMA 用指数衰减系数给越新的快照越高的权重,目的是“追踪最新状态并抹平抖动”;SWA 给窗口内每个快照相同的权重,目的是“还原谷底中心”。比喻来说,EMA 像只认最近几串脚印的追踪者,而 SWA 像综合所有探路报告、要找到谷底正中心的领队。

为何常见:两者都只需维护一份模型副本,代码形态几乎一样,初学者很容易把“都叫平均”当成“效果等价”。

误区训练是越走越好的,那么最后一次更新得到的权重理应最接近最优解,平均旧权重只会拖后腿。

正解训练后期学习率虽小但梯度估计仍有噪声,最后一步踩的位置只是“低损失区域里随机的一点”,可能刚好偏到盆地边沿。多份快照平均能降低方差(方差缩至 1/T),验证集误差通常更低、更平滑。就像最后到达的向导站的位置可能最靠崖边,多份报告平均出来的营地才在谷底正中央。

为何常见:人们习惯相信“最新信息最有价值”,而且两者差距往往只有零点几个百分点,容易让人误以为平均毫无意义。

误区权重平均完直接 load 进模型去验证就行,BN 层是训练时自动更新的,不用额外处理。

正解BN 的 running mean/var 是从旧权重的前向中积累出来的,SWA 换上去的平均权重会改变激活分布,旧统计量随之失效。必须把平均权重装回模型,在训练集(或子集)上以无梯度模式跑一遍前向,重算 BN 统计量后再验证,否则精度可能不升反降。

为何常见:很多人只知道 BN 在训练时会“自动记录统计量”,却忽略了统计量是绑定在具体权重之上的。

误区既然平均能降噪,那从第一轮就开始平均,快照又多又稳,效果应该最好。

正解训练前中期模型还在快速下山,权重彼此相距很远,平均这些“赶路中的位置”只会得到一个悬在半山腰的假中心。通常建议训练到 75% 之后、学习率已经压得很低时再开始收集,此时快照都聚集在谷底附近,平均才有意义。

为何常见:直觉上“多几个样本平均更准”,但忽略了 SWA 的前提是快照必须来自同一个平坦盆地。

误区论文里 SWA 动不动就提升一两个点,我随便套到任何任务上应该也能大涨。

正解SWA 的收益来自“随机梯度噪声 + 平坦损失区域”的配合。如果任务本身噪声很小、损失曲面很剧烈,或者模型对权重极度敏感,收益就有限;一般提升 0.5%~2% 是常态,且小数据集上更容易看到效果。

为何常见:论文通常挑选了对 SWA 友好的实验条件来展示,读者看惯了亮眼数字,容易忽略背后的适用条件。

面试题

Q1. 关于 SWA 的核心操作,下列哪一项描述最准确?

单选题 · easy

  • A.把最后一轮权重做指数平滑
  • B.对训练后期多个快照权重取平均← 正确答案
  • C.把训练集数据分批求平均
  • D.对验证集多个模型输出取平均

答案:B。SWA 的关键动作是收集训练后期多个 epoch 的权重快照并逐参数平均(B)。A 描述的是 EMA,C 是数据层面的操作,D 是模型集成。好比把多份位置报告平均出一个中心营地,而不是只信最后一份。

Q2. SWA 通常在训练进程的哪个阶段开始收集权重快照?

单选题 · easy

  • A.训练刚开始前几步
  • B.训练结束之后才启动
  • C.学习率还没衰减时
  • D.训练后期接近收敛时← 正确答案

答案:D。SWA 应在训练后期、模型已接近收敛时启动收集(D)。早期模型还在下山,快照相距远,平均没有意义;训练结束后才启动则收集不到任何快照。这对应探险队“先下山,再记录位置”的节奏。

Q3. 为什么平均后期权重能提升泛化能力?

单选题 · mid

  • A.平均后的参数数量一定变少
  • B.噪声互相抵消接近平坦谷底中心← 正确答案
  • C.平均使模型层数变深结构变宽
  • D.平均直接改变损失函数的形状

答案:B。随机梯度噪声把各快照推到谷底附近不同方向,平均后噪声互相抵消,权重更接近平坦极小值的中心(B),而平坦极小值在数据扰动下更稳。参数数量、层数和损失函数形状都不因平均而改变,A/C/D 均为干扰项。

Q4. 对使用 BatchNorm 的模型,加载 SWA 平均权重后必须做的一步是?

单选题 · mid

  • A.显式清空 BN 的动量参数
  • B.冻结全部 BN 层不参与推理
  • C.把 BN 换成 LayerNorm
  • D.重算 BN 的 running mean/var← 正确答案

答案:D。平均权重改变了激活分布,旧 BN 统计量失效,需要在训练集子集上重算 running mean/var(D)。清空动量和换层都不解决统计量错位问题,冻结 BN 反而会让推理更不稳定。

Q5. SWA 与 EMA 的主要区别在于?

单选题 · mid

  • A.SWA 等权平均快照,EMA 指数加权当前权重← 正确答案
  • B.EMA 等权平均快照,SWA 指数加权当前权重
  • C.SWA 只作用于卷积层,EMA 只作用于全连接层
  • D.SWA 用在测试时,EMA 用在训练时

答案:A。SWA 给窗口内每个快照相同的权重,目标是还原谷底中心;EMA 用指数衰减给新权重更高权重,目标是平滑追踪最新状态(A)。二者都可在训练中维护副本,但加权方式与目的不同。

Q6. 若独立收集 T 个快照进行 SWA,权重方差的缩减约为?

单选题 · hard

  • A.方差保持不变几乎不变
  • B.方差扩大到原来的 T 倍
  • C.方差减小为原来的 T 分之一← 正确答案
  • D.方差减小为原来的 T 平方分之一

答案:C。在快照近似独立同分布的假设下,平均 T 个随机向量的方差降为原来的 1/T(C)。这正是 SWA 降噪能力的数学根源——十份独立报告平均,误差显著小于任何单份。

Q7. 关于 SWA 调参,通常推荐的做法是?

单选题 · hard

  • A.从第一轮就开始收集所有轮次权重
  • B.学习率全程保持初始最大值
  • C.快照周期越大越好无需上限
  • D.训练后 75% 阶段用低学习率收集快照← 正确答案

答案:D。推荐在训练 75% 之后把学习率降到一个较小的常数(或沿用余弦退火末段),再周期性收集快照(D)。早期启动、全程大学习率、周期过大都会让快照偏离谷底,削弱平均效果。

Q8. 下列哪些做法属于 SWA 的合理环节?

多选题 · easy

  • A.维护一份平均权重的副本模型← 正确答案
  • B.在训练后期周期性保存权重快照← 正确答案
  • C.用整个训练集搜索最优学习率
  • D.必要时重算 BatchNorm 统计量← 正确答案

答案:ABD。SWA 需要副本模型(A)、周期性快照(B),若模型含 BN 还要重算统计量(D)。C 是学习率搜索,与 SWA 流程无关。爬山队需要有记账员、有节奏地记录位置,并重新测风向,但不需要重新规划整趟路线。

Q9. SWA 与深度集成(Deep Ensemble)相比,正确的说法是?

多选题 · mid

  • A.两者都能提升稳健性与泛化← 正确答案
  • B.SWA 推理成本与单模型相同← 正确答案
  • C.集成需要多个模型并行推理← 正确答案
  • D.SWA 需要多个模型并行存储

答案:ABC。SWA 和深度集成都能提升稳健性与泛化(A);SWA 只有一份平均权重,推理成本与单模型相同(B);集成要同时跑多个模型(C)。SWA 并不需要存储或运行多个模型,D 错误。

Q10. 在哪些场景下 SWA 能带来明显收益?

多选题 · mid

  • A.梯度下降存在较大随机噪声← 正确答案
  • B.损失曲面存在大片平坦区域← 正确答案
  • C.需要稳定复现泛化性能的交付← 正确答案
  • D.每个 batch 都使用全量数据训练

答案:ABC。SWA 受益于梯度噪声(A)与平坦极小值(B),也适合对稳定性要求高的交付场景(C)。D 是全批量梯度下降,几乎没有噪声,SWA 的降噪收益自然无从谈起。