PyTorch搭建带Dropout的卷积网络报RuntimeError: mat1 dim 1 must match mat2 dim 0
问题排查与修复方案
你的代码存在两个核心错误,逐一修正即可:
- 第一个错误:全连接层输入维度计算错误
你当前代码中Flatten层输出的特征维度不是32,因此第一个Linear层的输入参数设置错误,导致矩阵乘法维度不匹配报错。
针对输入尺寸为100*100的图片,经过所有卷积和池化层后的特征尺寸计算如下:
- 第一层卷积后尺寸:100 - 3 + 1 = 98 → 98*98
- 第一层池化后尺寸:(98 - 2) // 3 + 1 = 32 → 32*32
- 第二层卷积后尺寸:32 - 3 + 1 =30 → 30*30
- 第二层池化后尺寸:(30-2)//3 +1=10 → 10*10
- 第三层卷积后尺寸:10-3+1=8 → 8*8
- 第三层池化后尺寸:(8-2)//3 +1=3 → 3*3
最终Flatten后单样本特征数为 32(通道数) * 3 * 3 = 288,需要将第一个Linear层的输入参数从32改为288。
- 第二个错误:Dropout类型使用错误
Dropout2d是为2D特征图(卷积输出的[N,C,H,W]格式)设计的API,会随机置零整个通道,全连接层输出为二维[N, 特征数]格式,应该使用普通的Dropout。
修正后代码
import torch class ConvNet(torch.nn.Module): def __init__(self): super().__init__() self.layers = torch.nn.Sequential( #layer1 torch.nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=3), torch.nn.BatchNorm2d(num_features=16), torch.nn.ReLU(), #layer2 torch.nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=3), torch.nn.BatchNorm2d(num_features=32), torch.nn.ReLU(), #layer3 torch.nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=3), torch.nn.BatchNorm2d(num_features=32), torch.nn.Flatten(), torch.nn.Linear(288,16), torch.nn.Dropout(p=0.1), torch.nn.Linear(16, 2) ) def forward(self, x): return self.layers(x) test_convnet = ConvNet().to('cuda') test_input = torch.randn(16, 3, 100, 100, device='cuda') test_output = test_convnet(test_input) print(test_output.shape) # 输出为 torch.Size([16, 2])
实用提示
如果后续不确定Flatten后的维度,可以在forward函数中Flatten操作后加一行print(x.shape)先打印实际维度,再设置Linear层的输入参数,避免手动计算出错。
内容的提问来源于stack exchange,提问作者Melih
相关产品推荐
相关产品推荐

