Jermmy / pytorch-quantization-demo

A simple network quantization demo using pytorch from scratch.
Apache License 2.0
481 stars 94 forks source link

遇到一个神奇的 Bug #4

Closed qiulinzhang closed 10 months ago

qiulinzhang commented 3 years ago

在 quantization_aware_training.py 88行,full_inference(model, test_loader),将这一句复制一遍,即这一句跑两次,会发现量化后掉点10%,这一步就是执行了推理操作,但是没有改变参数,调试了一上午,也没有发现问题在哪。带BN的网络有问题,不带BN的网络是正常的,但是经过参数比对,这两部操作后,BN的参数也没有发生变化

Jermmy commented 3 years ago

我也复现出来了,费解。。

Usigned commented 3 years ago

推理时会更新每一层的qi qw qo参数吧

Jermmy commented 3 years ago

推理时会更新每一层的qi qw qo参数吧

不会的,量化参数在量化训练后就确定了。

innovatedmonster commented 10 months ago

个人感觉:我感觉是因为quantize_aware_training时更新了model.bn1和bn2的参数,然后第二次执行full_inference时使用的是model.bn1和model.bn2,这就相当于在第二次full_inference时使用bn层参数不是那个训练好的参数,而是训练好->被打乱后的参数。

现象:以下所指的model是NetBN类的,我刚才把model.bn1.weight都打印出来,第一个full_inference执行后的model.bn1.weight和在执行quantize_aware_training后的full_inference的weight不同。

依据:在运行quantize_aware_training时,model.quantize_forward(data),它调用了NetBN类的qconv1算子(来自QConvBNReLU类)的forward,而在forward中,bn_module算子的均值方差都在更新,而这个bn_module正是bn1和bn2

疑问:我不理解为啥bn1和bn2的weight也更新了,感知量化的时候只是更新了均值和方差,并且没有运行bn1和bn2的 y = gamma*x+bias这类函数,按理说并不会进行梯度更新,从而gamma和bias不应该变化才对(这里的gamma指的是bn层的weight)

Jermmy commented 10 months ago

这个 bug 是 full_inference(model, test_loader) 执行两次引起的,只是推理,理论上不会改变 BN 参数,所以才令人费解。。