Skip to content

负面结果也是一份结果

我做了一个模块,实验前我认为它会让模型更准,实验后它把准确率从 77.23% 拉到了 56.78%。

背景

基线模型在一个图像分类任务上稳定在 77.23%,这个数字我们先固定了下来,作为对照。然后我设计了一个新的注意力路由模块,思路是让模型对不同尺度特征动态分配权重——这是论文里常见的做法,看起来很有道理。

按规矩,动手之前我们把判定标准写下来了:在同一套数据划分、同一个评估协议下,如果新模块不能带来稳定提升,就判定为失败,不做任何事后调整。 这个"预先写下来"的动作,当时的我其实并不太情愿,觉得有点形式主义。

结果

配置最好准确率说明
基线77.23%稳定收敛
新模块(第一版)56.78%训练在第 61 个 epoch 崩坏
新模块(改进版)更低第 34 个 epoch 就崩了

第二版改得更激进,崩得也更早。到这里,方向的问题已经很清楚了。

诊断

挖下去发现是路由权重塌缩:训练早期,模块就把绝大部分权重集中到了极少数通道上,剩下的通道基本不再更新。表现出来就是——网络还在跑,loss 也在降,但模型实际上已经放弃了大部分特征。所谓"动态分配权重",退化成了"只用一个通道"。

这个问题不是学习率或者初始化能解决的,它是设计上的:我给路由加了一个会自我强化的归一化方式,一旦某个通道稍微占优,就会被放大成绝对优势。

为什么我把这次失败完整记录了下来

因为它在几件事上比一次成功更有价值:

  1. 它证明了评估协议是有用的。 如果事先没写下判定标准,"56.78%" 这个数字很容易被解释成"超参数没调好""再训久一点就好了",然后无限期地拖下去。
  2. 它给出了一个可复用的诊断路径。 "路由权重塌缩"这个现象,以及定位它用的方法(看权重分布随训练的变化,而不是只看 loss),后来我对别的模型也用过。
  3. 它让后面的人少走弯路。 我把失败的配置、崩坏发生的 epoch、以及为什么第二版更早崩的原因,都写进了实验记录。

我现在怎么做实验

  • 判定标准写在实验开始之前,写在一个不想改就不方便改的地方
  • 失败实验和成功实验用同一套记录格式,不写"试了不行"这种话
  • 结论只写实验能支撑的部分,"看起来有效但没验证"一律标注为未验证

做研究最容易骗的是自己。把标准提前写死,是成本最低的一种防止自欺的办法。

由 VitePress 构建 · 部署于 Cloudflare Pages 与 GitHub Pages

热爱 DeepSeek V4.1 Flash · 快、省、够用,一个人也能把整条流水线跑完