修改PyTorch ResNet18报张量维度不匹配RuntimeError原因排查
ResNet18修改步长后张量尺寸不匹配报错原因
核心问题
报错由残差块的主分支与捷径分支输出尺寸不一致导致:你仅修改了layer3首个卷积块主分支conv1的步长,没有同步修改同个残差块捷径分支(downsample层)的步长参数,两个分支输出特征图尺寸分别为16×16和8×8,无法完成逐元素相加操作。
尺寸推导验证
顺着网络结构逐层计算输出尺寸,可以完全对应报错信息:
- 输入尺寸:3×64×64
- 首层卷积conv1(7×7, stride=2, padding=3)输出:64×32×32
- 你修改后的maxpool层(stride=1)输出:64×32×32(原始ResNet该层stride=2,会输出16×16,修改后少了一次2倍下采样)
- layer1所有卷积步长为1,输出:64×32×32
- layer2首个残差块步长为2,完成2倍下采样,输出:128×16×16
- 进入layer3的第一个残差块(layer3[0]):
- 主分支:你将conv1的步长从默认2改为1,conv2默认步长为1,因此主分支最终输出尺寸为256×16×16,对应报错里的tensor a尺寸16
- 捷径分支:该残差块默认携带downsample层,用于对齐通道数和下采样尺寸,你未修改该层参数,其中1×1卷积的步长仍为默认2,因此捷径分支输出尺寸为256×8×8,对应报错里的tensor b尺寸8
- 残差结构要求两个分支的输出张量形状完全一致才能逐元素相加,尺寸不匹配直接触发RuntimeError。
修复方法
补充修改layer3[0]中downsample层的卷积步长即可解决报错:
model = models.resnet18(pretrained=True) model.maxpool = nn.MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=False) model.layer3[0].conv1 = nn.Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False) # 同步修改捷径分支的步长 model.layer3[0].downsample[0].stride = (1, 1) model.fc = nn.Linear(model.fc.in_features, 100)
修改完成后,网络总下采样倍数为8,最终layer4输出的特征图尺寸恰好是要求的8×8×512。
内容的提问来源于stack exchange,提问作者SHIYUKUN
相关产品推荐
相关产品推荐

