From ce0e0285f4563dbd5b7f55b64e4fc0fccbc695ef Mon Sep 17 00:00:00 2001 From: romaingallo <beromrousse@gmail.com> Date: Thu, 21 Nov 2024 11:49:59 +0100 Subject: [PATCH] Ex1 --- TD2 Deep Learning.ipynb | 551 ++++++++++++++++++++++++++++++++++++++-- ex1Modele1.png | Bin 0 -> 20491 bytes ex1Modele2.png | Bin 0 -> 22230 bytes 3 files changed, 529 insertions(+), 22 deletions(-) create mode 100644 ex1Modele1.png create mode 100644 ex1Modele2.png diff --git a/TD2 Deep Learning.ipynb b/TD2 Deep Learning.ipynb index a14730c..a0419bf 100644 --- a/TD2 Deep Learning.ipynb +++ b/TD2 Deep Learning.ipynb @@ -157,10 +157,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "6e18f2fd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CUDA is not available. Training on CPU ...\n" + ] + } + ], "source": [ "import torch\n", "\n", @@ -183,10 +191,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "462666a2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to data\\cifar-10-python.tar.gz\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 170M/170M [00:17<00:00, 9.66MB/s] \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Extracting data\\cifar-10-python.tar.gz to data\n", + "Files already downloaded and verified\n" + ] + } + ], "source": [ "import numpy as np\n", "from torchvision import datasets, transforms\n", @@ -255,10 +286,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "id": "317bf070", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Net(\n", + " (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n", + " (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n", + " (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n", + " (fc1): Linear(in_features=400, out_features=120, bias=True)\n", + " (fc2): Linear(in_features=120, out_features=84, bias=True)\n", + " (fc3): Linear(in_features=84, out_features=10, bias=True)\n", + ")\n" + ] + } + ], "source": [ "import torch.nn as nn\n", "import torch.nn.functional as F\n", @@ -304,10 +350,65 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "id": "4b53f229", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 0 \tTraining Loss: 43.310613 \tValidation Loss: 38.297743\n", + "Validation loss decreased (inf --> 38.297743). Saving model ...\n", + "Epoch: 1 \tTraining Loss: 34.186083 \tValidation Loss: 30.914800\n", + "Validation loss decreased (38.297743 --> 30.914800). Saving model ...\n", + "Epoch: 2 \tTraining Loss: 30.325666 \tValidation Loss: 28.688646\n", + "Validation loss decreased (30.914800 --> 28.688646). Saving model ...\n", + "Epoch: 3 \tTraining Loss: 28.072272 \tValidation Loss: 27.418195\n", + "Validation loss decreased (28.688646 --> 27.418195). Saving model ...\n", + "Epoch: 4 \tTraining Loss: 26.500710 \tValidation Loss: 25.774103\n", + "Validation loss decreased (27.418195 --> 25.774103). Saving model ...\n", + "Epoch: 5 \tTraining Loss: 25.252793 \tValidation Loss: 25.000141\n", + "Validation loss decreased (25.774103 --> 25.000141). Saving model ...\n", + "Epoch: 6 \tTraining Loss: 24.158602 \tValidation Loss: 23.680893\n", + "Validation loss decreased (25.000141 --> 23.680893). Saving model ...\n", + "Epoch: 7 \tTraining Loss: 23.210504 \tValidation Loss: 23.369460\n", + "Validation loss decreased (23.680893 --> 23.369460). Saving model ...\n", + "Epoch: 8 \tTraining Loss: 22.340226 \tValidation Loss: 23.335326\n", + "Validation loss decreased (23.369460 --> 23.335326). Saving model ...\n", + "Epoch: 9 \tTraining Loss: 21.590825 \tValidation Loss: 22.373804\n", + "Validation loss decreased (23.335326 --> 22.373804). Saving model ...\n", + "Epoch: 10 \tTraining Loss: 20.892846 \tValidation Loss: 22.866940\n", + "Epoch: 11 \tTraining Loss: 20.180947 \tValidation Loss: 21.824822\n", + "Validation loss decreased (22.373804 --> 21.824822). Saving model ...\n", + "Epoch: 12 \tTraining Loss: 19.453305 \tValidation Loss: 22.748037\n", + "Epoch: 13 \tTraining Loss: 18.863672 \tValidation Loss: 22.272626\n", + "Epoch: 14 \tTraining Loss: 18.243816 \tValidation Loss: 22.050470\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[31], line 17\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[38;5;66;03m# Train the model\u001b[39;00m\n\u001b[0;32m 16\u001b[0m model\u001b[38;5;241m.\u001b[39mtrain()\n\u001b[1;32m---> 17\u001b[0m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtrain_loader\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Move tensors to GPU if CUDA is available\u001b[39;49;00m\n\u001b[0;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtrain_on_gpu\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcuda\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcuda\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\dataloader.py:701\u001b[0m, in \u001b[0;36m_BaseDataLoaderIter.__next__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sampler_iter \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# TODO(https://github.com/pytorch/pytorch/issues/76750)\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_reset() \u001b[38;5;66;03m# type: ignore[call-arg]\u001b[39;00m\n\u001b[1;32m--> 701\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_next_data\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 702\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 703\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[0;32m 704\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_dataset_kind \u001b[38;5;241m==\u001b[39m _DatasetKind\u001b[38;5;241m.\u001b[39mIterable\n\u001b[0;32m 705\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 706\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called\n\u001b[0;32m 707\u001b[0m ):\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\dataloader.py:757\u001b[0m, in \u001b[0;36m_SingleProcessDataLoaderIter._next_data\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 755\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_next_data\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 756\u001b[0m index \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_next_index() \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[1;32m--> 757\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_dataset_fetcher\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfetch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindex\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[0;32m 758\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory:\n\u001b[0;32m 759\u001b[0m data \u001b[38;5;241m=\u001b[39m _utils\u001b[38;5;241m.\u001b[39mpin_memory\u001b[38;5;241m.\u001b[39mpin_memory(data, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory_device)\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\_utils\\fetch.py:52\u001b[0m, in \u001b[0;36m_MapDatasetFetcher.fetch\u001b[1;34m(self, possibly_batched_index)\u001b[0m\n\u001b[0;32m 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__(possibly_batched_index)\n\u001b[0;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 52\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43midx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mpossibly_batched_index\u001b[49m\u001b[43m]\u001b[49m\n\u001b[0;32m 53\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 54\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[possibly_batched_index]\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\_utils\\fetch.py:52\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__(possibly_batched_index)\n\u001b[0;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 52\u001b[0m data \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m idx \u001b[38;5;129;01min\u001b[39;00m possibly_batched_index]\n\u001b[0;32m 53\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 54\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[possibly_batched_index]\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\datasets\\cifar.py:119\u001b[0m, in \u001b[0;36mCIFAR10.__getitem__\u001b[1;34m(self, index)\u001b[0m\n\u001b[0;32m 116\u001b[0m img \u001b[38;5;241m=\u001b[39m Image\u001b[38;5;241m.\u001b[39mfromarray(img)\n\u001b[0;32m 118\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m--> 119\u001b[0m img \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtransform\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 121\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtarget_transform \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 122\u001b[0m target \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtarget_transform(target)\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\transforms.py:95\u001b[0m, in \u001b[0;36mCompose.__call__\u001b[1;34m(self, img)\u001b[0m\n\u001b[0;32m 93\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__call__\u001b[39m(\u001b[38;5;28mself\u001b[39m, img):\n\u001b[0;32m 94\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m t \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransforms:\n\u001b[1;32m---> 95\u001b[0m img \u001b[38;5;241m=\u001b[39m \u001b[43mt\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 96\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m img\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\nn\\modules\\module.py:1736\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1734\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[0;32m 1735\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1736\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_impl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\nn\\modules\\module.py:1747\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1742\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[0;32m 1743\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[0;32m 1744\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[0;32m 1745\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[0;32m 1746\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[1;32m-> 1747\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforward_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1749\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 1750\u001b[0m called_always_called_hooks \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mset\u001b[39m()\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\transforms.py:277\u001b[0m, in \u001b[0;36mNormalize.forward\u001b[1;34m(self, tensor)\u001b[0m\n\u001b[0;32m 269\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mforward\u001b[39m(\u001b[38;5;28mself\u001b[39m, tensor: Tensor) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tensor:\n\u001b[0;32m 270\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 271\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m 272\u001b[0m \u001b[38;5;124;03m tensor (Tensor): Tensor image to be normalized.\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 275\u001b[0m \u001b[38;5;124;03m Tensor: Normalized Tensor image.\u001b[39;00m\n\u001b[0;32m 276\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 277\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mF\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnormalize\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmean\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstd\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minplace\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\functional.py:350\u001b[0m, in \u001b[0;36mnormalize\u001b[1;34m(tensor, mean, std, inplace)\u001b[0m\n\u001b[0;32m 347\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(tensor, torch\u001b[38;5;241m.\u001b[39mTensor):\n\u001b[0;32m 348\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mimg should be Tensor Image. Got \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(tensor)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 350\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mF_t\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnormalize\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmean\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmean\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstd\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstd\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minplace\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minplace\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\_functional_tensor.py:917\u001b[0m, in \u001b[0;36mnormalize\u001b[1;34m(tensor, mean, std, inplace)\u001b[0m\n\u001b[0;32m 912\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 913\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mExpected tensor to be a tensor image of size (..., C, H, W). Got tensor.size() = \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtensor\u001b[38;5;241m.\u001b[39msize()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 914\u001b[0m )\n\u001b[0;32m 916\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m inplace:\n\u001b[1;32m--> 917\u001b[0m tensor \u001b[38;5;241m=\u001b[39m \u001b[43mtensor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mclone\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 919\u001b[0m dtype \u001b[38;5;241m=\u001b[39m tensor\u001b[38;5;241m.\u001b[39mdtype\n\u001b[0;32m 920\u001b[0m mean \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mas_tensor(mean, dtype\u001b[38;5;241m=\u001b[39mdtype, device\u001b[38;5;241m=\u001b[39mtensor\u001b[38;5;241m.\u001b[39mdevice)\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], "source": [ "import torch.optim as optim\n", "\n", @@ -316,7 +417,7 @@ "\n", "n_epochs = 30 # number of epochs to train the model\n", "train_loss_list = [] # list to store loss to visualize\n", - "valid_loss_min = np.Inf # track change in validation loss\n", + "valid_loss_min = np.inf # track change in validation loss\n", "\n", "for epoch in range(n_epochs):\n", " # Keep track of training and validation loss\n", @@ -378,30 +479,45 @@ " valid_loss_min = valid_loss" ] }, - { - "cell_type": "markdown", - "id": "13e1df74", - "metadata": {}, - "source": [ - "Does overfit occur? If so, do an early stopping." - ] - }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "id": "d39df818", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "\n", - "plt.plot(range(n_epochs), train_loss_list)\n", + "plt.plot(range(len(train_loss_list)), train_loss_list)\n", "plt.xlabel(\"Epoch\")\n", "plt.ylabel(\"Loss\")\n", "plt.title(\"Performance of Model 1\")\n", "plt.show()" ] }, + { + "cell_type": "markdown", + "id": "fa67ac46", + "metadata": {}, + "source": [ + "Does overfit occur ?\n", + "\n", + "*La validation loss baisse jusqu'à l'époque 14, puis se stabilise aux époques suivantes. Le modèle overfit après l'époque 14.*\n", + "\n", + "*The validation loss decreases until epoch 14, then stabilizes in subsequent epochs. The model overfits after epoch 14.*" + ] + }, { "cell_type": "markdown", "id": "11df8fd4", @@ -412,10 +528,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "id": "e93efdfc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Utilisateur\\AppData\\Local\\Temp\\ipykernel_5932\\3291884398.py:1: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model.load_state_dict(torch.load(\"./model_cifar.pt\"))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 22.460758\n", + "\n", + "Test Accuracy of airplane: 70% (708/1000)\n", + "Test Accuracy of automobile: 64% (648/1000)\n", + "Test Accuracy of bird: 45% (453/1000)\n", + "Test Accuracy of cat: 47% (471/1000)\n", + "Test Accuracy of deer: 47% (476/1000)\n", + "Test Accuracy of dog: 46% (463/1000)\n", + "Test Accuracy of frog: 67% (678/1000)\n", + "Test Accuracy of horse: 64% (649/1000)\n", + "Test Accuracy of ship: 81% (811/1000)\n", + "Test Accuracy of truck: 68% (687/1000)\n", + "\n", + "Test Accuracy (Overall): 60% (6044/10000)\n" + ] + } + ], "source": [ "model.load_state_dict(torch.load(\"./model_cifar.pt\"))\n", "\n", @@ -484,6 +629,8 @@ "id": "944991a2", "metadata": {}, "source": [ + "*Test Accuracy (Overall): 60% (6044/10000)*\n", + "\n", "Build a new network with the following structure.\n", "\n", "- It has 3 convolutional layers of kernel size 3 and padding of 1.\n", @@ -496,6 +643,366 @@ "Compare the results obtained with this new network to those obtained previously." ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e1e4ad3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Net(\n", + " (conv1): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", + " (conv2): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", + " (conv3): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", + " (pool): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)\n", + " (fc1): Linear(in_features=576, out_features=512, bias=True)\n", + " (fc2): Linear(in_features=512, out_features=64, bias=True)\n", + " (fc3): Linear(in_features=64, out_features=10, bias=True)\n", + ")\n" + ] + }, + { + "data": { + "text/plain": [ + "' \\nclass Net(nn.Module):\\n def __init__(self):\\n super(Net, self).__init__()\\n self.conv1 = nn.Conv2d(3, 6, 5)\\n self.pool = nn.MaxPool2d(2, 2)\\n self.conv2 = nn.Conv2d(6, 16, 5)\\n self.fc1 = nn.Linear(16 * 5 * 5, 120)\\n self.fc2 = nn.Linear(120, 84)\\n self.fc3 = nn.Linear(84, 10)\\n\\n def forward(self, x):\\n x = self.pool(F.relu(self.conv1(x)))\\n x = self.pool(F.relu(self.conv2(x)))\\n x = x.view(-1, 16 * 5 * 5)\\n x = F.relu(self.fc1(x))\\n x = F.relu(self.fc2(x))\\n x = self.fc3(x)\\n return x\\n'" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "\n", + "# define the CNN architecture\n", + "\n", + "\n", + "class Net(nn.Module):\n", + " def __init__(self):\n", + " super(Net, self).__init__()\n", + " self.conv1 = nn.Conv2d(3, 16, 3, padding=1)\n", + " self.conv2 = nn.Conv2d(16, 32, 3, padding=1)\n", + " self.conv3 = nn.Conv2d(32, 64, 3, padding=1)\n", + " self.pool = nn.MaxPool2d(3, 2)\n", + " self.fc1 = nn.Linear(64 * 3 * 3, 512)\n", + " self.fc2 = nn.Linear(512, 64)\n", + " self.fc3 = nn.Linear(64, 10) # Dropout whose value you will suggest ???\n", + "\n", + " def forward(self, x):\n", + " x = self.pool(F.relu(self.conv1(x)))\n", + " x = self.pool(F.relu(self.conv2(x)))\n", + " x = self.pool(F.relu(self.conv3(x)))\n", + " x = x.view(-1, 64 * 3 * 3)\n", + " x = F.relu(self.fc1(x))\n", + " x = F.relu(self.fc2(x))\n", + " x = self.fc3(x)\n", + " return x\n", + "\n", + "\n", + "# create a complete CNN\n", + "modelEx = Net()\n", + "print(modelEx)\n", + "# move tensors to GPU if CUDA is available\n", + "if train_on_gpu:\n", + " modelEx.cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "4af16458", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 0 \tTraining Loss: 45.114236 \tValidation Loss: 40.789144\n", + "Validation loss decreased (inf --> 40.789144). Saving model ...\n", + "Epoch: 1 \tTraining Loss: 36.672867 \tValidation Loss: 32.992202\n", + "Validation loss decreased (40.789144 --> 32.992202). Saving model ...\n", + "Epoch: 2 \tTraining Loss: 31.540151 \tValidation Loss: 29.471859\n", + "Validation loss decreased (32.992202 --> 29.471859). Saving model ...\n", + "Epoch: 3 \tTraining Loss: 28.217329 \tValidation Loss: 26.253962\n", + "Validation loss decreased (29.471859 --> 26.253962). Saving model ...\n", + "Epoch: 4 \tTraining Loss: 25.529990 \tValidation Loss: 24.321873\n", + "Validation loss decreased (26.253962 --> 24.321873). Saving model ...\n", + "Epoch: 5 \tTraining Loss: 23.226547 \tValidation Loss: 22.153841\n", + "Validation loss decreased (24.321873 --> 22.153841). Saving model ...\n", + "Epoch: 6 \tTraining Loss: 21.182890 \tValidation Loss: 20.297892\n", + "Validation loss decreased (22.153841 --> 20.297892). Saving model ...\n", + "Epoch: 7 \tTraining Loss: 19.363431 \tValidation Loss: 19.952192\n", + "Validation loss decreased (20.297892 --> 19.952192). Saving model ...\n", + "Epoch: 8 \tTraining Loss: 17.804383 \tValidation Loss: 18.367063\n", + "Validation loss decreased (19.952192 --> 18.367063). Saving model ...\n", + "Epoch: 9 \tTraining Loss: 16.602377 \tValidation Loss: 17.354809\n", + "Validation loss decreased (18.367063 --> 17.354809). Saving model ...\n", + "Epoch: 10 \tTraining Loss: 15.480934 \tValidation Loss: 17.487981\n", + "Epoch: 11 \tTraining Loss: 14.417038 \tValidation Loss: 16.533617\n", + "Validation loss decreased (17.354809 --> 16.533617). Saving model ...\n", + "Epoch: 12 \tTraining Loss: 13.486131 \tValidation Loss: 15.517560\n", + "Validation loss decreased (16.533617 --> 15.517560). Saving model ...\n", + "Epoch: 13 \tTraining Loss: 12.624461 \tValidation Loss: 15.282706\n", + "Validation loss decreased (15.517560 --> 15.282706). Saving model ...\n", + "Epoch: 14 \tTraining Loss: 11.833298 \tValidation Loss: 15.360621\n", + "Epoch: 15 \tTraining Loss: 11.090945 \tValidation Loss: 15.871890\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[23], line 17\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[38;5;66;03m# Train the model\u001b[39;00m\n\u001b[0;32m 16\u001b[0m modelEx\u001b[38;5;241m.\u001b[39mtrain()\n\u001b[1;32m---> 17\u001b[0m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtrain_loader\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Move tensors to GPU if CUDA is available\u001b[39;49;00m\n\u001b[0;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtrain_on_gpu\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcuda\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcuda\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\dataloader.py:701\u001b[0m, in \u001b[0;36m_BaseDataLoaderIter.__next__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sampler_iter \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# TODO(https://github.com/pytorch/pytorch/issues/76750)\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_reset() \u001b[38;5;66;03m# type: ignore[call-arg]\u001b[39;00m\n\u001b[1;32m--> 701\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_next_data\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 702\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 703\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[0;32m 704\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_dataset_kind \u001b[38;5;241m==\u001b[39m _DatasetKind\u001b[38;5;241m.\u001b[39mIterable\n\u001b[0;32m 705\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 706\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called\n\u001b[0;32m 707\u001b[0m ):\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\dataloader.py:757\u001b[0m, in \u001b[0;36m_SingleProcessDataLoaderIter._next_data\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 755\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_next_data\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 756\u001b[0m index \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_next_index() \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[1;32m--> 757\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_dataset_fetcher\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfetch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindex\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[0;32m 758\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory:\n\u001b[0;32m 759\u001b[0m data \u001b[38;5;241m=\u001b[39m _utils\u001b[38;5;241m.\u001b[39mpin_memory\u001b[38;5;241m.\u001b[39mpin_memory(data, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory_device)\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\_utils\\fetch.py:52\u001b[0m, in \u001b[0;36m_MapDatasetFetcher.fetch\u001b[1;34m(self, possibly_batched_index)\u001b[0m\n\u001b[0;32m 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__(possibly_batched_index)\n\u001b[0;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 52\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43midx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mpossibly_batched_index\u001b[49m\u001b[43m]\u001b[49m\n\u001b[0;32m 53\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 54\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[possibly_batched_index]\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\utils\\data\\_utils\\fetch.py:52\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__(possibly_batched_index)\n\u001b[0;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m---> 52\u001b[0m data \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m idx \u001b[38;5;129;01min\u001b[39;00m possibly_batched_index]\n\u001b[0;32m 53\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 54\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[possibly_batched_index]\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\datasets\\cifar.py:119\u001b[0m, in \u001b[0;36mCIFAR10.__getitem__\u001b[1;34m(self, index)\u001b[0m\n\u001b[0;32m 116\u001b[0m img \u001b[38;5;241m=\u001b[39m Image\u001b[38;5;241m.\u001b[39mfromarray(img)\n\u001b[0;32m 118\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m--> 119\u001b[0m img \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtransform\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 121\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtarget_transform \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 122\u001b[0m target \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtarget_transform(target)\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\transforms.py:95\u001b[0m, in \u001b[0;36mCompose.__call__\u001b[1;34m(self, img)\u001b[0m\n\u001b[0;32m 93\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__call__\u001b[39m(\u001b[38;5;28mself\u001b[39m, img):\n\u001b[0;32m 94\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m t \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransforms:\n\u001b[1;32m---> 95\u001b[0m img \u001b[38;5;241m=\u001b[39m \u001b[43mt\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 96\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m img\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\nn\\modules\\module.py:1736\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1734\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[0;32m 1735\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1736\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_impl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torch\\nn\\modules\\module.py:1747\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1742\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[0;32m 1743\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[0;32m 1744\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[0;32m 1745\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[0;32m 1746\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[1;32m-> 1747\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforward_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1749\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 1750\u001b[0m called_always_called_hooks \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mset\u001b[39m()\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\transforms.py:277\u001b[0m, in \u001b[0;36mNormalize.forward\u001b[1;34m(self, tensor)\u001b[0m\n\u001b[0;32m 269\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mforward\u001b[39m(\u001b[38;5;28mself\u001b[39m, tensor: Tensor) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tensor:\n\u001b[0;32m 270\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 271\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m 272\u001b[0m \u001b[38;5;124;03m tensor (Tensor): Tensor image to be normalized.\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 275\u001b[0m \u001b[38;5;124;03m Tensor: Normalized Tensor image.\u001b[39;00m\n\u001b[0;32m 276\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 277\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mF\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnormalize\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmean\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstd\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minplace\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\functional.py:350\u001b[0m, in \u001b[0;36mnormalize\u001b[1;34m(tensor, mean, std, inplace)\u001b[0m\n\u001b[0;32m 347\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(tensor, torch\u001b[38;5;241m.\u001b[39mTensor):\n\u001b[0;32m 348\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mimg should be Tensor Image. Got \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(tensor)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 350\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mF_t\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnormalize\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmean\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmean\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstd\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstd\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minplace\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minplace\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python311\\site-packages\\torchvision\\transforms\\_functional_tensor.py:922\u001b[0m, in \u001b[0;36mnormalize\u001b[1;34m(tensor, mean, std, inplace)\u001b[0m\n\u001b[0;32m 920\u001b[0m mean \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mas_tensor(mean, dtype\u001b[38;5;241m=\u001b[39mdtype, device\u001b[38;5;241m=\u001b[39mtensor\u001b[38;5;241m.\u001b[39mdevice)\n\u001b[0;32m 921\u001b[0m std \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mas_tensor(std, dtype\u001b[38;5;241m=\u001b[39mdtype, device\u001b[38;5;241m=\u001b[39mtensor\u001b[38;5;241m.\u001b[39mdevice)\n\u001b[1;32m--> 922\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43m(\u001b[49m\u001b[43mstd\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m==\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43many\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m:\n\u001b[0;32m 923\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstd evaluated to zero after conversion to \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mdtype\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, leading to division by zero.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 924\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m mean\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "import torch.optim as optim\n", + "\n", + "criterion = nn.CrossEntropyLoss() # specify loss function\n", + "optimizer = optim.SGD(modelEx.parameters(), lr=0.01) # specify optimizer\n", + "\n", + "n_epochs = 30 # number of epochs to train the model\n", + "train_loss_list = [] # list to store loss to visualize\n", + "valid_loss_min = np.inf # track change in validation loss\n", + "\n", + "for epoch in range(n_epochs):\n", + " # Keep track of training and validation loss\n", + " train_loss = 0.0\n", + " valid_loss = 0.0\n", + "\n", + " # Train the model\n", + " modelEx.train()\n", + " for data, target in train_loader:\n", + " # Move tensors to GPU if CUDA is available\n", + " if train_on_gpu:\n", + " data, target = data.cuda(), target.cuda()\n", + " # Clear the gradients of all optimized variables\n", + " optimizer.zero_grad()\n", + " # Forward pass: compute predicted outputs by passing inputs to the model\n", + " output = modelEx(data)\n", + " # Calculate the batch loss\n", + " loss = criterion(output, target)\n", + " # Backward pass: compute gradient of the loss with respect to model parameters\n", + " loss.backward()\n", + " # Perform a single optimization step (parameter update)\n", + " optimizer.step()\n", + " # Update training loss\n", + " train_loss += loss.item() * data.size(0)\n", + "\n", + " # Validate the model\n", + " modelEx.eval()\n", + " for data, target in valid_loader:\n", + " # Move tensors to GPU if CUDA is available\n", + " if train_on_gpu:\n", + " data, target = data.cuda(), target.cuda()\n", + " # Forward pass: compute predicted outputs by passing inputs to the model\n", + " output = modelEx(data)\n", + " # Calculate the batch loss\n", + " loss = criterion(output, target)\n", + " # Update average validation loss\n", + " valid_loss += loss.item() * data.size(0)\n", + "\n", + " # Calculate average losses\n", + " train_loss = train_loss / len(train_loader)\n", + " valid_loss = valid_loss / len(valid_loader)\n", + " train_loss_list.append(train_loss)\n", + "\n", + " # Print training/validation statistics\n", + " print(\n", + " \"Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}\".format(\n", + " epoch, train_loss, valid_loss\n", + " )\n", + " )\n", + "\n", + " # Save model if validation loss has decreased\n", + " if valid_loss <= valid_loss_min:\n", + " print(\n", + " \"Validation loss decreased ({:.6f} --> {:.6f}). Saving model ...\".format(\n", + " valid_loss_min, valid_loss\n", + " )\n", + " )\n", + " torch.save(modelEx.state_dict(), \"model_cifarEx.pt\")\n", + " valid_loss_min = valid_loss\n" + ] + }, + { + "cell_type": "markdown", + "id": "73c43cc5", + "metadata": {}, + "source": [ + "*La validation loss baisse jusqu'à l'époque 13, puis se stabilise : on arrête le training.*\n", + "\n", + "*The validation loss decreases until epoch 13, then stabilizes: we stop training.*" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "bfff558d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# print(len(train_loss_list))\n", + "\n", + "plt.plot(range(len(train_loss_list)), train_loss_list)\n", + "plt.xlabel(\"Epoch\")\n", + "plt.ylabel(\"Loss\")\n", + "plt.title(\"Performance of Model 2\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55c1bf75", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Utilisateur\\AppData\\Local\\Temp\\ipykernel_5932\\3002838268.py:1: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " modelEx.load_state_dict(torch.load(\"./model_cifarEx.pt\"))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 15.633493\n", + "\n", + "Test Accuracy of airplane: 77% (776/1000)\n", + "Test Accuracy of automobile: 79% (795/1000)\n", + "Test Accuracy of bird: 57% (570/1000)\n", + "Test Accuracy of cat: 59% (592/1000)\n", + "Test Accuracy of deer: 72% (726/1000)\n", + "Test Accuracy of dog: 62% (623/1000)\n", + "Test Accuracy of frog: 73% (730/1000)\n", + "Test Accuracy of horse: 77% (775/1000)\n", + "Test Accuracy of ship: 83% (832/1000)\n", + "Test Accuracy of truck: 87% (874/1000)\n", + "\n", + "Test Accuracy (Overall): 72% (7293/10000)\n" + ] + }, + { + "data": { + "text/plain": [ + "' \\nmodel.load_state_dict(torch.load(\"./model_cifar.pt\"))\\n\\n# track test loss\\ntest_loss = 0.0\\nclass_correct = list(0.0 for i in range(10))\\nclass_total = list(0.0 for i in range(10))\\n\\nmodel.eval()\\n# iterate over test data\\nfor data, target in test_loader:\\n # move tensors to GPU if CUDA is available\\n if train_on_gpu:\\n data, target = data.cuda(), target.cuda()\\n # forward pass: compute predicted outputs by passing inputs to the model\\n output = model(data)\\n # calculate the batch loss\\n loss = criterion(output, target)\\n # update test loss\\n test_loss += loss.item() * data.size(0)\\n # convert output probabilities to predicted class\\n _, pred = torch.max(output, 1)\\n # compare predictions to true label\\n correct_tensor = pred.eq(target.data.view_as(pred))\\n correct = (\\n np.squeeze(correct_tensor.numpy())\\n if not train_on_gpu\\n else np.squeeze(correct_tensor.cpu().numpy())\\n )\\n # calculate test accuracy for each object class\\n for i in range(batch_size):\\n label = target.data[i]\\n class_correct[label] += correct[i].item()\\n class_total[label] += 1\\n\\n# average test loss\\ntest_loss = test_loss / len(test_loader)\\nprint(\"Test Loss: {:.6f}\\n\".format(test_loss))\\n\\nfor i in range(10):\\n if class_total[i] > 0:\\n print(\\n \"Test Accuracy of %5s: %2d%% (%2d/%2d)\"\\n % (\\n classes[i],\\n 100 * class_correct[i] / class_total[i],\\n np.sum(class_correct[i]),\\n np.sum(class_total[i]),\\n )\\n )\\n else:\\n print(\"Test Accuracy of %5s: N/A (no training examples)\" % (classes[i]))\\n\\nprint(\\n \"\\nTest Accuracy (Overall): %2d%% (%2d/%2d)\"\\n % (\\n 100.0 * np.sum(class_correct) / np.sum(class_total),\\n np.sum(class_correct),\\n np.sum(class_total),\\n )\\n)\\n'" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "modelEx.load_state_dict(torch.load(\"./model_cifarEx.pt\"))\n", + "\n", + "# track test loss\n", + "test_loss = 0.0\n", + "class_correct = list(0.0 for i in range(10))\n", + "class_total = list(0.0 for i in range(10))\n", + "\n", + "modelEx.eval()\n", + "# iterate over test data\n", + "for data, target in test_loader:\n", + " # move tensors to GPU if CUDA is available\n", + " if train_on_gpu:\n", + " data, target = data.cuda(), target.cuda()\n", + " # forward pass: compute predicted outputs by passing inputs to the model\n", + " output = modelEx(data)\n", + " # calculate the batch loss\n", + " loss = criterion(output, target)\n", + " # update test loss\n", + " test_loss += loss.item() * data.size(0)\n", + " # convert output probabilities to predicted class\n", + " _, pred = torch.max(output, 1)\n", + " # compare predictions to true label\n", + " correct_tensor = pred.eq(target.data.view_as(pred))\n", + " correct = (\n", + " np.squeeze(correct_tensor.numpy())\n", + " if not train_on_gpu\n", + " else np.squeeze(correct_tensor.cpu().numpy())\n", + " )\n", + " # calculate test accuracy for each object class\n", + " for i in range(batch_size):\n", + " label = target.data[i]\n", + " class_correct[label] += correct[i].item()\n", + " class_total[label] += 1\n", + "\n", + "# average test loss\n", + "test_loss = test_loss / len(test_loader)\n", + "print(\"Test Loss: {:.6f}\\n\".format(test_loss))\n", + "\n", + "for i in range(10):\n", + " if class_total[i] > 0:\n", + " print(\n", + " \"Test Accuracy of %5s: %2d%% (%2d/%2d)\"\n", + " % (\n", + " classes[i],\n", + " 100 * class_correct[i] / class_total[i],\n", + " np.sum(class_correct[i]),\n", + " np.sum(class_total[i]),\n", + " )\n", + " )\n", + " else:\n", + " print(\"Test Accuracy of %5s: N/A (no training examples)\" % (classes[i]))\n", + "\n", + "print(\n", + " \"\\nTest Accuracy (Overall): %2d%% (%2d/%2d)\"\n", + " % (\n", + " 100.0 * np.sum(class_correct) / np.sum(class_total),\n", + " np.sum(class_correct),\n", + " np.sum(class_total),\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "56bf7bf5", + "metadata": {}, + "source": [ + "*On a une précision de 72%, contre 60% avec le modèle précédent. Le temps de calcul pour les deux modèles a été équivalent : 4min17s pour le 1er modèle, 5min45s pour le 2nd.*\n", + "\n", + "*We have an accuracy of 72%, compared to 60% with the previous model. The calculation time for the two models was equivalent: 4min17s for the 1st model, 5min45s for the 2nd.*" + ] + }, { "cell_type": "markdown", "id": "bc381cf4", diff --git a/ex1Modele1.png b/ex1Modele1.png new file mode 100644 index 0000000000000000000000000000000000000000..df0701b84b29ee83ce41e20f2beaddc61a036c8c GIT binary patch literal 20491 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 literal 0 HcmV?d00001 diff --git a/ex1Modele2.png b/ex1Modele2.png new file mode 100644 index 0000000000000000000000000000000000000000..e2326985b0b34f73525df026ea9be20d2a2c3223 GIT binary patch literal 22230 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�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 literal 0 HcmV?d00001 -- GitLab