Useful operations you must know to begin PyTorch
import torch
import numpy as np
import os
import ipyparams
<IPython.core.display.Javascript object>
Initialize tensors with known values
a is an integer tensor created in the CPU memory.
b is a float tensor created in the CPU memory.
c is a float tensor created in the GPU memory.
d is a float tensor created in the GPU memory which also stores its gradient.
a = torch.tensor([[1,2,3],[4,5,6]])
print(a)
b = torch.tensor([[1,2,3],[4,5,6]], dtype = torch.float32)
print(b)
c = torch.tensor([[1,2,3],[4,5,6]], dtype = torch.float32, device = 'cuda')
print(c)
d = torch.tensor([[1,2,3],[4,5,6]], dtype = torch.float32, device = 'cuda', requires_grad = True)
print(d)
tensor([[1, 2, 3],
[4, 5, 6]])
tensor([[1., 2., 3.],
[4., 5., 6.]])
tensor([[1., 2., 3.],
[4., 5., 6.]], device='cuda:0')
tensor([[1., 2., 3.],
[4., 5., 6.]], device='cuda:0', requires_grad=True)
Another initializers
xe is an uninitialized tensor.
xz is a zero tensor.
xr initializersis a random tensor.
xi is an identity tensor.
xe = torch.empty(size = (3,3))
xz = torch.zeros((3,3))
xr = torch.rand(3) # size = (1,3)
print(xr)
xi = torch.eye(3)
print(xi)
tensor([0.1361, 0.1786, 0.3227])
tensor([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Initialize a tensor with a series of numbers from start to end inclusive by step
xa = torch.arange(start = 0, end = 5, step = 1)
print(xa)
tensor([0, 1, 2, 3, 4])
Initialize a tensor with a series of numbers from start to end with steps
xl = torch.linspace(start = 0, end = 5, steps = 10) print(xl)
To generate Gausiian random numbers
torch.randn(1,5)
xn = torch.empty(size = (1,5)).normal_(mean = 0, std = 1)
print(xn)
tensor([[ 1.0059, -0.2311, 0.8946, 0.7181, 0.0745]])
To generate random numbers of uniform distribution
torch.rand(5)
xu = torch.empty(1,5).uniform_(0,1)
print(xu)
tensor([[0.9168, 0.1489, 0.6728, 0.6304, 0.3752]])
To create a diagonal matrix
xd = torch.diag(torch.tensor([1,2,3])) # error: torch.diag([1,2,3])
print(xd)
tensor([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
Conversion between a tensor and a numpy array
np_array = np.zeros((5,5))
tensor = torch.from_numpy(np_array)
np_array_back = tensor.numpy()
Elementwise multiplication and division
e1 = torch.rand(3, 2)
e2 = torch.rand(3, 2)
e3 = e1 * e2 # e3 = torch.dot(e1, e2)
e4 = e1 / e2 # e4 = torch.true_divide(e1, e2)
e5 = torch.true_divide(e1, e2)
Elementwise exponentiation
x = torch.rand(3,3)
z = x**2 # z = x.pow(2)
Matrix multiplication
x1 = torch.rand(2,5)
x2 = torch.rand(5,3)
x3 = torch.mm(x1, x2) # x3 = x1.mm(x2)
Batch matrix multiplication
batch = 32
n = 10
m = 20
p = 30
t1 = torch.rand(batch, n, m)
t2 = torch.rand(batch, m, p)
t3 = torch.bmm(t1, t2) # batch x n x p
Matrix exponentiation
me = torch.rand(5, 5)
me1 = torch.matrix_power(me, 3) # me1 = me.matrix_power(3)
Transpose
x = torch.arange(9)
x_3x3 =x.view(3,3) # Reshaping a tensor which is applied for a contiguous memory
y = x_3x3.t() # This is not a contiguous memory
y1 = y.contiguous().view(9) # or use y1 = y.reshape(3,3),
# which can be applied for a non-contigous memory
Permute
x = torch.rand(10, 3, 5) # size 10x3x5
y = x.permute(0, 2, 1) # size 10x5x3
Concatenation
x1 = torch.rand(2,5)
x2 = torch.rand(2,5)
x3 = torch.cat((x1, x2)) # default: concatenation in the o-th dimension
print(x3.size())
x4 = torch.cat((x1, x2), dim = 1)
print(x4.size())
torch.Size([4, 5])
torch.Size([2, 10])
Unsqeeze and sqeeze
x = torch.arange(10) # 10
print(x)
x.unsqueeze_(-2) # or torch.unsqueeze(x, 0) # 1x10
print(x)
x.unsqueeze_(-1) # or torch.unsqueeze(x, 0) # 1x10x1
print(x)
x.unsqueeze_(0) # or torch.unsqueeze(x, 0) # 1x1x10x1
print(x)
x.unsqueeze_(1) # or torch.unsqueeze(x, 1) # 1x1x1x10x1
print(x)
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
tensor([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
tensor([[[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]]])
tensor([[[[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]]]])
tensor([[[[[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]]]]])
Type conversion
x = torch.tensor([[1,2,3], [-4,5,6], [7,8,9]])
xb = x.bool() # boolean
xby = x.byte() # uint8
xs = x.short() # int16
xi = x.int() # int32
xl = x.long() # int64
xh = x.half() # float16
xf = x.float() # float32
xd = x.double() # float64
Indexing
x = torch.arange(10) # x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y = x[(x < 2) & (x > 0)] # y = [1]
z = x[3:6] # z = [3, 4, 5]
Statistical functions
x1 = torch.tensor([[1,2,3], [-4,5,6], [7,8,9]])
xa = torch.abs(x1)
sum_x1 = torch.sum(x1, dim = 0) # vertical sum
mean_x1 = torch.mean(x1.float(), dim = 0)
values, indices = torch.max(x1, dim = 0)
values, indices = torch.min(x1, dim = 0)
z1 = torch.argmax(x1, dim = 0)
z2 = torch.argmin(x1, dim = 0)
sorted_x1, indices = torch.sort(x1, dim = 0, descending = False) # sorting in the ascending
# order
Logic
x = torch.tensor([[1, 0, 2, 1], [1, 1, 1, 1]])
y = torch.tensor([[1, 1, 2, 2], [1, 1, 1, 1]])
a1 = x.any() # Is there any non-zero element?
a2 = x.all() # Are all elements non-zero?
a3 = torch.eq(x, y) # elementwise comparison
Miscellaneous
x = torch.arange(10)
r = x.remainder(2) # modulus 2
e = x.numel() # number of elements
n = x.ndimension() # dimension
u = torch.unique(x) # eliminates non-consecutive duplicate values
"""
w = []
for xe in x:
if xe > 5:
w.append(xe)
else:
w.append(xe*2)
"""
w = torch.where(x > 5, x, x*2) # [0, 2, 4, 6, 8, 10, 6, 7, 8, 9]