Python 如何将自己模型的权重传递到最后一层中相同网络但不同数量的类?

Python 如何将自己模型的权重传递到最后一层中相同网络但不同数量的类?,python,deep-learning,pytorch,Python,Deep Learning,Pytorch,我在Pytorch有自己的网络。它首先针对二进制分类器(2类)进行训练。经过10万个纪元后,我获得了训练重量10000\u model.pth。现在,我想用这个模型来解决使用相同网络的4类分类器问题。因此,我想将二进制分类器中所有训练过的权重转移到4类问题中,而不需要lass层进行随机初始化。我怎么做呢?这是我的模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__()

我在Pytorch有自己的网络。它首先针对二进制分类器(2类)进行训练。经过10万个纪元后,我获得了训练重量
10000\u model.pth
。现在,我想用这个模型来解决使用相同网络的4类分类器问题。因此,我想将二进制分类器中所有训练过的权重转移到4类问题中,而不需要lass层进行随机初始化。我怎么做呢?这是我的模型

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5, 1)
        self.conv2 = nn.Conv2d(20, 50, 5, 1)
        self.conv_classify= nn.Conv2d(50, 2, 1, 1, bias=True) # number of class

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv_classify(x))
        return x
这就是我所做的

model = Net ()
checkpoint_dict = torch.load('10000_model.pth')        
pretrained_dict = checkpoint_dict['state_dict']
model_dict = model.state_dict()
# 1. filter out unnecessary keys
pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
# 2. overwrite entries in the existing state dict
model_dict.update(pretrained_dict)
# 3. load the new state dict
model.load_state_dict(model_dict)
现在,我必须手动按名称删除预训练的dict

pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
pretrained_dict.pop('conv_classify.weight', None)
pretrained_dict.pop('conv_classify.bias', None)
这意味着
pretrained_dict={k:v代表k,如果model_dict}中的k不起任何作用,则pretrained_dict.items()中的v为


怎么了?我正在使用pytorch 1.0。谢谢

这两个网络都有相同的层,因此在
状态下有相同的密钥
,确实如此

pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
什么也不做。两者之间的区别在于重量张量(它们的形状)而不是它们的名称。换句话说,您可以通过
[v.shape for v In model.state_dict().values()]
而不是
model.state_dict().keys()
来区分两者。您的“变通”方法是正确的。如果你想让这少一点手动,我会使用

merged_dict = {}
for key in model_dict.keys():
    if 'conv_classify' in key: # or perhaps a more complex criterion
        merged_dict[key] = model_dict[key]
    else:
        merged_dict[key] = pretrained_dict[key]

两个网络具有相同的层,因此在
状态下具有相同的密钥

pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
什么也不做。两者之间的区别在于重量张量(它们的形状)而不是它们的名称。换句话说,您可以通过
[v.shape for v In model.state_dict().values()]
而不是
model.state_dict().keys()
来区分两者。您的“变通”方法是正确的。如果你想让这少一点手动,我会使用

merged_dict = {}
for key in model_dict.keys():
    if 'conv_classify' in key: # or perhaps a more complex criterion
        merged_dict[key] = model_dict[key]
    else:
        merged_dict[key] = pretrained_dict[key]

谢谢你的回答。因此,我将用您的代码替换步骤1。是吗?是的,这是作为第1步的替代。我还没有试过完整的代码,所以可能有一些必要的修复。谢谢你的回答。因此,我将用您的代码替换步骤1。是吗?是的,这是作为第1步的替代。我还没有试过完整的代码,所以可能有一些必要的修复。