================
by Jawad Haider
01 - Tensor Operations¶
- 1 Tensor Operations
- 1.1 Perform standard imports
- 1.2 Indexing and slicing
- 1.3 Reshape tensors with .view()
- 1.4 Tensor Arithmetic
- 1.5 Dot products
- 1.6 Matrix multiplication
- 2 Advanced operations
- 2.1 L2 or Euclidian Norm
- 2.2 Number of elements
- 2.3 Great work!
Tensor Operations¶
This section covers: * Indexing and slicing * Reshaping tensors (tensor views) * Tensor arithmetic and basic operations * Dot products * Matrix multiplication * Additional, more advanced operations
Perform standard imports¶
Indexing and slicing¶
Extracting specific values from a tensor works just the same as with
NumPy arrays
Image source: http://www.scipy-lectures.org/_images/numpy_indexing.png
tensor([[0, 1],
[2, 3],
[4, 5]])
tensor([1, 3, 5])
tensor([[1],
[3],
[5]])
Reshape tensors with .view()¶
view()
and
reshape()
do essentially the same thing by returning a reshaped tensor without
changing the original tensor in place.
There’s a good discussion of
the differences
here.
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])
Views reflect the most current data¶
tensor([[234, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]])
Views can infer the correct size¶
By passing in -1 PyTorch will infer the correct value from the given tensor
tensor([[234, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]])
tensor([[234, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]])
Adopt another tensor’s shape with .view_as()¶
view_as(input) only works with tensors that have the same number of elements.
tensor([[234, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]])
Tensor Arithmetic¶
Adding tensors can be performed a few different ways depending on the
desired result.
As a simple expression:
a = torch.tensor([1,2,3], dtype=torch.float)
b = torch.tensor([4,5,6], dtype=torch.float)
print(a + b)
tensor([5., 7., 9.])
As arguments passed into a torch operation:
tensor([5., 7., 9.])
With an output tensor passed in as an argument:
result = torch.empty(3)
torch.add(a, b, out=result) # equivalent to result=torch.add(a,b)
print(result)
tensor([5., 7., 9.])
Changing a tensor in-place
tensor([5., 7., 9.])
In the above example: a.add*(b) changed a.
Basic Tensor Operations¶
OPERATION | FUNCTION | DESCRIPTION |
---|---|---|
a + b | a.add(b) | element wise addition |
a - b | a.sub(b) | subtraction |
a \* b | a.mul(b) | multiplication |
a / b | a.div(b) | division |
a % b | a.fmod(b) | modulo (remainder after division) |
ab | a.pow(b) | power |
OPERATION | FUNCTION | DESCRIPTION |
---|---|---|
\|a\| | torch.abs(a) | absolute value |
1/a | torch.reciprocal(a) | reciprocal |
$\sqrt{a}$ | torch.sqrt(a) | square root |
log(a) | torch.log(a) | natural log |
ea | torch.exp(a) | exponential |
12.34 ==\> 12. | torch.trunc(a) | truncated integer |
12.34 ==\> 0.34 | torch.frac(a) | fractional component |
OPERATION | FUNCTION | DESCRIPTION |
---|---|---|
sin(a) | torch.sin(a) | sine |
cos(a) | torch.sin(a) | cosine |
tan(a) | torch.sin(a) | tangent |
arcsin(a) | torch.asin(a) | arc sine |
arccos(a) | torch.acos(a) | arc cosine |
arctan(a) | torch.atan(a) | arc tangent |
sinh(a) | torch.sinh(a) | hyperbolic sine |
cosh(a) | torch.cosh(a) | hyperbolic cosine |
tanh(a) | torch.tanh(a) | hyperbolic tangent |
OPERATION | FUNCTION | DESCRIPTION |
---|---|---|
$\sum a$ | torch.sum(a) | sum |
$\bar a$ | torch.mean(a) | mean |
amax | torch.max(a) | maximum |
amin | torch.min(a) | minimum |
torch.max(a,b) returns a tensor of size a containing the element wise max between a and b |
For example, torch.div(a,b) performs floor division (truncates the decimal) for integer types, and classic division for floats.
Use the space below to experiment with different operations¶
a = torch.tensor([1,2,3], dtype=torch.float)
b = torch.tensor([4,5,6], dtype=torch.float)
print(torch.add(a,b).sum())
tensor(21.)
Dot products¶
A dot product is
the sum of the products of the corresponding entries of two 1D tensors.
If the tensors are both vectors, the dot product is given as:
\(\begin{bmatrix} a & b & c \end{bmatrix} \;\cdot\; \begin{bmatrix} d & e & f \end{bmatrix} = ad + be + cf\)
If the tensors include a column vector, then the dot product is the sum
of the result of the multiplied matrices. For example:
\(\begin{bmatrix} a & b & c \end{bmatrix} \;\cdot\; \begin{bmatrix} d \\ e \\ f \end{bmatrix} = ad + be + cf\)
Dot products can be expressed as
torch.dot(a,b)
or a.dot(b)
or b.dot(a)
a = torch.tensor([1,2,3], dtype=torch.float)
b = torch.tensor([4,5,6], dtype=torch.float)
print(a.mul(b)) # for reference
print()
print(a.dot(b))
tensor([ 4., 10., 18.])
tensor(32.)
Matrix multiplication¶
2D Matrix multiplication is possible when the number of columns in tensor A matches the number of rows in tensor B. In this case, the product of tensor A with size \((x,y)\) and tensor B with size \((y,z)\) results in a tensor of size \((x,z)\)
$\begin{bmatrix} a & b & c \\ d & e & f \end{bmatrix} \;\times\; \begin{bmatrix} m & n \\ p & q \\ r & s \end{bmatrix} = \begin{bmatrix} (am+bp+cr) & (an+bq+cs) \\ (dm+ep+fr) & (dn+eq+fs) \end{bmatrix}$
Matrix multiplication can be computed using
torch.mm(a,b)
or a.mm(b)
or a @ b
a = torch.tensor([[0,2,4],[1,3,5]], dtype=torch.float)
b = torch.tensor([[6,7],[8,9],[10,11]], dtype=torch.float)
print('a: ',a.size())
print('b: ',b.size())
print('a x b: ',torch.mm(a,b).size())
a: torch.Size([2, 3])
b: torch.Size([3, 2])
a x b: torch.Size([2, 2])
tensor([[56., 62.],
[80., 89.]])
tensor([[56., 62.],
[80., 89.]])
tensor([[56., 62.],
[80., 89.]])
Matrix multiplication with broadcasting¶
Matrix multiplication that involves
broadcasting
can be computed using
torch.matmul(a,b)
or a.matmul(b)
or a @ b
torch.Size([2, 3, 5])
However, the same operation raises a RuntimeError with torch.mm():
RuntimeError: matrices expected, got 3D, 2D tensors at ..\aten\src\TH/generic/THTensorMath.cpp:956
Advanced operations¶
L2 or Euclidian Norm¶
See torch.norm()
The
Euclidian
Norm gives the vector norm of \(x\) where \(x=(x_1,x_2,...,x_n)\).
It is calculated as
\({\displaystyle \left\|{\boldsymbol {x}}\right\|_{2}:={\sqrt {x_{1}^{2}+\cdots +x_{n}^{2}}}}\)
When applied to a matrix, torch.norm() returns the Frobenius norm by default.
tensor(17.)
Number of elements¶
See torch.numel()
Returns the number of elements in a tensor.
21
This can be useful in certain calculations like Mean Squared Error:
def mse(t1, t2):
diff = t1 - t2
return
torch.sum(diff * diff) / diff.numel()