RuntimeError: mat1 and mat2 shapes cannot be multiplied (1x20 and 1x1)

RuntimeError: mat1 and mat2 shapes cannot be multiplied (1x20 and 1x1)

我是 AI 新手,按照教程构建了线性回归模型。当我转到 运行 代码时,我得到一个 RuntimeError,它说“mat1 和 mat2 形状不能相乘(1x20 和 1x1)”,我认为 x_train 变量可能是导致这个问题的原因,但我不知道如何修复它。这是这个程序的代码。

import torch
import torch.utils.data
import torch.nn as nn
import matplotlib.pyplot as plt


x_train = torch.arange(1,21,dtype=torch.float32)
true_w = 2.0
true_b = 3
y_true = torch.tensor(true_w*x_train+true_b,dtype=torch.float32)
y_train = y_true-torch.normal(mean=0,std=5,size=(1,20))

net = nn.Sequential(
    nn.Linear(1,1)
)
epochs = 1000
learning_rate = 0.01
optimizer = torch.optim.SGD(net.parameters(),lr=learning_rate

for epoch in range(epochs):
    optimizer.zero_grad()
    # outputs = net(x_train)
    # loss  = nn.MSELoss(outputs,y_true)
# line below caused RuntimeError: mat1 and mat2 shapes cannot be multiplied (1x20 and 1x1)
    outputs = net(x_train)
    loss = nn.MSELoss(outputs,y_true)
    if epoch %100==0:
        print('epoch:{},loss:{}'.format(epoch,loss.item()))
    loss.backward()
    loss.step()

您的 x_train 具有形状 torch.Size([20]),您的模型认为它是具有 20 个特征的向量,但您的模型被定义为 nn.Linear(1,1),因此它期望输入大小为 1。

如果你希望x_train是一批20个大小为1的样本,你可以使用unsqueeze()添加一个额外的维度:

x_train = torch.arange(1,21,dtype=torch.float32).unsqueeze(1)
print(x_train.shape)

输出将为 torch.Size([20, 1]),因此您的输入现在的批次维度为 20,每个示例的大小为 1。

我认为您的训练循环中还有其他一些问题需要解决:

  • 您应该先创建 MSELoss 对象,然后在循环中调用它而不是 re-creating 每个时期都调用它。
  • loss.step() 会抛出一个错误:你应该改为调用 optimizer.step()

最终代码如下所示:

import torch
import torch.utils.data
import torch.nn as nn
import matplotlib.pyplot as plt

x_train = torch.arange(1, 21, dtype=torch.float32).unsqueeze(1)
true_w = 2.0
true_b = 3
y_true = torch.tensor(true_w*x_train+true_b, dtype=torch.float32)
y_train = y_true - torch.normal(mean=0, std=5, size=(1,20))

net = nn.Sequential(nn.Linear(1, 1))
epochs = 1000
learning_rate = 0.01
optimizer = torch.optim.SGD(net.parameters(), lr=learning_rate)
criterion = nn.MSELoss()

for epoch in range(epochs):
    optimizer.zero_grad()
    outputs = net(x_train)
    loss = criterion(outputs, y_true)
    if epoch %100==0:
        print('epoch:{},loss:{}'.format(epoch,loss.item()))
    loss.backward()
    optimizer.step()