{ "cells": [ { "cell_type": "markdown", "id": "a7351d98", "metadata": {}, "source": [ "Getting started with Tensors\n", "=====\n", "\n", "Tensors are specialized data structures similar to the dataframe that we used as part of pandas. You can also think of a tensor like an array or a matrix. PyTorch uses tensors to encode the inputs and outputs of a model and the parameters of that model.\n", "\n", "Tensors work in a similar manner to NumPy's ndarrays with the exception that tensors can run on GPUs or other specialized hardware to accelerate computing." ] }, { "cell_type": "markdown", "id": "32a472a7", "metadata": {}, "source": [ "#### Installing PyTorch\n", "We must first have PyTorch installed to work with tensors.\n", "\n", "The following `pip` command can be used to install PyTorch on a CUDA-capable system. (Note: These types of systems require an NVIDIA GPU to use the full range of PyTorch's power. That is why we use the systems build for class by Professor Gregg.)\n", "\n", "PyTorch provides a tool to help you construct a command for installing PyTorch based on your personal system. You can find the tool [here](https://pytorch.org/get-started/locally/)." ] }, { "cell_type": "code", "execution_count": null, "id": "c7c3f080", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: torch in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (2.8.0+cu126)\n", "Collecting torchvision\n", " Using cached torchvision-0.23.0-cp313-cp313-win_amd64.whl.metadata (6.1 kB)\n", "Requirement already satisfied: filelock in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (3.13.1)\n", "Requirement already satisfied: typing-extensions>=4.10.0 in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (4.12.2)\n", "Requirement already satisfied: sympy>=1.13.3 in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (1.13.3)\n", "Requirement already satisfied: networkx in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (3.3)\n", "Requirement already satisfied: jinja2 in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (3.1.4)\n", "Requirement already satisfied: fsspec in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (2024.6.1)\n", "Requirement already satisfied: setuptools in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torch) (70.2.0)\n", "Requirement already satisfied: numpy in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torchvision) (2.3.3)\n", "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from torchvision) (11.0.0)\n", "Requirement already satisfied: mpmath<1.4,>=1.1.0 in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from sympy>=1.13.3->torch) (1.3.0)\n", "Requirement already satisfied: MarkupSafe>=2.0 in c:\\users\\kyle\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from jinja2->torch) (2.1.5)\n", "Using cached torchvision-0.23.0-cp313-cp313-win_amd64.whl (1.6 MB)\n", "Installing collected packages: torchvision\n", "Successfully installed torchvision-0.23.0\n" ] } ], "source": [ "!pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu129\n" ] }, { "cell_type": "markdown", "id": "8524abc8", "metadata": {}, "source": [ "#### Testing to Verify the PyTorch Installation\n", "\n", "Importing PyTorch and creating a quick tensor." ] }, { "cell_type": "code", "execution_count": null, "id": "ec1d8897", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[0.8712, 0.7688, 0.1699],\n", " [0.9080, 0.0574, 0.4872],\n", " [0.4267, 0.5377, 0.4509],\n", " [0.0985, 0.1213, 0.3744],\n", " [0.5374, 0.2675, 0.5842]])\n" ] } ], "source": [ "import torch\n", "x = torch.rand(5, 3)\n", "print(x)" ] }, { "cell_type": "markdown", "id": "53cb81ee", "metadata": {}, "source": [ "The following command will determine if the CUDA driver is available." ] }, { "cell_type": "code", "execution_count": 5, "id": "a06d8c9e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "torch.cuda.is_available()" ] }, { "cell_type": "markdown", "id": "2a2572c8", "metadata": {}, "source": [ "### Initializing Tensors\n", "\n", "Here are some methods that we can use to get started with tensors. Our first method will be the most direct approach.\n", "\n", "**From Existing Data**\n", "\n", "We can create a tensor directly from manually typed data. Using this method will cause the interpreter to automatically infer the data type to use in the newly created tensor.\n", "\n", "Let's work of a single 2-by-2 matrix." ] }, { "cell_type": "code", "execution_count": 7, "id": "19b0c3f0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[16, 3],\n", " [ 7, 9]])\n" ] } ], "source": [ "data = [[16, 3],[7, 9]]\n", "t_data = torch.tensor(data)\n", "\n", "print(t_data)" ] }, { "cell_type": "markdown", "id": "407e4cdc", "metadata": {}, "source": [ "**From a NumPy array**\n", "\n", "We can also use an existing NumPy array to create a PyTorch tensor.\n", "\n", "We will first need to create a NumPy array using the `np.array()` method. \n", "\n", "Once we have the NumPy array we can then use `torch.from_numpy()` to create a PyTorch tensor from the NumPy array." ] }, { "cell_type": "code", "execution_count": 8, "id": "67697ee6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[16, 3],\n", " [ 7, 9]])\n" ] } ], "source": [ "import numpy as np\n", "\n", "# Creating the NumPy array using our previous list\n", "npa_data = np.array(data)\n", "\n", "t_npa_data = torch.from_numpy(npa_data)\n", "\n", "print(t_npa_data)" ] }, { "cell_type": "markdown", "id": "613e4e7d", "metadata": {}, "source": [ "**From a Pandas DataFrame**\n", "\n", "We can also convert our Pandas DataFrame to a PyTorch Tensor.\n", "\n", "There are multiple methods, but essentially each approach involves first converting the Pandas DataFrame to a NumPy array then creating the PyTorch tensor from that new NumPy array.\n", "\n", "*Note:* This method will still attempt to determine the best single data type for the tensor based on the NumPy rules we previous discussed." ] }, { "cell_type": "code", "execution_count": 9, "id": "ed738c39", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[1.0010e+03, 2.6600e+00, 1.0240e+03, 2.5000e+02, 2.1140e+03],\n", " [1.0020e+03, 2.1000e+00, 5.1200e+02, 2.5000e+02, 9.9500e+02],\n", " [1.0030e+03, 1.4200e+00, 5.1200e+02, 8.0000e+01, 4.7800e+02],\n", " [1.0040e+03, 2.8000e+00, 1.0240e+03, 2.5000e+02, 6.4900e+02],\n", " [1.0050e+03, 3.2000e+00, 5.1200e+02, 2.5000e+02, 6.3000e+02],\n", " [1.0060e+03, 3.2000e+00, 1.0240e+03, 3.2000e+02, 1.0490e+03],\n", " [1.0070e+03, 2.2000e+00, 1.0240e+03, 2.0000e+02, 5.1000e+02],\n", " [1.0080e+03, 2.2000e+00, 2.0480e+03, 2.5000e+02, 7.7000e+02],\n", " [1.0090e+03, 2.0000e+00, 1.0240e+03, 2.5000e+02, 6.5000e+02],\n", " [1.0100e+03, 2.8000e+00, 2.0480e+03, 3.0000e+02, 7.7000e+02],\n", " [1.0110e+03, 1.8600e+00, 2.0480e+03, 1.6000e+02, 9.5900e+02],\n", " [1.0120e+03, 2.8000e+00, 1.0240e+03, 1.6000e+02, 6.4900e+02],\n", " [1.0130e+03, 3.0600e+00, 5.1200e+02, 8.0000e+01, 5.2900e+02]],\n", " dtype=torch.float64)\n" ] } ], "source": [ "import pandas as pd\n", "\n", "# Create a pandas DataFrame from our previous CSV file\n", "df = pd.read_csv('data.csv')\n", "\n", "# Directly convert the DataFrame to a Tensor (using a NumPy as an intermediary)\n", "tensor = torch.tensor(df.to_numpy())\n", "\n", "# Display the newly created tensor\n", "print(tensor)" ] }, { "cell_type": "markdown", "id": "9acf99b9", "metadata": {}, "source": [ "Consider the tensor show in the previous example. \n", "\n", "- Did our method work as expected?\n", "- What happened to our data?\n", "- Are we okay with this outcome?" ] }, { "cell_type": "markdown", "id": "9eef70aa", "metadata": {}, "source": [ "**Creating a tensor from an existing tensor**\n", "\n", "Our newly created tensor will keep the properties (shape, datatype) of the input tensor, unless we specifically override the input." ] }, { "cell_type": "code", "execution_count": 10, "id": "4d9eb35d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ones Tensor: \n", " tensor([[1, 1],\n", " [1, 1]]) \n", "\n" ] } ], "source": [ "# Keep the properties of t_data, but construct a new tensor of all ones.\n", "t_ones = torch.ones_like(t_data)\n", "print(f\"Ones Tensor: \\n {t_ones} \\n\")" ] }, { "cell_type": "markdown", "id": "49fcbdab", "metadata": {}, "source": [ "In the following example, we will create a tensor of random values. \n", "\n", "*Note:* this approach can only be used to create random values that have floating point types." ] }, { "cell_type": "code", "execution_count": 14, "id": "3ef4bb6c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Random Value Tensor: \n", " tensor([[0.5861, 0.1221, 0.8072, 0.6685, 0.4411],\n", " [0.9686, 0.5550, 0.1226, 0.2525, 0.2597],\n", " [0.0669, 0.8760, 0.7293, 0.4882, 0.2929],\n", " [0.3558, 0.9144, 0.5391, 0.8796, 0.2190],\n", " [0.2198, 0.9182, 0.9133, 0.4234, 0.2630],\n", " [0.7266, 0.9230, 0.9522, 0.5222, 0.8928],\n", " [0.3732, 0.4264, 0.6953, 0.8100, 0.9065],\n", " [0.3424, 0.6432, 0.4148, 0.3817, 0.6327],\n", " [0.3395, 0.9025, 0.1558, 0.8592, 0.7259],\n", " [0.4717, 0.5777, 0.6340, 0.8586, 0.4283],\n", " [0.5756, 0.1980, 0.0107, 0.3129, 0.5350],\n", " [0.4272, 0.6499, 0.7659, 0.6622, 0.5533],\n", " [0.4475, 0.2302, 0.3771, 0.5629, 0.6528]]) \n", "\n" ] } ], "source": [ "# Construct a new tensor of random numbers with the same shape as tensor,\n", "# but override the data type to use the one provided\n", "t_rand = torch.rand_like(tensor, dtype=torch.float)\n", "print(f\"Random Value Tensor: \\n {t_rand} \\n\")" ] }, { "cell_type": "markdown", "id": "9ed98126", "metadata": {}, "source": [ "**Creating a tensor with constant or random values**\n", "\n", "We can directly provide the expected `shape` for a new tensor by creating a tuple of tensor dimensions." ] }, { "cell_type": "code", "execution_count": 15, "id": "481226c3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Random Tensor: \n", " tensor([[0.9390, 0.0276, 0.5290, 0.0051, 0.4503, 0.4903],\n", " [0.8943, 0.9303, 0.3389, 0.9929, 0.9794, 0.4265],\n", " [0.6850, 0.0034, 0.3708, 0.8432, 0.9888, 0.2426]]) \n", "\n", "Ones Tensor: \n", " tensor([[1., 1., 1., 1., 1., 1.],\n", " [1., 1., 1., 1., 1., 1.],\n", " [1., 1., 1., 1., 1., 1.]]) \n", "\n", "Zeros Tensor: \n", " tensor([[0., 0., 0., 0., 0., 0.],\n", " [0., 0., 0., 0., 0., 0.],\n", " [0., 0., 0., 0., 0., 0.]]) \n", "\n" ] } ], "source": [ "shape = (3, 6)\n", "rand_tensor = torch.rand(shape)\n", "ones_tensor = torch.ones(shape)\n", "zeros_tensor = torch.zeros(shape)\n", "\n", "print(f\"Random Tensor: \\n {rand_tensor} \\n\")\n", "print(f\"Ones Tensor: \\n {ones_tensor} \\n\")\n", "print(f\"Zeros Tensor: \\n {zeros_tensor} \\n\")" ] }, { "cell_type": "markdown", "id": "b8f5b376", "metadata": {}, "source": [ "---------------------" ] }, { "cell_type": "markdown", "id": "caab8bc9", "metadata": {}, "source": [ "Attributes of Tensors\n", "==============\n", "\n", "Should we need them, PyTorch has various methods that will allow use to determine information about the shape, datatype, and device on which the tensor is stored.\n", "\n", "- `[tensor].shape` == Shape of the `[tensor]`\n", "- `[tensor].dtype` == Data type of the `[tensor]`\n", "- `[tensor].device` == Device location of the `[tensor]`" ] }, { "cell_type": "code", "execution_count": 16, "id": "305a75fc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shape of tensor: torch.Size([3, 6])\n", "Datatype of tensor: torch.float32\n", "Device tensor is stored on: cpu\n" ] } ], "source": [ "tensor = torch.rand(3, 6)\n", "\n", "print(f\"Shape of tensor: {tensor.shape}\")\n", "print(f\"Datatype of tensor: {tensor.dtype}\")\n", "print(f\"Device tensor is stored on: {tensor.device}\")" ] }, { "cell_type": "markdown", "id": "3b688ad5", "metadata": {}, "source": [ "---------------------" ] }, { "cell_type": "markdown", "id": "cf6dee0c", "metadata": {}, "source": [ "Operations with Tensors\n", "======\n", "\n", "There are an extremely large list of operations that can be completed on tensors, such as, transposing, indexing, slicing, mathematical operations, linear algebra, random sampling, etc. \n", "\n", "For a more comprehensive list look [here](https://pytorch.org/docs/stable/torch.html).\n", "\n", "To utilize the full power of PyTorch, we will want to run the commands on the GPU (at typically higher speeds than on a CPU). " ] }, { "cell_type": "code", "execution_count": 17, "id": "57a048a7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tensor is now stored on: cuda:0\n" ] } ], "source": [ "# Move the tensor to the GPU if the GPU is available\n", "if torch.cuda.is_available():\n", " tensor = tensor.to('cuda')\n", " print(f\"Tensor is now stored on: {tensor.device}\")" ] }, { "cell_type": "markdown", "id": "33f870b5", "metadata": {}, "source": [ "**NumPy-like indexing and slicing:**\n", "\n", "We can use the `[ ]` with `:` and `,` in a similar manner to NumPy to both index and slice an existing tensor." ] }, { "cell_type": "code", "execution_count": null, "id": "6d28b634", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Our initial tensor: \n", "tensor([[16, 3],\n", " [ 7, 9]])\n", "\n", "Tensor after: \n", "tensor([[16, 0],\n", " [ 7, 0]])\n", "\n" ] } ], "source": [ "print(f\"Initial tensor: \\n{t_data}\\n\")\n", "\n", "# Making a change to the tensor\n", "t_data[:,1] = 0\n", "print(f\"Tensor after: \\n{t_data}\\n\")" ] }, { "cell_type": "code", "execution_count": 20, "id": "42a29461", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Initial tensor: \n", "tensor([[16, 3],\n", " [ 7, 9],\n", " [ 8, 2]])\n", "\n", "Tensor after: \n", "tensor([[ 16, 3],\n", " [888, 888],\n", " [888, 888]])\n", "\n" ] } ], "source": [ "# Making a new t_data\n", "data = [[16, 3],[7, 9],[8, 2]]\n", "t_data = torch.tensor(data)\n", "\n", "print(f\"Initial tensor: \\n{t_data}\\n\")\n", "\n", "# Making a change to the tensor\n", "t_data[1:] = 888\n", "print(f\"Tensor after: \\n{t_data}\\n\")" ] }, { "cell_type": "code", "execution_count": 21, "id": "03d38b38", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Initial tensor: \n", "tensor([[ 16, 3],\n", " [888, 888],\n", " [888, 888]])\n", "\n", "Tensor after: \n", "tensor([[ 16, 3],\n", " [888, 888],\n", " [ 77, 888]])\n", "\n" ] } ], "source": [ "print(f\"Initial tensor: \\n{t_data}\\n\")\n", "\n", "# Making a change to the tensor\n", "t_data[2:,0] = 77\n", "print(f\"Tensor after: \\n{t_data}\\n\")" ] }, { "cell_type": "markdown", "id": "0a3ebc74", "metadata": {}, "source": [ "**`expand()`**\n", "\n", "This method will expand a tensor into a number of tensors, a number of rows in tensors, and a number of columns in tensors.\n", "\n", "Syntax: tensor.expand(n,r,c)\n", "\n", "where,\n", "- tensor is the input tensor\n", "- n is the number of tensors to return\n", "- r is the number of rows in each tensor\n", "- c is the number of columns in each tensor" ] }, { "cell_type": "code", "execution_count": 22, "id": "bafe7c1a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89]])\n", "\n", "Before: \n", "tensor([[[10, 20, 30],\n", " [45, 67, 89]],\n", "\n", " [[10, 20, 30],\n", " [45, 67, 89]],\n", "\n", " [[10, 20, 30],\n", " [45, 67, 89]]])\n", "\n" ] } ], "source": [ "data = torch.tensor([[10, 20, 30], [45, 67, 89]])\n", "\n", "print(f\"Before: \\n{data}\\n\")\n", "\n", "data2 = data.expand(3, 2, 3)\n", "\n", "print(f\"Before: \\n{data2}\\n\")" ] }, { "cell_type": "markdown", "id": "0345ba58", "metadata": {}, "source": [ "**`narrow()`**\n", "\n", "This method will work in a similar manner to filtering the tensor based on columns like we saw as part of our pandas discussions.\n", "\n", "Syntax: torch.narrow(tensor,d,i,l)\n", "\n", "where,\n", "- tensor is the input tensor\n", "- d is the dimension to narrow\n", "- i is the starting index of the vector\n", "- l is the length of the new tensor along the dimension - d" ] }, { "cell_type": "code", "execution_count": 23, "id": "870e15da", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88]])\n", "\n", "Removing the first column: \n", "tensor([[20, 30],\n", " [67, 89],\n", " [15, 88]])\n", "\n", "Removing the third column: \n", "tensor([[10, 20],\n", " [45, 67],\n", " [57, 15]])\n", "\n" ] } ], "source": [ "data = torch.tensor([[10, 20, 30], [45, 67, 89], [57, 15, 88]])\n", "\n", "print(f\"Before: \\n{data}\\n\")\n", "\n", "# narrow the tensor with 1 dimension starting from the 1st index\n", "# length of the new tensor will be 2\n", "print(f\"Removing the first column: \\n{torch.narrow(data, 1, 1, 2)}\\n\")\n", "\n", "# narrow the tensor with 1 dimension starting from index 0\n", "# length of the new tensor will be 2\n", "print(f\"Removing the third column: \\n{torch.narrow(data, 1, 0, 2)}\\n\")" ] }, { "cell_type": "markdown", "id": "e510e321", "metadata": {}, "source": [ "**`where()`**\n", "\n", "This method will allow us to create a new tensor based on applying a condition to the existing tensor.\n", "\n", "Syntax: torch.where(condition,statement1,statement2)\n", "\n", "where,\n", "- condition is used to check the existing tensor condition by applying conditions on the existing tensors\n", "- statememt1 is executed when condition is `true`\n", "- statememt2 is executed when condition is `false`" ] }, { "cell_type": "code", "execution_count": 24, "id": "514756e3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88]])\n", "\n", "Evens and odds: \n", "tensor([[0, 0, 0],\n", " [1, 1, 1],\n", " [1, 1, 0]])\n", "\n" ] } ], "source": [ "data = torch.tensor([[10, 20, 30], [45, 67, 89], [57, 15, 88]])\n", "\n", "print(f\"Before: \\n{data}\\n\")\n", "\n", "# set the number to 0 when the number is even, otherwise set the value to 1\n", "print(f\"Evens and odds: \\n{torch.where(data%2 == 0,0,1)}\\n\")" ] }, { "cell_type": "markdown", "id": "72217d76", "metadata": {}, "source": [ "** Joining tensors**\n", "\n", "We can use `torch.cat` to concatenate a sequence of tensors along a given dimension.\n", "\n", "The default behavior of this method is `dim=0`, but we can specify a different dimension such as `dim=1`." ] }, { "cell_type": "code", "execution_count": 30, "id": "7d85d3b1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88]])\n", "\n", "Default After: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88],\n", " [10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88],\n", " [10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88]])\n", "\n", "dim=1 After: \n", "tensor([[10, 20, 30, 10, 20, 30, 10, 20, 30],\n", " [45, 67, 89, 45, 67, 89, 45, 67, 89],\n", " [57, 15, 88, 57, 15, 88, 57, 15, 88]])\n", "\n" ] } ], "source": [ "data = torch.tensor([[10, 20, 30], [45, 67, 89], [57, 15, 88]])\n", "\n", "print(f\"Before: \\n{data}\\n\")\n", "\n", "data1 = torch.cat([data, data, data])\n", "\n", "print(f\"Default After: \\n{data1}\\n\")\n", "\n", "data2 = torch.cat([data, data, data], dim=1)\n", "\n", "print(f\"dim=1 After: \\n{data2}\\n\")" ] }, { "cell_type": "markdown", "id": "6ede4843", "metadata": {}, "source": [ "**Multiplying tensors**\n", "\n", "Tensors work in similar manners to matrices, so frequently we will need to multiply them together." ] }, { "cell_type": "code", "execution_count": null, "id": "ba301e3a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88]])\n", "\n", "tensor.mul(tensor) \n", " tensor([[ 100, 400, 900],\n", " [2025, 4489, 7921],\n", " [3249, 225, 7744]]) \n", "\n", "tensor * tensor \n", " tensor([[ 100, 400, 900],\n", " [2025, 4489, 7921],\n", " [3249, 225, 7744]])\n" ] } ], "source": [ "# Starting data\n", "print(f\"Before: \\n{data}\\n\")\n", "\n", "# To compute the element-wise product\n", "print(f\"tensor.mul(tensor) \\n {data.mul(data)} \\n\")\n", "\n", "# Alternative syntax:\n", "print(f\"tensor * tensor \\n {data * data}\")" ] }, { "cell_type": "markdown", "id": "2f52af64", "metadata": {}, "source": [ "The previous method will take the element in matrix 1 and multiply it by the element in matrix 2 in the same location.\n", "\n", "We can also computes the matrix multiplication between two tensors." ] }, { "cell_type": "code", "execution_count": 32, "id": "bb5ef9e9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before: \n", "tensor([[10, 20, 30],\n", " [45, 67, 89],\n", " [57, 15, 88]])\n", "\n", "tensor.matmul(tensor.T) \n", " tensor([[ 1400, 4460, 3510],\n", " [ 4460, 14435, 11402],\n", " [ 3510, 11402, 11218]]) \n", "\n", "tensor @ tensor.T \n", " tensor([[ 1400, 4460, 3510],\n", " [ 4460, 14435, 11402],\n", " [ 3510, 11402, 11218]])\n" ] } ], "source": [ "# Starting data\n", "print(f\"Before: \\n{data}\\n\")\n", "\n", "# To compute the result of the matrix multiplication\n", "print(f\"tensor.matmul(tensor.T) \\n {data.matmul(data.T)} \\n\")\n", "\n", "# Alternative syntax:\n", "print(f\"tensor @ tensor.T \\n {data @ data.T}\")" ] }, { "cell_type": "markdown", "id": "f2c657a0", "metadata": {}, "source": [ "-----------------------" ] }, { "cell_type": "markdown", "id": "ceaf9707", "metadata": {}, "source": [ "Tensor to NumPy array\n", "==============\n", "\n", "Just like when we started, we can convert a PyTorch tensor into a NumPy array." ] }, { "cell_type": "code", "execution_count": 34, "id": "84019333", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t: tensor([1., 1., 1., 1., 1.])\n", "n: [1. 1. 1. 1. 1.]\n" ] } ], "source": [ "# Creating a simple tensor\n", "t = torch.ones(5)\n", "print(f\"t: {t}\")\n", "\n", "# Converting that tensor to numpy array\n", "n = t.numpy()\n", "print(f\"n: {n}\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.13.7" } }, "nbformat": 4, "nbformat_minor": 5 }