diff --git a/TD2 Deep Learning.ipynb b/TD2 Deep Learning.ipynb index 00e4fdc78c068248ca0742c64725d155b3681f0d..1c2d223184315363de42ad2c12d6f77987f81718 100644 --- a/TD2 Deep Learning.ipynb +++ b/TD2 Deep Learning.ipynb @@ -33,10 +33,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "330a42f5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: torch in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (2.5.1)\n", + "Requirement already satisfied: torchvision in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (0.20.1)\n", + "Requirement already satisfied: jinja2 in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torch) (2.11.3)\n", + "Requirement already satisfied: fsspec in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torch) (2022.2.0)\n", + "Requirement already satisfied: filelock in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torch) (3.6.0)\n", + "Requirement already satisfied: typing-extensions>=4.8.0 in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torch) (4.12.2)\n", + "Requirement already satisfied: networkx in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torch) (2.7.1)\n", + "Requirement already satisfied: sympy==1.13.1 in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torch) (1.13.1)\n", + "Requirement already satisfied: mpmath<1.4,>=1.1.0 in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from sympy==1.13.1->torch) (1.2.1)\n", + "Requirement already satisfied: numpy in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torchvision) (1.22.4)\n", + "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from torchvision) (9.0.1)\n", + "Requirement already satisfied: MarkupSafe>=0.23 in c:\\users\\eloua\\nouveau dossier\\lib\\site-packages (from jinja2->torch) (2.0.1)\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], "source": [ "%pip install torch torchvision" ] @@ -52,10 +72,72 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "b1950f0a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([[ 1.0305e+00, 2.1928e-01, -5.8484e-01, -4.2694e-01, 9.4086e-02,\n", + " -1.5717e-01, -6.9468e-01, 3.6041e-01, -8.0000e-02, -1.1150e+00],\n", + " [-8.1360e-01, 5.7366e-01, -3.9370e-01, -2.1028e-01, -8.5509e-01,\n", + " 4.4009e-01, -3.4995e-01, 1.0338e+00, 1.9398e-01, -1.0608e+00],\n", + " [ 1.2515e+00, -1.0458e+00, -7.0494e-01, 8.1538e-01, 1.4329e-01,\n", + " -1.0582e+00, 1.4210e+00, 3.0752e-01, 2.0237e+00, 1.9417e-01],\n", + " [-8.8335e-01, 2.1310e+00, 1.3559e+00, 1.1505e+00, -9.8069e-02,\n", + " -2.9167e-01, -3.7658e-01, 5.4823e-01, 5.6016e-01, -1.1355e+00],\n", + " [-1.8523e+00, 8.4509e-01, 4.9774e-01, 5.5219e-01, 1.8432e+00,\n", + " -1.2231e+00, -7.4602e-01, 6.2106e-01, 2.1055e-01, -7.6698e-01],\n", + " [-1.9545e+00, 9.4290e-01, -1.8900e-03, -1.5746e+00, 2.8379e-01,\n", + " 1.0765e-01, -4.5590e-01, -1.1182e+00, 5.4219e-01, -1.4630e+00],\n", + " [ 1.3065e-01, 7.4744e-01, -1.2504e+00, -1.2077e-01, -2.1310e+00,\n", + " 9.1643e-01, -1.3295e+00, 1.4490e+00, 5.5368e-02, 9.4062e-01],\n", + " [-1.1280e+00, -5.4262e-01, -9.2099e-01, 7.0206e-01, 1.8870e-01,\n", + " 1.4340e+00, 6.1384e-01, 2.1229e-01, 1.3686e+00, 4.4983e-02],\n", + " [ 8.1227e-01, -3.4309e-02, 3.0000e-01, -2.1976e+00, 1.5052e+00,\n", + " 1.0231e+00, 2.3562e-02, -3.9516e-01, -1.1958e+00, -1.1450e+00],\n", + " [-5.3217e-01, -9.4708e-01, 3.5960e-01, 3.1978e-01, 6.5693e-01,\n", + " 1.2438e+00, -3.4286e-01, -8.4294e-01, 8.6192e-02, -1.6249e+00],\n", + " [-1.6462e+00, -2.8996e-01, -1.7270e-01, 3.9132e-01, 2.0564e-01,\n", + " 6.2459e-02, 6.9755e-01, 4.8864e-01, 2.0693e+00, 1.8460e+00],\n", + " [ 4.8269e-01, 1.6141e+00, 6.9728e-01, 5.2733e-01, 7.5356e-01,\n", + " 1.0753e+00, -8.0632e-02, 1.7839e+00, 1.2324e-01, -1.1968e+00],\n", + " [-1.3453e+00, 3.9696e-01, -6.9182e-01, -1.1625e+00, 8.5186e-01,\n", + " -9.5603e-01, 2.0826e+00, -5.8598e-01, -4.8563e-01, 2.8007e-01],\n", + " [-5.3753e-02, 8.5545e-01, 1.3453e+00, 2.2817e-01, -1.0763e+00,\n", + " 3.7051e-01, -7.3824e-01, -1.7190e+00, 1.2376e+00, -2.4513e-01]])\n", + "AlexNet(\n", + " (features): Sequential(\n", + " (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))\n", + " (1): ReLU(inplace=True)\n", + " (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)\n", + " (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))\n", + " (4): ReLU(inplace=True)\n", + " (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)\n", + " (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", + " (7): ReLU(inplace=True)\n", + " (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", + " (9): ReLU(inplace=True)\n", + " (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", + " (11): ReLU(inplace=True)\n", + " (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)\n", + " )\n", + " (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))\n", + " (classifier): Sequential(\n", + " (0): Dropout(p=0.5, inplace=False)\n", + " (1): Linear(in_features=9216, out_features=4096, bias=True)\n", + " (2): ReLU(inplace=True)\n", + " (3): Dropout(p=0.5, inplace=False)\n", + " (4): Linear(in_features=4096, out_features=4096, bias=True)\n", + " (5): ReLU(inplace=True)\n", + " (6): Linear(in_features=4096, out_features=1000, bias=True)\n", + " )\n", + ")\n" + ] + } + ], "source": [ "import torch\n", "\n", @@ -95,10 +177,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "6e18f2fd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CUDA is not available. Training on CPU ...\n" + ] + } + ], "source": [ "import torch\n", "\n", @@ -121,10 +211,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "462666a2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Files already downloaded and verified\n", + "Files already downloaded and verified\n" + ] + } + ], "source": [ "import numpy as np\n", "from torchvision import datasets, transforms\n", @@ -193,10 +292,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "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", @@ -242,10 +356,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "4b53f229", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Input \u001b[1;32mIn [6]\u001b[0m, in \u001b[0;36m<cell line: 10>\u001b[1;34m()\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[38;5;28;01mfor\u001b[39;00m data, target \u001b[38;5;129;01min\u001b[39;00m train_loader:\n\u001b[0;32m 18\u001b[0m \u001b[38;5;66;03m# Move tensors to GPU if CUDA is available\u001b[39;00m\n\u001b[0;32m 19\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m train_on_gpu:\n\u001b[0;32m 20\u001b[0m data, target \u001b[38;5;241m=\u001b[39m data\u001b[38;5;241m.\u001b[39mcuda(), target\u001b[38;5;241m.\u001b[39mcuda()\n", + "File \u001b[1;32m~\\Nouveau dossier\\lib\\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~\\Nouveau dossier\\lib\\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~\\Nouveau dossier\\lib\\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[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[idx] \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~\\Nouveau dossier\\lib\\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~\\Nouveau dossier\\lib\\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~\\Nouveau dossier\\lib\\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~\\Nouveau dossier\\lib\\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;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32m~\\Nouveau dossier\\lib\\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 forward_call(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\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~\\Nouveau dossier\\lib\\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;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~\\Nouveau dossier\\lib\\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~\\Nouveau dossier\\lib\\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", @@ -326,10 +463,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "d39df818", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "\n", @@ -350,10 +500,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "e93efdfc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\eloua\\AppData\\Local\\Temp\\ipykernel_8492\\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: 21.756315\n", + "\n", + "Test Accuracy of airplane: 73% (731/1000)\n", + "Test Accuracy of automobile: 78% (788/1000)\n", + "Test Accuracy of bird: 53% (532/1000)\n", + "Test Accuracy of cat: 46% (468/1000)\n", + "Test Accuracy of deer: 55% (551/1000)\n", + "Test Accuracy of dog: 41% (412/1000)\n", + "Test Accuracy of frog: 71% (719/1000)\n", + "Test Accuracy of horse: 64% (648/1000)\n", + "Test Accuracy of ship: 74% (744/1000)\n", + "Test Accuracy of truck: 66% (661/1000)\n", + "\n", + "Test Accuracy (Overall): 62% (6254/10000)\n" + ] + } + ], "source": [ "model.load_state_dict(torch.load(\"./model_cifar.pt\"))\n", "\n", @@ -419,7 +598,7 @@ }, { "cell_type": "markdown", - "id": "944991a2", + "id": "bcf219cf", "metadata": {}, "source": [ "Build a new network with the following structure.\n", @@ -434,6 +613,256 @@ "Compare the results obtained with this new network to those obtained previously." ] }, + { + "cell_type": "markdown", + "id": "3e2a6f61", + "metadata": {}, + "source": [ + "CNN Structure" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "67033ac0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CNN(\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=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n", + " (fc1): Linear(in_features=1024, 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", + " (dropout): Dropout(p=0.4, inplace=False)\n", + ")\n" + ] + } + ], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "\n", + "class CNN(nn.Module):\n", + " def __init__(self, dropout_value=0.4):\n", + " super(CNN, self).__init__()\n", + " # Convolutional layers\n", + " self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)\n", + " self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n", + " self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n", + " \n", + " # MaxPooling layer\n", + " self.pool = nn.MaxPool2d(kernel_size=2)\n", + " \n", + " # Fully connected layers\n", + " self.fc1 = nn.Linear(64 * 4 * 4, 512) # input image size is 32x32\n", + " self.fc2 = nn.Linear(512, 64)\n", + " self.fc3 = nn.Linear(64, 10) # Assuming 10 output classes\n", + " \n", + " # Dropout layer\n", + " self.dropout = nn.Dropout(p=dropout_value)\n", + "\n", + " def forward(self, x):\n", + " # Convolutional layers with ReLU and pooling\n", + " x = self.pool(torch.relu(self.conv1(x))) # Conv1 -> ReLU -> Pool\n", + " #print(\"Shape after Conv1 + Pool:\", x.shape)\n", + " \n", + " x = self.pool(torch.relu(self.conv2(x))) # Conv2 -> ReLU -> Pool\n", + " #print(\"Shape after Conv2 + Pool:\", x.shape)\n", + " \n", + " x = self.pool(torch.relu(self.conv3(x))) # Conv3 -> ReLU -> Pool\n", + " #print(\"Shape after Conv3 + Pool:\", x.shape)\n", + " \n", + " # Flatten the output\n", + " x = torch.flatten(x, 1)\n", + " #print(\"Shape after Flattening:\", x.shape)\n", + " \n", + " # Fully connected layers\n", + " x = self.dropout(F.relu(self.fc1(x)))\n", + " x = self.dropout(F.relu(self.fc2(x)))\n", + " x = self.fc3(x)\n", + " \n", + " return x\n", + "\n", + "# Model instantiation\n", + "model1 = CNN(dropout_value=0.4)\n", + "print(model1)\n", + "# move tensors to GPU if CUDA is available\n", + "if train_on_gpu:\n", + " model1.cuda()\n", + " \n", + "#input_tensor = torch.randn(batch_size, 3, 32, 32) # CIFAR-10 image size\n", + "#model = CNN(dropout_value=0.4) # Instantiate the model\n", + "#output = model(input_tensor)\n", + "\n", + "#print(\"Output shape:\", output.shape) # Should be [batch_size, 10]" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "95629205", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 0 \tTraining Loss: 44.197613 \tValidation Loss: 40.215276\n", + "Validation loss decreased (inf --> 40.215276). Saving model ...\n", + "Epoch: 1 \tTraining Loss: 38.467062 \tValidation Loss: 34.526591\n", + "Validation loss decreased (40.215276 --> 34.526591). Saving model ...\n", + "Epoch: 2 \tTraining Loss: 33.661273 \tValidation Loss: 30.167926\n", + "Validation loss decreased (34.526591 --> 30.167926). Saving model ...\n", + "Epoch: 3 \tTraining Loss: 30.869085 \tValidation Loss: 28.323083\n", + "Validation loss decreased (30.167926 --> 28.323083). Saving model ...\n", + "Epoch: 4 \tTraining Loss: 28.970111 \tValidation Loss: 26.628171\n", + "Validation loss decreased (28.323083 --> 26.628171). Saving model ...\n", + "Epoch: 5 \tTraining Loss: 27.452613 \tValidation Loss: 26.199421\n", + "Validation loss decreased (26.628171 --> 26.199421). Saving model ...\n", + "Epoch: 6 \tTraining Loss: 25.914476 \tValidation Loss: 23.764141\n", + "Validation loss decreased (26.199421 --> 23.764141). Saving model ...\n", + "Epoch: 7 \tTraining Loss: 24.249988 \tValidation Loss: 22.064054\n", + "Validation loss decreased (23.764141 --> 22.064054). Saving model ...\n", + "Epoch: 8 \tTraining Loss: 22.873817 \tValidation Loss: 22.064090\n", + "Epoch: 9 \tTraining Loss: 21.494869 \tValidation Loss: 20.166262\n", + "Validation loss decreased (22.064054 --> 20.166262). Saving model ...\n", + "Epoch: 10 \tTraining Loss: 20.376597 \tValidation Loss: 19.364416\n", + "Validation loss decreased (20.166262 --> 19.364416). Saving model ...\n", + "Epoch: 11 \tTraining Loss: 19.276140 \tValidation Loss: 18.517585\n", + "Validation loss decreased (19.364416 --> 18.517585). Saving model ...\n", + "Epoch: 12 \tTraining Loss: 18.297486 \tValidation Loss: 18.442464\n", + "Validation loss decreased (18.517585 --> 18.442464). Saving model ...\n", + "Epoch: 13 \tTraining Loss: 17.443514 \tValidation Loss: 17.434145\n", + "Validation loss decreased (18.442464 --> 17.434145). Saving model ...\n", + "Epoch: 14 \tTraining Loss: 16.590350 \tValidation Loss: 17.478173\n", + "Epoch: 15 \tTraining Loss: 15.774860 \tValidation Loss: 17.659180\n", + "Epoch: 16 \tTraining Loss: 14.950333 \tValidation Loss: 16.470274\n", + "Validation loss decreased (17.434145 --> 16.470274). Saving model ...\n", + "Epoch: 17 \tTraining Loss: 14.307792 \tValidation Loss: 16.560596\n", + "Epoch: 18 \tTraining Loss: 13.616580 \tValidation Loss: 16.897359\n", + "Epoch: 19 \tTraining Loss: 12.822283 \tValidation Loss: 16.807405\n", + "Epoch: 20 \tTraining Loss: 12.265942 \tValidation Loss: 16.145765\n", + "Validation loss decreased (16.470274 --> 16.145765). Saving model ...\n", + "Epoch: 21 \tTraining Loss: 11.622514 \tValidation Loss: 15.571411\n", + "Validation loss decreased (16.145765 --> 15.571411). Saving model ...\n", + "Epoch: 22 \tTraining Loss: 10.992820 \tValidation Loss: 15.829255\n", + "Epoch: 23 \tTraining Loss: 10.491268 \tValidation Loss: 15.969115\n", + "Epoch: 24 \tTraining Loss: 9.982615 \tValidation Loss: 15.879691\n", + "Epoch: 25 \tTraining Loss: 9.484194 \tValidation Loss: 16.662651\n", + "Epoch: 26 \tTraining Loss: 8.875920 \tValidation Loss: 16.290887\n", + "Epoch: 27 \tTraining Loss: 8.446034 \tValidation Loss: 16.507190\n", + "Epoch: 28 \tTraining Loss: 7.938818 \tValidation Loss: 17.239120\n", + "Epoch: 29 \tTraining Loss: 7.549957 \tValidation Loss: 17.333169\n" + ] + } + ], + "source": [ + "import torch.optim as optim\n", + "\n", + "criterion = nn.CrossEntropyLoss() # specify loss function\n", + "optimizer = optim.SGD(model1.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", + " model1.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 = model1(data)\n", + " #print(\"Output shape:\", output.shape)\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", + " model1.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 = model1(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(model1.state_dict(), \"model_cifar.pt\")\n", + " valid_loss_min = valid_loss" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "b8383f00", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.plot(range(n_epochs), train_loss_list)\n", + "plt.xlabel(\"Epoch\")\n", + "plt.ylabel(\"Loss\")\n", + "plt.title(\"Performance of Model\")\n", + "plt.show()" + ] + }, { "cell_type": "markdown", "id": "bc381cf4", @@ -451,7 +880,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "ef623c26", "metadata": {}, "outputs": [], @@ -459,45 +888,267 @@ "import os\n", "\n", "\n", - "def print_size_of_model(model, label=\"\"):\n", - " torch.save(model.state_dict(), \"temp.p\")\n", + "def print_size_of_model(model1, label=\"\"):\n", + " torch.save(model1.state_dict(), \"temp.p\")\n", " size = os.path.getsize(\"temp.p\")\n", - " print(\"model: \", label, \" \\t\", \"Size (KB):\", size / 1e3)\n", + " print(\"model1: \", label, \" \\t\", \"Size (KB):\", size / 1e3)\n", " os.remove(\"temp.p\")\n", " return size\n", "\n", "\n", - "print_size_of_model(model, \"fp32\")" + "#print_size_of_model(model1, \"fp32\")" ] }, { "cell_type": "markdown", - "id": "05c4e9ad", + "id": "7b108e17", "metadata": {}, "source": [ - "Post training quantization example" + "For each class, compare the classification test accuracy of the initial model and the quantized model. Also give the overall test accuracy for both models." + ] + }, + { + "cell_type": "markdown", + "id": "e44fd2c5", + "metadata": {}, + "source": [ + "Evaluating initial model" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, + "id": "77dc66d5", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\eloua\\AppData\\Local\\Temp\\ipykernel_12860\\2808483823.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", + " model1.load_state_dict(torch.load(\"./model_cifar.pt\"))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 15.828842\n", + "\n", + "Test Accuracy of airplane: 79% (798/1000)\n", + "Test Accuracy of automobile: 86% (868/1000)\n", + "Test Accuracy of bird: 64% (642/1000)\n", + "Test Accuracy of cat: 55% (558/1000)\n", + "Test Accuracy of deer: 67% (678/1000)\n", + "Test Accuracy of dog: 63% (633/1000)\n", + "Test Accuracy of frog: 78% (788/1000)\n", + "Test Accuracy of horse: 76% (764/1000)\n", + "Test Accuracy of ship: 84% (840/1000)\n", + "Test Accuracy of truck: 81% (811/1000)\n", + "\n", + "Test Accuracy (Overall): 73% (7380/10000)\n" + ] + } + ], + "source": [ + "model1.load_state_dict(torch.load(\"./model_cifar.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", + "model1.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 = model1(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": "58dc1a45", + "metadata": {}, + "source": [ + "Quantized model" + ] + }, + { + "cell_type": "code", + "execution_count": 50, "id": "c4c65d4b", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model1: int8 \t Size (KB): 659.806\n" + ] + }, + { + "data": { + "text/plain": [ + "659806" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import torch.quantization\n", "\n", "\n", - "quantized_model = torch.quantization.quantize_dynamic(model, dtype=torch.qint8)\n", + "quantized_model = torch.quantization.quantize_dynamic(model1, dtype=torch.qint8)\n", "print_size_of_model(quantized_model, \"int8\")" ] }, { "cell_type": "markdown", - "id": "7b108e17", + "id": "0b08420b", "metadata": {}, "source": [ - "For each class, compare the classification test accuracy of the initial model and the quantized model. Also give the overall test accuracy for both models." + "Evaluating quantized model" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "5e338dd6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 15.831681\n", + "\n", + "Test Accuracy of airplane: 79% (799/1000)\n", + "Test Accuracy of automobile: 86% (868/1000)\n", + "Test Accuracy of bird: 64% (648/1000)\n", + "Test Accuracy of cat: 55% (556/1000)\n", + "Test Accuracy of deer: 67% (674/1000)\n", + "Test Accuracy of dog: 63% (631/1000)\n", + "Test Accuracy of frog: 78% (786/1000)\n", + "Test Accuracy of horse: 76% (764/1000)\n", + "Test Accuracy of ship: 84% (840/1000)\n", + "Test Accuracy of truck: 81% (810/1000)\n", + "\n", + "Test Accuracy (Overall): 73% (7376/10000)\n" + ] + } + ], + "source": [ + "\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", + "quantized_model.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 = quantized_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\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", + ")" ] }, { @@ -521,13 +1172,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "id": "b4d13080", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Predicted class is: Golden Retriever\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import json\n", "from PIL import Image\n", + "from torchvision import transforms\n", + "from torchvision import models\n", + "import matplotlib.pyplot as plt\n", "\n", "# Choose an image to pass through the model\n", "test_image = \"dog.png\"\n", @@ -586,6 +1258,217 @@ " \n" ] }, + { + "cell_type": "markdown", + "id": "a82906fa", + "metadata": {}, + "source": [ + "# Étude du code\n", + "\n", + "1. Chargement des étiquettes\n", + "\n", + "```python\n", + "with open(\"imagenet-simple-labels.json\") as f:\n", + " labels = json.load(f)\n", + "```\n", + "\n", + "Ce fichier JSON contient une liste de 1000 étiquettes correspondant aux classes du jeu de données ImageNet, sur lequel le modèle ResNet-50 a été pré-entraîné. Chaque sortie du modèle correspond à l'indice d'une classe dans ce fichier.\n", + "\n", + "2. Prétraitement de l'image\n", + "\n", + "```python\n", + "data_transform = transforms.Compose(\n", + " [\n", + " transforms.Resize((224, 224)),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n", + " ]\n", + ")\n", + "```\n", + "\n", + "Redimensionnement en la taille standard d'entrée pour ResNet50. Conversion en tenseur PyTorch et normalisation des canaux RGB.\n", + "\n", + "3. Chargement et affichage de l'image\n", + "\n", + "```python\n", + "image = Image.open(test_image)\n", + "plt.imshow(image), plt.xticks([]), plt.yticks([])\n", + "```\n", + "\n", + "Chargement et affichage de l'image\n", + "\n", + "4. Transformation et préparation\n", + "\n", + "```python\n", + "image = data_transform(image).unsqueeze(0)\n", + "```\n", + "\n", + "Ajoute une dimension supplémentaire pour représenter le batch size.\n", + "\n", + "5. Chargement du modèle ResNet50 pré-entraîné\n", + "\n", + "```python\n", + "model = models.resnet50(pretrained=True)\n", + "model.eval()\n", + "```\n", + "\n", + "6. Prédiction\n", + "\n", + "```python\n", + "out = model(image)\n", + "print(\"Predicted class is: {}\".format(labels[out.argmax()]))\n", + "```\n", + "Trouve l'indice de la classe ayant la plus haute probabilité avec out.argmax() et utilise cet indice pour récupérer l'étiquette correspondante.\n" + ] + }, + { + "cell_type": "markdown", + "id": "cef9ecfc", + "metadata": {}, + "source": [ + "# Model size" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "3d515c84", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model1: fp32 \t Size (KB): 102523.238\n", + "model1: int8 \t Size (KB): 96379.996\n", + "Predicted class is: Golden Retriever\n" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "print_size_of_model(model, \"fp32\")\n", + "\n", + "# Quantize the model dynamically\n", + "quantized_model = torch.quantization.quantize_dynamic(\n", + " model, {torch.nn.Linear}, dtype=torch.qint8\n", + ")\n", + "\n", + "# Check the size of the quantized model\n", + "print_size_of_model(quantized_model, \"int8\")\n", + "\n", + "# Set layers such as dropout and batchnorm in evaluation mode\n", + "quantized_model.eval()\n", + "\n", + "# Get the 1000-dimensional model output\n", + "out = quantized_model(image)\n", + "# Find the predicted class\n", + "print(\"Predicted class is: {}\".format(labels[out.argmax()]))" + ] + }, + { + "cell_type": "markdown", + "id": "05232ae1", + "metadata": {}, + "source": [ + "# Expérimentation avec d'autres modèles pré-entrainés" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "574dc65d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Testing model: resnet18\n", + "model1: fp32 \t Size (KB): 46828.292\n", + "Predicted class: Dobermann\n", + "model1: fp32 \t Size (KB): 45293.114\n", + "(Quantized) Predicted class: Dobermann\n", + "Testing model: vgg16\n", + "model1: fp32 \t Size (KB): 553439.178\n", + "Predicted class: Dobermann\n", + "model1: fp32 \t Size (KB): 182540.454\n", + "(Quantized) Predicted class: Dobermann\n", + "Testing model: mobilenet_v2\n", + "model1: fp32 \t Size (KB): 14242.18\n", + "Predicted class: Dobermann\n", + "model1: fp32 \t Size (KB): 10403.002\n", + "(Quantized) Predicted class: Dobermann\n", + "Testing model: efficientnet_b0\n", + "model1: fp32 \t Size (KB): 21427.998\n", + "Predicted class: Dobermann\n", + "model1: fp32 \t Size (KB): 17588.82\n", + "(Quantized) Predicted class: Dobermann\n" + ] + } + ], + "source": [ + "import torch\n", + "from torchvision import transforms, models\n", + "from PIL import Image\n", + "import matplotlib.pyplot as plt\n", + "import json\n", + "\n", + "with open(\"imagenet-simple-labels.json\") as f:\n", + " labels = json.load(f)\n", + "\n", + "data_transform = transforms.Compose([\n", + " transforms.Resize((224, 224)),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n", + "])\n", + "\n", + "test_image = \"dog2.jpg\"\n", + "image = Image.open(test_image)\n", + "plt.imshow(image)\n", + "plt.xticks([]), plt.yticks([])\n", + "plt.show()\n", + "\n", + "image = data_transform(image).unsqueeze(0)\n", + "\n", + "# Liste des modèles à tester\n", + "model_names = [\"resnet18\", \"vgg16\", \"mobilenet_v2\", \"efficientnet_b0\"]\n", + "\n", + "# Tester chaque modèle\n", + "for model_name in model_names:\n", + " print(f\"Testing model: {model_name}\")\n", + "\n", + " # Charger le modèle préentraîné\n", + " model = getattr(models, model_name)(pretrained=True)\n", + " model.eval()\n", + " print_size_of_model(model, \"fp32\")\n", + "\n", + " # Obtenir la prédiction\n", + " with torch.no_grad():\n", + " out = model(image)\n", + " predicted_class = labels[out.argmax()]\n", + " print(f\"Predicted class: {predicted_class}\")\n", + " \n", + " quantized_model = torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)\n", + " print_size_of_model(quantized_model, \"fp32\")\n", + " \n", + " with torch.no_grad():\n", + " out = quantized_model(image)\n", + " predicted_class = labels[out.argmax()]\n", + " print(f\"(Quantized) Predicted class: {predicted_class}\")\n" + ] + }, { "cell_type": "markdown", "id": "5d57da4b", @@ -883,7 +1766,7 @@ }, { "cell_type": "markdown", - "id": "bbd48800", + "id": "047f82d4", "metadata": {}, "source": [ "Experiments:\n", @@ -926,7 +1809,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.8.5 ('base')", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -940,7 +1823,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.9.12" }, "vscode": { "interpreter": { diff --git a/hymenoptera_data.zip b/hymenoptera_data.zip new file mode 100644 index 0000000000000000000000000000000000000000..e5fa9b5ef9baa5ff38fd271deb3d7f7f68921a16 Binary files /dev/null and b/hymenoptera_data.zip differ diff --git a/hymenoptera_data/train/ants/formica.jpeg b/hymenoptera_data/train/ants/formica.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..af83327233be73099c700fce654749842aad4a9d Binary files /dev/null and b/hymenoptera_data/train/ants/formica.jpeg differ diff --git a/hymenoptera_data/train/ants/imageNotFound.gif b/hymenoptera_data/train/ants/imageNotFound.gif new file mode 100644 index 0000000000000000000000000000000000000000..bdeaae94004e06c6a35d147ec58fb35062076b52 Binary files /dev/null and b/hymenoptera_data/train/ants/imageNotFound.gif differ