自定义ResNet18添加简单注意力层后前向传播报错如何修复
问题修复方案
错误根因
报错核心原因是注意力层卷积的输入通道数配置错误:
ResNet18初始化时传入的layers参数默认值为[2,2,2,2],对应四个残差块的重复次数,你直接把layers[0]作为卷积层的输入输出通道数,导致第一个卷积层的输入通道数被设为2,但layer1的输出实际是64通道,和输入维度不匹配触发报错。
另外你当前设置的卷积输出通道数为2,即使输入通道数修正后,也会出现后续和原特征图x相乘时通道维度不匹配的问题。
修复代码
你可以根据要实现的注意力类型调整,这里给出兼容你原有逻辑的修改方案:
# 修改后的注意力层定义 self.layer_attend1 = nn.Sequential( # 输入通道数改为layer1输出的64,输出通道数也保持64匹配原特征图通道数 nn.Conv2d(64, 64, stride=2, padding=1, kernel_size=3), nn.AdaptiveAvgPool2d(1), nn.Softmax(1) )
如果是做通道注意力,也可以简化为更常用的实现:
self.layer_attend1 = nn.Sequential( nn.AdaptiveAvgPool2d(1), nn.Conv2d(64, 64, kernel_size=1, bias=False), nn.Sigmoid() # 通道注意力常用Sigmoid替换Softmax,避免权重被过度归一化 )
额外注意:你加载了预训练权重,新增的注意力层没有预训练参数,加载权重时需要设置strict=False,避免参数不匹配报错:
# 加载checkpoint的代码修改为类似如下结构 checkpoint = torch.load('runs/nondisjoint_l2norm/model_best.pth.tar') model.load_state_dict(checkpoint['state_dict'], strict=False)
断点不触发解决方法
- 确认你修改的代码和运行的代码是同一路径下的同一文件,避免运行了缓存或其他位置的旧代码
- 把测试时DataLoader的
num_workers参数设为0,多进程数据加载场景下断点不会在子进程中触发 - 检查VSCode调试配置的
program字段是否指向你当前运行的main.py文件
内容的提问来源于stack exchange,提问作者Mona Jalal
相关产品推荐
相关产品推荐

