PyTorch 自定义卷积模板,backward 报错 RuntimeError: one of the variables needed for gradient computation has b

PyTorch 自定义卷积模板,backward 报错 RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation

问题,如题目所述

主要原因是 Tensor 变量有 “就地更改” 的,比如 ReLU(inplace=True),或者有 +=, -= 操作符,需要声明新的变量并赋值。自己的问题主要是在 slice 切片时产生的。

原代码

在 batch_size 维度进行图像归一化时,由 x_out[i] = x_out[i] - ** 引发,可能是切片操作指向的引用发生了 “就地更改” 。

    def forward(self, x):
        """默认输入三通道图像, [B,C,H,W]"""
        batch_size, in_channels, H, W = x.size()[:]
        conv_groups = in_channels  # 这里默认 group 单通道分离,不然出来是灰度图

        kernel_ = self.kernel.repeat(in_channels, in_channels // conv_groups, 1, 1)
        weight_ = nn.Parameter(data=kernel_, requires_grad=False)
        x_out = F.conv2d(input=x, weight=weight_, padding=2, groups=conv_groups)  
        # x_out = nn.Conv2d(in_channels, in_channels, 3, padding=2, groups=conv_groups)(x)

        # for i in range(batch_size):
        #     x_out[i] = x_out[i] - torch.min(x_out[i])   # not inplace, cannot use -=
        #     x_out[i] = x_out[i] / torch.max(x_out[i])   # max(x - min) = max_x - min_x
        #     x_out[i] = torch.mul(x_out[i], self.alpha)  # 拉伸后亮一些

        return x_out

更正方案一

声明新的变量再赋值,避免 inplace 操作。

		nor_list = []
		for i in range(batch_size):
		      nor_ = x_out[i] - torch.min(x_out[i])   
		      nor_ = nor_ / torch.max(nor_)           
		      nor_ = torch.mul(nor_, self.alpha)    
		      nor_list.append(nor_)
	    x_nor = torch.cat(nor_list, dim=0)
	    if (batch_size == 1):
	          x_nor = x_nor.unsqueeze(0)

更正方案二

采用广播机制,去掉 for 循环,相对更优雅。

		x_out = torch.reshape(x_out, (batch_size, -1))  
        x_nor = x_out - torch.min(x_out, 1, keepdim=True)[0]
        x_nor = x_nor / torch.max(x_nor, 1, keepdim=True)[0]
        x_nor = torch.reshape(x_nor, (batch_size, in_channels, H, W))
        x_nor = torch.mul(x_nor, self.alpha)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值