ResNet/VGG网络维度压缩与梯度反向传播报错排查求助
问题排查与解决方法
一、ResNet维度压缩报错(TypeError)
报错原因
- 层调用错误:代码中
if self.out_channel != 256: x = self.layer2仅将x赋值为Sequential层对象,而非调用该层处理后的Tensor,导致后续F.conv2d接收的输入是模块而非张量,触发类型错误。 - 卷积核维度错误:手动创建的
filters维度为(batch_size, out_channel,1,1),不符合PyTorchF.conv2d对weight的维度要求(正确维度应为(out_channels, in_channels/groups, kernel_size[0], kernel_size[1])),且用全1卷积核做通道压缩完全没必要。
解决方法
- 修正层调用逻辑,确保执行前向传播:
if self.out_channel != 256: x = self.layer2(x) # 调用层的前向传播,得到处理后的Tensor - 用1x1卷积层替代手动卷积操作:在模型
__init__中定义专门的通道压缩层,无需手动创建卷积核:# __init__中定义layer2 self.layer2 = nn.Conv2d(256, self.out_channel, kernel_size=1, bias=False) - 删除后续多余的
F.conv2d代码,直接使用上述卷积层完成通道压缩。
二、VGG训练梯度报错(RuntimeError)
报错原因
- inplace操作破坏梯度依赖:自定义的
tonser_nolmal(推测是tensor_normal笔误)函数或Evaluation().MAE方法中存在inplace操作(如x /= ...、x += ...),修改了梯度计算所需的原始Tensor版本,导致反向传播失败。 - 冗余卷积操作:VGG的
conv3_3已经完成了256到20通道的压缩,后续的F.conv2d属于冗余操作,且其卷积核维度错误,可能引发Tensor状态异常。
解决方法
- 删除冗余的
F.conv2d代码:conv3_3的最后一层已经将通道压缩到目标维度,直接使用该输出即可:def forward(self, x): x = self.conv1_1(x) x = self.conv1_2(x) x = self.conv2_1(x) x = self.conv2_2(x) x = self.conv3_1(x) x = self.conv3_2(x) feature = self.conv3_3(x) return feature, feature # 根据需求调整返回值 - 修正inplace操作:将所有修改原始Tensor的操作改为非inplace形式,例如:
# 替换tonser_nolmal中的inplace操作 def tensor_normal(x): # 原inplace写法:x /= torch.norm(x) return x / torch.norm(x) # 返回新Tensor,不修改原始值 - 精准定位inplace操作:在训练代码开头添加异常检测,打印具体出错的操作:
torch.autograd.set_detect_anomaly(True)
内容的提问来源于stack exchange,提问作者lllittleX
相关产品推荐
相关产品推荐

