{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial Pytorch" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "source: https://github.com/jhui/jhui.github.io/blob/master/_posts/2018-02-09-PyTorch-Basic-operations.markdown" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[2.5226e-18, 2.5930e-09, 1.0186e-11],\n", " [3.0883e-09, 2.6707e-06, 4.0744e-11]])\n" ] } ], "source": [ "x = torch.Tensor(2, 3) # Create an un-initialized Tensor of size 2x3\n", "print(x) # Print out the Tensor" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Tensor" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(x)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.is_tensor(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sample programs" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[0.3785, 0.9980, 0.9008],\n", " [0.4766, 0.1663, 0.8045]])\n" ] } ], "source": [ "# Initialize\n", "\n", "x = torch.Tensor(2, 3) # An un-initialized Tensor object. x holds garbage data.\n", "y = torch.rand(2, 3) # Initialize with random values\n", "\n", "# Operations\n", "\n", "z1 = x + y\n", "z2 = torch.add(x, y) # Same as above\n", "\n", "print(z2) # [torch.FloatTensor of size 2x3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### in place" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0.3785, 0.9980, 0.9008],\n", " [0.4766, 0.1663, 0.8045]])" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.add_(y) # Same as x = x + y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### out" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1., 2., 3.],\n", " [4., 5., 6.]])" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = torch.Tensor([[1,2,3],[4,5,6]])\n", "x" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1., 1., 1.],\n", " [1., 1., 1.]])" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = torch.ones(2,3)\n", "y" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[2., 3., 4.],\n", " [5., 6., 7.]])" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r1 = torch.add(x, y)\n", "r1" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[2., 3., 4.],\n", " [5., 6., 7.]])" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x+y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### indexing" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([2., 5.])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:, 1] # Can use numpy type indexing" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0., 2., 3.],\n", " [0., 5., 6.]])" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:, 0] = 0 # For assignment\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### conversion between NumPy ndarray and Tensor" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([1, 2, 3])" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Conversion\n", "a = np.array([1, 2, 3])\n", "v = torch.from_numpy(a) # Convert a numpy array to a Tensor\n", "v" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3])" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = v.numpy() # Tensor to numpy\n", "b" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "b[1] = -1 # Numpy and Tensor share the same memory\n", "assert(a[1] == b[1]) # Change Numpy will also change the Tensor" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, -1, 3])" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([ 1, -1, 3])" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, -1, 3])" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tensor meta-data" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([2, 3])" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = torch.Tensor(2,3)\n", "x.size() # torch.Size([2, 3])" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([2, 3])" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.shape" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.numel(x) # 6: number of elements in x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Reshape tensor" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[-0.1663, 0.0727, 1.3484],\n", " [-0.8737, -0.2693, -0.5124]])" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = torch.randn(2, 3) # Size 2x3\n", "x" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([-0.1663, 0.0727, 1.3484, -0.8737, -0.2693, -0.5124])" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = x.view(6) # Resize x to size 6\n", "y" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[-0.1663, 0.0727],\n", " [ 1.3484, -0.8737],\n", " [-0.2693, -0.5124]])" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = x.view(-1, 2) # Size 3x2\n", "z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a Tensor" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Creating and initializing a Tensor" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [], "source": [ "v = torch.Tensor(2, 3) # An un-initialized torch.FloatTensor of size 2x3\n", "v = torch.Tensor([[1,2],[4,5]]) # A Tensor initialized with a specific array\n", "v = torch.LongTensor([1,2,3]) # A Tensor of type Long\n", "v = torch.FloatTensor([1,2,3]) # A Tensor of type Float" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([1., 2., 3.])" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create a random Tensor" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.manual_seed(1)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [], "source": [ "v = torch.randperm(4) # Size 4. Random permutation of integers from 0 to 3\n", "v = torch.rand(2, 3) # Initialize with random number (uniform distribution)\n", "v = torch.randn(2, 3) # With normal distribution (SD=1, mean=0)" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[-0.6617, -0.0426, -1.3328],\n", " [ 0.5161, 0.7455, -0.0751]])" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tensor type" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[-0.6919, -0.4043, 0.2222],\n", " [ 0.5773, -1.7637, 0.2264],\n", " [-0.2355, 0.3019, -0.2770],\n", " [ 0.4771, -0.1103, 0.2913],\n", " [ 0.5848, 0.2149, -0.4090]])" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = torch.randn(5, 3)\n", "x" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[ 0, 0, 0],\n", " [ 0, -1, 0],\n", " [ 0, 0, 0],\n", " [ 0, 0, 0],\n", " [ 0, 0, 0]])" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.type(torch.LongTensor)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Identity matrices, Fill Tensor with 0, 1 or values" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([3., 3., 3.])" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eye = torch.eye(3) # Create an identity 3x3 tensor\n", "\n", "v = torch.ones(10) # A tensor of size 10 containing all ones\n", "v = torch.ones(2, 1, 2, 1) # Size 2x1x2x1\n", "v = torch.ones_like(eye) # A tensor with same shape as eye. Fill it with 1.\n", "\n", "v = torch.zeros(10) # A tensor of size 10 containing all zeros\n", "\n", "# 1 1 1\n", "# 2 2 2\n", "# 3 3 3\n", "v = torch.ones(3, 3)\n", "v[1].fill_(2)\n", "v[2].fill_(3)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1., 1., 1.],\n", " [1., 1., 1.],\n", " [1., 1., 1.]])" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v = torch.ones(3, 3)\n", "v" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([2., 2., 2.])" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v[1].fill_(2)" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1., 1., 1.],\n", " [2., 2., 2.],\n", " [1., 1., 1.]])" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initialize Tensor with a range of value" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [], "source": [ "v = torch.arange(5) # similar to range(5) but creating a Tensor\n", "v = torch.arange(0, 5, step=1) # Size 5. Similar to range(0, 5, 1)\n", "\n", "# 0 1 2\n", "# 3 4 5\n", "# 6 7 8\n", "v = torch.arange(9)\n", "v = v.view(3, 3)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8]])" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initialize a linear or log scale Tensor" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [], "source": [ "v = torch.linspace(1, 10, steps=10) # Create a Tensor with 10 linear points for (1, 10) inclusively\n", "v = torch.logspace(start=-10, end=10, steps=5) # Size 5: 1.0e-10 1.0e-05 1.0e+00, 1.0e+05, 1.0e+10" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([1.0000e-10, 1.0000e-05, 1.0000e+00, 1.0000e+05, 1.0000e+10])" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Indexing, Slicing, Joining, Mutating Ops" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8]])" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 0 1 2\n", "# 3 4 5\n", "# 6 7 8\n", "x = torch.arange(9)\n", "x = x.view(3, 3)\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Concatenate, Stack" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8],\n", " [0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8],\n", " [0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8]])" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Concatenation\n", "r = torch.cat((x, x, x), 0) # Concatenate in the 0 dimension\n", "r" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[0, 1, 2, 0, 1, 2, 0, 1, 2],\n", " [3, 4, 5, 3, 4, 5, 3, 4, 5],\n", " [6, 7, 8, 6, 7, 8, 6, 7, 8]]),\n", " torch.Size([3, 9]))" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Concatenation\n", "r = torch.cat((x, x, x), 1) # Concatenate in the 1 dimension\n", "r, r.shape" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[1.0000e-10, 1.0000e-05, 1.0000e+00, 1.0000e+05, 1.0000e+10],\n", " [1.0000e-10, 1.0000e-05, 1.0000e+00, 1.0000e+05, 1.0000e+10]]),\n", " torch.Size([2, 5]))" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Stack\n", "r = torch.stack((v, v))\n", "r, r.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Squeeze and unsqueeze" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``unsqueeze()`` \"adds\" superficial 1 dimension to tensor (at specified dimension), while ``squeeze()`` removes all superficial 1 dimensions from tensor." ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([2, 2])" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = torch.ones(2,1,2,1) # Size 2x1x2x1\n", "r = torch.squeeze(t) # Size 2x2\n", "r.size()" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([2, 2, 1])" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r = torch.squeeze(t, 1) # Squeeze dimension 1: Size 2x2x1\n", "r.size()" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[1.],\n", " [2.],\n", " [3.]])" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Un-squeeze a dimension\n", "x = torch.Tensor([1, 2, 3])\n", "r = torch.unsqueeze(x, 0) # Size: 1x3\n", "r = torch.unsqueeze(x, 1) # Size: 3x1\n", "r" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reduction operations" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [], "source": [ "v = torch.arange(9)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([ 0, 1, 3, 6, 10, 15, 21, 28, 36])" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Accumulate sum\n", "# 0 1 2\n", "# 3 5 7\n", "# 9 12 15\n", "r = torch.cumsum(v, dim=0)\n", "r" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([[0., 1., 2.],\n", " [3., 4., 5.],\n", " [6., 7., 8.]]),\n", " tensor([1., 4., 7.]))" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mean\n", "# 1 4 7\n", "w = v.type(torch.FloatTensor)\n", "w = w.view(3,3)\n", "r = torch.mean(w, 1) # Size 3: Mean in dim 1\n", "w,r" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([ 3, 12, 21])" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Sum\n", "# 3 12 21\n", "w = v.view(3,3)\n", "r = torch.sum(w, 1) # Sum over dim 1\n", "r" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "36" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 36\n", "r = torch.sum(w)\n", "r.item()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# END" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "fastai2", "language": "python", "name": "fastai2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.1" } }, "nbformat": 4, "nbformat_minor": 4 }