You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CNN适配CIFAR10时遇矩阵维度不匹配RuntimeError求助

问题解决:RuntimeError 维度不匹配

错误核心原因

你遇到的RuntimeError: mat1 and mat2 shapes cannot be multiplied (32x400 and 600x120),本质是全连接层fc1的输入维度和定义不匹配:

  • 经过卷积+池化后,每个样本的特征被展平成了400维(对应batch_size=32时的32x400)
  • 但你定义的fc1 = nn.Linear(600, 120)要求输入是600维,导致矩阵乘法无法执行。

特征维度计算过程(关键)

CIFAR10输入是32x32x3的图片,一步步推导特征图尺寸:

  1. conv1 + 池化:
    • conv1 = nn.Conv2d(3,6,5):无padding、stride=1,输出尺寸 = 32 -5 +1 =28 → 特征图为28x28x6
    • 经过MaxPool2d(2,2):尺寸减半 → 14x14x6
  2. conv2 + 池化:
    • conv2 = nn.Conv2d(6,16,5):输出尺寸 = 14 -5 +1=10 → 特征图为10x10x16
    • 经过MaxPool2d(2,2):尺寸减半 → 5x5x16
  3. 展平后:5*5*16 =400 → 每个样本对应400维特征,batch_size=32时就是32x400

解决方案

方案1:直接修正全连接层输入维度(最简单)

把fc1的输入维度改成计算出的400,同时可以去掉冗余的全连接层过渡(fc2→fc3的2维映射没必要):

class Network(nn.Module):
    def __init__(self):
        super(Network, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # 修正fc1的输入维度为400
        self.fc1 = nn.Linear(400, 120)
        # 直接从120维映射到10个分类,去掉冗余的fc2、fc3层级
        self.fc2 = nn.Linear(120, 10)
        self.flatten = nn.Flatten(1)
    
    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.flatten(x)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

方案2:用AdaptiveMaxPool调整特征图尺寸(适配自定义输入维度)

如果你坚持要让fc1输入为特定维度(比如接近你原本想的600),可以在展平前加AdaptiveMaxPool2d,把特征图调整到合适尺寸(需满足通道数 * 高 * 宽 = 目标输入维度):

class Network(nn.Module):
    def __init__(self):
        super(Network, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # 新增自适应池化,把特征图调整为6x6
        self.adaptive_pool = nn.AdaptiveMaxPool2d((6,6))
        # 16*6*6=576,对应fc1的输入维度
        self.fc1 = nn.Linear(576, 120)
        self.fc2 = nn.Linear(120, 10)
        self.flatten = nn.Flatten(1)
    
    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        # 加自适应池化调整特征图尺寸
        x = self.adaptive_pool(x)
        x = self.flatten(x)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

额外注意点

  • 你定义了归一化transform但实际加载数据集时没用到,建议统一:cifar10 = torchvision.datasets.CIFAR10(root='./data', download=True, transform=transform)
  • CIFAR10实际包含60000张图,你代码里的pivot=40000划分训练/验证集是合理的。

内容的提问来源于stack exchange,提问作者rzan1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:20:37