HTML generated from Jupyter notebook: pytorch-basics.ipynb

The basics

You can find excellent documentation for Pytorch at https://pytorch.org/docs/stable/index.html

In [38]:
import torch
In [39]:
t = torch.tensor([[1,2,3],[4,5,6]])
t
Out[39]:
tensor([[1, 2, 3],
        [4, 5, 6]])
In [40]:
t.t()
Out[40]:
tensor([[1, 4],
        [2, 5],
        [3, 6]])
In [41]:
print(t.permute(-1,0))
tensor([[1, 4],
        [2, 5],
        [3, 6]])
In [42]:
print('shape:',t.shape)
print('size:',t.size())
print('dim:',t.dim())
print('type:',t.type())
print('num elements:', torch.numel(t))
shape: torch.Size([2, 3])
size: torch.Size([2, 3])
dim: 2
type: torch.LongTensor
num elements: 6

Changing tensor views

In [52]:
t = torch.tensor([[1,2,3],[4,5,6]])

print(t)
print('View example:\n', t.view(1,-1))
print('View example:\n', t.view(-1,1))
print('View example:\n', t.view(3,2))
tensor([[1, 2, 3],
        [4, 5, 6]])
View example:
 tensor([[1, 2, 3, 4, 5, 6]])
View example:
 tensor([[1],
        [2],
        [3],
        [4],
        [5],
        [6]])
View example:
 tensor([[1, 2],
        [3, 4],
        [5, 6]])

Slicing

In [44]:
# First row
print('Matlab or numpy style slicing:\n',t[1,:])

# Second column
print('Matlab or numpy style slicing:\n',t[:,1])

# Lower right most element
print('Matlab or numpy style slicing:\n',t[-1,-1])

# Lower right most 1 x 1 submatrix
print('Matlab or numpy style slicing:\n',t[-1:,-1:])

# Lower right most 2 x 2submatrix
print('Matlab or numpy style slicing:\n',t[-2:,-2:])
Matlab or numpy style slicing:
 tensor([4, 5, 6])
Matlab or numpy style slicing:
 tensor([2, 5])
Matlab or numpy style slicing:
 tensor(6)
Matlab or numpy style slicing:
 tensor([[6]])
Matlab or numpy style slicing:
 tensor([[2, 3],
        [5, 6]])

Torch and Numpy

In [54]:
import numpy as np

a = np.random.randn(2, 4)

# Constructing a torch tensor from a numpy array
t = torch.from_numpy(a)

# Back to numpy
b = t.numpy()

print('numpy:\n', a)
print('torch:\n', t)
print(type(a))
print(type(t))
print(type(b))
numpy:
 [[-1.83469076 -3.24983939  0.01820917 -2.30882129]
 [ 0.10859685 -2.29857205 -0.56827454 -0.34940507]]
torch:
 tensor([[-1.8347, -3.2498,  0.0182, -2.3088],
        [ 0.1086, -2.2986, -0.5683, -0.3494]], dtype=torch.float64)
<class 'numpy.ndarray'>
<class 'torch.Tensor'>
<class 'numpy.ndarray'>

Some common schemes for tensor creation

In [47]:
# A zero tensor
print('Zero tensor:\n', torch.zeros(2,3,4))

# A one tensor
print('Ones tensor:\n', torch.ones(2,3,4))

# Some random tensors
print('Random - Uniform, between 0 and 1):\n', torch.rand(2,3,4))
print('Random - Normal, mean 0 and standard deviation 1 :\n', torch.randn(2,3,4))
Zero tensor:
 tensor([[[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]],

        [[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]]])
Ones tensor:
 tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]],

        [[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])
Random - Uniform, between 0 and 1):
 tensor([[[0.7195, 0.8974, 0.2553, 0.8781],
         [0.4330, 0.9897, 0.1136, 0.7497],
         [0.3699, 0.1504, 0.8127, 0.9753]],

        [[0.8365, 0.6016, 0.1002, 0.1545],
         [0.2338, 0.2391, 0.1702, 0.7490],
         [0.1597, 0.3666, 0.0014, 0.0194]]])
