pytorch linear regression given wrong results
I implemented a simple linear regression and I’m getting some poor results. Just wondering if these results are normal or I’m making some mistake.

I tried different optimizers and learning rates, I always get bad/poor results

Here is my code:

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)


There are the poor results :

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


The results should be weight = 6 , bias = 5

Problem Solution

Actually your batch_size is problematic. If you have it set as one, your targetneeds the same shape as outputs (which you are, correctly, reshaping with view(-1, 1)).

Your loss should be defined like this:

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


This network is correct

Results

Your results will not be bias=5 (yes, weight will go towards 6 indeed) as you are adding random noise to target (and as it's a single value for all your data points, only bias will be affected).

If you want bias equal to 5 remove addition of noise.

You should increase number of your epochs as well, as your data is quite small and network (linear regression in fact) is not really powerful. 10000 say should be fine and your loss should oscillate around 0 (if you change your noise to something sensible).

Noise

You are creating multiple gaussian distributions with different variations, hence your loss would be higher. Linear regression is unable to fit your data and find sensible bias (as the optimal slope is still approximately 6 for your noise, you may try to increase multiplication of 5 to 1000 and see what weight and bias will be learned).

Style (a little offtopic)

Please read documentation about PyTorch and keep your code up to date (e.g. Variable is deprecated in favor of Tensor and rightfully so). 

This part of code:

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)


Could be written succinctly like this (without much thought):

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


I know deep learning has it's reputation for bad code and fatal practice, but please do not help spreading this approach.
