PyTorch矩阵乘法报错:32x1与32x32无法相乘原因排查
解决PyTorch RuntimeError:mat1与mat2形状无法相乘(32x1和32x32)
问题描述
编写了如下NN_test神经网络,使用SGD优化器和L1Loss损失函数,以批量大小32进行训练时,出现RuntimeError,提示mat1 and mat2 shapes cannot be multiplied (32x1 and 32x32)。
神经网络代码:
import torch import torch.nn as nn class NN_test(nn.Module): def __init__(self): super().__init__() self.hidden1 = nn.Linear(32, 32) self.act1 = nn.ReLU() self.hidden2 = nn.Linear(32, 8) self.act2 = nn.ReLU() self.output = nn.Linear(8, 1) self.act_output = nn.Sigmoid() def forward(self, x): x = self.act1(self.hidden1(x)) x = self.act2(self.hidden2(x)) x = self.act_output(self.output(x)) return x model = NN_test() model = model.to(torch.float64)
训练循环代码:
# Create loss function loss_fn = nn.L1Loss() # Create optimizer optimizer = torch.optim.SGD(params=model.parameters(), # optimize newly created model's parameters lr=0.01) torch.manual_seed(42) BATCH_SIZE = 32 # Set the number of epochs epochs = 1000 # Put data on the available device # Without this, error will happen (not all model/data on device) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") X_train = x_scaled.to(device) X_test = x_scaled_test.to(device) y_train = y_scaled.to(device) y_test = y_scaled_test.to(device) for epoch in range(epochs): for batch in range(0, len(X_train), BATCH_SIZE): ### Training model.train() # train mode is on by default after construction # 1. Forward pass y_pred = model(X_train[batch:batch+BATCH_SIZE]) # 2. Calculate loss loss = loss_fn(y_pred, y_train[batch:batch+BATCH_SIZE]) # 3. Zero grad optimizer optimizer.zero_grad() # 4. Loss backward loss.backward() # 5. Step the optimizer optimizer.step() ### Testing model.eval() # put the model in evaluation mode for testing (inference) # 1. Forward pass with torch.inference_mode(): test_pred = model(X_test[batch:batch+BATCH_SIZE]) # 2. Calculate the loss test_loss = loss_fn(test_pred, y_test[batch:batch+BATCH_SIZE]) if epoch % 100 == 0: print(f"Epoch: {epoch} | Train loss: {loss} | Test loss: {test_loss}")
报错信息:
RuntimeError: mat1 and mat2 shapes cannot be multiplied (32x1 and 32x32)
问题原因
报错核心是输入数据的特征维度与模型第一层的输入要求不匹配:
- 模型的
hidden1 = nn.Linear(32, 32)要求输入张量的最后一维为32(即每个样本有32个特征)。 - 实际输入的
X_train[batch:batch+BATCH_SIZE]形状为(32, 1),即批量大小32,每个样本仅1个特征。 - 全连接层的矩阵乘法规则要求第一个矩阵的列数等于第二个矩阵的行数,这里
(32,1)的输入与(32,32)的层权重无法满足相乘条件,因此触发报错。
解决方案
根据数据实际情况,选择以下一种方式修正:
- 调整模型输入维度:如果数据确实每个样本只有1个特征,修改模型第一层的输入特征数为1:
self.hidden1 = nn.Linear(1, 32) # 将in_features从32改为1 - 调整输入数据形状:如果数据实际有32个特征,但当前形状错误(比如维度顺序颠倒或缺失),通过
reshape或unsqueeze修正:# 将输入调整为[样本数, 32]的形状 X_train = X_train.reshape(-1, 32) X_test = X_test.reshape(-1, 32) - 检查数据预处理:确认
x_scaled的预处理流程是否正确,是否误将32维特征压缩为1维。
额外注意事项
训练循环的测试部分存在潜在问题:当X_test样本数不是BATCH_SIZE的整数倍时,最后一次切片会获取到不足32个样本的张量。建议使用PyTorch的DataLoader管理批量数据,替代手动切片,避免此类问题。
内容的提问来源于stack exchange,提问作者AlterEGO
相关产品推荐
相关产品推荐

