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

PyTorch网络报错:mat1与mat2无法相乘,求解决方法

解决PyTorch中mat1和mat2形状不匹配的问题

问题原因

报错Runtime Error: mat1 and mat2 shapes cannot be multiplied (16x756900 and 3048516x30)是因为全连接层fc1的输入特征数设置错误,和实际经过卷积、池化后得到的特征图展平后的维度不匹配:

  • 代码中fc1的in_features写的是36*291*291=3048516,但实际输入经过两次卷积+池化后,展平后的特征数是36*145*145=756900(对应报错里的16x756900,16是batch size)。

正确的特征尺寸计算步骤

输入形状为[3,600,600],一步步计算各层输出尺寸:

  1. conv1 + pool:
    • conv1:kernel=11, padding=0,输出尺寸 = (600 - 11)/1 + 1 = 590,形状变为[8,590,590]
    • MaxPool2d(2,2):输出尺寸 = (590 - 2)/2 + 1 = 295,形状变为[8,295,295]
  2. conv2 + pool:
    • conv2:kernel=5, padding=0,输出尺寸 = (295 -5)/1 +1 =291,形状变为[36,291,291]
    • MaxPool2d(2,2):输出尺寸 = floor((291 -2)/2 +1) =145,形状变为[36,145,145]
  3. 展平后特征数:36 *145 *145 =756900

修复后的代码

方法一:直接修正fc1的in_features为正确值:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        
        self.conv1 = nn.Conv2d(3,8,11, padding=0)
        self.pool = nn.MaxPool2d(2,2)
        self.conv2 = nn.Conv2d(8, 36, 5, padding=0)
        self.fc1 = nn.Linear(36*145*145, 30)  # 修正输入特征数
        self.fc2 = nn.Linear(30, 20)
        self.fc3 = nn.Linear(20, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 测试代码
if __name__ == "__main__":
    input_tensor = torch.randn(16,3,600,600)
    net = Net()
    output = net(input_tensor)
    print(output.shape)  # 预期输出 torch.Size([16,10])

方法二:动态计算全连接层输入特征数(适合输入尺寸可能变化的场景):

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        
        self.conv1 = nn.Conv2d(3,8,11, padding=0)
        self.pool = nn.MaxPool2d(2,2)
        self.conv2 = nn.Conv2d(8, 36, 5, padding=0)
        # 先不定义fc1,第一次前向传播时动态初始化
        self.fc2 = nn.Linear(30, 20)
        self.fc3 = nn.Linear(20, 10)
        self._fc_initialized = False

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1)
        
        if not self._fc_initialized:
            # 根据实际展平后的特征数初始化fc1
            self.fc1 = nn.Linear(x.shape[1], 30).to(x.device)
            self._fc_initialized = True
            
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 测试代码
if __name__ == "__main__":
    input_tensor = torch.randn(16,3,600,600)
    net = Net()
    output = net(input_tensor)
    print(output.shape)

注意事项

  • 计算卷积/池化层输出尺寸时,默认padding=0、stride=1的情况下,公式为:输出尺寸 = floor((输入尺寸 - kernel_size)/stride) + 1
  • 动态初始化全连接层时,需注意模型保存和加载的兼容性,因为fc1是第一次前向传播后才创建的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:15:59