问题:
模型在训练过程中可以正常训练,但是测试的时候出现了错误,如下所示:
RuntimeError: Error(s) in loading state_dict for ModuleList:
Missing key(s) in state_dict: "0.weight", "1.weight", "1.bias", "1.running_mean", "1.running_var",
Unexpected key(s) in state_dict: "conv1.weight", "bn1.weight", "bn1.bias", "bn1.running_mean", "bn1.running_var",
说明:
比如我们之前定义的一个模型model_1,训练之后保存了模型参数,命名为checkpoint_1;然后我们在model_1的基础上修改了模型,在内部添加了一些新的参数(或者更改了参数的名称),命名为model_2,训练之后保存了模型参数,命名为checkpoint_2。
一般而言,我们在测试时,使用的模型model,要加载相应的模型参数信息,即checkpoint。
Unexpected key(s) in state_dict: ...
这类错误。因为checkpoint_2内保存的模型参数是model_2的参数,而model_2是在model_1的基础上添加了一些参数,我们把模型参数checkpoint_2加载到模型model_1上,就会多出一些不能匹配的参数。Missing key(s) in state_dict: ...
这类错误。因为checkpoint_1内保存的模型参数是model_1的参数,而model_1要比model_2内部少一些参数,我们把模型参数checkpoint_1加载到模型model_2上,就会出现缺少参数这类错误。转载
预训练模型使用
model = ResNet50()
model = nn.DataParallel(model).cuda()
加载预训练模型是使用
model = ResNet50().cuda()
checkpoint = torch.load(args.net_cache)
model.load_state_dict(checkpoint['state_dict'])//
报错:RuntimeError: Error(s) in loading state_dict for Resnet50 Unexpected key(s) in state_dict:““
说明加载模型和预训练模型环境不一致,本来修改如下(后经权重输出对比发现这种方式加载的model与原model权重不一致):
model = ResNet50().cuda()
checkpoint = torch.load(args.net_cache)
model.load_state_dict(checkpoint['state_dict'],False)//
model.load_state_dict(state_dict, strict=True)
解决1:由于用DataParallel训练的模型数据并行方式的,key中会包含”module“关键字,加载时直接用:
model = ResNet50().cuda()
model = nn.DataParallel(model)
checkpoint = torch.load(args.net_cache)
model.load_state_dict(checkpoint['state_dict'])//
解决2: 去掉DataParallel 预训练model中的module(可行权重值一致):
model = ResNet50().cuda()
checkpoint = torch.load(args.net_cache)
model.load_state_dict({k.replace('module.',''):v for k,v in checkpoint['state_dict'].items()})