pytorch线性回归给出错误结果

时间:2019-03-20 21:12:11

标签: linear-regression pytorch

我实现了一个简单的线性回归,但结果却很糟糕。只是想知道这些结果是否正常,或者我在犯一些错误。

我尝试了不同的优化程序和学习率,但总是会得到不好的结果

这是我的代码:

import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from torch.autograd import Variable 

class LinearRegressionPytorch(nn.Module):

   def __init__(self, input_dim=1, output_dim=1):

       super(LinearRegressionPytorch, self).__init__()
       self.linear = nn.Linear(input_dim, output_dim)

   def forward(self,x):
       x = x.view(x.size(0),-1)
       y = self.linear(x)
       return y

input_dim=1 
output_dim = 1
if torch.cuda.is_available():
   model = LinearRegressionPytorch(input_dim, output_dim).cuda()
else:
   model = LinearRegressionPytorch(input_dim, output_dim) 

criterium = nn.MSELoss()
l_rate =0.00001
optimizer = torch.optim.SGD(model.parameters(), lr=l_rate)
#optimizer = torch.optim.Adam(model.parameters(),lr=l_rate)
epochs = 100

#create data
x = np.random.uniform(0,10,size = 100) #np.linspace(0,10,100); 
y = 6*x+5
mu = 0
sigma = 5
noise =  np.random.normal(mu, sigma, len(y))
y_noise = y+noise

#pass it to pytorch
x_data = torch.from_numpy(x).float()
y_data = torch.from_numpy(y_noise).float()
if torch.cuda.is_available():
   inputs = Variable(x_data).cuda()
   target = Variable(y_data).cuda()
else:
   inputs = Variable(x_data)
   target = Variable(y_data)

for epoch in range(epochs):

   #predict data
   pred_y= model(inputs)

   #compute loss
   loss = criterium(pred_y, target)

   #zero grad and optimization
   optimizer.zero_grad()
   loss.backward()
   optimizer.step()

   #if epoch % 50 == 0:
   #   print(f'epoch = {epoch}, loss =  {loss.item()}')


#print params
for name, param in model.named_parameters():
   if param.requires_grad:
       print(name, param.data)

结果很差:

linear.weight tensor([[1.7374]], device='cuda:0')
linear.bias tensor([0.1815], device='cuda:0')

结果应为权重= 6,偏差= 5

1 个答案:

答案 0 :(得分:1)

问题解决方案

实际上您的batch_size有问题。如果您将其设置为1,则您的target需要与输出相同的形状(正确的是,您要用view(-1, 1)进行重塑)。

您的损失应定义为:

loss = criterium(pred_y, target.view(-1, 1))

此网络正确

结果

您的结果不会 bias=5(是的,weight确实会走向6),因为您正在向target添加随机噪声(由于它是所有数据点的单个值,因此仅bias会受到影响。)

如果您想让bias等于5,请消除噪声。

您还应该增加时期数,因为您的数据非常小并且网络(实际上是线性回归)的功能并不强大。 10000说应该没问题,您的损耗应该在0附近振荡(如果您将噪声更改为合理的值)。

噪音

您正在创建具有不同变化的多个高斯分布,因此损失会更高。线性回归无法拟合您的数据并无法找到合理的偏差(由于噪声的最佳斜率仍约为6,因此您可以尝试将51000的乘积增加,然后看看weightbias将被学习。)

样式(有点题外话)

请阅读有关PyTorch的文档,并使代码保持最新(例如,Variable已弃用Tensor,理应如此)。

这部分代码:

x_data = torch.from_numpy(x).float()
y_data = torch.from_numpy(y_noise).float()
if torch.cuda.is_available():
    inputs = Tensor(x_data).cuda()
    target = Tensor(y_data).cuda()
else:
    inputs = Tensor(x_data)
    target = Tensor(y_data)

可以这样简洁地写(无需过多思考):

inputs = torch.from_numpy(x).float()
target = torch.from_numpy(y_noise).float()
if torch.cuda.is_available():
    inputs = inputs.cuda()
    target = target.cuda()

我知道深度学习在不良代码和致命实践中享有盛名,但是并不能帮助推广这种方法。