PyTorch报错mat1 and mat2 cannot be multiplied 如何调整网络参数?
报错原因
你遇到的报错是全连接层输入维度和卷积输出的特征维度不匹配导致的。报错信息中的32x33856是数据经过两次卷积+池化、展平后实际输出的张量形状(32为batch size,33856为单样本特征数),但你定义fc1时硬编码的输入维度是100*100*64=640000,两个维度无法匹配,矩阵乘法运算自然报错。
你可以手动核对特征维度计算过程:
输入为100x100x3的图像:
- 第一次无padding的3x3卷积后,特征尺寸为
(100 - 3)/1 +1 = 98,得到98x98x64的特征 - 第一次2倍最大池化后,尺寸减半,变为49x49x64
- 第二次无padding的3x3卷积后,特征尺寸为
(49 - 3)/1 +1 =47,得到47x47x64的特征 - 第二次2倍最大池化后,尺寸向下取整减半,变为23x23x64
- 展平后单样本维度为
23*23*64=33856,和报错信息中的数值完全吻合。
修复方案
1. 快速修复:直接修改fc1的输入维度
将网络中定义fc1的代码行修改为:
self.fc1 = nn.Linear(23*23*64, 256)
即可直接解决维度不匹配的问题。
2. 推荐方案:自动计算展平维度,避免后续修改网络时重复踩坑
你可以在网络初始化时用虚拟张量自动计算全连接层的输入维度,后续修改卷积参数、输入图像尺寸时都不需要手动计算维度:
class ChordClassificationNetwork(nn.Module): def __init__(self, input_shape=(3,100,100), train_model=False): super(ChordClassificationNetwork, self).__init__() self.train_model = train_model self.firstConv = nn.Conv2d(3, 64, (3, 3)) self.secondConv = nn.Conv2d(64, 64, (3, 3)) self.pool = nn.MaxPool2d(2) self.drop = nn.Dropout(0.25) self.flatten = nn.Flatten() # 自动计算全连接层输入维度 with torch.no_grad(): dummy = torch.randn(1, *input_shape) x = self.pool(F.relu(self.firstConv(dummy))) x = self.pool(F.relu(self.secondConv(x))) fc_in_dim = self.flatten(x).shape[1] self.fc1 = nn.Linear(fc_in_dim, 256) self.fc2 = nn.Linear(256, 256) self.outLayer = nn.Linear(256, 7) def forward(self, x): x = self.firstConv(x) x = F.relu(x) x = self.pool(x) x = self.secondConv(x) x = F.relu(x) x = self.pool(x) x = self.drop(x) x = self.flatten(x) x = self.fc1(x) x = F.relu(x) x = self.drop(x) x = self.fc2(x) x = F.relu(x) x = self.drop(x) x = self.outLayer(x) output = F.softmax(x, dim=1) return output
额外注意事项
你当前的代码还有两处逻辑问题需要同步调整:
- 你做的是7分类任务,损失函数不应该用
BCELoss,应该换成nn.CrossEntropyLoss(),同时删掉forward最后的F.softmax(x, dim=1)直接返回x即可,CrossEntropyLoss内部会自动处理softmax计算,避免数值溢出。 - 准确率计算部分的0.5阈值逻辑是二分类场景使用的,7分类应该修改为取每个样本输出的最大值对应的索引作为预测类别:
predictions = scores.argmax(dim=1),同时标签需要为0~6的类别索引格式,如果当前你的标签是one-hot格式,需要对应调整。
内容的提问来源于stack exchange,提问作者Deffo
相关产品推荐
相关产品推荐