Random - Normal, mean 0 and standard deviation 1 :
 tensor([[[ 0.4914,  1.6938, -1.2021, -0.6227],
         [-1.2622, -0.1029, -1.5681,  0.3354],
         [ 0.8180, -0.0373, -0.9285,  0.2488]],

        [[-1.3298, -0.1274,  0.9967, -2.1217],
         [ 1.1931, -2.5695,  0.3961, -0.2329],
         [ 0.8081, -1.0356, -1.8319,  0.1061]]])

Tensor concatenation

In [10]:
t1 = torch.tensor([[1,2,3],[4,5,7]])
t2 = torch.tensor([[8,9,10],[11,12,13]])

print('t1:\n', t1)
print('t2:\n', t2)

# Concatenating two tensors along 0 (first, rows in this case) dimension
print(torch.cat((t1,t2),0))

# Concatenating two tensors along 1 (second, columns in this case) dimension
print(torch.cat((t1,t2),1))
t1:
 tensor([[1, 2, 3],
        [4, 5, 7]])
t2:
 tensor([[ 8,  9, 10],
        [11, 12, 13]])
tensor([[ 1,  2,  3],
        [ 4,  5,  7],
        [ 8,  9, 10],
        [11, 12, 13]])
tensor([[ 1,  2,  3,  8,  9, 10],
        [ 4,  5,  7, 11, 12, 13]])
In [30]:
t = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])

# Computing cummulative sum
print(t)
print(t.cumsum(-1))
print(t.cumsum(-2))
tensor([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])
tensor([[ 1,  3,  6],
        [ 4,  9, 15],
        [ 7, 15, 24]])
tensor([[ 1,  2,  3],
        [ 5,  7,  9],
        [12, 15, 18]])

Adding a dimension to a tensor

Tensor Concatnation

In [32]:
# First, the numpy way
x = np.random.rand(3,4)
print('Before', x.shape)
x = x[None,:,:]
print('After', x.shape)

# Next, the torch way
t = torch.rand(3,4)
print('Before:', t.shape)
t1 = t.unsqueeze(0)
print('After:', t1.shape)

# Say we get another 3x4 matrix (say a grayscale image or a frame)
t2 = torch.rand(3,4)

# Say we want to combine t1 and t2, such that the first dimension
# iterates over the frames

t.unsqueeze_(0) # inplace unsqueeze, we just added a dimension
t2.unsqueeze_(0)

t_and_t2 = torch.cat((t1,t2),0) # The first dimension is the 
print(t_and_t2.shape)
Before (3, 4)
After (1, 3, 4)
Before: torch.Size([3, 4])
After: torch.Size([1, 3, 4])
torch.Size([2, 3, 4])

Testing for equality

In [55]:
t1 = torch.tensor([[1,2,3],[4,5,6],[7,8,9]])
t2 = torch.tensor([[1,20,3],[40,5,6],[7,8,9]])

# Element wise equality test
print(torch.eq(t1,t2))
tensor([[1, 0, 1],
        [0, 1, 1],
        [1, 1, 1]], dtype=torch.uint8)
In [81]:
t = torch.rand(2,3)
print('t:\n', t)

# Log
print('log t:\n', torch.log(t))

# Negative
print('neg t:\n', torch.neg(t))

# Power
print('power t:\n', torch.pow(t, 2))

# Reciprocal
print('reciprocal t:\n', torch.reciprocal(t))

# Round
print('round t:\n', torch.round(t))

# Sigmoid
print('sigmoid t:\n', torch.sigmoid(t))

# Sign
print('sign t:\n', torch.sign(t))

# sqrt
print('sqrt t:\n', torch.sqrt(t))

