L2 Tensors Multidimensional Arrays
L2 Tensors Multidimensional Arrays
Tensors
• PyTorch is a library for Python programs that facilitates building deep
learning projects
• PyTorch is an open-source machine learning library based on the
Torch library, developed by Facebook’s AI Research lab
• Tensors, the basic data structure in PyTorch
• The PyTorch library primarily supports NVIDIA CUDA-based GPUs
Transforming an input representation to an output representation
• A deep neural network typically learns the transformation from one form of data to
another in stages
• This means the partially transformed data between each stage can be thought of as a
sequence of intermediate representations (2nd step in figure).
• Intermediate representations are the results of combining the input with the weights of
the previous layer of neurons.
• Each intermediate representation is unique to the inputs that preceded it
• For image recognition, early representations can be things such as edge detection or
certain textures like fur.
• Deeper representations can capture more complex structures like ears, noses, or eyes.
• In general, such intermediate representations are collections of floating-point numbers
that characterize the input
• Such characterization is specific to the task at hand and is learned from relevant
examples.
• These collections of floating-point numbers and their manipulation are at the heart of
modern AI
Transforming an input representation to an output representation
Verify that the numpy array and torch tensor have similar data types which is float64 as shown above
Methods for NumPy to PyTorch and PyTorch to NumPy
• The two main methods for NumPy to PyTorch (and back again) are:
print("\nResizing") Transposing
print(t.resize_(2, 6)) tensor([[ 1, 7],
# transposing the tensor [ 2, 8],
[ 3, 9],
print("\nTransposing") [ 4, 10],
print(t.transpose(1, 0)) [ 5, 11],
[ 6, 12]])
Restructuring Tensors in Pytorch - reshape vs resize
import torch
Original Tensor:
original_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
tensor([[1, 2, 3],
# Reshape example
[4, 5, 6]])
new_shape = (3, 2)
Reshaped Tensor:
reshaped_tensor = original_tensor.reshape(new_shape)
tensor([[1, 2],
print("Original Tensor:")
print(original_tensor)
[3, 4],
print("Reshaped Tensor:")
[5, 6]])
print(reshaped_tensor)
print()
Resized Tensor (inplace):
# Resize example (inplace) tensor([[1, 2],
new_size = (3, 2) [3, 4],
original_tensor.resize_(new_size) [5, 6]])
print("Resized Tensor (inplace):")
print(original_tensor) Original Tensor:
print() tensor([[1, 2],
# Transpose example [3, 4],
transposed_tensor = original_tensor.transpose(0, 1) [5, 6]])
print("Original Tensor:") Transposed Tensor:
print(original_tensor) tensor([[1, 3, 5],
print("Transposed Tensor:") [2, 4, 6]])
print(transposed_tensor)
Reshape vs resize
• reshape
• The reshape operation is used to change the shape of the tensor. In this example, the
original tensor is reshaped from a 2x3 matrix to a 3x2 matrix.
• The reshape operation is used to change the shape of a tensor while keeping the same
underlying data. It creates a new view of the original tensor with the specified shape.
• resize (Inplace):
• The resize_ operation is an inplace operation used to change the size of the tensor. Here,
the original tensor is resized to a new size of 3x2.
• The resize_ method is the inplace version that modifies the original tensor. It's
recommended to use inplace operations to avoid deprecated warnings
• transpose
• The transpose operation is used to swap dimensions of the tensor. There is no inplace
version of transpose. It always returns a new tensor
Mathematical Operations on Tensors in PyTorch
We can perform various mathematical operations on tensors using Pytorch similar to NumPy arrays
Also works with operators - +, - *, /
import torch
# defining two tensors
t1 = torch.tensor([1, 2, 3, 4])
tensor2 + tensor1
t2 = torch.tensor([5, 6, 7, 8])
tensor([ 6, 8, 10, 12])
# adding two tensors
print("tensor2 + tensor1") tensor2 - tensor1
print(torch.add(t2, t1)) tensor([4, 4, 4, 4])
# subtracting two tensor
tensor2 * tensor1
print("\ntensor2 - tensor1") tensor([ 5, 12, 21, 32])
print(torch.sub(t2, t1))
# multiplying two tensors tensor2 / tensor1
print("\ntensor2 * tensor1") tensor([5.0000, 3.0000, 2.3333, 2.0000])
print(torch.mul(t2, t1))
# diving two tensors
print("\ntensor2 / tensor1")
print(torch.div(t2, t1))
From Python lists to PyTorch tensors
• List indexing vs Tensor indexing
Import the torch module
• List of three numbers in Python Creates a one-dimensional tensor of size 3 filled with 1s
# output
print("\nOutput :\n", torch.matmul(mat_1, mat_2))
Matrix Multiplication using PyTorch - torch.matmul()
matrix A :
tensor([[[ 0.3437, -0.1045, 0.2069],
Ex3: N-dimensional argument (N>2) [-0.7087, 3.0298, 1.8346],
import torch [ 1.0761, -0.2179, -0.0404]],
# creating Tensors using randn() [[ 0.9028, 0.6267, -0.6288],
mat_1 = torch.randn(2, 3, 3) [-0.3468, -0.3376, 1.8786],
mat_2 = torch.randn(3) [-0.9405, -0.8161, 0.2485]]])
matrix B :
# printing the matrices tensor([-0.6310, -0.3815, -0.3336])
print("matrix A :\n", mat_1)
print("\nmatrix B :\n", mat_2) Output :
tensor([[-0.2460, -1.3208, -0.5824],
[-0.5990, -0.2790, 0.8220]])
# output
print("\nOutput :\n", torch.matmul(mat_1, mat_2))
Matrix Multiplication using PyTorch - torch.bmm()
• provides batched matrix multiplication for the cases where both the
matrices to be multiplied are of only 3-Dimensions (x×y×z) and the
first dimension (x) of both the matrices must be same.
• This does not support broadcasting. The syntax is as given below.
Ex: the matrix_1 is of dimension 2×3×3. The second matrix is of dimension 2×3×4.
import torch
# 3D matrices
mat_1 = torch.randn(2, 3, 3)
mat_2 = torch.randn(2, 3, 4)
print("matrix A :\n",mat_1)
print("\nmatrix B :\n",mat_2)
print("\nOutput :\n",torch.bmm(mat_1,mat_2))
Matrix Multiplication using PyTorch - torch.bmm()
matrix A :
tensor([[[ 0.8639, 1.6221, 0.1931], Output :
[ 2.3902, 0.3274, -1.7375], tensor([[[ 1.6419e+00, -4.8024e-01, -1.5295e+00, -1.7787e+00],
[ 0.6995, -0.2053, -0.5686]], [ 9.6655e-01, -5.3465e-04, -3.2939e+00, -4.6965e+00],
[-2.3310e-02, 1.5936e-01, -9.3928e-01, -1.3900e+00]],
[[-0.9331, -0.3916, -0.8546],
[-0.5468, -1.8374, -0.3086], [[-8.1845e-01, 9.7871e-01, 4.3389e-01, -5.3530e-01],
[-2.2238, -1.2308, -1.0526]]]) [-1.1076e+00, 2.1758e+00, 1.8967e+00, 5.6492e-01],
[-2.5444e+00, 3.0107e+00, 1.2547e+00, -1.0021e+00]]])
matrix B :
tensor([[[-7.7382e-02, 5.3086e-01, -1.6793e+00, -
2.2021e+00],
[ 1.1075e+00, -6.5119e-01, 8.2038e-04, 1.1264e-01],
[-4.5405e-01, 6.0790e-01, -4.1423e-01, -3.0507e-01]],
• @ operator:
• The @ – Simon H operator, when applied on matrices performs
multiplication element-wise on 1D matrices and
• normal matrix multiplication on 2D matrices.
• If both the matrices have the same dimension, then the matrix
multiplication is carried out normally without any
broadcasting/prepending.
• If any one of the matrices is of a different dimension, then appropriate
broadcasting is carried out first and then the multiplication is carried out.
• This operator applies to N-Dimensional matrices also
Matrix Multiplication using PyTorch - @ operator
# single dimensional matrices
oneD_1 = torch.tensor([3, 6, 2]) # 2x3x4 dimensional matrix
oneD_2 = torch.tensor([4, 1, 9]) ND_2 = torch.tensor([[[0.2431, -0.1044, -0.1437, -1.4982],
# two dimensional matrices [-1.4318, -0.2510, 1.6247, 0.5623],
twoD_1 = torch.tensor([[1, 2, 3], [1.5265, -0.8568, -2.1125, -0.9463]],
[4, 3, 8],
[1, 7, 2]]) [[0.0182, 0.5207, 1.2890, -1.3232],
twoD_2 = torch.tensor([[2, 4, 1], [-0.2275, -0.8006, -0.6909, -1.0108],
[1, 3, 6], [1.3881, -0.0327, -1.4890, -0.5550]]])
[2, 6, 5]])
# N-dimensional matrices (N>2) print("1D matrices output :\n", oneD_1 @ oneD_2)
# 2x3x3 dimensional matrix print("\n2D matrices output :\n", twoD_1 @ twoD_2)
ND_1 = torch.tensor([[[-0.0135, -0.9197, -0.3395], print("\nN-D matrices output :\n", ND_1 @ ND_2)
[-1.0369, -1.3242, 1.4799],
print("\n Mixed matrices output :\n", oneD_1 @ twoD_1 @
twoD_2)
[-0.0182, -1.2917, 0.6575]],
1D matrices output :
tensor(36)
2D matrices output :
tensor([[10, 28, 28],
[27, 73, 62],
[13, 37, 53]])
N-D matrices output :
tensor([[[ 0.7953, 0.5231, -0.7751, -0.1757],
[ 3.9030, -0.8274, -5.1287, -0.5915],
[ 2.8487, -0.2372, -3.4850, -1.3212]],