前言
在前面两篇文章之中,我们大致介绍了有序损坏实验在跨域的强力效应,并且初步地制定了一些门槛用来筛选是否保留顺序差异。
可能读者心里早就有这样一个问题了:那拿数据集训练又不是每张图训练一次够了,我所说的顺序差异可能早就埋没在大量训练次数的大量退化中了,研究这个对实际训练真的有帮助吗?
对于这个疑问,我持保留意见。这次试验,我回答这个问题:如果这种影响不可避免的话,是否可以设置一种操作使模型输出一致从而消除顺序影响?
Baseline草稿
先初步定下四组对照:
| 组 | 训练时看到什么 | 这个组回答的问题 |
|---|---|---|
| T0 | 干净单视图 | 普通干净训练的参考水平 |
| T1 | 一种损坏顺序 | 单方向退化训练本身有什么影响 |
| T2 | AB 和 BA 两种视图 | 成对增加数据后会怎样 |
| T3 | 与 T2 相同的视图,再加一致性损失 | 在相同数据上,额外要求两个输出一致是否有帮助 |
训练配置:VOC2007 trainval 上训练 yolo11n,三个种子(20260811 / 20260812 / 20260813),每组 30 epoch。训练完观察T3-T2的差值能看到设置的一次性操作是否生效,T2-T1则能大致看到见过全顺序的模型是否能消除顺序影响。
实验设计
对于T1T2的比较问题,很容易实现,照常训练就行。对于T3的一致性输出的额外要求,则需要再设计。
类别比较——JS散度
众所周知,YOLO架构将最后的类别检测转化为了一个概率分布预测问题。那么,使用JS散度就很适合T3的设计。
框比较——smooth-L1
L1:
smooth-L1:
将二者以正则化的方式加到损失函数的尾部,参与损失函数的计算,并且将二者乘以权重:
sg表示冻结梯度,c是置信度。冻结梯度是为了避免模型在学习过程中为了降损失而降低置信度。(没接触过这些的我会在文末介绍)
同时更新复合门槛:
| 门槛 | 要求 |
|---|---|
| 平均 corrupted AP50-95 增益 | ≥+0.005 |
| 95% bootstrap 下界 | > 0 |
| 正种子数 | ≥ 2 / 3 |
| clean AP 非回归 | 不低于-0.002 |
| 最差主 cell 非回归 | 不低于-0.002 |
| 配对推理延迟 | 落在预设范围内 |
最终跑出来的结果,主估计量是T3−T2 的种子均值AP50-95:
| 种子 | 退化图上差值 [95% CI] | 干净图上差值 | 最差差值 |
|---|---|---|---|
| 20260811 | −0.00017 [−0.00393, +0.00359] | +0.00114 | −0.00167 |
| 20260812 | −0.00565 [−0.00952, −0.00196] | −0.00820 | −0.00937 |
| 20260813 | +0.01010 [+0.00625, +0.01456] | +0.01257 | +0.00674 |
| 均值 | +0.00143 | +0.00184 | −0.00937 |
可以看到后两者都没有过制定的门槛,也就是说一致性正则失败了,收益很小。那么,是不是因为有序影响本就在训练中削弱,本身上限就不高导致的收益不大呢?
| treatment | seed 20260811 | seed 20260812 | seed 20260813 |
|---|---|---|---|
| T0(干净) | 0.191 | 0.193 | 0.198 |
| T1(单方向损坏) | 0.138 | 0.136 | 0.137 |
| T2(成对双向) | 0.090 | 0.087 | 0.082 |
| T3(成对 + 正则) | 0.091 | 0.078 | 0.095 |
由此可见,顺序影响并没有消失在正则化制定的策略下,从这个角度证明顺序影响的力量比我们想象的更加深沉,需要另辟蹊径。
局限性
有一说一,不知道各位注意到T2相对于T1接近腰斩的数值没有。这解释了本项实验的一个最大漏洞:损坏图过于多,占比甚至反超了干净图,喧宾夺主了。因此,本项实验只能作为一个参考建议。
【附】JS散度与smooth-L1
A.1
普通监督学习是:
图片 + 标签 → 模型 → 预测 → 和标签比 → 算损失 → 更新参数但很多场景没有标签,或者标签很少。这时还有一个可利用的假设:
同一张图,稍微扰动一下,模型的输出不应该发生剧烈变化。
比如同一张猫图:
- 原图 → 模型说“猫”;
- 加一点噪声 → 模型还应该说“猫”;
- 换个亮度 → 模型还应该说“猫”。
如果模型对“猫图 + 噪声”突然说“狗”,说明它的表示不稳定。一致性正则就是把这个“不应该变”的直觉写成损失函数。
通用形式:
:有标签时的常规损失;
:无标签时,比较两个扰动视图的输出;
:控制一致性约束的强度。
它不需要新标签,只需要同一输入的两个版本。
A.2
| 方法 | 两个视图怎么来 |
|---|---|
| Π-model | 同一张图做两次随机增强 |
| Mean Teacher | 学生网络看增强图,教师网络看另一版本 |
| FixMatch | 弱增强 + 强增强 |
| V7-B / V7-C | 同一张图,交换退化处理顺序(AB / BA) |
前三个是半监督学习的标准做法;V7 只是把“扰动”换成了“处理顺序”。
A.3
模型对一张图输出类别概率,比如:
视图 AB:猫 0.9,狗 0.1 视图 BA:猫 0.8,狗 0.2这两个分布很接近。要衡量“接近程度”,先看 KL 散度:
KL 有两个问题:
- 不对称:
;
- 会爆:如果 P_c>0 而 Q_c=0,直接无穷大。
JS 散度先取两个分布的中间点:
再分别算两边到 M 的 KL,取平均:
性质:
- 对称:
;
- 有界:自然对数下,范围是
;
- 完全一样时为 0。
数值例子 1:两个分布很接近。
数值例子 2:两个分布完全相反。
接近上界。
所以 JS 就是一个“两个概率分布差多远”的分数:0 表示完全一致,越大越不一致。训练时把它当损失最小化,就是逼两个视图的类别预测靠近。
A.4
类别是概率分布,框是四个连续坐标。框不能也用 JS,因为框不是概率分布。
直接用 L2:
问题是 L2 对大误差惩罚太重。一个离群框会产生巨大损失,把训练带偏。
L1:
L1 对离群值更稳,但在 0 附近不可导,训练不够平滑。
smooth-L1 是两者的折中:
- 误差小:像 L2,平滑;
- 误差大:像 L1,不被离群值拖走;
是切换点,代码里取
。
数值感受一下():
| 误差 x | L2 | L1 | smooth-L1 |
|---|---|---|---|
| 0.05 | 0.0025 | 0.05 | 0.011 |
| 0.50 | 0.25 | 0.50 | 0.444 |
A.5
检测输出是密集的:特征图上每个位置都有预测,但大部分位置是背景。
如果对所有位置一视同仁,背景位置会稀释前景的约束。所以 V7 乘了一个权重:
:该位置的平均 sigmoid 置信度;
- 置信度高 → 更像前景 → 权重大;
- 置信度低 → 更像背景 → 权重小;
,停止梯度。
为什么要停止梯度?如果不停止,模型会发现一条捷径:
把置信度整体压低 ↓ 权重 w 变小 ↓ 一致性损失变小这样一致性损失确实下降了,但不是因为两个视图变一致,而是因为模型把权重关掉了。stop-gradient 让 w 只作为“选择位置”的系数,不参与梯度,堵住这条捷径。
A.6
一致性损失和检测损失的数值尺度可能差很多。直接相加会有两种风险:
- 一致性损失太大 → 模型只顾“拉一致”,忘了检测;
- 一致性损失太小 → 正则几乎不起作用。
所以加一个校准系数 c:
c 在正式训练前用一小批数据估计:
假设初始时:
那么:
一致性项变成:
占检测损失 2 的 25%。这就是“初始占比不超过 25%”的含义:先让模型学会检测,再逐渐受一致性约束。
A.7
V7-B 的 T3:
类别项对所有位置取平均;只有框项乘权重。
V7-C 的 T4:
类别项也乘权重,让前景位置主导。
A.8
核心不是公式写错,而是目标错位:
- 一致性损失只要求“两个视图接近”,不要求“接近正确答案”;
- 两个坏视图可以一起变差来满足一致性;
- 训练集里损坏视图占比太高,clean AP 从约 0.19 掉到约 0.09。
一句话:
一致性正则是“让两个输出别差太远”,不是“让输出变对”。