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

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)

问题根源与修复方案

核心问题

  1. 数据类型错误:Dataset返回的是Python列表而非PyTorch张量,导致DataLoader堆叠后维度顺序颠倒——原本应该是[样本数, 特征数](10x8),实际变成了[特征数, 样本数](8x10),和Linear层的权重矩阵(8x8)无法进行正确的矩阵乘法。
  2. 冗余的pad_sequence:你的数据集每个样本都是固定8个元素,完全不需要用pad_sequence处理,反而会因为输入不是张量列表而进一步打乱维度。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:17:46