让 AI 记一笔 BatchNorm:这批方差是五,存下来的为何不是五
学习BatchNorm时,可以让AI做一张“本次计算”和“留给以后”的双栏账。两栏都写方差,却不一定使用同一个数;如果只抄一条标准化公式,切换评估模式后的结果就很难解释。
AI模型生成的概念插图:当前一批观测与保留统计的容器分开放置;不代表软件截图、真实实验或精确数据图。
先约定只有一个特征通道
输入是四条样本组成的一列[2,4,6,8],形状为4×1。使用PyTorch BatchNorm1d的定义,训练模式,eps=1e-5,gamma=1、beta=0,track_running_stats=True;初始运行均值为0、运行方差为1,momentum=0.1。这些值全部明示,避免AI自行补另一套初始化。
四个数的均值是5,离均差平方和为9+1+1+9=20。训练这一次前向计算采用除以4的方差,得到5。归一化输出依次约为[-1.341639445,-0.447213148,0.447213148,1.341639445]。这里的eps加在根号里面。
更新账本时,方差分母换成三
PyTorch官方文档明确区分:训练前向使用biased方差,而进入运行方差更新的本批估计使用unbiased方差。因此这批用于更新的值是20/(4-1)=20/3,不能直接把前一栏的5抄过去。
这套momentum约定是“新运行值=0.9×旧值+0.1×本批值”。所以运行均值变成0.5,运行方差变成0.9×1+0.1×(20/3)=47/30,约1.566666667。它也不是把新批保留九成;不同领域对momentum的命名习惯不能代替这里的明确公式。
现在立刻进入评估模式,输入单个数5。使用刚存下的统计量,得到(5-0.5)/√(47/30+1e-5),约3.595198105。虽然5恰好是刚才那批的均值,输出仍然不是0,因为运行均值只更新到了0.5。这个明显的差异正好用来检查AI有没有偷偷改回本批统计量。
给AI的交付物是状态表
可用提示词:“为一个BatchNorm1d通道建立训练前、训练后、评估时三行状态表。输入[2,4,6,8],初始running_mean=0、running_var=1,momentum=0.1,eps=1e-5,gamma=1、beta=0。分别写训练方差和更新运行方差所用估计,最后算评估输入5。解释哪些数来自当前批,哪些数来自保存状态。”
验收时让它做一项故意错误的对照:如果把5用于运行方差更新,会得到1.4,与47/30不符。这个差异来自分母,不是小数舍入误差。再检查运行均值确实是0.5,而非5或4.5。
本例只训练一批,运行统计尚未充分积累,不能据此比较模型效果。若track_running_stats=False,评估阶段仍使用批统计量,前面的评估推导就不适用;训练中每通道只有一个有效值也不能照搬四样本算例。复现时还要保留轴、模式和初始化记录,不能只保存最终四个输出。
资料核对日期:2026年10月2日。数值为原创教学设定,已用独立Python计算复核,不代表真实模型性能测试。


