PyTorch张量报错:Mat1与Mat2维度不兼容(8x10与8x8)求助
问题描述
已知该问题较为常见,但未找到匹配自身场景的解决方案。(注:熟悉矩阵乘法,问题不在此,烦请PyTorch相关从业者解答)
将10个由8个浮点数组成的输入样本送入输入维度为8的网络层,触发报错:
Mat1 and mat2 shapes cannot be multiplied (8x10 and 8x8)
(编辑:当前输入为8个10维张量,应为10个8维张量)
以下是相关代码:
数据集生成代码
class MyDataset(Dataset): def __init__(self): self.data = [] self.input_size = 0 for i in range(0,10): label = random.randint(0, 1) data = [random.uniform(0.0, 1.0) for _ in range(8)] self.data.append((data , label)) self.input_size = len(data ) if self.input_size < len(encoded_text) else self.input_size def __len__(self): return len(self.data) def __getitem__(self, idx): text, label = self.data[idx] return text, label
模型定义
class MyModel(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(MyModel, self).__init__() self.input = nn.Linear(input_size,hidden_size) self.hidden = nn.Linear(hidden_size, output_size) self.sigmoid = nn.Sigmoid() def forward(self, x): # padding is there as original dataset does not have full 8 floats inputs x_padded = pad_sequence(x, batch_first=True, padding_value=0).float() output = self.input(x_padded) >>>>>>>> ERROR return torch.sigmoid(output) def train_model(model, train_loader, criterion, optimizer, num_epochs): for epoch in range(num_epochs): for inputs, labels in train_loader: outputs = model(inputs)
初始化代码
if __name__ == "__main__": hidden_size = 8 # hidden size output_size = 1 # binary classification learning_rate = 0.001 num_epochs = 10 dataset = MyDataset() train_loader = DataLoader(dataset, batch_size=64, shuffle=True) input_size = dataset.input_size model = MyModel(input_size, hidden_size, output_size) criterion = nn.BCEWithLogitsLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) train_model(model, train_loader, criterion, optimizer, num_epochs)
问题根源与修复方案
核心问题
- 数据类型错误:Dataset返回的是Python列表而非PyTorch张量,导致DataLoader堆叠后维度顺序颠倒——原本应该是
[样本数, 特征数](10x8),实际变成了[特征数, 样本数](8x10),和Linear层的权重矩阵(8x8)无法进行正确的矩阵乘法。 - 冗余的pad_sequence:你的数据集每个样本都是固定8个元素,完全不需要用
pad_sequence处理,反而会因为输入不是张量列表而进一步打乱维度。 - input_size计算错误:代码中
len(encoded_text)是未定义变量,导致input_size取值错误。
修复步骤
1. 修正Dataset类
将返回的列表转为张量,并修复input_size的计算:
class MyDataset(Dataset): def __init__(self): self.data = [] self.input_size = 8 # 固定8个特征,直接赋值即可 for i in range(10): label = random.randint(0, 1) data = torch.tensor([random.uniform(0.0, 1.0) for _ in range(8)], dtype=torch.float32) self.data.append((data, label)) def __len__(self): return len(self.data) def __getitem__(self, idx): text, label = self.data[idx] return text, torch.tensor(label, dtype=torch.float32) # 标签也转为张量,适配损失函数
2. 修正模型的forward方法
去掉冗余的pad_sequence,直接处理batch张量:
class MyModel(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(MyModel, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.fc2 = nn.Linear(hidden_size, output_size) # 用BCEWithLogitsLoss的话,不需要提前加sigmoid,损失函数会内置计算 def forward(self, x): # x的形状是[batch_size, input_size],直接送入Linear层 x = torch.relu(self.fc1(x)) # 建议加激活函数,否则多层线性等于单层 output = self.fc2(x) return output # 直接返回logits,交给BCEWithLogitsLoss处理 def train_model(model, train_loader, criterion, optimizer, num_epochs): model.train() for epoch in range(num_epochs): running_loss = 0.0 for inputs, labels in train_loader: optimizer.zero_grad() outputs = model(inputs) # 调整标签形状,和输出匹配(outputs形状是[batch_size,1]) labels = labels.unsqueeze(1) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}')
3. 初始化代码无需大改
注意因为数据集只有10个样本,batch_size设为64的话,实际每个batch就是10个样本,不影响运行。
内容的提问来源于stack exchange,提问作者phil
相关产品推荐
相关产品推荐

