PyTorch RuntimeError:矩阵维度不匹配问题求助(CIFAR10任务)
问题分析与解决思路
核心错误原因
你遇到的RuntimeError本质是全连接层的输入输出维度不匹配,同时forward函数里存在重复调用层的逻辑错误:
- 全连接层维度定义错误:
fc1的输出是512维(输入为256*4*4=4096,输出512),但你定义的fc2输入维度是256,和fc1的输出维度完全不匹配,导致矩阵乘法失败。- 同理,
fc3的输入维度是256,但后续经过fc2后的输出维度(修正前)不匹配,进一步触发错误。
- forward函数逻辑错误:
你在forward里重复调用了fc2:
第一次调用的输出被直接丢弃,且第二次调用时输入维度依然不匹配,加剧了错误。x = self.fc2(x) x = F.relu(self.fc2(x))
代码修正方案
1. 修正全连接层与forward逻辑
调整全连接层的维度对齐前后层的输入输出,同时修复forward里的重复调用问题:
import torch import torch.nn as nn import torch.nn.functional as F class HWCNN(nn.Module): def __init__(self, num_channels, num_classes): super(HWCNN, self).__init__() self.conv1 = nn.Conv2d(num_channels, 32, 3, padding=1) self.conv2 = nn.Conv2d(32, 64, 3, stride=1, padding=1) self.pool1 = nn.MaxPool2d(2) self.conv3 = nn.Conv2d(64, 128, 3, stride=1, padding=1) self.conv4 = nn.Conv2d(128, 128, 3, stride=1, padding=1) self.pool2 = nn.MaxPool2d(2) self.conv5 = nn.Conv2d(128, 256, 3, stride=1, padding=1) self.conv6 = nn.Conv2d(256, 256, 3, stride=1, padding=1) self.pool3 = nn.MaxPool2d(2) self.fc1 = nn.Linear(256*4*4, 512) # 修正fc2输入维度为512(匹配fc1的输出) self.fc2 = nn.Linear(512, 512) # 修正fc3输入维度为512(匹配fc2的输出) self.fc3 = nn.Linear(512, 10) def forward(self, X): x = F.relu(self.conv1(X)) x = F.relu(self.conv2(x)) x = self.pool1(x) x = F.relu(self.conv3(x)) x = F.relu(self.conv4(x)) x = self.pool2(x) x = F.relu(self.conv5(x)) x = F.relu(self.conv6(x)) x = self.pool3(x) x = x.reshape(-1, 256*4*4) x = F.relu(self.fc1(x)) # 修复重复调用问题:单次过fc2后做激活 x = F.relu(self.fc2(x)) x = self.fc3(x) return x
2. 验证特征图尺寸(确认无问题)
你的reshape(-1, 256*4*4)是正确的:CIFAR10输入为32x32,经过3次MaxPool2d(2)(每次尺寸减半),最终特征图尺寸为4x4,通道数256,展平后维度256*4*4=4096,和fc1的输入维度完全匹配,这部分无需修改。
20epoch内达到80%准确率的优化建议
基础模型加上以下调整可快速达标:
- 优化器调整:将SGD替换为
Adam(或给SGD加momentum=0.9),初始学习率设为0.001,避免训练初期震荡。 - 添加Dropout防过拟合:在全连接层之间加入
nn.Dropout(0.5)。 - 学习率调度:使用
torch.optim.lr_scheduler.StepLR,每5个epoch将学习率减半。 - 数据增强:对训练集添加随机裁剪、水平翻转:
from torchvision import transforms train_transform = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) - 添加BatchNorm加速收敛:在卷积层后加入
nn.BatchNorm2d,比如self.bn1 = nn.BatchNorm2d(32),forward中改为x = F.relu(self.bn1(self.conv1(X)))。
内容的提问来源于stack exchange,提问作者Andrei0408
相关产品推荐
相关产品推荐