# argmax, along 0-th dimension (that moves along the rows)
print('argmax t:\n', torch.argmax(t, 0))

# mean, along 1-th dimension (that moves along the columns)
print('mean t:\n', torch.mean(t, 1))
t:
 tensor([[0.2439, 0.3184, 0.6584],
        [0.1138, 0.8716, 0.5599]])
log t:
 tensor([[-1.4112, -1.1445, -0.4179],
        [-2.1732, -0.1374, -0.5801]])
neg t:
 tensor([[-0.2439, -0.3184, -0.6584],
        [-0.1138, -0.8716, -0.5599]])
power t:
 tensor([[0.0595, 0.1014, 0.4335],
        [0.0130, 0.7597, 0.3134]])
reciprocal t:
 tensor([[4.1008, 3.1410, 1.5188],
        [8.7862, 1.1473, 1.7862]])
round t:
 tensor([[0., 0., 1.],
        [0., 1., 1.]])
sigmoid t:
 tensor([[0.5607, 0.5789, 0.6589],
        [0.5284, 0.7051, 0.6364]])
sign t:
 tensor([[1., 1., 1.],
        [1., 1., 1.]])
sqrt t:
 tensor([[0.4938, 0.5642, 0.8114],
        [0.3374, 0.9336, 0.7482]])
argmax t:
 tensor([0, 1, 0])
mean t:
 tensor([0.4069, 0.5151])

Vector and Matrix products

In [33]:
t1 = torch.tensor([0,1,0])
t2 = torch.tensor([1,0,0])
print(t1.cross(t2))
tensor([ 0,  0, -1])
In [34]:
t1 = torch.randn(4,3)
t2 = torch.randn(4,3)

# Row-wise vector cross product 
t1_cross_t2 = t1.cross(t2)

# Confirm that the dot products of the result with 
# the corresponding vectors in t1 and t2 is 0
for i in range(t1.size(0)):
    print('Row %d' % i, t1[i,:].dot(t1_cross_t2[i,:]))
Row 0 tensor(2.9802e-08)
Row 1 tensor(0.)
Row 2 tensor(2.9802e-08)
Row 3 tensor(0.)
In [35]:
m1 = torch.randn(4,3)
m2 = torch.randn(3, 2)

print('m1:\n', m1)
print('m2:\n', m2)
# Matrix multiplication
print('Matrix multiplication:\n', m1.mm(m2))
m1:
 tensor([[-0.7391, -0.2288, -1.1205],
        [-0.1904, -1.6060, -2.5085],
        [-0.5796,  0.5351,  2.2772],
        [-1.4934,  0.6584,  1.4462]])
m2:
 tensor([[ 1.2603,  0.3118],
        [-0.9736, -1.0500],
        [ 1.2579,  0.4808]])
Matrix multiplication:
 tensor([[-2.1181, -0.5289],
        [-1.8316,  0.4209],
        [ 1.6130,  0.3523],
        [-0.7040, -0.4617]])
In [36]:
m1 = torch.tensor([[1,2],[3,4]], dtype=torch.float32)
m2 = torch.tensor([[2,4],[-1,6]], dtype=torch.float32)
print('m1:\n', m1)
print('m2:\n', m2)
# Element-wise multiplication
print('Element-wise multiplication:\n', m1.mul(m2))
m1:
 tensor([[1., 2.],
        [3., 4.]])
m2:
 tensor([[ 2.,  4.],
        [-1.,  6.]])
Element-wise multiplication:
 tensor([[ 2.,  8.],
        [-3., 24.]])

CUDA GPU Support

In [37]:
# Checking if CUDA GPU is available
result = torch.cuda.is_available()
print('CUDA available (T/F):', result)

# How many CUDA devices are available?
result = torch.cuda.device_count()
print('Number of CUDA devices available:', result)
CUDA available (T/F): False
Number of CUDA devices available: 0