RuntimeError:矩阵形状不匹配问题修复求助(MNIST数据集CNN构建)
修复 RuntimeError: mat1 and mat2 shapes cannot be multiplied (2x720 and 784x10) 错误并构建MNIST CNN
这个错误的核心是全连接层的输入特征维度与你定义的权重矩阵维度不匹配。你当前的全连接层大概率错误使用了MNIST原始图像的784维(28×28)作为输入,但经过两次卷积+池化后,特征图的维度已经改变,扁平化后的特征数并非784,导致矩阵乘法无法执行。
先明确符合你需求的特征维度计算
基于你要求的层结构,以MNIST标准28×28灰度图(通道数1)为输入,逐层推导输出尺寸:
- 初始输入:
(batch_size, 1, 28, 28) - 第一层卷积(10个5×5滤波器,步长1,零填充):通过
padding=2实现same padding,输出尺寸保持28×28,通道数变为10 →(batch_size, 10, 28, 28) - 2×2最大池化(步长2):尺寸减半 →
(batch_size, 10, 14, 14) - 第二层卷积(20个5×5滤波器,步长1,零填充):same padding保持尺寸14×14,通道数变为20 →
(batch_size, 20, 14, 14) - 2×2最大池化:尺寸减半 →
(batch_size, 20, 7, 7) - 扁平化后特征数:
20×7×7 = 980
修复方案与完整代码
将全连接层的输入维度从784改为980,并确保前向传播时正确扁平化卷积输出:
import torch import torch.nn as nn import torch.nn.functional as F class MNIST_CNN(nn.Module): def __init__(self): super(MNIST_CNN, self).__init__() # 第一层卷积+池化 self.conv1 = nn.Conv2d(1, 10, kernel_size=5, padding=2, stride=1) self.pool1 = nn.MaxPool2d(2, stride=2) # 第二层卷积+池化 self.conv2 = nn.Conv2d(10, 20, kernel_size=5, padding=2, stride=1) self.pool2 = nn.MaxPool2d(2, stride=2) # 全连接层(输入维度为计算后的980,输出维度可按需调整) self.fc1 = nn.Linear(20*7*7, 512) # 若需MNIST分类(10类),可添加输出层 self.fc2 = nn.Linear(512, 10) def forward(self, x): # 第一层:卷积→ReLU→池化 x = self.pool1(F.relu(self.conv1(x))) # 第二层:卷积→ReLU→池化 x = self.pool2(F.relu(self.conv2(x))) # 扁平化特征图:将(batch, 20,7,7)转为(batch, 980) x = x.view(-1, 20*7*7) # 全连接层+ReLU激活 x = F.relu(self.fc1(x)) # 分类输出(若无需分类可删除此步) x = self.fc2(x) return x # 测试模型运行 model = MNIST_CNN() test_input = torch.randn(2, 1, 28, 28) # 匹配错误中的batch_size=2 output = model(test_input) print(output.shape) # 应为(2,10),说明模型无维度错误
额外说明
- 若你的原始代码未设置
padding=2,卷积后特征图尺寸会缩小,需重新计算扁平化特征数:比如无padding时,第一层卷积后尺寸为24,池化后12;第二层卷积后8,池化后4,此时扁平化特征数为20×4×4=320,全连接层输入需改为320。 - 若不需要分类输出,可删除
self.fc2层,确保后续逻辑匹配即可。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

