PyTorch下GaborNet报mat1 dim1需匹配mat2 dim0错误求解
报错根因
触发RuntimeError: mat1 dim 1 must match mat2 dim 0的直接原因是全连接层做矩阵乘法时,输入张量的特征维度和全连接层权重的维度不匹配,具体到你的代码有两个核心问题:
- 卷积层输出为4维结构(批次大小、通道数、特征图高度、特征图宽度),但
nn.Linear全连接层仅支持2维输入(批次大小、特征总数),你把卷积到全连接层之间必须的展平操作全部注释了,输入维度格式根本不匹配。 - 你目前只打印到了第一个池化层后的张量尺寸,后续c2卷积层、对应池化层的输出尺寸没有确认,fc1层定义的输入特征数和实际卷积输出的展平特征数不一致。
修复方案
- 补全前向传播中c1、c2卷积和对应池化层的计算逻辑,逐层打印输出尺寸,确认所有卷积、池化操作执行完后的最终4维张量形状。
- 在全连接层之前添加展平操作,不要硬编码固定的展平尺寸,用通用写法保留批次维度,将剩余维度合并为一维特征:
x = torch.flatten(x, start_dim=1)
- 根据卷积层最终输出的形状计算展平后的单样本特征总数(计算方式:通道数特征图高度特征图宽度),用这个数值作为fc1层的
in_features参数定义全连接层,不要随意填写数值。
修正后参考代码
import torch import torch.nn as nn import torch.nn.functional as F class GaborClsModel(nn.Module): def __init__(self, num_classes=你的分类类别数): super().__init__() self.g0 = modConv2d(in_channels=3, out_channels=32, kernel_size=(11, 11), stride=1) self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.c1 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=(2, 2), stride=1) self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.c2 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=(2, 2), stride=1) self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2) # 按150*150输入逐层计算: # g0输出尺寸140*140 → pool1后70*70,和你打印的尺寸一致 # c1输出尺寸69*69 → pool2后34*34 # c2输出尺寸33*33 → pool3后16*16 # 展平特征数=128*16*16=32768,按你实际打印的尺寸替换这个值 self.fc1 = nn.Linear(32768, 512) self.fc2 = nn.Linear(512, 128) self.fc3 = nn.Linear(128, num_classes) def forward(self, x): x = self.pool1(F.relu(self.g0(x))) x = self.pool2(F.relu(self.c1(x))) x = self.pool3(F.relu(self.c2(x))) # 必须添加的展平操作 x = torch.flatten(x, start_dim=1) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x
卷积输出尺寸计算公式:
输出边长 = (输入边长 - 卷积核边长 + 2*填充数)/步长 + 1,如果你的网络没有三层池化、或者卷积参数有调整,按照公式重新计算展平特征数,替换fc1的in_features参数即可。
内容的提问来源于stack exchange,提问作者shel coop
相关产品推荐
相关产品推荐

