问题简要描述:
pytorch 中 model train 模式和eval 模式效果差异比较大,问题排查。没有使用到dropout 这个也是一个点
问题详细描述
bn的讲解
批量内某个通道进运算 X = gamma(X-mean)/var + beta
torch 中gamma 用weight 表示,beta 用bias表示,这个没有什么问题。 weight 和bias是可以训练的
训练时候的mean val的计算
训练的时候是计算当前batch 的mean, 比如当前(16, 20, 256, 256)那就是16张256x256的feature map的mean和val
eval时候的mean val
mean 和val 是训练中获得的, 不是由当前batch 计算的,也就是说,无论当前的batch 是 16, 20, 30 这里的mean和val都不会变
eval 中的mean 和val 是怎么从训练中得到的呢?
bn 参数
nn.BatchNorm2d(171, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
假设
- train总共 10次迭代,我们选择20个channel 中的第0个channel 来测试
- m*, v* 表示当前batch 计算到的均值和方差
- mean*,val* 表示如果当前停止训练,用于eval的均值和方差
训练步骤
iter | current mean | current val | running mean | running val |
---|---|---|---|---|
初始化 | 0 | 1 | ||
第1次训练 | m1 | v1 | 0*0.9 + 0.1 *m1=mean 1 | 1* 0.9 + 0.1* v1 = val1 |
第2次训练 | m2 | v2 | mean1*0.9 + 0.1 *m2=mean 2 | val1* 0.9 + 0.1* v2 = val2 |
第3次训练 | m3 | v3 | mean2*0.9 + 0.1 *m3=mean 3 | val2* 0.9 + 0.1* v3 = val3 |
tain 和eval 不同的原因
- error: bn 混用,实例化了一个bn,在不同的层之间使用训练的时候没问题; 测试的时候,running mean running val 只存了一组,所以产生了问题
- error:momentum = 0, 训练的时候不更新,始终是初始化的东西,所以精度也会不高
- right: bn 默认设置,一张照片的数据集,进行train 和eval 效果也不同,
训练的时候使用的是这一张照片的均值,测试的时候使用的这一张照片的均值的动量法,初始值是0,经过很多很多次训练才是一张照片的均值, 这个是哈eval和trian 才相同,为了加快测试速度可以将动量从0.1 调为0.9