我实现了一个简单的线性回归,但结果却很糟糕。只是想知道这些结果是否正常,或者我在犯一些错误。
我尝试了不同的优化程序和学习率,但总是会得到不好的结果
这是我的代码:
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
答案 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
,因此您可以尝试将5
与1000
的乘积增加,然后看看weight
和bias
将被学习。)
请阅读有关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()
我知道深度学习在不良代码和致命实践中享有盛名,但是请并不能帮助推广这种方法。