负面结果也是一份结果
我做了一个模块,实验前我认为它会让模型更准,实验后它把准确率从 77.23% 拉到了 56.78%。
背景
基线模型在一个图像分类任务上稳定在 77.23%,这个数字我们先固定了下来,作为对照。然后我设计了一个新的注意力路由模块,思路是让模型对不同尺度特征动态分配权重——这是论文里常见的做法,看起来很有道理。
按规矩,动手之前我们把判定标准写下来了:在同一套数据划分、同一个评估协议下,如果新模块不能带来稳定提升,就判定为失败,不做任何事后调整。 这个"预先写下来"的动作,当时的我其实并不太情愿,觉得有点形式主义。
结果
| 配置 | 最好准确率 | 说明 |
|---|---|---|
| 基线 | 77.23% | 稳定收敛 |
| 新模块(第一版) | 56.78% | 训练在第 61 个 epoch 崩坏 |
| 新模块(改进版) | 更低 | 第 34 个 epoch 就崩了 |
第二版改得更激进,崩得也更早。到这里,方向的问题已经很清楚了。
诊断
挖下去发现是路由权重塌缩:训练早期,模块就把绝大部分权重集中到了极少数通道上,剩下的通道基本不再更新。表现出来就是——网络还在跑,loss 也在降,但模型实际上已经放弃了大部分特征。所谓"动态分配权重",退化成了"只用一个通道"。
这个问题不是学习率或者初始化能解决的,它是设计上的:我给路由加了一个会自我强化的归一化方式,一旦某个通道稍微占优,就会被放大成绝对优势。
为什么我把这次失败完整记录了下来
因为它在几件事上比一次成功更有价值:
- 它证明了评估协议是有用的。 如果事先没写下判定标准,"56.78%" 这个数字很容易被解释成"超参数没调好""再训久一点就好了",然后无限期地拖下去。
- 它给出了一个可复用的诊断路径。 "路由权重塌缩"这个现象,以及定位它用的方法(看权重分布随训练的变化,而不是只看 loss),后来我对别的模型也用过。
- 它让后面的人少走弯路。 我把失败的配置、崩坏发生的 epoch、以及为什么第二版更早崩的原因,都写进了实验记录。
我现在怎么做实验
- 判定标准写在实验开始之前,写在一个不想改就不方便改的地方
- 失败实验和成功实验用同一套记录格式,不写"试了不行"这种话
- 结论只写实验能支撑的部分,"看起来有效但没验证"一律标注为未验证
做研究最容易骗的是自己。把标准提前写死,是成本最低的一种防止自欺的办法。