In [1]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import torch
from torch.autograd import Variable
import torch.nn as nn
In [2]:
X = np.arange(-5,5,0.01)
y = 4*X**3 + 2**X + 3
print(X.shape, y.shape)
In [3]:
plt.plot(X,y)
Out[3]:
In [4]:
batch = Variable(torch.from_numpy(X[:4, np.newaxis]))
batch
Out[4]:
In [5]:
torch.cat((batch, batch), 1)
Out[5]:
In [6]:
batch = Variable(torch.from_numpy(X[:4, np.newaxis])).float() ## Converting to float is important for GPU
batch
Out[6]:
In [7]:
nn.Linear(1,3)(batch)
Out[7]:
In [8]:
target = Variable(torch.from_numpy(y[:4, np.newaxis])).float()
target
Out[8]:
In [9]:
hidden = Variable(torch.zeros(1,3))
hidden
Out[9]:
In [10]:
h = nn.Linear(3,3)(hidden)
h
Out[10]:
In [11]:
x = nn.Linear(1,3)(batch)
x
Out[11]:
In [12]:
try:
x + h ## Will give error
except RuntimeError as e:
print(e)
In [13]:
h.expand_as(x) ## This makes h same size as x and compatible for addition
Out[13]:
In [14]:
x + h.expand_as(x) ## Finally
Out[14]:
In [15]:
x.size()
Out[15]:
In [16]:
x.size(0)
Out[16]:
In [17]:
x.size()[0], x.size()[1],
Out[17]:
In [18]:
isinstance(x.size(), tuple)
Out[18]:
In [19]:
x
Out[19]:
In [20]:
x.data
Out[20]:
In [21]:
try:
x.numpy()
except AttributeError as e:
print("Numpy conversion happens only on tensors and not variables.")
print(e)
In [22]:
x.data.numpy() ## succeeds
Out[22]:
In [23]:
np.random.seed(1337)
X = np.random.randn(1000,1)*4
W = np.array([0.5,])
bias = -1.68
In [24]:
y_true = np.dot(X, W) + bias
y = y_true + np.random.randn(X.shape[0])
In [25]:
plt.scatter(X, y, s=1, label="data")
plt.scatter(X, y_true, s=1, color='r', label="true")
plt.legend()
Out[25]:
In [26]:
def get_variable_from_np(X):
return Variable(torch.from_numpy(X)).float()
class LinearRegression(nn.Module):
def __init__(self, input_size, output_size):
super(LinearRegression, self).__init__()
self.x2o = nn.Linear(input_size, output_size)
def forward(self, X):
return self.x2o(X)
In [27]:
batch_size = 10
batch = get_variable_from_np(X[:batch_size])
batch
Out[27]:
In [28]:
model = LinearRegression(1, 1)
In [29]:
y_pred = model.forward(batch)
y_pred
Out[29]:
In [30]:
batch = get_variable_from_np(X[:])
y_pred = model.forward(batch)
y_pred_np = y_pred.squeeze().data.numpy()
plt.scatter(X, y, s=1, label="data")
plt.scatter(X, y_true, s=1, color='r', label="true")
plt.scatter(X, y_pred_np, s=1, color='k', alpha=0.5, label="fit")
plt.legend()
Out[30]:
In [31]:
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
losses = []
In [32]:
batch_size = 10
epochs = 100
print_every = 10
for i in range(epochs):
loss = 0
optimizer.zero_grad() # Important for each epoch
idx = np.random.randint(X.shape[0], size=batch_size)
batch = get_variable_from_np(X[idx])
target = get_variable_from_np(y[idx])
output = model.forward(batch)
loss += criterion(output, target)
loss.backward() # Calculate the gradients
optimizer.step() # Updates the parameters of the model
if (i+1) % print_every == 0:
print("Loss at epoch [%s]: %.3f" % (i, loss.data[0]))
losses.append(loss.data[0])
plt.plot(losses, '-or')
plt.xlabel("Epoch")
plt.xlabel("Loss")
Out[32]:
In [33]:
batch = get_variable_from_np(X[:])
y_pred = model.forward(batch)
y_pred_np = y_pred.squeeze().data.numpy()
plt.scatter(X, y, s=1, label="data")
plt.scatter(X, y_true, s=1, color='r', label="true")
plt.scatter(X, y_pred_np, s=1, color='k', alpha=0.5, label="fit")
plt.legend()
Out[33]:
In [34]:
list(model.x2o.parameters())
Out[34]:
In [35]:
model.x2o.weight
Out[35]:
In [36]:
model.x2o.bias
Out[36]:
In [37]:
print("Model W: %.3f, True W: %.3f" % (model.x2o.weight.data.numpy(), W))
print("Model bias: %.3f, True bias: %.3f" % (model.x2o.bias.data.numpy(), bias))
In [38]:
batch = Variable(torch.randn(10,3))
target = Variable(torch.randn(10,1))
no_gpu_model = LinearRegression(input_size=3, output_size=1)
In [39]:
no_gpu_model.forward(batch).size()
Out[39]:
In [40]:
torch.cuda.is_available()
Out[40]:
In [41]:
if torch.cuda.is_available():
gpu_model = no_gpu_model.cuda()
try:
print(gpu_model.forward(batch))
except TypeError as e:
print(e)
I have opened an issue related to the above error at: https://github.com/pytorch/pytorch/issues/584
In [42]:
if torch.cuda.is_available():
gpu_model = no_gpu_model.cuda()
try:
print(gpu_model.forward(batch.cuda()).size())
except TypeError as e:
print(e)
GPU to CPU fallback supported model
In [43]:
class LinearRegression(nn.Module):
def __init__(self, input_size, output_size):
super(LinearRegression, self).__init__()
self.x2o = nn.Linear(input_size, output_size)
def forward(self, X):
if next(self.x2o.parameters()).is_cuda:
if not X.is_cuda:
X = X.cuda()
return self.x2o(X)
In [44]:
batch = Variable(torch.randn(10,3))
target = Variable(torch.randn(10,1))
no_gpu_model = LinearRegression(input_size=3, output_size=1)
print("No GPU model: ", no_gpu_model.forward(batch).size())
if torch.cuda.is_available():
gpu_model = no_gpu_model.cuda()
try:
print("GPU model: ", gpu_model.forward(batch.cuda()).size())
except TypeError as e:
print(e)
In [ ]: