LESSON 14 · 阶段 D · 训练进阶 · LEARN NOTES

收进学习手册 · 2026-09-11 · duck.whatled.com

第 14 课 · 单变量 A/B 实验:像科学家一样调参

这一课解决什么问题:改了参数,结果变好变坏怎么判断?这一课教你强化学习版实验方法:一次只改一个变量、先预注册假设、跑 A/B 对照、写下有边界的结论——全程用本仓库 2026-09-06 的真实实验 exp001 演示。

前置:第 13 课 与 第 06 课。


1. 为什么一次只改一个变量

同时改脚高目标、速度上限和学习率,结果变好了——功劳算谁的?变坏了——锅算谁的?都不知道。这和种花一样:同时换土又换肥料,花开得再好你也学不到经验。强化学习训练一次成本不低(哪怕 exp001 那种小实验也要几分钟),让每次训练只回答一个问题,是最省钱的用法。

所以呢?"只改一处"不是风格偏好,而是让每一次训练都能产出可用结论的前提。

2. 第 0 步:预注册假设

预注册 = 在跑实验之前,把预期白纸黑字写下来。指南第 7.1 节给了一个真实例子,当时鸭子只会贴地碎步:

现象:air_time_mean 长期约 0.04 s,air_time 奖励近零。
假设:0.125 s 的奖励门槛太高,策略从未收到抬脚正反馈。
只改:threshold_min 0.125 → 0.04。
不改:速度范围、脚高目标、PPO、域随机化、随机种子。

先写预期的最大好处是防"事后诸葛":结果出来后,人总能给任何结果找到解释;而预注册的假设若被推翻,那才是真正学到了东西。

3. 真实案例:exp001,8 分钟跑完的 A/B

构建日志 2026-09-06 条目记录了一次教科书式的小实验:

所以呢?小实验跑得便宜,预注册让你赢得体面:结论早就写好了,数据只是来对答案的。

4. 结论要有边界:随机化的收益怎么看

B 组 reward 领先,能说"随机化没用"吗?不能。随后的扰动测试 exp001b(用 rl-series/scripts/eval_imu_robustness.py 扫全角度区间)显示:A 组更平稳,最大衰减 -4.6% vs B 的 -6.0%,10° 起 A 反超——但 1–2% 的差异在单个随机种子的噪声内,100 迭代尺度下的诚实结论是"不可测",留待长训练后复测。连回放里 A 摔 1 次、B 摔 4 次这种"肉眼证据",日志也标注了"属噪声,别过度解读"。

所以呢?exp001 的完整结论是:短期动力学差异可见(B 前期学得快);随机化的鲁棒性收益,要用扰动测试在更长训练上看。结论不带边界,就是谣言的开始。

5. 每个实验必须记录什么

指南 7.2 节的清单,docs/microduck-30day/README.md 的记录原则与之同源:

[ ] git commit 与 diff(改了哪几行)
[ ] task ID、环境数、迭代数、随机种子
[ ] 唯一变量是什么
[ ] A/B 两组的 checkpoint 与 run 目录
[ ] 同一组命令下的回放
[ ] 结论、是否回滚、下一步

docs/microduck-30day/experiments/experiment-log.csv 的每一行(lesson-01、expD、expE)就是按这个精神记的。另有一个很容易踩的坑(指南 7.3 节):检查日志里每个惩罚项的贡献是否始终 ≤ 0——惩罚函数符号配错权重,训练会静默地朝反方向走。

动手练习(20 分钟)

仿照第 2 节的格式,为"把 foot_swing_height.target_height 从 0.02 m 提到 0.03 m"写一份预注册:现象、假设、只改什么、不改什么、预期哪个指标动。写完先别跑,下一课正好要用。

自查清单

下一课预告

为什么"世界更乖"的 B 组反而可能是坑?第 15 课讲 sim2real 与域随机化:仿真和现实差在哪、怎么故意把仿真做"糙"、以及 expD 那次"指标变好但步态没成"的教训。

延伸资源

什么鸭 WHATDUCK · 复刻学习笔记 ← 全部手册 · 首页