diff --git a/Module1/Quickstart guide to PyTorch Basics.ipynb b/Module1/Quickstart guide to PyTorch Basics.ipynb new file mode 100644 index 0000000..bdcfea3 --- /dev/null +++ b/Module1/Quickstart guide to PyTorch Basics.ipynb @@ -0,0 +1,1762 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# Quickstart guide to PyTorch Basics\n", + "\n", + "LLM Bootcamp requires you to have PyTorch basics. In this Notebook, we have attached a Quickstart guide to get started with PyTorch along with important resources to get started with PyTorch.\n", + "\n", + "##⚡️LLM Bootcamp\n", + "Before proceeding with the further modules, we expect you to atleast have basic knowledge of PyTorch. This notebook is a Quickstart guide for PyTorch Basics\n", + "\n", + "If you are comfortable with PyTorch you can skip this notebook.\n", + "\n", + "**Get Started with PyTorch**\n", + "\n", + "An open source machine learning framework that accelerates the path from research prototyping to production deployment.\n", + "\n", + "pip install torch\n", + "\n", + "**Table of Contents:**\n", + "\n", + "- Basics\n", + "\n", + "- Tensor Operations\n", + "\n", + "- Extra PyTorch operations based on Tensor Shape\n", + "\n", + "- Ouickstart- Build A Neural Network" + ], + "metadata": { + "id": "KpHtA6MFNIAd" + } + }, + { + "cell_type": "code", + "source": [ + "import torch\n", + "import numpy as np" + ], + "metadata": { + "id": "F8wtIG0oHvDe" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Basics\n", + "Just like Tensorflow, we shall continue playing with Tensors in PyTorch as well." + ], + "metadata": { + "id": "zjMwEzKL8Rc6" + } + }, + { + "cell_type": "code", + "source": [ + "\n", + "#Create Tensor From Data(List)\n", + "data = [[1, 2],[3, 4]]\n", + "tensors = torch.tensor(data)\n", + "tensors" + ], + "metadata": { + "id": "SYTsICOL7F7E", + "outputId": "14f2bbbd-7cbf-4c59-9213-f4cf4958751e", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[1, 2],\n", + " [3, 4]])" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "source": [ + "#Create from NumPy\n", + "np_array = np.arange(10)\n", + "tensor_np = torch.from_numpy(np_array)\n", + "tensor_np" + ], + "metadata": { + "id": "CT64_RSH8RET", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "f5e25fca-5337-4797-80d1-43747efd682a" + }, + "execution_count": 4, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "metadata": {}, + "execution_count": 4 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "#### Shape, ndim and dtype\n", + "This is same as we saw in Numpy Tutorial - Day 1" + ], + "metadata": { + "id": "1mxBeeZ1_oWG" + } + }, + { + "cell_type": "code", + "source": [ + "\n", + "\n", + "tensor_np.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2OYIpc35_Oyb", + "outputId": "f6ed2bcc-c095-4c13-92bc-ca1de68153d6" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([10])" + ] + }, + "metadata": {}, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "tensor_np.ndim" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0Mhg28ES_WKC", + "outputId": "6425b9cf-29ee-46c5-8df9-29c9f4b875c7" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "source": [ + "tensor_np.dtype" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-c16Ns-I_4Mb", + "outputId": "864cd688-9c64-45ee-c69d-e0309f31d319" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.int64" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Tensor_Operations" + ], + "metadata": { + "id": "BSeEFDgk_-I_" + } + }, + { + "cell_type": "code", + "source": [ + "\n", + "ten1 = torch.tensor([1,2,3])\n", + "ten2 = torch.tensor([4,5,6])\n", + "ten1+ten2" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "W1-HyxDLA06O", + "outputId": "7a849d6f-5f0a-4c52-f1f4-b9927037ec24" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([5, 7, 9])" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "source": [ + "#You can either use + or torch.add to perform Tensor Additions\n", + "\n", + "torch.add(ten1,ten2)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6kq2m9GFBa2V", + "outputId": "54fbf26b-e218-4694-ae8b-3fbf6d117298" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([5, 7, 9])" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "torch.sub(ten2,ten1)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZIy7uuodBjqq", + "outputId": "951efb96-b274-420e-90a6-3771fc5ad068" + }, + "execution_count": 10, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([3, 3, 3])" + ] + }, + "metadata": {}, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "torch.subtract(ten2,ten1)\n", + "\n", + "#You can either use - or torch.sub to perform Tensor Additions" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "duDGqvRGBryr", + "outputId": "47fc9350-2d6e-4f28-bd4a-b93b6ef2d1c6" + }, + "execution_count": 11, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([3, 3, 3])" + ] + }, + "metadata": {}, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "source": [ + "ten1 - ten2" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "5zJkg6N2B6Oe", + "outputId": "9de0ca13-5f37-4a22-ddd5-8010359a89d8" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([-3, -3, -3])" + ] + }, + "metadata": {}, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "source": [ + "ten1 * 10" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "sVQcvf4FB_Pv", + "outputId": "685b2212-a196-4f9b-96ce-93e2b1e80f01" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([10, 20, 30])" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "ten1 **3" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "wc51j9g0CUUM", + "outputId": "62f05a21-d5e8-4a1c-a5d4-5b465d30653c" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([ 1, 8, 27])" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "source": [ + "ten1 /2" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "UHfyAuBZCCP9", + "outputId": "1fb47b38-8cf0-4f7e-ac16-6255b4e940dd" + }, + "execution_count": 15, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([0.5000, 1.0000, 1.5000])" + ] + }, + "metadata": {}, + "execution_count": 15 + } + ] + }, + { + "cell_type": "code", + "source": [ + "ten1 // 2" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "mjzlUy2UCFHY", + "outputId": "f29355f8-7684-4127-a335-18162387524c" + }, + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([0, 1, 1])" + ] + }, + "metadata": {}, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "source": [ + "ten1 %2" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-PEjPTokCOTK", + "outputId": "949f9570-abca-42d1-c64f-f71fa08146e7" + }, + "execution_count": 17, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([1, 0, 1])" + ] + }, + "metadata": {}, + "execution_count": 17 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "#### Matrix Multiplication" + ], + "metadata": { + "id": "mQRmzTh_Frzt" + } + }, + { + "cell_type": "markdown", + "source": [ + "**very important operation in Deep Learning- Matrix Multiplication**\n", + "- Rules of Matrix Multiplication:\n", + "\n", + "\n", + "(3,2) * (3,2) = Error\n", + "\n", + "(4,3) * (3,2) = (4,2)\n", + "\n", + "(2,2) * (2,5) = (2,5)" + ], + "metadata": { + "id": "xLvpduk6CmK3" + } + }, + { + "cell_type": "code", + "source": [ + "torch.matmul(ten1,ten2)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "pLTg9e9mDweX", + "outputId": "90e768b4-20f2-4d6e-ef44-f24ba7bc4d6d" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor(32)" + ] + }, + "metadata": {}, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "source": [ + "matrix4_3 = torch.tensor([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])\n", + "matrix4_3.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "qkoSxW6nD3vS", + "outputId": "0284da78-d2f2-4bb3-c920-c1e4ff283700" + }, + "execution_count": 19, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([4, 3])" + ] + }, + "metadata": {}, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "source": [ + "matrix3_2 = torch.tensor([[1,2], [3,4], [5,6]])\n", + "matrix3_2.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "PxraE7LKEAWA", + "outputId": "5f978b42-dba9-4ef1-c570-cb7f47922ec0" + }, + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([3, 2])" + ] + }, + "metadata": {}, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "source": [ + "result = torch.matmul(matrix4_3,matrix3_2) #=> will result in (4,2)\n", + "result" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "y1k1dhMiENfH", + "outputId": "96dece02-6cee-4d57-9645-c9776252fa35" + }, + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 22, 28],\n", + " [ 49, 64],\n", + " [ 76, 100],\n", + " [103, 136]])" + ] + }, + "metadata": {}, + "execution_count": 21 + } + ] + }, + { + "cell_type": "code", + "source": [ + "result.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "lFiPDmqiEfZv", + "outputId": "c451d134-2b9d-420a-81f2-f06b79480f7d" + }, + "execution_count": 22, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([4, 2])" + ] + }, + "metadata": {}, + "execution_count": 22 + } + ] + }, + { + "cell_type": "code", + "source": [ + "#You can also use torch.mm() which is a short for torch.matmul()\n", + "\n", + "torch.mm(matrix4_3,matrix3_2)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "nh654HoSEjXN", + "outputId": "ec902711-d8f5-4f95-ca36-33f2e637a7b4" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 22, 28],\n", + " [ 49, 64],\n", + " [ 76, 100],\n", + " [103, 136]])" + ] + }, + "metadata": {}, + "execution_count": 23 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "#### Transpose of tensor" + ], + "metadata": { + "id": "DU5LOx7KCjD_" + } + }, + { + "cell_type": "code", + "source": [ + "matrix4_3" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "LvmC3gXOCSuU", + "outputId": "cdb54d1c-77a2-40e5-b67c-f2a4634b9405" + }, + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 1, 2, 3],\n", + " [ 4, 5, 6],\n", + " [ 7, 8, 9],\n", + " [10, 11, 12]])" + ] + }, + "metadata": {}, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "source": [ + "matrix4_3.T" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "rok53r5CFbjG", + "outputId": "ae760659-d033-4251-fb76-05c136f3b7a4" + }, + "execution_count": 25, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 1, 4, 7, 10],\n", + " [ 2, 5, 8, 11],\n", + " [ 3, 6, 9, 12]])" + ] + }, + "metadata": {}, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "source": [ + "torch.t(matrix4_3)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "pkiyp0EvFhkh", + "outputId": "e7213ca3-6688-4488-f39c-ec58e817ef59" + }, + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 1, 4, 7, 10],\n", + " [ 2, 5, 8, 11],\n", + " [ 3, 6, 9, 12]])" + ] + }, + "metadata": {}, + "execution_count": 26 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "### Extra_PyTorch_operations_based_on_Tensor_Shape\n", + "- Zeros\n", + "- Ones\n", + "- Random\n", + "- Full" + ], + "metadata": { + "id": "UmwsW4h5F8_j" + } + }, + { + "cell_type": "code", + "source": [ + "tensorZeroes = torch.zeros((3,3))\n", + "tensorZeroes" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "KPi0VFjaILPJ", + "outputId": "2d82add4-61e4-4696-f4c3-4fed780a6091" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[0., 0., 0.],\n", + " [0., 0., 0.],\n", + " [0., 0., 0.]])" + ] + }, + "metadata": {}, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "source": [ + "tensorOnes = torch.ones((3,3))\n", + "tensorOnes" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "gMnih1D1IRsg", + "outputId": "85f0ac8d-fe54-4d83-d583-58edf9d1fba3" + }, + "execution_count": 28, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[1., 1., 1.],\n", + " [1., 1., 1.],\n", + " [1., 1., 1.]])" + ] + }, + "metadata": {}, + "execution_count": 28 + } + ] + }, + { + "cell_type": "code", + "source": [ + "tensorRandomN = torch.randn((3,3)) #includes negative tensors\n", + "tensorRandomN" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "OKXLYp6MIg-g", + "outputId": "a34c6bbf-80a3-41d7-f04c-c1011759368d" + }, + "execution_count": 29, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[ 0.7668, 0.7389, 1.1770],\n", + " [-1.5145, 1.5947, -0.3392],\n", + " [-0.3251, 0.9855, -0.2110]])" + ] + }, + "metadata": {}, + "execution_count": 29 + } + ] + }, + { + "cell_type": "code", + "source": [ + "tensorRandom = torch.rand((3,3)) #includes only positive tensors\n", + "tensorRandom" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2JYQWB7pInG-", + "outputId": "5cc600c7-81a6-4687-c7ca-ac9a421815d3" + }, + "execution_count": 30, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[0.7060, 0.7018, 0.5381],\n", + " [0.1404, 0.3814, 0.2676],\n", + " [0.7314, 0.3326, 0.6800]])" + ] + }, + "metadata": {}, + "execution_count": 30 + } + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "\n", + "customFill = torch.full((3,3),5)\n", + "customFill" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "HUbqpqGuIuuT", + "outputId": "5e741711-cf57-4563-d348-5b2c8b37bb55" + }, + "execution_count": 31, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[5, 5, 5],\n", + " [5, 5, 5],\n", + " [5, 5, 5]])" + ] + }, + "metadata": {}, + "execution_count": 31 + } + ] + }, + { + "cell_type": "code", + "source": [ + "\n", + "initialFill = torch.full((3,3),0.01)\n", + "initialFill" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "TY9DNCDLI1Yf", + "outputId": "92a921e2-c645-4f6b-ce34-759f249074c9" + }, + "execution_count": 32, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "tensor([[0.0100, 0.0100, 0.0100],\n", + " [0.0100, 0.0100, 0.0100],\n", + " [0.0100, 0.0100, 0.0100]])" + ] + }, + "metadata": {}, + "execution_count": 32 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "###Quickstart\n", + "#####Install **Torchvision**, The torchvision package consists of popular datasets, model architectures, and common image transformations for computer vision." + ], + "metadata": { + "id": "pmDF_K9KI3vK" + } + }, + { + "cell_type": "code", + "source": [ + "\n", + "pip install torchvision --no-deps" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "WVaRm8iRKI0F", + "outputId": "1e65ba8c-4c2b-4f2c-a0cd-fe9082983774" + }, + "execution_count": 33, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: torchvision in /usr/local/lib/python3.10/dist-packages (0.15.2+cu118)\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from torch.utils.data import DataLoader\n", + "from torchvision import datasets\n", + "from torchvision.transforms import ToTensor\n", + "from torch import nn" + ], + "metadata": { + "id": "pRDYln36KW17" + }, + "execution_count": 34, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Download training data from open datasets.\n", + "training_data = datasets.FashionMNIST(\n", + "root=\"data\",\n", + "train=True,\n", + "download=True,\n", + "transform=ToTensor(),\n", + ")" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xpgbTNOHKS96", + "outputId": "23989501-7712-4f6e-a3df-7cae1cc197fb" + }, + "execution_count": 35, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz to data/FashionMNIST/raw/train-images-idx3-ubyte.gz\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 26421880/26421880 [00:02<00:00, 11820245.47it/s]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Extracting data/FashionMNIST/raw/train-images-idx3-ubyte.gz to data/FashionMNIST/raw\n", + "\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw/train-labels-idx1-ubyte.gz\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 29515/29515 [00:00<00:00, 202467.13it/s]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Extracting data/FashionMNIST/raw/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw\n", + "\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 4422102/4422102 [00:01<00:00, 3712034.39it/s]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Extracting data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw\n", + "\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz\n", + "Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 5148/5148 [00:00<00:00, 10548254.51it/s]" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Extracting data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw\n", + "\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "?training_data" + ], + "metadata": { + "id": "9_ljYopbKm_g" + }, + "execution_count": 36, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "type(training_data)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "CFtZ9aHUKemF", + "outputId": "a91cbd1c-83ce-46ce-e78d-3c250fe8325b" + }, + "execution_count": 37, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torchvision.datasets.mnist.FashionMNIST" + ] + }, + "metadata": {}, + "execution_count": 37 + } + ] + }, + { + "cell_type": "code", + "source": [ + "len(training_data) # There are 60000 (img, labels) tuples in the training data" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "TqnIB5yHN8pb", + "outputId": "c76b4d46-0326-4efc-cf05-9b3057462c75" + }, + "execution_count": 38, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "60000" + ] + }, + "metadata": {}, + "execution_count": 38 + } + ] + }, + { + "cell_type": "code", + "source": [ + "img, label=training_data[0]" + ], + "metadata": { + "id": "OgsxJi8gSU3P" + }, + "execution_count": 39, + "outputs": [] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "gqwQLUMGSfDZ" + }, + "execution_count": 39, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "img.shape # img shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "xD-4oXB1OS_0", + "outputId": "1453f183-4cb2-4973-b29f-09ecf6f32051" + }, + "execution_count": 40, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "torch.Size([1, 28, 28])" + ] + }, + "metadata": {}, + "execution_count": 40 + } + ] + }, + { + "cell_type": "code", + "source": [ + "label # The tag number that the image belongs to" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "TBPcXgpoPYJB", + "outputId": "5ff7b387-cc38-4d51-bd43-8f25f3d71ce1" + }, + "execution_count": 41, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "9" + ] + }, + "metadata": {}, + "execution_count": 41 + } + ] + }, + { + "cell_type": "code", + "source": [ + "# Download test data from open datasets.\n", + "test_data = datasets.FashionMNIST(\n", + "root=\"data\",\n", + "train=False,\n", + "download=True,\n", + "transform=ToTensor(),\n", + ")" + ], + "metadata": { + "id": "32_co4cLKcDY" + }, + "execution_count": 42, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "len(test_data)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "LEGASWNZQ--3", + "outputId": "a5eed85e-f929-49bb-eba4-b3eb37b75dab" + }, + "execution_count": 43, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "10000" + ] + }, + "metadata": {}, + "execution_count": 43 + } + ] + }, + { + "cell_type": "code", + "source": [ + "timg, label=test_data[0]" + ], + "metadata": { + "id": "UJs3W-4vSw_U" + }, + "execution_count": 44, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "timg.shape,label" + ], + "metadata": { + "id": "2rCJl_BjTAMZ", + "outputId": "ab41c4b8-8953-4134-e879-e5effb1a6baa", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 45, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(torch.Size([1, 28, 28]), 9)" + ] + }, + "metadata": {}, + "execution_count": 45 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "**Dataloader** wraps an iterable over our dataset, and supports automatic batching, sampling, shuffling and multiprocess data loading.\n", + "\n", + " Here we define a batch size of 64, i.e. each element in the dataloader iterable will return a batch of 64 features and labels." + ], + "metadata": { + "id": "KP0sTB8qRhGn" + } + }, + { + "cell_type": "code", + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.figure(figsize=(12,10))\n", + "for i in range(9):\n", + " plt.subplot(3,3,i+1)\n", + " sample_image,sample_label = training_data[i]\n", + " plt.imshow(sample_image[0])\n", + " plt.title(sample_label)" + ], + "metadata": { + "id": "OehhjX8XRwAY", + "outputId": "b0fbfb25-0f4d-4962-e3c9-8e88543d94e8", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 290 + } + }, + "execution_count": 46, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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Ph455mN6MB/7J2dfEe3u7taGDRs0Z86cno8Fg0HNmTNHa9euzeLKBqZt27apsbGx1/GsrKxUfX09x/MwWlpaJElVVVWSpA0bNigajfY6hpMnT9bYsWM5hvAV8zG9mI9HhhmJXMR8TC/m45FhPvZPzm5E9+7dq3g8rurq6l4fr66uVmNjY5ZWNXC9f8w4nv2TSCS0ePFinX766ZoyZYqk945hUVGRhg4d2uu8HEP4jfmYXszH5DEjkauYj+nFfEwe87H/CrK9ACAXLVy4UJs2bdJzzz2X7aUAQM5hRgJA35iP/Zezr4iOGDFCoVDoA+8m1dTUpJqamiytauB6/5hxPN0WLVqkxx57TE8//bTGjBnT8/Gamhp1d3erubm51/k5hvAb8zG9mI/JYUYilzEf04v5mBzmY3JydiNaVFSk6dOna/Xq1T0fSyQSWr16tWbNmpXFlQ1M48ePV01NTa/j2draqvXr13M8/8rzPC1atEgPPfSQfve732n8+PG98unTp6uwsLDXMdy8ebO2b9/OMYSvmI/pxXzsH2YkBgLmY3oxH/uH+XhkcvpXc5csWaIFCxbolFNO0cyZM3X77bervb1dV199dbaXlpPa2tq0ZcuWnv9v27ZNGzduVFVVlcaOHavFixfr29/+tiZOnKjx48frxhtvVG1trS688MLsLTqHLFy4UCtXrtQjjzyi8vLynt/Zr6ysVElJiSorK3XNNddoyZIlqqqqUkVFha677jrNmjVLp556apZXj3zDfEwO8zF1zEgMFMzH5DAfU8d8PEJZftdep//4j//wxo4d6xUVFXkzZ8701q1bl+0l5aynn37ak/SB04IFCzzPe+8tuG+88UavurraC4fD3rnnnutt3rw5u4vOIX0dO0neihUres7T2dnpffGLX/SGDRvmlZaWehdddJG3a9eu7C0aeY352H/Mx9QxIzGQMB/7j/mYOubjkQl4nudlfLcLAAAAAMBf5ezfiAIAAAAABic2ogAAAAAAX7ERRdr85S9/0WWXXaYJEyaotLRUI0aM0FlnnaVHH30020sDgKyLRCL6yle+otraWpWUlKi+vl5PPvlktpcFAFn14osvatGiRTrxxBNVVlamsWPH6uMf/7jeeOONbC8NGcbfiCJtHn/8cd1xxx2aNWuWamtr1dHRoV/84hf6/e9/r//8z//Utddem+0lAkDWXHnllfr5z3+uxYsXa+LEibrnnnv04osv6umnn9YZZ5yR7eUBQFZceuml+sMf/qDLLrtMU6dOVWNjo+688061tbVp3bp1mjJlSraXiAxhI4qMisfjmj59urq6uvT6669nezkAkBUvvPCC6uvrddttt+nLX/6yJKmrq0tTpkzRqFGj9Pzzz2d5hQCQHc8//7xOOeUUFRUV9XzszTff1EknnaRLL71UP/7xj7O4OmQSv5qLjAqFQqqrq1Nzc3O2lwIAWfPzn/9coVCo12+GFBcX65prrtHatWvV0NCQxdUBQPacdtppvTahkjRx4kSdeOKJeu2117K0KviBjSjSrr29XXv37tXWrVv1ve99T7/5zW907rnnZntZAJA1f/zjHzVp0iRVVFT0+vjMmTMlSRs3bszCqgAgN3mep6amJo0YMSLbS0EGFWR7ARh8vvSlL+k///M/JUnBYFAXX3yx7rzzziyvCgCyZ9euXRo9evQHPv7+x3bu3On3kgAgZ91///169913dcstt2R7KcggNqJIu8WLF+vSSy/Vzp079bOf/UzxeFzd3d3ZXhYAZE1nZ6fC4fAHPl5cXNyTAwCk119/XQsXLtSsWbO0YMGCbC8HGcSv5iLtJk+erDlz5ujTn/60HnvsMbW1temCCy4Q74sFIF+VlJQoEol84ONdXV09OQDku8bGRn30ox9VZWVlz9/WY/BiI4qMu/TSS/Xiiy/SBwUgb40ePVq7du36wMff/1htba3fSwKAnNLS0qL58+erublZq1atYi7mATaiyLj3f+WspaUlyysBgOw4+eST9cYbb6i1tbXXx9evX9+TA0C+6urq0gUXXKA33nhDjz32mE444YRsLwk+YCOKtNm9e/cHPhaNRnXfffeppKSEoQIgb1166aWKx+P6wQ9+0POxSCSiFStWqL6+XnV1dVlcHQBkTzwe1+WXX661a9fqwQcf1KxZs7K9JPiENytC2nzuc59Ta2urzjrrLB111FFqbGzU/fffr9dff13/9m//piFDhmR7iQCQFfX19brsssu0dOlS7d69W8cee6zuvfdevf322/rhD3+Y7eUBQNZ86Utf0q9+9StdcMEF2r9/v3784x/3yj/1qU9laWXItIDHO8ggTR544AH98Ic/1J///Gft27dP5eXlmj59uq677jr90z/9U7aXBwBZ1dXVpRtvvFE//vGP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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "batch_size = 64\n", + "\n", + "train_dataloader = DataLoader(training_data,batch_size=batch_size)\n", + "test_dataloader= DataLoader(test_data, batch_size=batch_size)\n", + "\n", + "for X, y in testing:\n", + " print(f\"Shape of X: {X.shape}\")\n", + " print(f\"Shape of y: {y.shape}\")\n", + " break" + ], + "metadata": { + "id": "K3Ia3MzCVFxM", + "outputId": "54e339e4-4e68-4de0-97ed-d477ae2bf565", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 66, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shape of X: torch.Size([64, 1, 28, 28])\n", + "Shape of y: torch.Size([64])\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "for X,y in training:\n", + " print(torch.max(X))\n", + " print(torch.min(X))\n", + " break" + ], + "metadata": { + "id": "PGyH5shxbXaF", + "outputId": "01004bc5-f94c-4a7c-e2d1-a804610715a7", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 48, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "tensor(1.)\n", + "tensor(0.)\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "\n", + "### Model building\n", + "Define a neural network class by subclassing **nn.Module** , and initialize the neural network layers in __init__.\n", + "\n", + "Every nn.Module subclass implements the operations on input data in the forward method." + ], + "metadata": { + "id": "DkhaffnUbplo" + } + }, + { + "cell_type": "code", + "source": [ + "class NeuralNetwork(nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.flatten = nn.Flatten()\n", + " self.linear_relu_stack = nn.Sequential(\n", + " nn.Linear(28*28, 512),\n", + " nn.ReLU(),\n", + " nn.Linear(512, 512),\n", + " nn.ReLU(),\n", + " nn.Linear(512, 10),\n", + " )\n", + "\n", + " def forward(self, x):\n", + " x = self.flatten(x)\n", + " logits = self.linear_relu_stack(x)\n", + " return logits" + ], + "metadata": { + "id": "D7ZWvQmNgjMb" + }, + "execution_count": 60, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "def train_loop(dataloader, model, loss_fn, optimizer):\n", + " size = len(dataloader.dataset)\n", + " # Set the model to training mode - important for batch normalization and dropout layers\n", + " # Unnecessary in this situation but added for best practices\n", + " model.train()\n", + " for batch, (X, y) in enumerate(dataloader):\n", + " # Compute prediction and loss\n", + " pred = model(X)\n", + " loss = loss_fn(pred, y)\n", + "\n", + " # Backpropagation\n", + " loss.backward()\n", + " optimizer.step()\n", + " optimizer.zero_grad()\n", + "\n", + " if batch % 100 == 0:\n", + " loss, current = loss.item(), (batch + 1) * len(X)\n", + " print(f\"loss: {loss:>7f} [{current:>5d}/{size:>5d}]\")\n", + "\n", + "\n", + "def test_loop(dataloader, model, loss_fn):\n", + " # Set the model to evaluation mode - important for batch normalization and dropout layers\n", + " # Unnecessary in this situation but added for best practices\n", + " model.eval()\n", + " size = len(dataloader.dataset)\n", + " num_batches = len(dataloader)\n", + " test_loss, correct = 0, 0\n", + "\n", + " # Evaluating the model with torch.no_grad() ensures that no gradients are computed during test mode\n", + " # also serves to reduce unnecessary gradient computations and memory usage for tensors with requires_grad=True\n", + " with torch.no_grad():\n", + " for X, y in dataloader:\n", + " pred = model(X)\n", + " test_loss += loss_fn(pred, y).item()\n", + " correct += (pred.argmax(1) == y).type(torch.float).sum().item()\n", + "\n", + " test_loss /= num_batches\n", + " correct /= size\n", + " print(f\"Test Error: \\n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \\n\")" + ], + "metadata": { + "id": "8gUX4GTNflsd" + }, + "execution_count": 62, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "\n", + "model = NeuralNetwork()\n", + "\n", + "# Loss Function and Optimizer\n", + "loss_fn = nn.CrossEntropyLoss()\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=1e-5)" + ], + "metadata": { + "id": "FZfo8EFKc139" + }, + "execution_count": 64, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "#loss_fn = nn.CrossEntropyLoss()\n", + "#optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)\n", + "\n", + "epochs = 10\n", + "for t in range(epochs):\n", + " print(f\"Epoch {t+1}\\n-------------------------------\")\n", + " train_loop(train_dataloader, model, loss_fn, optimizer)\n", + " test_loop(test_dataloader, model, loss_fn)\n", + "print(\"Done!\")" + ], + "metadata": { + "id": "WGNzgc21hNIv", + "outputId": "44a86437-9884-45f4-beb6-afc2bf0b98aa", + "colab": { + "base_uri": "https://localhost:8080/" + } + }, + "execution_count": 67, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1\n", + "-------------------------------\n", + "loss: 2.309284 [ 64/60000]\n", + "loss: 2.205355 [ 6464/60000]\n", + "loss: 1.977302 [12864/60000]\n", + "loss: 1.781697 [19264/60000]\n", + "loss: 1.408237 [25664/60000]\n", + "loss: 1.272241 [32064/60000]\n", + "loss: 1.169993 [38464/60000]\n", + "loss: 1.043139 [44864/60000]\n", + "loss: 0.994844 [51264/60000]\n", + "loss: 0.898466 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 67.9%, Avg loss: 0.898348 \n", + "\n", + "Epoch 2\n", + "-------------------------------\n", + "loss: 0.927513 [ 64/60000]\n", + "loss: 0.955703 [ 6464/60000]\n", + "loss: 0.708044 [12864/60000]\n", + "loss: 0.898090 [19264/60000]\n", + "loss: 0.738703 [25664/60000]\n", + "loss: 0.739710 [32064/60000]\n", + "loss: 0.773765 [38464/60000]\n", + "loss: 0.751834 [44864/60000]\n", + "loss: 0.734376 [51264/60000]\n", + "loss: 0.713160 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 75.3%, Avg loss: 0.698978 \n", + "\n", + "Epoch 3\n", + "-------------------------------\n", + "loss: 0.664758 [ 64/60000]\n", + "loss: 0.759621 [ 6464/60000]\n", + "loss: 0.524777 [12864/60000]\n", + "loss: 0.765561 [19264/60000]\n", + "loss: 0.630300 [25664/60000]\n", + "loss: 0.631898 [32064/60000]\n", + "loss: 0.650088 [38464/60000]\n", + "loss: 0.689169 [44864/60000]\n", + "loss: 0.656049 [51264/60000]\n", + "loss: 0.630540 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 78.4%, Avg loss: 0.618572 \n", + "\n", + "Epoch 4\n", + "-------------------------------\n", + "loss: 0.566174 [ 64/60000]\n", + "loss: 0.658641 [ 6464/60000]\n", + "loss: 0.447832 [12864/60000]\n", + "loss: 0.700783 [19264/60000]\n", + "loss: 0.577810 [25664/60000]\n", + "loss: 0.579068 [32064/60000]\n", + "loss: 0.579147 [38464/60000]\n", + "loss: 0.666817 [44864/60000]\n", + "loss: 0.624433 [51264/60000]\n", + "loss: 0.575802 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 80.0%, Avg loss: 0.572408 \n", + "\n", + "Epoch 5\n", + "-------------------------------\n", + "loss: 0.510373 [ 64/60000]\n", + "loss: 0.597321 [ 6464/60000]\n", + "loss: 0.403381 [12864/60000]\n", + "loss: 0.657211 [19264/60000]\n", + "loss: 0.542515 [25664/60000]\n", + "loss: 0.544466 [32064/60000]\n", + "loss: 0.534232 [38464/60000]\n", + "loss: 0.657896 [44864/60000]\n", + "loss: 0.610059 [51264/60000]\n", + "loss: 0.536132 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 81.0%, Avg loss: 0.542587 \n", + "\n", + "Epoch 6\n", + "-------------------------------\n", + "loss: 0.471370 [ 64/60000]\n", + "loss: 0.558277 [ 6464/60000]\n", + "loss: 0.373987 [12864/60000]\n", + "loss: 0.623326 [19264/60000]\n", + "loss: 0.516122 [25664/60000]\n", + "loss: 0.517792 [32064/60000]\n", + "loss: 0.502440 [38464/60000]\n", + "loss: 0.653071 [44864/60000]\n", + "loss: 0.601150 [51264/60000]\n", + "loss: 0.505485 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 81.8%, Avg loss: 0.521625 \n", + "\n", + "Epoch 7\n", + "-------------------------------\n", + "loss: 0.440899 [ 64/60000]\n", + "loss: 0.531618 [ 6464/60000]\n", + "loss: 0.352678 [12864/60000]\n", + "loss: 0.596314 [19264/60000]\n", + "loss: 0.494141 [25664/60000]\n", + "loss: 0.495663 [32064/60000]\n", + "loss: 0.478423 [38464/60000]\n", + "loss: 0.648328 [44864/60000]\n", + "loss: 0.593854 [51264/60000]\n", + "loss: 0.480929 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 82.3%, Avg loss: 0.505905 \n", + "\n", + "Epoch 8\n", + "-------------------------------\n", + "loss: 0.415017 [ 64/60000]\n", + "loss: 0.512357 [ 6464/60000]\n", + "loss: 0.335735 [12864/60000]\n", + "loss: 0.574628 [19264/60000]\n", + "loss: 0.475450 [25664/60000]\n", + "loss: 0.477158 [32064/60000]\n", + "loss: 0.459064 [38464/60000]\n", + "loss: 0.643172 [44864/60000]\n", + "loss: 0.586849 [51264/60000]\n", + "loss: 0.461083 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 82.7%, Avg loss: 0.493490 \n", + "\n", + "Epoch 9\n", + "-------------------------------\n", + "loss: 0.392959 [ 64/60000]\n", + "loss: 0.497598 [ 6464/60000]\n", + "loss: 0.321871 [12864/60000]\n", + "loss: 0.556399 [19264/60000]\n", + "loss: 0.459459 [25664/60000]\n", + "loss: 0.461655 [32064/60000]\n", + "loss: 0.443326 [38464/60000]\n", + "loss: 0.636505 [44864/60000]\n", + "loss: 0.579597 [51264/60000]\n", + "loss: 0.444843 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 83.0%, Avg loss: 0.483345 \n", + "\n", + "Epoch 10\n", + "-------------------------------\n", + "loss: 0.373844 [ 64/60000]\n", + "loss: 0.486166 [ 6464/60000]\n", + "loss: 0.310201 [12864/60000]\n", + "loss: 0.541019 [19264/60000]\n", + "loss: 0.445114 [25664/60000]\n", + "loss: 0.449067 [32064/60000]\n", + "loss: 0.430682 [38464/60000]\n", + "loss: 0.629879 [44864/60000]\n", + "loss: 0.572779 [51264/60000]\n", + "loss: 0.431877 [57664/60000]\n", + "Test Error: \n", + " Accuracy: 83.3%, Avg loss: 0.474775 \n", + "\n", + "Done!\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "### Further reading:\n", + "- Book:\n", + " * [Deep learning with Pytorch(GitHub)](https://github.com/deep-learning-with-pytorch/dlwpt-code)\n", + "- Tutorial:\n", + " * [PyTorch](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)\n", + " * [Zero to Mastery Learn PyTorch for Deep Learning](https://www.learnpytorch.io/)\n", + "- Reference:\n", + " * [Official documentation](https://pytorch.org/tutorials/beginner/basics/intro.html)" + ], + "metadata": { + "id": "D1cpOSnvaKdS" + } + } + ] +} \ No newline at end of file