输入图像尺寸变更时的CNN架构调整方法咨询
问题原因与解决方法
错误原因
报错是因为输入图像尺寸变更后,卷积+池化后的特征图尺寸改变,但全连接层fc1的输入维度仍沿用32×32图像计算的固定值16*5*5=400,和实际输出的16*6*6=576不匹配,导致矩阵乘法无法执行。
针对36×36图像的直接修改
修改fc1的输入维度为重新计算后的16*6*6=576,调整后的代码如下:
class Net(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 6, 5) self.pool = nn.MaxPool2d(2, 2) self.conv2 = nn.Conv2d(6, 16, 5) # 修改fc1输入维度为16*6*6=576 self.fc1 = nn.Linear(16 * 6 * 6, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 15) def forward(self, x): x = self.pool(F2.relu(self.conv1(x))) x = self.pool(F2.relu(self.conv2(x))) x = torch.flatten(x, 1) # 展平除batch外的所有维度 x = F2.relu(self.fc1(x)) x = F2.relu(self.fc2(x)) x = self.fc3(x) return x
通用适配任意输入尺寸的方法
如果后续需要频繁调整输入图像尺寸,推荐用自适应池化层替代固定步长的MaxPool,强制将卷积后的特征图统一为固定尺寸(比如5×5),这样全连接层的输入维度无需修改,代码调整如下:
class Net(nn.Module): def __init__(self): super().__init__() self.conv1 = nn.Conv2d(3, 6, 5) # 替换为自适应最大池化,指定输出尺寸为(5,5) self.adaptive_pool = nn.AdaptiveMaxPool2d((5, 5)) self.conv2 = nn.Conv2d(6, 16, 5) # 保持原有的16*5*5输入维度 self.fc1 = nn.Linear(16 * 5 * 5, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 15) def forward(self, x): x = F2.relu(self.conv1(x)) x = self.adaptive_pool(x) x = F2.relu(self.conv2(x)) x = self.adaptive_pool(x) x = torch.flatten(x, 1) x = F2.relu(self.fc1(x)) x = F2.relu(self.fc2(x)) x = self.fc3(x) return x
特征图尺寸手动计算方法
若需自行计算卷积池化后的尺寸,可参考以下公式:
- 卷积层输出尺寸:
(输入尺寸 - 卷积核尺寸 + 2*填充)/步长 + 1(默认padding=0,stride=1) - 池化层输出尺寸:
输入尺寸/步长(输入尺寸能被步长整除时)
以36×36输入为例:
- 经过conv1(核5):
(36-5)+1=32→ 32×32 - 经过MaxPool2d(2,2):
32/2=16→16×16 - 经过conv2(核5):
(16-5)+1=12→12×12 - 经过MaxPool2d(2,2):
12/2=6→6×6 - 展平后维度:
16*6*6=576
内容的提问来源于stack exchange,提问作者Varun Khare
相关产品推荐
相关产品推荐

