Skip to content

conv输出进入BN后有精度问题? #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Serissa opened this issue Feb 18, 2022 · 2 comments
Open

conv输出进入BN后有精度问题? #17

Serissa opened this issue Feb 18, 2022 · 2 comments

Comments

@Serissa
Copy link

Serissa commented Feb 18, 2022

您好!我在做RM的时候发现,conv输出进入BN输出有精度问题?

        idconv1 = nn.Conv2d(self.in_planes, self.in_planes+self.mid_planes, kernel_size=3, stride=1, padding=1, bias=False).eval()
        idbn1 = nn.BatchNorm2d(self.in_planes+self.mid_planes).eval()
        # init dirac_ kernel weight, bias, mean var to idconv1
        nn.init.dirac_(idconv1.weight.data[:self.in_planes])
        bn_var_sqrt1 = torch.sqrt(self.running1.running_var + self.running1.eps)
        idbn1.weight.data[:self.in_planes] = bn_var_sqrt1
        idbn1.bias.data[:self.in_planes] = self.running1.running_mean
        idbn1.running_mean.data[:self.in_planes] = self.running1.running_mean
        idbn1.running_var.data[:self.in_planes] = self.running1.running_var
        # init conv1 to idconv1
        idconv1.weight.data[self.in_planes:] = self.conv1.weight.data
        idbn1.weight.data[self.in_planes:] = self.bn1.weight.data
        idbn1.bias.data[self.in_planes:] = self.bn1.bias.data
        idbn1.running_mean.data[self.in_planes:] = self.bn1.running_mean
        idbn1.running_var.data[self.in_planes:] = self.bn1.running_var

图片
左边三conv2d输出结果,右边三batchnorm2d输出结果,其中conv2d输出为0的值在batchnorm2d中输出成一个很小的值(1.6642e-08),请问这是什么原因造成的?如何修改代码消除这种现象。

@fxmeng
Copy link
Owner

fxmeng commented Feb 18, 2022

您好!我在做RM的时候发现,conv输出进入BN输出有精度问题?
左边三conv2d输出结果,右边三batchnorm2d输出结果,其中conv2d输出为0的值在batchnorm2d中输出成一个很小的值(1.6642e-08),请问这是什么原因造成的?如何修改代码消除这种现象。

感谢关注RMNet,您所说的精度问题根据我的观察推测是由BN层引起的,按照使用场景:

  1. 带残差的网络训练完,转化为plain model后直接用于推理。此时通常并不需要BN层,因此可以在先去除BN层,再去残差,这种方案可以减小精度误差。代码如下:
    https://github.com/fxmeng/RMNet/blob/8b848b79a8863c4ea64afffaa0e5dd0de888ac70/models/easy_resnet2vgg.py
    https://github.com/fxmeng/RMNet/blob/e111ecc48cc8b8159b9e8584e8ba68eb3a9b829a/models/easy_mb2_mb1.py
  2. 带残差的网络训练完,转化为plain model后,还想要继续finetune。此时由于精度问题导致的准确率变化,一般小到可以忽略不计,直接finetune就可以。注意,bn层在训练过程中是很有用的,若需要finetune,就不要去掉bn层。

@Serissa
Copy link
Author

Serissa commented Feb 18, 2022

理解了,谢谢!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants