代码笔记18 pytorch中加载ResNet,导致过拟合或者测试时model.train()高于model.eval()
作者:互联网
问题
训练网络往往需要加载预训练模型,主流的就是ResNet一类的预训练好的参数
但我在加载了预训练模型,并冻结与训练参数后,进行训练时,发现了两个问题
1
在进行test中model.train()的准确率要远高于model.eval()差别大概在7个点左右。
其中model.eval() 负责改变batchnorm、dropout的工作方式,如在eval()模式下,dropout是不工作的。
这种问题出现一般网上有几种回答,可以看看这个[1]不过很遗憾,我并不是这里的问题。还有认为是eval时batchsize过小的原因,导致每个mini-batch的数据分布无法符合整个数据集,我的batchsize时32,比我训练是还要大。
不过我测试了一下,在训练好的模型上,使用train()模式,带有dropout()系数的准确率是低于不使用dropout的,差别在4个点左右。
2
过拟合,训练集和测试集准确率差了15个点。
解决
在此非常感谢博客[2],说的太有道理了。
问题就在于我冻结Resnet参数时,冻结了所有的参数包括BatchNorm2D中的权重与偏差值。这样导致的问题就是,在Resnet中的bn层所学习到的参数是基于Imagenet数据集的数据分布的并且被冻结后不会再学习,当然会导致train()模式下的精度降低,以及过拟合的发生,一切都解释的通了。
代码
把我冻结参数的代码放上来
def _freeze_parameters(self):
# cant freeze if not load, because the freeze_dict is null
if bool(self.freezedict) == False:
print('freeze params must after loading ResNet!')
os._exit(0)
freeze_dict = self.freezedict
state_dict = self.state_dict(keep_vars=True)
for k, v in freeze_dict.items():
if k in state_dict:
state_dict[k].requires_grad = False
# freeze parameters in ResNet except BatchNorm!!!!
# or the batchnorm will not trainable, and keep the mean and var (weights and bias) on Imagenet dataset
for m in self.modules():
if isinstance(m,nn.BatchNorm2d):
m.weight.requires_grad = True
m.bias.requires_grad = True
Refrences
[1] https://blog.csdn.net/yucong96/article/details/88652964
[2] https://blog.csdn.net/aojue1109/article/details/88181927?spm=1001.2014.3001.5506
标签:训练,18,self,ResNet,freeze,dict,eval,model 来源: https://www.cnblogs.com/HumbleHater/p/16391958.html