两个网络连接时只训练后一个网络参数的解决办法

文章讲述了在训练深度学习网络时遇到的问题,包括不同模型层的参数名不一致、直接赋值无效以及如何确保前一网络参数在反向传播时不参与训练。作者通过修改参数名、使用`copy_`方法加载权重,并在forward函数中使用`torch.no_grad()`上下文来保持某些参数不变,成功解决了这些问题。
摘要由CSDN通过智能技术生成

本人的网络情况是:前一个网络是之前训练好的,后一个网络需要用到前面网络的输出以及backbone的特征层。但是试了网上的一些方法发现都不太行,我的model1指的是前一个网络,model2是整个网络。碰到的问题如下:

1、model2和model1对应层的参数名不一样!虽然是同一层,由于我构造网络时把model1设成了model2 的backbone,导致我的model2对应层的参数名比model1多了‘backbone_neck.’。所以在给model1加载参数时一定要改了名再赋值。

2、在赋值时直接用‘param=’赋值也不行,不知道原因在哪,但是导致的结果就是参数依然没有加载进去,采用chatgpt建议的model2.state_dict()[name].copy_成功了,最后我采用了如下方法:

checkpoint=torch.load(weights_path, map_location=torch.device('cpu'))#得到的是参数字典
    netpara=checkpoint['net']
    #model1.load_state_dict(netpara, strict=False)#载入模型
    i=0
    for (name, param) in model2.named_parameters():
            model1name=name[14: ]

#'backbone_neck.'model2对应的名字比model1多14个字符
            if model1name in netpara:
                model2.state_dict()[name].copy_(netpara[model1name])
                param.requires_grad=False
            else:
                pass

3、为了保证model1的参数固定好了反向传播时不会参与训练,我在model2定义的类里,在def foward部分,用到model1的输出时,加了with torch.no_grad():,事实证明确实有用,即使参数没加载进去的时候,每个epoch的model1内的参数都是固定的,没有参与训练,如下:

 def forward(self, x: torch.Tensor):
        x=x.to(device=device)
        with torch.no_grad():
          ..........=self.backbone_neck(x)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值