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 :
import torch

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

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

Out:
tensor([[1, 4],
[2, 5],
[3, 6]])
In :
print(t.permute(-1,0))

tensor([[1, 4],
[2, 5],
[3, 6]])

In :
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 :
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([,
,
,
,
,
])
View example:
tensor([[1, 2],
[3, 4],
[5, 6]])


## Slicing¶

In :
# 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([])
Matlab or numpy style slicing:
tensor([[2, 3],
[5, 6]])


## Torch and Numpy¶

In :
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 :
# 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 :
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 :
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¶ In :
# 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 :
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 :
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 :
t1 = torch.tensor([0,1,0])
t2 = torch.tensor([1,0,0])
print(t1.cross(t2))

tensor([ 0,  0, -1])

In :
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 :
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 :
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 :
# 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