Linear Regression using pyTorch

In [3]:
import torch
import torch.nn as nn
from torch.autograd import Variable
import numpy as np
In [17]:
# Training Data
train_X = np.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,
                         7.042,10.791,5.313,7.997,5.654,9.27,3.1],dtype='float32')
train_Y = np.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,
                         2.827,3.465,1.65,2.904,2.42,2.94,1.3],dtype='float32')
n_samples = train_X.shape[0]
In [18]:
print(train_X.shape)
train_X = train_X.reshape(-1,1) # Note the Size of this numpy array after reshape
train_Y = train_Y.reshape(-1,1)
print(train_X.shape)
(17,)
(17, 1)

Create Model

1) Derive from nn.Module
2) write the forward() function
In [12]:
class linearRegModel(nn.Module):
    def __init__(self,input_dim,output_dim):
        super(linearRegModel,self).__init__()
        #Applies a linear transformation to the data: :math:`y = Ax + b`
        self.linear = nn.Linear(input_dim,output_dim)
    def forward(self,x):
        out = self.linear(x)
        return out
In [13]:
input_dim = 1 #In our simple Example we are trying to find linear fit for set of points (x,y)
output_dim = 1

#Create Model
model = linearRegModel(1,1)

#Create Loss Function. This should be a scalar to use backward from pyTorch
criterion = nn.MSELoss()

#Create Optimizer
learning_rate=0.014
optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate)
In [21]:
epochs = 1000
displayStep = 50
for epoch in range(epochs):
    #Create Torch Variables from numpy Array
    inp = Variable(torch.from_numpy(train_X))
    labels = Variable(torch.from_numpy(train_Y))
    
    #Clear Gradients in the Optimizer every epoch
    optimizer.zero_grad()
    
    outputs = model(inp) # This actually calls operator() and it has some bells and whistles before it calls forward
    
    loss = criterion(outputs,labels)
    
    #Get the Gradients w.r.t Params
    loss.backward()
    
    #Update the Parameters
    optimizer.step()
    
    if(epoch%displayStep==0):
        print('epoch {}, loss {}'.format(epoch,loss.data[0])) # Note How the Scalar Value loss is being accessed
    
epoch 0, loss 0.26262953877449036
epoch 50, loss 0.23915916681289673
epoch 100, loss 0.22075317800045013
epoch 150, loss 0.2063187211751938
epoch 200, loss 0.1949988454580307
epoch 250, loss 0.1861215978860855
epoch 300, loss 0.17915979027748108
epoch 350, loss 0.17370019853115082
epoch 400, loss 0.16941866278648376
epoch 450, loss 0.16606095433235168
epoch 500, loss 0.16342777013778687
epoch 550, loss 0.16136279702186584
epoch 600, loss 0.15974336862564087
epoch 650, loss 0.15847337245941162
epoch 700, loss 0.1574774533510208
epoch 750, loss 0.1566963940858841
epoch 800, loss 0.1560838520526886
epoch 850, loss 0.15560346841812134
epoch 900, loss 0.1552267223596573
epoch 950, loss 0.15493136644363403
In [22]:
import matplotlib.pyplot as plt
%matplotlib inline
In [27]:
plt.plot(train_X,train_Y,'ro',label="Original Data")
#Note: How Data needs to be converted to Variable before calling the model
Pred_Y = model(Variable(torch.from_numpy(train_X)))

#Note: How data is extracted from a Torch Variable
plt.plot(train_X,Pred_Y.data.numpy(),label="Fitted Line")
Out[27]:
[<matplotlib.lines.Line2D at 0xa26bef0>]
In [ ]: