diff --git a/TD2 Deep Learning.ipynb b/TD2 Deep Learning.ipynb index 748e18cfe7c16e442aa63082ef6f5cab6fb53d4c..800a4978f81ffeea5ec1a17873dfe13225686df9 100644 --- a/TD2 Deep Learning.ipynb +++ b/TD2 Deep Learning.ipynb @@ -35,12 +35,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "I am using a personal remote jupyter server that is running on a pc with two gpus." + "> I am using a personal remote jupyter server through ssh tunneling that is running on a pc with two gpus." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -91,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "b1950f0a", "metadata": {}, "outputs": [ @@ -196,7 +196,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -206,7 +206,9 @@ "import numpy as np\n", "from torchvision import datasets, transforms\n", "from torch.utils.data.sampler import SubsetRandomSampler\n", - "import torch.optim as optim\n" + "import torch.optim as optim\n", + "import os\n", + "import matplotlib.pyplot as plt" ] }, { @@ -244,7 +246,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "462666a2", "metadata": {}, "outputs": [ @@ -321,7 +323,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 4, "id": "317bf070", "metadata": {}, "outputs": [ @@ -383,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "4b53f229", "metadata": {}, "outputs": [ @@ -533,7 +535,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "d39df818", "metadata": {}, "outputs": [ @@ -549,8 +551,6 @@ } ], "source": [ - "import matplotlib.pyplot as plt\n", - "\n", "plt.plot([i for i in range(len(train_loss_list))], train_loss_list)\n", "plt.plot([i for i in range(len(running_validation_loss))], running_validation_loss)\n", "plt.xlabel(\"Epoch\")\n", @@ -570,7 +570,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "id": "e93efdfc", "metadata": {}, "outputs": [ @@ -681,7 +681,9 @@ ">> With our Conv2D layers (P=1, S=1), we see that H' = H\n", ">> The formula is the same for the MaxPool2D Layer, except that there is no padding. With S=2, we see that $H''=\\frac{H'}{2}$ \n", "\n", - "So, with 3 Conv2D/MaxPool2D layers, it yields: $H'''=\\frac{H}{8}=4$" + "So, with 3 Conv2D/MaxPool2D layers, it yields: $H'''=\\frac{H}{8}=4$ <br>\n", + "\n", + "I set the dropout probability value to 20%. " ] }, { @@ -701,6 +703,7 @@ " (fc1): Linear(in_features=1024, out_features=520, bias=True)\n", " (fc2): Linear(in_features=520, out_features=64, bias=True)\n", " (fc3): Linear(in_features=64, out_features=10, bias=True)\n", + " (dropout): Dropout(p=0.2, inplace=False)\n", ")\n" ] } @@ -719,6 +722,8 @@ " self.fc2 = nn.Linear(520, 64)\n", " self.fc3 = nn.Linear(64, 10)\n", "\n", + " self.dropout = nn.Dropout(p=0.2)\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", @@ -726,10 +731,8 @@ "\n", " x = x.view(-1, 64 * 4 * 4)\n", "\n", - " # print(f'before first fully connected: x.shape = {x.shape}')\n", - " x = F.relu(self.fc1(x))\n", - " # print(f'after first fully connected, x.shape = {x.shape}')\n", - " x = F.relu(self.fc2(x))\n", + " x = self.dropout(F.relu(self.fc1(x)))\n", + " x = self.dropout(F.relu(self.fc2(x)))\n", " x = self.fc3(x)\n", " return x\n", "\n", @@ -758,37 +761,43 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 0 \tTraining Loss: 46.006892 \tValidation Loss: 45.902350\n", - "Validation loss decreased (inf --> 45.902350). Saving model ...\n", - "Epoch: 1 \tTraining Loss: 41.949796 \tValidation Loss: 36.844486\n", - "Validation loss decreased (45.902350 --> 36.844486). Saving model ...\n", - "Epoch: 2 \tTraining Loss: 33.086672 \tValidation Loss: 30.098764\n", - "Validation loss decreased (36.844486 --> 30.098764). Saving model ...\n", - "Epoch: 3 \tTraining Loss: 29.172206 \tValidation Loss: 27.395244\n", - "Validation loss decreased (30.098764 --> 27.395244). Saving model ...\n", - "Epoch: 4 \tTraining Loss: 26.212147 \tValidation Loss: 24.835946\n", - "Validation loss decreased (27.395244 --> 24.835946). Saving model ...\n", - "Epoch: 5 \tTraining Loss: 23.674865 \tValidation Loss: 23.665005\n", - "Validation loss decreased (24.835946 --> 23.665005). Saving model ...\n", - "Epoch: 6 \tTraining Loss: 21.537375 \tValidation Loss: 22.157728\n", - "Validation loss decreased (23.665005 --> 22.157728). Saving model ...\n", - "Epoch: 7 \tTraining Loss: 19.794596 \tValidation Loss: 20.653111\n", - "Validation loss decreased (22.157728 --> 20.653111). Saving model ...\n", - "Epoch: 8 \tTraining Loss: 18.270990 \tValidation Loss: 19.718919\n", - "Validation loss decreased (20.653111 --> 19.718919). Saving model ...\n", - "Epoch: 9 \tTraining Loss: 16.823296 \tValidation Loss: 20.004760\n", - "Epoch: 10 \tTraining Loss: 15.458834 \tValidation Loss: 17.884271\n", - "Validation loss decreased (19.718919 --> 17.884271). Saving model ...\n", - "Epoch: 11 \tTraining Loss: 14.178309 \tValidation Loss: 17.752411\n", - "Validation loss decreased (17.884271 --> 17.752411). Saving model ...\n", - "Epoch: 12 \tTraining Loss: 12.889527 \tValidation Loss: 17.701482\n", - "Validation loss decreased (17.752411 --> 17.701482). Saving model ...\n", - "Epoch: 13 \tTraining Loss: 11.683957 \tValidation Loss: 17.989905\n", - "Epoch: 14 \tTraining Loss: 10.442382 \tValidation Loss: 17.920712\n", - "Epoch: 15 \tTraining Loss: 9.205376 \tValidation Loss: 18.604749\n", - "Epoch: 16 \tTraining Loss: 7.967563 \tValidation Loss: 19.343018\n", - "Epoch: 17 \tTraining Loss: 6.736769 \tValidation Loss: 20.532125\n", - "Epoch: 18 \tTraining Loss: 5.702138 \tValidation Loss: 20.230931\n" + "Epoch: 0 \tTraining Loss: 45.291307 \tValidation Loss: 41.467732\n", + "Validation loss decreased (inf --> 41.467732). Saving model ...\n", + "Epoch: 1 \tTraining Loss: 37.767105 \tValidation Loss: 33.637928\n", + "Validation loss decreased (41.467732 --> 33.637928). Saving model ...\n", + "Epoch: 2 \tTraining Loss: 32.266966 \tValidation Loss: 30.793828\n", + "Validation loss decreased (33.637928 --> 30.793828). Saving model ...\n", + "Epoch: 3 \tTraining Loss: 29.370246 \tValidation Loss: 28.459198\n", + "Validation loss decreased (30.793828 --> 28.459198). Saving model ...\n", + "Epoch: 4 \tTraining Loss: 27.237783 \tValidation Loss: 26.010235\n", + "Validation loss decreased (28.459198 --> 26.010235). Saving model ...\n", + "Epoch: 5 \tTraining Loss: 25.380958 \tValidation Loss: 23.901516\n", + "Validation loss decreased (26.010235 --> 23.901516). Saving model ...\n", + "Epoch: 6 \tTraining Loss: 23.636782 \tValidation Loss: 22.804922\n", + "Validation loss decreased (23.901516 --> 22.804922). Saving model ...\n", + "Epoch: 7 \tTraining Loss: 21.998417 \tValidation Loss: 21.619554\n", + "Validation loss decreased (22.804922 --> 21.619554). Saving model ...\n", + "Epoch: 8 \tTraining Loss: 20.665297 \tValidation Loss: 20.153347\n", + "Validation loss decreased (21.619554 --> 20.153347). Saving model ...\n", + "Epoch: 9 \tTraining Loss: 19.285314 \tValidation Loss: 19.312094\n", + "Validation loss decreased (20.153347 --> 19.312094). Saving model ...\n", + "Epoch: 10 \tTraining Loss: 18.254966 \tValidation Loss: 18.946857\n", + "Validation loss decreased (19.312094 --> 18.946857). Saving model ...\n", + "Epoch: 11 \tTraining Loss: 17.092745 \tValidation Loss: 18.101710\n", + "Validation loss decreased (18.946857 --> 18.101710). Saving model ...\n", + "Epoch: 12 \tTraining Loss: 16.019090 \tValidation Loss: 18.111891\n", + "Epoch: 13 \tTraining Loss: 15.158885 \tValidation Loss: 17.427234\n", + "Validation loss decreased (18.101710 --> 17.427234). Saving model ...\n", + "Epoch: 14 \tTraining Loss: 14.151792 \tValidation Loss: 17.373706\n", + "Validation loss decreased (17.427234 --> 17.373706). Saving model ...\n", + "Epoch: 15 \tTraining Loss: 13.173746 \tValidation Loss: 18.196510\n", + "Epoch: 16 \tTraining Loss: 12.204733 \tValidation Loss: 16.975662\n", + "Validation loss decreased (17.373706 --> 16.975662). Saving model ...\n", + "Epoch: 17 \tTraining Loss: 11.365704 \tValidation Loss: 16.331832\n", + "Validation loss decreased (16.975662 --> 16.331832). Saving model ...\n", + "Epoch: 18 \tTraining Loss: 10.508265 \tValidation Loss: 16.603407\n", + "Epoch: 19 \tTraining Loss: 9.691825 \tValidation Loss: 16.714202\n", + "Epoch: 20 \tTraining Loss: 8.907784 \tValidation Loss: 17.250531\n" ] }, { @@ -806,8 +815,7 @@ "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torchvision/datasets/cifar.py:118\u001b[0m, in \u001b[0;36mCIFAR10.__getitem__\u001b[0;34m(self, index)\u001b[0m\n\u001b[1;32m 115\u001b[0m img \u001b[39m=\u001b[39m Image\u001b[39m.\u001b[39mfromarray(img)\n\u001b[1;32m 117\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtransform \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m--> 118\u001b[0m img \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mtransform(img)\n\u001b[1;32m 120\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtarget_transform \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 121\u001b[0m target \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtarget_transform(target)\n", "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torchvision/transforms/transforms.py:95\u001b[0m, in \u001b[0;36mCompose.__call__\u001b[0;34m(self, img)\u001b[0m\n\u001b[1;32m 93\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__call__\u001b[39m(\u001b[39mself\u001b[39m, img):\n\u001b[1;32m 94\u001b[0m \u001b[39mfor\u001b[39;00m t \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtransforms:\n\u001b[0;32m---> 95\u001b[0m img \u001b[39m=\u001b[39m t(img)\n\u001b[1;32m 96\u001b[0m \u001b[39mreturn\u001b[39;00m img\n", "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torchvision/transforms/transforms.py:137\u001b[0m, in \u001b[0;36mToTensor.__call__\u001b[0;34m(self, pic)\u001b[0m\n\u001b[1;32m 129\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__call__\u001b[39m(\u001b[39mself\u001b[39m, pic):\n\u001b[1;32m 130\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 131\u001b[0m \u001b[39m Args:\u001b[39;00m\n\u001b[1;32m 132\u001b[0m \u001b[39m pic (PIL Image or numpy.ndarray): Image to be converted to tensor.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 135\u001b[0m \u001b[39m Tensor: Converted image.\u001b[39;00m\n\u001b[1;32m 136\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 137\u001b[0m \u001b[39mreturn\u001b[39;00m F\u001b[39m.\u001b[39;49mto_tensor(pic)\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torchvision/transforms/functional.py:138\u001b[0m, in \u001b[0;36mto_tensor\u001b[0;34m(pic)\u001b[0m\n\u001b[1;32m 126\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor.\u001b[39;00m\n\u001b[1;32m 127\u001b[0m \u001b[39mThis function does not support torchscript.\u001b[39;00m\n\u001b[1;32m 128\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 135\u001b[0m \u001b[39m Tensor: Converted image.\u001b[39;00m\n\u001b[1;32m 136\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 137\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m torch\u001b[39m.\u001b[39mjit\u001b[39m.\u001b[39mis_scripting() \u001b[39mand\u001b[39;00m \u001b[39mnot\u001b[39;00m torch\u001b[39m.\u001b[39mjit\u001b[39m.\u001b[39mis_tracing():\n\u001b[0;32m--> 138\u001b[0m _log_api_usage_once(to_tensor)\n\u001b[1;32m 139\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (F_pil\u001b[39m.\u001b[39m_is_pil_image(pic) \u001b[39mor\u001b[39;00m _is_numpy(pic)):\n\u001b[1;32m 140\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mTypeError\u001b[39;00m(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mpic should be PIL Image or ndarray. Got \u001b[39m\u001b[39m{\u001b[39;00m\u001b[39mtype\u001b[39m(pic)\u001b[39m}\u001b[39;00m\u001b[39m\"\u001b[39m)\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torchvision/utils.py:582\u001b[0m, in \u001b[0;36m_log_api_usage_once\u001b[0;34m(obj)\u001b[0m\n\u001b[1;32m 580\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(obj, FunctionType):\n\u001b[1;32m 581\u001b[0m name \u001b[39m=\u001b[39m obj\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m\n\u001b[0;32m--> 582\u001b[0m torch\u001b[39m.\u001b[39;49m_C\u001b[39m.\u001b[39;49m_log_api_usage_once(\u001b[39mf\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39m{\u001b[39;49;00mmodule\u001b[39m}\u001b[39;49;00m\u001b[39m.\u001b[39;49m\u001b[39m{\u001b[39;49;00mname\u001b[39m}\u001b[39;49;00m\u001b[39m\"\u001b[39;49m)\n", + "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torchvision/transforms/functional.py:166\u001b[0m, in \u001b[0;36mto_tensor\u001b[0;34m(pic)\u001b[0m\n\u001b[1;32m 164\u001b[0m \u001b[39m# handle PIL Image\u001b[39;00m\n\u001b[1;32m 165\u001b[0m mode_to_nptype \u001b[39m=\u001b[39m {\u001b[39m\"\u001b[39m\u001b[39mI\u001b[39m\u001b[39m\"\u001b[39m: np\u001b[39m.\u001b[39mint32, \u001b[39m\"\u001b[39m\u001b[39mI;16\u001b[39m\u001b[39m\"\u001b[39m: np\u001b[39m.\u001b[39mint16, \u001b[39m\"\u001b[39m\u001b[39mF\u001b[39m\u001b[39m\"\u001b[39m: np\u001b[39m.\u001b[39mfloat32}\n\u001b[0;32m--> 166\u001b[0m img \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mfrom_numpy(np\u001b[39m.\u001b[39marray(pic, mode_to_nptype\u001b[39m.\u001b[39;49mget(pic\u001b[39m.\u001b[39;49mmode, np\u001b[39m.\u001b[39;49muint8), copy\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m))\n\u001b[1;32m 168\u001b[0m \u001b[39mif\u001b[39;00m pic\u001b[39m.\u001b[39mmode \u001b[39m==\u001b[39m \u001b[39m\"\u001b[39m\u001b[39m1\u001b[39m\u001b[39m\"\u001b[39m:\n\u001b[1;32m 169\u001b[0m img \u001b[39m=\u001b[39m \u001b[39m255\u001b[39m \u001b[39m*\u001b[39m img\n", "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } @@ -887,7 +895,7 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "<Figure size 640x480 with 1 Axes>" ] @@ -897,8 +905,6 @@ } ], "source": [ - "import matplotlib.pyplot as plt\n", - "\n", "plt.plot(range(len(train_loss_list)), train_loss_list)\n", "plt.xlabel(\"Epoch\")\n", "plt.ylabel(\"Loss\")\n", @@ -915,20 +921,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "Test Loss: 17.963702\n", + "Test Loss: 16.366131\n", "\n", - "Test Accuracy of airplane: 83% (835/1000)\n", - "Test Accuracy of automobile: 79% (795/1000)\n", - "Test Accuracy of bird: 52% (520/1000)\n", - "Test Accuracy of cat: 62% (627/1000)\n", - "Test Accuracy of deer: 68% (686/1000)\n", - "Test Accuracy of dog: 50% (509/1000)\n", - "Test Accuracy of frog: 71% (717/1000)\n", - "Test Accuracy of horse: 75% (755/1000)\n", - "Test Accuracy of ship: 81% (818/1000)\n", - "Test Accuracy of truck: 72% (722/1000)\n", + "Test Accuracy of airplane: 77% (774/1000)\n", + "Test Accuracy of automobile: 82% (826/1000)\n", + "Test Accuracy of bird: 67% (678/1000)\n", + "Test Accuracy of cat: 51% (511/1000)\n", + "Test Accuracy of deer: 63% (636/1000)\n", + "Test Accuracy of dog: 59% (596/1000)\n", + "Test Accuracy of frog: 78% (788/1000)\n", + "Test Accuracy of horse: 81% (819/1000)\n", + "Test Accuracy of ship: 82% (823/1000)\n", + "Test Accuracy of truck: 81% (818/1000)\n", "\n", - "Test Accuracy (Overall): 69% (6984/10000)\n" + "Test Accuracy (Overall): 72% (7269/10000)\n" ] } ], @@ -999,7 +1005,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - ">We observe an increased test accuracy with the modified model (from 63% to 69%)" + ">We observe an increased test accuracy with the modified model (from 63% to 72%). <br>\n", + "> I also made an experiment without the dropout layers. The overall accuracy was the same (72%). " ] }, { @@ -1014,12 +1021,18 @@ "The Exercise is to quantize post training the above CNN model. Compare the size reduction and the impact on the classification accuracy \n", "\n", "\n", - "The size of the model is simply the size of the file." + "The size of the model is simply the size of the file.\n", + "\n", + "> Important: Dynamic and static quantization are not supported yet by CUDA, so everything has to run on cpu quantization. <br>\n", + "[https://discuss.pytorch.org/t/does-dynamic-quantization-support-gpu/119231](https://discuss.pytorch.org/t/does-dynamic-quantization-support-gpu/119231) <br>\n", + "[https://discuss.pytorch.org/t/dose-static-quantization-support-cuda/85720](https://discuss.pytorch.org/t/dose-static-quantization-support-cuda/85720) <br> <br>\n", + "\n", + "Documentation for quantize_dynamic: [https://pytorch.org/tutorials/recipes/recipes/dynamic_quantization.html](https://pytorch.org/tutorials/recipes/recipes/dynamic_quantization.html)" ] }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 10, "id": "ef623c26", "metadata": {}, "outputs": [ @@ -1036,96 +1049,75 @@ "2365954" ] }, - "execution_count": 49, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "import os\n", - "\n", - "\n", "def print_size_of_model(model, label=\"\"):\n", - " torch.save(custom_model.state_dict(), \"temp.p\")\n", + " torch.save(model.state_dict(), \"temp.p\")\n", " size = os.path.getsize(\"temp.p\")\n", " print(\"model: \", label, \" \\t\", \"Size (KB):\", size / 1e3)\n", " os.remove(\"temp.p\")\n", " return size\n", "\n", - "\n", "print_size_of_model(custom_model, \"fp32\")" ] }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "model: fp32 \t Size (KB): 2365.954\n", - "model: int8 \t Size (KB): 2365.954\n" + "First model\n", + "model: fp32 \t Size (KB): 251.278\n", + "model: int8 \t Size (KB): 76.522\n", + "Division of the memory for the first model: 3.28\n", + "\n", + "\n", + "Custom model\n", + "model: fp32 \t Size (KB): 2365.826\n", + "model: int8 \t Size (KB): 668.574\n", + "Division of the memory for the custom model: 3.54\n" ] - }, - { - "data": { - "text/plain": [ - "2365954" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ + "print(f'First model')\n", "first_model = Net()\n", - "first_model = first_model.load_state_dict(torch.load(\"./model_cifar.pt\"))\n", - "print_size_of_model(first_model, \"fp32\")\n", - "quantized_first_model = torch.quantization.quantize_dynamic(custom_model, dtype=torch.qint8)\n", - "print_size_of_model(quantized_first_model, \"int8\")" + "first_model.load_state_dict(torch.load(\"./model_cifar.pt\"))\n", + "first_model_size = print_size_of_model(first_model, \"fp32\")\n", + "quantized_first_model = torch.quantization.quantize_dynamic(first_model, dtype=torch.qint8)\n", + "first_model_quant_size = print_size_of_model(quantized_first_model, \"int8\")\n", + "print(f'Division of the memory for the first model: {first_model_size/first_model_quant_size:.2f}')\n", + "\n", + "print(f'\\n\\nCustom model')\n", + "custom_model = CustomNet()\n", + "custom_model.load_state_dict(torch.load(\"./custom_model2_cifar.pt\"))\n", + "custom_model_size = print_size_of_model(custom_model, \"fp32\")\n", + "quantized_custom_model = torch.quantization.quantize_dynamic(custom_model, {nn.Linear, nn.Conv2d, nn.MaxPool2d}, dtype=torch.qint8)\n", + "custom_model_quant_size = print_size_of_model(quantized_custom_model, \"int8\")\n", + "print(f'Division of the memory for the custom model: {custom_model_size/custom_model_quant_size:.2f}')" ] }, { "cell_type": "markdown", - "id": "05c4e9ad", "metadata": {}, "source": [ - "Post training quantization example" + "The size of the model in kB is divided by more than 3 for both models." ] }, { - "cell_type": "code", - "execution_count": 62, - "id": "c4c65d4b", + "cell_type": "markdown", + "id": "05c4e9ad", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "model: int8 \t Size (KB): 2365.954\n" - ] - }, - { - "data": { - "text/plain": [ - "2365954" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "import torch.quantization\n", - "\n", - "\n", - "quantized_model = torch.quantization.quantize_dynamic(custom_model, dtype=torch.qint8)\n", - "print_size_of_model(quantized_model, \"int8\")" + "Post training quantization example" ] }, { @@ -1140,30 +1132,33 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Compute correct classes for the quantized model" + "#### Compute correct classes for the quantized model\n", + "As explained earlier, everything is run on cpu when the model is quantized." ] }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 12, "metadata": {}, "outputs": [ { - "ename": "NotImplementedError", - "evalue": "Could not run 'quantized::linear_dynamic' with arguments from the 'CUDA' backend. This could be because the operator doesn't exist for this backend, or was omitted during the selective/custom build process (if using custom build). If you are a Facebook employee using PyTorch on mobile, please visit https://fburl.com/ptmfixes for possible resolutions. 'quantized::linear_dynamic' is only available for these backends: [CPU, BackendSelect, Python, FuncTorchDynamicLayerBackMode, Functionalize, Named, Conjugate, Negative, ZeroTensor, ADInplaceOrView, AutogradOther, AutogradCPU, AutogradCUDA, AutogradXLA, AutogradMPS, AutogradXPU, AutogradHPU, AutogradLazy, AutogradMeta, Tracer, AutocastCPU, AutocastCUDA, FuncTorchBatched, FuncTorchVmapMode, Batched, VmapMode, FuncTorchGradWrapper, PythonTLSSnapshot, FuncTorchDynamicLayerFrontMode, PreDispatch, PythonDispatcher].\n\nCPU: registered at ../aten/src/ATen/native/quantized/cpu/qlinear_dynamic.cpp:662 [kernel]\nBackendSelect: fallthrough registered at ../aten/src/ATen/core/BackendSelectFallbackKernel.cpp:3 [backend fallback]\nPython: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:153 [backend fallback]\nFuncTorchDynamicLayerBackMode: registered at ../aten/src/ATen/functorch/DynamicLayer.cpp:498 [backend fallback]\nFunctionalize: registered at ../aten/src/ATen/FunctionalizeFallbackKernel.cpp:290 [backend fallback]\nNamed: registered at ../aten/src/ATen/core/NamedRegistrations.cpp:7 [backend fallback]\nConjugate: registered at ../aten/src/ATen/ConjugateFallback.cpp:17 [backend fallback]\nNegative: registered at ../aten/src/ATen/native/NegateFallback.cpp:19 [backend fallback]\nZeroTensor: registered at ../aten/src/ATen/ZeroTensorFallback.cpp:86 [backend fallback]\nADInplaceOrView: fallthrough registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:86 [backend fallback]\nAutogradOther: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:53 [backend fallback]\nAutogradCPU: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:57 [backend fallback]\nAutogradCUDA: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:65 [backend fallback]\nAutogradXLA: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:69 [backend fallback]\nAutogradMPS: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:77 [backend fallback]\nAutogradXPU: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:61 [backend fallback]\nAutogradHPU: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:90 [backend fallback]\nAutogradLazy: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:73 [backend fallback]\nAutogradMeta: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:81 [backend fallback]\nTracer: registered at ../torch/csrc/autograd/TraceTypeManual.cpp:296 [backend fallback]\nAutocastCPU: fallthrough registered at ../aten/src/ATen/autocast_mode.cpp:382 [backend fallback]\nAutocastCUDA: fallthrough registered at ../aten/src/ATen/autocast_mode.cpp:249 [backend fallback]\nFuncTorchBatched: registered at ../aten/src/ATen/functorch/LegacyBatchingRegistrations.cpp:710 [backend fallback]\nFuncTorchVmapMode: fallthrough registered at ../aten/src/ATen/functorch/VmapModeRegistrations.cpp:28 [backend fallback]\nBatched: registered at ../aten/src/ATen/LegacyBatchingRegistrations.cpp:1075 [backend fallback]\nVmapMode: fallthrough registered at ../aten/src/ATen/VmapModeRegistrations.cpp:33 [backend fallback]\nFuncTorchGradWrapper: registered at ../aten/src/ATen/functorch/TensorWrapper.cpp:203 [backend fallback]\nPythonTLSSnapshot: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:161 [backend fallback]\nFuncTorchDynamicLayerFrontMode: registered at ../aten/src/ATen/functorch/DynamicLayer.cpp:494 [backend fallback]\nPreDispatch: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:165 [backend fallback]\nPythonDispatcher: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:157 [backend fallback]\n", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2 Deep Learning.ipynb Cell 38\u001b[0m line \u001b[0;36m1\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=10'>11</a>\u001b[0m data, target \u001b[39m=\u001b[39m data\u001b[39m.\u001b[39mcuda(), target\u001b[39m.\u001b[39mcuda()\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=11'>12</a>\u001b[0m \u001b[39m# forward pass: compute predicted outputs by passing inputs to the quantized_model\u001b[39;00m\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=12'>13</a>\u001b[0m output \u001b[39m=\u001b[39m quantized_model(data)\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=13'>14</a>\u001b[0m \u001b[39m# calculate the batch loss\u001b[39;00m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=14'>15</a>\u001b[0m loss \u001b[39m=\u001b[39m criterion(output, target)\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torch/nn/modules/module.py:1518\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1516\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_compiled_call_impl(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs) \u001b[39m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m 1517\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 1518\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_impl(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torch/nn/modules/module.py:1527\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1522\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1523\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1524\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1525\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1526\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1527\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1529\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m 1530\u001b[0m result \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", - "\u001b[1;32m/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2 Deep Learning.ipynb Cell 38\u001b[0m line \u001b[0;36m2\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=18'>19</a>\u001b[0m x \u001b[39m=\u001b[39m x\u001b[39m.\u001b[39mview(\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m, \u001b[39m64\u001b[39m \u001b[39m*\u001b[39m \u001b[39m4\u001b[39m \u001b[39m*\u001b[39m \u001b[39m4\u001b[39m)\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=20'>21</a>\u001b[0m \u001b[39m# print(f'before first fully connected: x.shape = {x.shape}')\u001b[39;00m\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=21'>22</a>\u001b[0m x \u001b[39m=\u001b[39m F\u001b[39m.\u001b[39mrelu(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mfc1(x))\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=22'>23</a>\u001b[0m \u001b[39m# print(f'after first fully connected, x.shape = {x.shape}')\u001b[39;00m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/vl/Documents/4A/liming_chen_deep/be2/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y113sZmlsZQ%3D%3D?line=23'>24</a>\u001b[0m x \u001b[39m=\u001b[39m F\u001b[39m.\u001b[39mrelu(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfc2(x))\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torch/nn/modules/module.py:1518\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1516\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_compiled_call_impl(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs) \u001b[39m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m 1517\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 1518\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_impl(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torch/nn/modules/module.py:1527\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1522\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1523\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1524\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1525\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1526\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1527\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1529\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m 1530\u001b[0m result \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torch/ao/nn/quantized/dynamic/modules/linear.py:54\u001b[0m, in \u001b[0;36mLinear.forward\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 51\u001b[0m Y \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mops\u001b[39m.\u001b[39mquantized\u001b[39m.\u001b[39mlinear_dynamic(\n\u001b[1;32m 52\u001b[0m x, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_packed_params\u001b[39m.\u001b[39m_packed_params)\n\u001b[1;32m 53\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m---> 54\u001b[0m Y \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39;49mops\u001b[39m.\u001b[39;49mquantized\u001b[39m.\u001b[39;49mlinear_dynamic(\n\u001b[1;32m 55\u001b[0m x, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_packed_params\u001b[39m.\u001b[39;49m_packed_params, reduce_range\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m)\n\u001b[1;32m 56\u001b[0m \u001b[39melif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_packed_params\u001b[39m.\u001b[39mdtype \u001b[39m==\u001b[39m torch\u001b[39m.\u001b[39mfloat16:\n\u001b[1;32m 57\u001b[0m Y \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mops\u001b[39m.\u001b[39mquantized\u001b[39m.\u001b[39mlinear_dynamic_fp16(\n\u001b[1;32m 58\u001b[0m x, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_packed_params\u001b[39m.\u001b[39m_packed_params)\n", - "File \u001b[0;32m~/.local/lib/python3.10/site-packages/torch/_ops.py:692\u001b[0m, in \u001b[0;36mOpOverloadPacket.__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 687\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__call__\u001b[39m(\u001b[39mself\u001b[39m, \u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[1;32m 688\u001b[0m \u001b[39m# overloading __call__ to ensure torch.ops.foo.bar()\u001b[39;00m\n\u001b[1;32m 689\u001b[0m \u001b[39m# is still callable from JIT\u001b[39;00m\n\u001b[1;32m 690\u001b[0m \u001b[39m# We save the function ptr as the `op` attribute on\u001b[39;00m\n\u001b[1;32m 691\u001b[0m \u001b[39m# OpOverloadPacket to access it here.\u001b[39;00m\n\u001b[0;32m--> 692\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_op(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs \u001b[39mor\u001b[39;49;00m {})\n", - "\u001b[0;31mNotImplementedError\u001b[0m: Could not run 'quantized::linear_dynamic' with arguments from the 'CUDA' backend. This could be because the operator doesn't exist for this backend, or was omitted during the selective/custom build process (if using custom build). If you are a Facebook employee using PyTorch on mobile, please visit https://fburl.com/ptmfixes for possible resolutions. 'quantized::linear_dynamic' is only available for these backends: [CPU, BackendSelect, Python, FuncTorchDynamicLayerBackMode, Functionalize, Named, Conjugate, Negative, ZeroTensor, ADInplaceOrView, AutogradOther, AutogradCPU, AutogradCUDA, AutogradXLA, AutogradMPS, AutogradXPU, AutogradHPU, AutogradLazy, AutogradMeta, Tracer, AutocastCPU, AutocastCUDA, FuncTorchBatched, FuncTorchVmapMode, Batched, VmapMode, FuncTorchGradWrapper, PythonTLSSnapshot, FuncTorchDynamicLayerFrontMode, PreDispatch, PythonDispatcher].\n\nCPU: registered at ../aten/src/ATen/native/quantized/cpu/qlinear_dynamic.cpp:662 [kernel]\nBackendSelect: fallthrough registered at ../aten/src/ATen/core/BackendSelectFallbackKernel.cpp:3 [backend fallback]\nPython: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:153 [backend fallback]\nFuncTorchDynamicLayerBackMode: registered at ../aten/src/ATen/functorch/DynamicLayer.cpp:498 [backend fallback]\nFunctionalize: registered at ../aten/src/ATen/FunctionalizeFallbackKernel.cpp:290 [backend fallback]\nNamed: registered at ../aten/src/ATen/core/NamedRegistrations.cpp:7 [backend fallback]\nConjugate: registered at ../aten/src/ATen/ConjugateFallback.cpp:17 [backend fallback]\nNegative: registered at ../aten/src/ATen/native/NegateFallback.cpp:19 [backend fallback]\nZeroTensor: registered at ../aten/src/ATen/ZeroTensorFallback.cpp:86 [backend fallback]\nADInplaceOrView: fallthrough registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:86 [backend fallback]\nAutogradOther: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:53 [backend fallback]\nAutogradCPU: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:57 [backend fallback]\nAutogradCUDA: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:65 [backend fallback]\nAutogradXLA: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:69 [backend fallback]\nAutogradMPS: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:77 [backend fallback]\nAutogradXPU: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:61 [backend fallback]\nAutogradHPU: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:90 [backend fallback]\nAutogradLazy: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:73 [backend fallback]\nAutogradMeta: registered at ../aten/src/ATen/core/VariableFallbackKernel.cpp:81 [backend fallback]\nTracer: registered at ../torch/csrc/autograd/TraceTypeManual.cpp:296 [backend fallback]\nAutocastCPU: fallthrough registered at ../aten/src/ATen/autocast_mode.cpp:382 [backend fallback]\nAutocastCUDA: fallthrough registered at ../aten/src/ATen/autocast_mode.cpp:249 [backend fallback]\nFuncTorchBatched: registered at ../aten/src/ATen/functorch/LegacyBatchingRegistrations.cpp:710 [backend fallback]\nFuncTorchVmapMode: fallthrough registered at ../aten/src/ATen/functorch/VmapModeRegistrations.cpp:28 [backend fallback]\nBatched: registered at ../aten/src/ATen/LegacyBatchingRegistrations.cpp:1075 [backend fallback]\nVmapMode: fallthrough registered at ../aten/src/ATen/VmapModeRegistrations.cpp:33 [backend fallback]\nFuncTorchGradWrapper: registered at ../aten/src/ATen/functorch/TensorWrapper.cpp:203 [backend fallback]\nPythonTLSSnapshot: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:161 [backend fallback]\nFuncTorchDynamicLayerFrontMode: registered at ../aten/src/ATen/functorch/DynamicLayer.cpp:494 [backend fallback]\nPreDispatch: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:165 [backend fallback]\nPythonDispatcher: registered at ../aten/src/ATen/core/PythonFallbackKernel.cpp:157 [backend fallback]\n" + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 16.382165\n", + "\n", + "Test Accuracy of airplane: 77% (773/1000)\n", + "Test Accuracy of automobile: 82% (823/1000)\n", + "Test Accuracy of bird: 68% (680/1000)\n", + "Test Accuracy of cat: 50% (507/1000)\n", + "Test Accuracy of deer: 63% (634/1000)\n", + "Test Accuracy of dog: 59% (596/1000)\n", + "Test Accuracy of frog: 78% (784/1000)\n", + "Test Accuracy of horse: 81% (817/1000)\n", + "Test Accuracy of ship: 82% (823/1000)\n", + "Test Accuracy of truck: 82% (820/1000)\n", + "\n", + "Test Accuracy (Overall): 72% (7257/10000)\n" ] } ], @@ -1173,14 +1168,11 @@ "class_correct_quantized = list(0.0 for i in range(10))\n", "class_total_quantized = list(0.0 for i in range(10))\n", "\n", - "quantized_model.eval()\n", + "quantized_custom_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 quantized_model\n", - " output = quantized_model(data)\n", + " output = quantized_custom_model(data)\n", " # calculate the batch loss\n", " loss = criterion(output, target)\n", " # update test loss\n", @@ -1189,11 +1181,7 @@ " _, 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", + " correct = (np.squeeze(correct_tensor.numpy()))\n", " # calculate test accuracy for each object class\n", " for i in range(batch_size):\n", " label = target.data[i]\n", @@ -1229,27 +1217,19 @@ ] }, { - "cell_type": "code", - "execution_count": 40, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "class_correct = [728.0, 836.0, 637.0, 617.0, 635.0, 562.0, 664.0, 767.0, 876.0, 743.0]\n", - "class_total = [1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0]\n" - ] - } - ], "source": [ - "print(f'class_correct = {class_correct}')\n", - "print(f'class_total = {class_total}')" + "> We see that the overall accuracy is the same for the quantized model. <br>\n", + "There are only 5 more wronlgy classified classes for the quantized model, out of 10.000 instances.\n", + "<br>\n", + "\n", + "Now I will plot the class accuracy of both models." ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -1259,42 +1239,41 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0.728, 0.836, 0.637, 0.617, 0.635, 0.562, 0.664, 0.767, 0.876, 0.743]" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test_accuracy_classes" - ] - }, - { - "cell_type": "code", - "execution_count": 46, + "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "<BarContainer object of 10 artists>" + "([<matplotlib.axis.XTick at 0x7fe03035bf40>,\n", + " <matplotlib.axis.XTick at 0x7fe03035bdf0>,\n", + " <matplotlib.axis.XTick at 0x7fe0303c4f10>,\n", + " <matplotlib.axis.XTick at 0x7fe0303dd9c0>,\n", + " <matplotlib.axis.XTick at 0x7fe0305277f0>,\n", + " <matplotlib.axis.XTick at 0x7fe030554850>,\n", + " <matplotlib.axis.XTick at 0x7fe030555030>,\n", + " <matplotlib.axis.XTick at 0x7fe030527160>,\n", + " <matplotlib.axis.XTick at 0x7fe0305554b0>,\n", + " <matplotlib.axis.XTick at 0x7fe030555c90>],\n", + " [Text(1.175, 0, 'airplane'),\n", + " Text(2.175, 0, 'automobile'),\n", + " Text(3.175, 0, 'bird'),\n", + " Text(4.175, 0, 'cat'),\n", + " Text(5.175, 0, 'deer'),\n", + " Text(6.175, 0, 'dog'),\n", + " Text(7.175, 0, 'frog'),\n", + " Text(8.175, 0, 'horse'),\n", + " Text(9.175, 0, 'ship'),\n", + " Text(10.175, 0, 'truck')])" ] }, - "execution_count": 46, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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+/Zf5sHI592/fN79y+fdv97vn/fYsWPfdpuqTmAdOXJkZs+endbW1t513d3daW1tzfz580+7z/z58/tsnyRPPPHEGbcHAIaWqr+maW5uzrJlyzJnzpzMnTs3mzZtyrFjx7J8+fIkydKlSzNp0qRs2LAhSbJq1ap84hOfyP33359Pf/rTeeSRR/K9730vW7dufW/fCQAwIFUdI0uWLMmRI0eybt26tLe3Z9asWdm5c2caGhqSJG1tbRk+/K0DLtdee222b9+eO+64I7fddls++tGP5lvf+lauuOKK9+5dcM5qa2vT0tJyytdinB8+7/7l8+5fPu/+NZg+72E9PW93vQ0AwPnjt2kAgKLECABQlBgBAIoSIwBAUWJkCNqwYUN+/ud/PmPGjMm4ceOyePHiHDx4sPRYQ8Y999yTYcOG5eabby49yqD18ssv58Ybb8yll16aUaNG5corr8z3vve90mMNSl1dXVm7dm0uu+yyjBo1Kh/5yEdy5513vv1vkfCO/fM//3MWLVqUiRMnZtiwYaf8tltPT0/WrVuXCRMmZNSoUWlsbMx//Md/lBn2HImRIeipp57KypUr853vfCdPPPFEfvKTn+S6667LsWPHSo826D377LP50z/901x11VWlRxm0/vu//zsLFizIBRdckL//+7/Pv//7v+f+++/PxRdfXHq0Qenee+/NAw88kK9+9as5cOBA7r333tx33335kz/5k9KjDRrHjh3LzJkzs3nz5tM+ft999+UrX/lKtmzZku9+97v5wAc+kIULF+b48eP9POm5c2kvOXLkSMaNG5ennnoqv/iLv1h6nEHrtddeyzXXXJOvfe1rueuuuzJr1qxs2rSp9FiDzurVq/Ov//qv+Zd/+ZfSowwJv/qrv5qGhoY89NBDvet+7dd+LaNGjcrDDz9ccLLBadiwYXn00UezePHiJG8cFZk4cWL+4A/+IF/4wheSvPFL9w0NDfn617+ez3zmMwWnfeccGSFHjx5NklxyySWFJxncVq5cmU9/+tNpbGwsPcqg9u1vfztz5szJb/zGb2TcuHG5+uqr8+CDD5Yea9C69tpr09ramueffz5J8m//9m95+umn88u//MuFJxsafvSjH6W9vb3Pf1fGjh2befPmZffu3QUnq8778ld76T/d3d25+eabs2DBAnfFPY8eeeSR7Nu3L88++2zpUQa9F198MQ888ECam5tz22235dlnn83v//7vZ+TIkVm2bFnp8Qad1atXp7OzM9OmTUtNTU26urpy991354Ybbig92pDQ3t6eJL13Qf+phoaG3scGAjEyxK1cuTLPPfdcnn766dKjDFqHDh3KqlWr8sQTT6Surq70OINed3d35syZk/Xr1ydJrr766jz33HPZsmWLGDkP/vIv/zLf+MY3sn379nzsYx/L/v37c/PNN2fixIk+b94xX9MMYU1NTfm7v/u7PPnkk/nQhz5UepxBa+/evTl8+HCuueaajBgxIiNGjMhTTz2Vr3zlKxkxYkS6urpKjzioTJgwITNmzOizbvr06Wlrays00eB26623ZvXq1fnMZz6TK6+8MjfddFNuueWW3h9L5fwaP358kqSjo6PP+o6Ojt7HBgIxMgT19PSkqakpjz76aP7pn/4pl112WemRBrVPfvKT+cEPfpD9+/f3LnPmzMkNN9yQ/fv3p6ampvSIg8qCBQtOuVT9+eefz8/+7M8Wmmhwe/311/v8OGqS1NTUpLu7u9BEQ8tll12W8ePHp7W1tXddZ2dnvvvd72b+/PkFJ6uOr2mGoJUrV2b79u35m7/5m4wZM6b3e8WxY8dm1KhRhacbfMaMGXPK+Tgf+MAHcumllzpP5zy45ZZbcu2112b9+vX5zd/8zezZsydbt27N1q1bS482KC1atCh33313pkyZko997GP5/ve/n40bN+a3fuu3So82aLz22mt54YUXev/+0Y9+lP379+eSSy7JlClTcvPNN+euu+7KRz/60Vx22WVZu3ZtJk6c2HvFzYDQw5CT5LTLn//5n5cebcj4xCc+0bNq1arSYwxaf/u3f9tzxRVX9NTW1vZMmzatZ+vWraVHGrQ6Ozt7Vq1a1TNlypSeurq6ng9/+MM9t99+e8+JEydKjzZoPPnkk6f9b/ayZct6enp6erq7u3vWrl3b09DQ0FNbW9vzyU9+sufgwYNlh66S+4wAAEU5ZwQAKEqMAABFiREAoCgxAgAUJUYAgKLECABQlBgBAIoSIwBAUWIEAChKjAAARYkRAKAoMQIAFPX/AI7r7kdazFZTAAAAAElFTkSuQmCC", + "image/png": "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KgrTpk1DREQEHB0dsXv3bmWScXh4OIyMcu3k5URERKRy2Q43cXFxMDExydResGDBHO9m7e3tneVmKAA4ePDgG/uuWbMmR49JRERE6pTtIZHatWtj48aNmdo3bNiAGjVq5EpRRERERDmV7ZGbqVOnokePHrhx4wZat24NAAgODsb69euxefPmXC+QiIiIKDuyHW66dOmCX375BbNnz8bmzZthbm6OunXrYv/+/ShRosT7qJGIiIjoreVoV/BOnTqhU6dOAICYmBj89NNP+PTTT3Hq1CmkpaXlaoFERERE2ZHj3ZAOHz6MwYMHo1y5cliwYAFat26N//3vf7lZGxEREVG2ZWvkJiIiAmvWrMGqVasQExOD//znP0hKSsIvv/zCycRERERkEN565KZLly5wcHDA+fPnsXjxYjx48ADLli17n7URERERZdtbj9zs2rULY8aMwSeffPLOp10gIiIiel/eeuTmyJEjiI2NhZOTE1xcXLB8+XJER0e/z9qIiIiIsu2tw02jRo2wcuVKPHz4EB9//DE2bNiAcuXKQavVYu/evYiNjX2fdRIRERG9lWzvLWVhYYGhQ4fiyJEjuHDhAsaPH485c+agdOnS6Nq16/uokYiIiOitvdMZKR0cHDB37lzcu3cPP/30U27VRERERJRjuXK6bWNjY3h4eGD79u25cXdEREREOZYr4YaIiIjIUDDcEBERkaow3BAREZGqMNwQERGRqjDcEBERkaow3BAREZGqMNwQERGRqjDcEBERkaow3BAREZGqMNwQERGRqjDcEBERkaow3BAREZGqMNwQERGRqjDcEBERkaow3BAREZGqMNwQERGRqjDcEBERkaow3BAREZGqGES4CQgIgJ2dHczMzODi4oLjx4+/dtmtW7fC2dkZxYoVg4WFBRwdHbF27do8rJaIiIgMmd7DzcaNG+Hr6ws/Pz+cPn0adevWhbu7Ox49epTl8iVKlMDkyZMREhKC8+fPw9PTE56entizZ08eV05ERESGSO/hZuHChfDy8oKnpydq1KiBwMBAFCpUCEFBQVku37JlS3Tv3h3Vq1eHvb09fHx8UKdOHRw5ciSPKyciIiJDpNdwk5ycjFOnTsHNzU1pMzIygpubG0JCQv6xv4ggODgYYWFhaN68+fsslYiIiPKJAvp88OjoaKSlpcHa2lqn3draGleuXHltv+fPn8PGxgZJSUkwNjbGN998g7Zt22a5bFJSEpKSkpTrMTExuVM8ERERGSS9hpucKlKkCM6ePYu4uDgEBwfD19cXlSpVQsuWLTMt6+/vj+nTp+d9kURERKQXeg03VlZWMDY2RmRkpE57ZGQkypQp89p+RkZGqFy5MgDA0dERoaGh8Pf3zzLcTJw4Eb6+vsr1mJgY2Nra5s4TICIiIoOj1zk3JiYmcHJyQnBwsNKm1WoRHBwMV1fXt74frVars+kpI1NTUxQtWlTnQkREROql981Svr6+GDx4MJydndGwYUMsXrwY8fHx8PT0BAAMGjQINjY28Pf3B/ByM5OzszPs7e2RlJSEnTt3Yu3atfj222/1+TSIiIjIQOg93PTu3RtRUVGYNm0aIiIi4OjoiN27dyuTjMPDw2Fk9PcAU3x8PEaOHIl79+7B3Nwc1apVw7p169C7d299PQUiIiIyIHoPNwDg7e0Nb2/vLG87ePCgzvWZM2di5syZeVAVERER5Ud6P4gfERERUW5iuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVYbghIiIiVWG4ISIiIlVhuCEiIiJVMYhwExAQADs7O5iZmcHFxQXHjx9/7bIrV65Es2bNULx4cRQvXhxubm5vXJ6IiIj+XfQebjZu3AhfX1/4+fnh9OnTqFu3Ltzd3fHo0aMslz948CD69u2LAwcOICQkBLa2tmjXrh3u37+fx5UTERGRIdJ7uFm4cCG8vLzg6emJGjVqIDAwEIUKFUJQUFCWy//4448YOXIkHB0dUa1aNXz//ffQarUIDg7O48qJiIjIEOk13CQnJ+PUqVNwc3NT2oyMjODm5oaQkJC3uo+EhASkpKSgRIkSWd6elJSEmJgYnQsRERGpl17DTXR0NNLS0mBtba3Tbm1tjYiIiLe6j88//xzlypXTCUgZ+fv7w9LSUrnY2tq+c91ERERkuPS+WepdzJkzBxs2bMC2bdtgZmaW5TITJ07E8+fPlcvdu3fzuEoiIiLKSwX0+eBWVlYwNjZGZGSkTntkZCTKlCnzxr7z58/HnDlzsG/fPtSpU+e1y5mamsLU1DRX6iUiIiLDp9eRGxMTEzg5OelMBk6fHOzq6vrafnPnzsWMGTOwe/duODs750WpRERElE/odeQGAHx9fTF48GA4OzujYcOGWLx4MeLj4+Hp6QkAGDRoEGxsbODv7w8A+PrrrzFt2jSsX78ednZ2ytycwoULo3Dhwnp7HkRERGQY9B5uevfujaioKEybNg0RERFwdHTE7t27lUnG4eHhMDL6e4Dp22+/RXJyMj788EOd+/Hz88OXX36Zl6UTERGRAdJ7uAEAb29veHt7Z3nbwYMHda7fvn37/RdERERE+Va+3luKiIiI6FUMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCoMN0RERKQqDDdERESkKgw3REREpCp6DzcBAQGws7ODmZkZXFxccPz48dcue+nSJfTs2RN2dnbQaDRYvHhx3hVKRERE+YJew83GjRvh6+sLPz8/nD59GnXr1oW7uzsePXqU5fIJCQmoVKkS5syZgzJlyuRxtURERJQf6DXcLFy4EF5eXvD09ESNGjUQGBiIQoUKISgoKMvlGzRogHnz5qFPnz4wNTXN42qJiIgoP9BbuElOTsapU6fg5ub2dzFGRnBzc0NISIi+yiIiIqJ8roC+Hjg6OhppaWmwtrbWabe2tsaVK1dy7XGSkpKQlJSkXI+Jicm1+yYiIiLDo/cJxe+bv78/LC0tlYutra2+SyIiIqL3SG/hxsrKCsbGxoiMjNRpj4yMzNXJwhMnTsTz58+Vy927d3PtvomIiMjw6C3cmJiYwMnJCcHBwUqbVqtFcHAwXF1dc+1xTE1NUbRoUZ0LERERqZfe5twAgK+vLwYPHgxnZ2c0bNgQixcvRnx8PDw9PQEAgwYNgo2NDfz9/QG8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PsSkSZPAnEtERGrA49yohIgowaZ79+44ffo0ihQpgmvXrmHRokXo2bMn7t+/j6FDh6JcuXJo1KgRIiIiULBgQZw5cwZVqlQxmEnQRERE74LhRiU0Gg1evHiBXr164fnz5zh27BhsbGzwySefYPLkyTA1NcXIkSPx5MkTtG3bFq6urrhw4QIGDBjA49cQEZGqMNyoyJUrV1ChQgV8+umnsLGxwddff41Nmzahbt268PHxQalSpbB06VK4uroiIiICo0aNQr9+/fRdNhERUa7ihGIVef78Oc6fP49mzZrB398f33//PZYtW4aOHTuibt26MDExwaJFi9C0aVN9l0pERPTecEKxilhaWqJZs2ZISEjA7t27MX78eHTs2BGxsbEoUaIETp06hUWLFiE1NVXfpRIREb03DDcqdPPmTZw9exbly5cHADx+/Bj29va4efMm1q9fjwIFuDWSiIjUi+FGhWrVqgVXV1cMHToU/fv3R4MGDZCWlgY7OzuYmprquzwiIqL3inNuVEqr1SqnVahdu7ZyHikiIiK1Y7hRuayOWExERKRmDDdERESkKpxzQ0RERKrCcENERESqwnBDREREqsJwQ0RERKrCcENERESqwnBDREREqsJwQ0RERKrCcENEBkej0eCXX37RdxlElE8x3BBRnouIiMDo0aNRqVIlmJqawtbWFl26dEFwcLC+SyMiFeDpoYkoT92+fRtNmjRBsWLFMG/ePNSuXRspKSnYs2cPRo0ahStXrui7RCLK5zhyQ0R5auTIkdBoNDh+/Dh69uyJqlWrombNmvD19cX//ve/LPt8/vnnqFq1KgoVKoRKlSph6tSpSElJUW4/d+4cWrVqhSJFiqBo0aJwcnLCyZMnAQB37txBly5dULx4cVhYWKBmzZrYuXOn0vfixYvo0KEDChcuDGtrawwcOBDR0dHK7Zs3b0bt2rVhbm6OkiVLws3NDfHx8e/p1SGi3MCRGyLKM0+ePMHu3bsxa9YsWFhYZLq9WLFiWfYrUqQI1qxZg3LlyuHChQvw8vJCkSJF8NlnnwEA+vfvj3r16uHbb7+FsbExzp49i4IFCwIARo0aheTkZBw+fBgWFha4fPkyChcuDAB49uwZWrdujeHDh2PRokV48eIFPv/8c/znP//B/v378fDhQ/Tt2xdz585F9+7dERsbiz///BM8JR+RYWO4IaI8c/36dYgIqlWrlq1+U6ZMUf62s7PDp59+ig0bNijhJjw8HBMmTFDut0qVKsry4eHh6NmzJ2rXrg0AqFSpknLb8uXLUa9ePcyePVtpCwoKgq2tLa5evYq4uDikpqaiR48eqFChAgAo90NEhovhhojyTE5HPDZu3IilS5fixo0bSuAoWrSocruvry+GDx+OtWvXws3NDb169YK9vT0AYMyYMfjkk0/wxx9/wM3NDT179kSdOnUAvNycdeDAAWUkJ6MbN26gXbt2aNOmDWrXrg13d3e0a9cOH374IYoXL56j50FEeYNzbogoz1SpUgUajSZbk4ZDQkLQv39/dOzYEb///jvOnDmDyZMnIzk5WVnmyy+/xKVLl9CpUyfs378fNWrUwLZt2wAAw4cPx82bNzFw4EBcuHABzs7OWLZsGQAgLi4OXbp0wdmzZ3Uu165dQ/PmzWFsbIy9e/di165dqFGjBpYtWwYHBwfcunUrd18YIspVGuHGYyLKQx06dMCFCxcQFhaWad7Ns2fPUKxYMWg0Gmzbtg0eHh5YsGABvvnmG9y4cUNZbvjw4di8eTOePXuW5WP07dsX8fHx2L59e6bbJk6ciB07duD8+fOYPHkytmzZgosXL6JAgX8eyE5LS0OFChXg6+sLX1/f7D1xIsozHLkhojwVEBCAtLQ0NGzYEFu2bMG1a9cQGhqKpUuXwtXVNdPyVapUQXh4ODZs2IAbN25g6dKlyqgMALx48QLe3t44ePAg7ty5g6NHj+LEiROoXr06AGDs2LHYs2cPbt26hdOnT+PAgQPKbaNGjcKTJ0/Qt29fnDhxAjdu3MCePXvg6emJtLQ0/PXXX5g9ezZOnjyJ8PBwbN26FVFRUUp/IjJQQkSUxx48eCCjRo2SChUqiImJidjY2EjXrl3lwIEDIiICQLZt26YsP2HCBClZsqQULlxYevfuLYsWLRJLS0sREUlKSpI+ffqIra2tmJiYSLly5cTb21tevHghIiLe3t5ib28vpqamUqpUKRk4cKBER0cr93316lXp3r27FCtWTMzNzaVatWoyduxY0Wq1cvnyZXF3d5dSpUqJqampVK1aVZYtW5ZXLxMR5RA3SxEREZGqcLMUERERqQrDDREREakKww0RERGpCsMNERERqQrDDREREakKww0RERGpCsMNERERqQrDDREREakKww0RERGpCsMNERERqQrDDREREakKww0RERGpyv8BFF9dgn7yJJsAAAAASUVORK5CYII=", "text/plain": [ "<Figure size 640x480 with 1 Axes>" ] @@ -1304,7 +1283,20 @@ } ], "source": [ - "plt.bar([i for i in range(1,11)], test_accuracy_classes, color='blue', edgecolor='black')" + "bar_width = 0.35\n", + "indexes = np.asarray([i for i in range(1,11)]) \n", + "plt.bar(indexes, test_accuracy_classes, width=bar_width, color='blue', edgecolor='black')\n", + "plt.bar(indexes+bar_width, test_accuracy_classes_quantized, width=bar_width, color='green', edgecolor='black')\n", + "plt.xlabel('Classes')\n", + "plt.ylabel('Accuracy')\n", + "plt.xticks(indexes + bar_width / 2, classes, rotation=40) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> We can see that the class accuracy are similar, even better with the quantized model for trucks." ] }, { @@ -1312,7 +1304,9 @@ "id": "a0a34b90", "metadata": {}, "source": [ - "Try training aware quantization to mitigate the impact on the accuracy (doc available here https://pytorch.org/docs/stable/quantization.html#torch.quantization.quantize_dynamic)" + "Try training aware quantization to mitigate the impact on the accuracy (doc available here https://pytorch.org/docs/stable/quantization.html#torch.quantization.quantize_dynamic)\n", + "> Since I trained on gpu and quantization is not available on gpu, I didn't do the quantization aware training. \n", + "<br> I will do it in the 4th part, since training is very fast for transfer-learning and can be done with the cpu." ] }, { @@ -1328,7 +1322,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": null, "id": "b4d13080", "metadata": {}, "outputs": [ @@ -1408,7 +1402,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1454,7 +1448,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": null, "id": "be2d31f5", "metadata": {}, "outputs": [ @@ -1556,7 +1550,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": null, "id": "572d824c", "metadata": {}, "outputs": [