diff --git a/TD2 Deep Learning.ipynb b/TD2 Deep Learning.ipynb index e5f12d3cb23bf5802d15d07fc791f60e5a48eefe..50e28feb6f9f0ded848b9c1488a9210861bd987c 100644 --- a/TD2 Deep Learning.ipynb +++ b/TD2 Deep Learning.ipynb @@ -493,7 +493,8 @@ "id": "13e1df74", "metadata": {}, "source": [ - "Overfit occurs so we do an early stopping at epoch 13 (should have been done at epoch 12)." + "Overfit occurs so we do an early stopping at epoch 13 (should have been done at epoch 12).\n", + "Now we can plot the performance :" ] }, { @@ -520,7 +521,7 @@ "plt.plot(range(n_epochs_overfit), train_loss_list[:-1])\n", "plt.xlabel(\"Epoch\")\n", "plt.ylabel(\"Loss\")\n", - "plt.title(\"Performance of Model 1\")\n", + "plt.title(\"Performance of Model 0\")\n", "plt.show()" ] }, @@ -643,7 +644,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "CNN definition following the structure required above" + "### 1. CNN definition following the structure required above" ] }, { @@ -732,7 +733,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Loss function and training using SGD (Stochastic Gradient Descent) optimizer" + "### 2. Loss function and training using SGD (Stochastic Gradient Descent) optimizer" ] }, { @@ -871,7 +872,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Compare the results with the previous model's results" + "### 3. Compare the performance with the previous model's performance." ] }, { @@ -898,10 +899,25 @@ "plt.plot(range(n_epochs_overfit), train_loss_list_1[:-3], color = \"green\", label = \"Model 1\")\n", "plt.xlabel(\"Epoch\")\n", "plt.ylabel(\"Loss\")\n", - "plt.title(\"Comparison of Performance for of Model 0 and Model 1\")\n", + "plt.title(\"Comparison of Performance of Model 0 and Model 1\")\n", + "plt.legend()\n", "plt.show()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For model 1, test loss is 18.15, while test loss is 20.42 for model 0. Thus model 1 has a better loss than model 0. However, what is unexpected is that, in the beginning, model 1's loss decreases slower than model 0's." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. Compare the accuracy with the previous model's accuracy" + ] + }, { "cell_type": "code", "execution_count": 14, @@ -917,8 +933,73 @@ } ], "source": [ - "print(train_loss_list)\n", - "print(train_loss_list_1)" + "model_1.load_state_dict(torch.load(\"./model_1_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", + "model_1.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 = model_1(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", + "metadata": {}, + "source": [ + "For model 1, accuracy is , while accuracy is for model 0." ] }, { @@ -1984,24 +2065,102 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 46, "metadata": {}, "outputs": [ { - "ename": "FileNotFoundError", - "evalue": "[WinError 3] Le chemin d’accès spécifié est introuvable: 'hymenoptera_data\\\\test'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32md:\\Users\\lucil\\Documents\\S9\\Apprentissage profond\\mod_4_6-td2\\TD2 Deep Learning.ipynb Cell 56\u001b[0m line \u001b[0;36m4\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=46'>47</a>\u001b[0m data_dir \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mhymenoptera_data\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=47'>48</a>\u001b[0m \u001b[39m# Create train, validation and test datasets and loaders\u001b[39;00m\n\u001b[1;32m---> <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=48'>49</a>\u001b[0m image_datasets \u001b[39m=\u001b[39m {\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=49'>50</a>\u001b[0m x: datasets\u001b[39m.\u001b[39mImageFolder(os\u001b[39m.\u001b[39mpath\u001b[39m.\u001b[39mjoin(data_dir, x), data_transforms[x])\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=50'>51</a>\u001b[0m \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m [\u001b[39m\"\u001b[39m\u001b[39mtrain\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mval\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mtest\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=51'>52</a>\u001b[0m }\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=52'>53</a>\u001b[0m dataloaders \u001b[39m=\u001b[39m {\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=53'>54</a>\u001b[0m x: torch\u001b[39m.\u001b[39mutils\u001b[39m.\u001b[39mdata\u001b[39m.\u001b[39mDataLoader(\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=54'>55</a>\u001b[0m image_datasets[x], batch_size\u001b[39m=\u001b[39m\u001b[39m4\u001b[39m, shuffle\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, num_workers\u001b[39m=\u001b[39m\u001b[39m4\u001b[39m\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=55'>56</a>\u001b[0m )\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=56'>57</a>\u001b[0m \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m [\u001b[39m\"\u001b[39m\u001b[39mtrain\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mval\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mtest\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=57'>58</a>\u001b[0m }\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=60'>61</a>\u001b[0m dataset_sizes \u001b[39m=\u001b[39m {x: \u001b[39mlen\u001b[39m(image_datasets[x]) \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m [\u001b[39m\"\u001b[39m\u001b[39mtrain\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mval\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mtest\u001b[39m\u001b[39m\"\u001b[39m]}\n", - "\u001b[1;32md:\\Users\\lucil\\Documents\\S9\\Apprentissage profond\\mod_4_6-td2\\TD2 Deep Learning.ipynb Cell 56\u001b[0m line \u001b[0;36m5\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=46'>47</a>\u001b[0m data_dir \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mhymenoptera_data\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=47'>48</a>\u001b[0m \u001b[39m# Create train, validation and test datasets and loaders\u001b[39;00m\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=48'>49</a>\u001b[0m image_datasets \u001b[39m=\u001b[39m {\n\u001b[1;32m---> <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=49'>50</a>\u001b[0m x: datasets\u001b[39m.\u001b[39mImageFolder(os\u001b[39m.\u001b[39mpath\u001b[39m.\u001b[39mjoin(data_dir, x), data_transforms[x])\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=50'>51</a>\u001b[0m \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m [\u001b[39m\"\u001b[39m\u001b[39mtrain\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mval\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mtest\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=51'>52</a>\u001b[0m }\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=52'>53</a>\u001b[0m dataloaders \u001b[39m=\u001b[39m {\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=53'>54</a>\u001b[0m x: torch\u001b[39m.\u001b[39mutils\u001b[39m.\u001b[39mdata\u001b[39m.\u001b[39mDataLoader(\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=54'>55</a>\u001b[0m image_datasets[x], batch_size\u001b[39m=\u001b[39m\u001b[39m4\u001b[39m, shuffle\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, num_workers\u001b[39m=\u001b[39m\u001b[39m4\u001b[39m\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=55'>56</a>\u001b[0m )\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=56'>57</a>\u001b[0m \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m [\u001b[39m\"\u001b[39m\u001b[39mtrain\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mval\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mtest\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=57'>58</a>\u001b[0m }\n\u001b[0;32m <a href='vscode-notebook-cell:/d%3A/Users/lucil/Documents/S9/Apprentissage%20profond/mod_4_6-td2/TD2%20Deep%20Learning.ipynb#Y111sZmlsZQ%3D%3D?line=60'>61</a>\u001b[0m dataset_sizes \u001b[39m=\u001b[39m {x: \u001b[39mlen\u001b[39m(image_datasets[x]) \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m [\u001b[39m\"\u001b[39m\u001b[39mtrain\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mval\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mtest\u001b[39m\u001b[39m\"\u001b[39m]}\n", - "File \u001b[1;32mc:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torchvision\\datasets\\folder.py:309\u001b[0m, in \u001b[0;36mImageFolder.__init__\u001b[1;34m(self, root, transform, target_transform, loader, is_valid_file)\u001b[0m\n\u001b[0;32m 301\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__init__\u001b[39m(\n\u001b[0;32m 302\u001b[0m \u001b[39mself\u001b[39m,\n\u001b[0;32m 303\u001b[0m root: \u001b[39mstr\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 307\u001b[0m is_valid_file: Optional[Callable[[\u001b[39mstr\u001b[39m], \u001b[39mbool\u001b[39m]] \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m,\n\u001b[0;32m 308\u001b[0m ):\n\u001b[1;32m--> 309\u001b[0m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39m\u001b[39m__init__\u001b[39m(\n\u001b[0;32m 310\u001b[0m root,\n\u001b[0;32m 311\u001b[0m loader,\n\u001b[0;32m 312\u001b[0m IMG_EXTENSIONS \u001b[39mif\u001b[39;00m is_valid_file \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39melse\u001b[39;00m \u001b[39mNone\u001b[39;00m,\n\u001b[0;32m 313\u001b[0m transform\u001b[39m=\u001b[39mtransform,\n\u001b[0;32m 314\u001b[0m target_transform\u001b[39m=\u001b[39mtarget_transform,\n\u001b[0;32m 315\u001b[0m is_valid_file\u001b[39m=\u001b[39mis_valid_file,\n\u001b[0;32m 316\u001b[0m )\n\u001b[0;32m 317\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mimgs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msamples\n", - "File \u001b[1;32mc:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torchvision\\datasets\\folder.py:144\u001b[0m, in \u001b[0;36mDatasetFolder.__init__\u001b[1;34m(self, root, loader, extensions, transform, target_transform, is_valid_file)\u001b[0m\n\u001b[0;32m 134\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__init__\u001b[39m(\n\u001b[0;32m 135\u001b[0m \u001b[39mself\u001b[39m,\n\u001b[0;32m 136\u001b[0m root: \u001b[39mstr\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 141\u001b[0m is_valid_file: Optional[Callable[[\u001b[39mstr\u001b[39m], \u001b[39mbool\u001b[39m]] \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m,\n\u001b[0;32m 142\u001b[0m ) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m 143\u001b[0m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39m\u001b[39m__init__\u001b[39m(root, transform\u001b[39m=\u001b[39mtransform, target_transform\u001b[39m=\u001b[39mtarget_transform)\n\u001b[1;32m--> 144\u001b[0m classes, class_to_idx \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfind_classes(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mroot)\n\u001b[0;32m 145\u001b[0m samples \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmake_dataset(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mroot, class_to_idx, extensions, is_valid_file)\n\u001b[0;32m 147\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mloader \u001b[39m=\u001b[39m loader\n", - "File \u001b[1;32mc:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torchvision\\datasets\\folder.py:218\u001b[0m, in \u001b[0;36mDatasetFolder.find_classes\u001b[1;34m(self, directory)\u001b[0m\n\u001b[0;32m 191\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mfind_classes\u001b[39m(\u001b[39mself\u001b[39m, directory: \u001b[39mstr\u001b[39m) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Tuple[List[\u001b[39mstr\u001b[39m], Dict[\u001b[39mstr\u001b[39m, \u001b[39mint\u001b[39m]]:\n\u001b[0;32m 192\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"Find the class folders in a dataset structured as follows::\u001b[39;00m\n\u001b[0;32m 193\u001b[0m \n\u001b[0;32m 194\u001b[0m \u001b[39m directory/\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 216\u001b[0m \u001b[39m (Tuple[List[str], Dict[str, int]]): List of all classes and dictionary mapping each class to an index.\u001b[39;00m\n\u001b[0;32m 217\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 218\u001b[0m \u001b[39mreturn\u001b[39;00m find_classes(directory)\n", - "File \u001b[1;32mc:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torchvision\\datasets\\folder.py:40\u001b[0m, in \u001b[0;36mfind_classes\u001b[1;34m(directory)\u001b[0m\n\u001b[0;32m 35\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mfind_classes\u001b[39m(directory: \u001b[39mstr\u001b[39m) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Tuple[List[\u001b[39mstr\u001b[39m], Dict[\u001b[39mstr\u001b[39m, \u001b[39mint\u001b[39m]]:\n\u001b[0;32m 36\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"Finds the class folders in a dataset.\u001b[39;00m\n\u001b[0;32m 37\u001b[0m \n\u001b[0;32m 38\u001b[0m \u001b[39m See :class:`DatasetFolder` for details.\u001b[39;00m\n\u001b[0;32m 39\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[1;32m---> 40\u001b[0m classes \u001b[39m=\u001b[39m \u001b[39msorted\u001b[39m(entry\u001b[39m.\u001b[39mname \u001b[39mfor\u001b[39;00m entry \u001b[39min\u001b[39;00m os\u001b[39m.\u001b[39mscandir(directory) \u001b[39mif\u001b[39;00m entry\u001b[39m.\u001b[39mis_dir())\n\u001b[0;32m 41\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m classes:\n\u001b[0;32m 42\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mFileNotFoundError\u001b[39;00m(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mCouldn\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt find any class folder in \u001b[39m\u001b[39m{\u001b[39;00mdirectory\u001b[39m}\u001b[39;00m\u001b[39m.\u001b[39m\u001b[39m\"\u001b[39m)\n", - "\u001b[1;31mFileNotFoundError\u001b[0m: [WinError 3] Le chemin d’accès spécifié est introuvable: 'hymenoptera_data\\\\test'" + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torchvision\\models\\_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n", + " warnings.warn(\n", + "c:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torchvision\\models\\_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet18_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet18_Weights.DEFAULT` to get the most up-to-date weights.\n", + " warnings.warn(msg)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + "----------\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\lucil\\anaconda3\\Lib\\site-packages\\torch\\optim\\lr_scheduler.py:136: UserWarning: Detected call of `lr_scheduler.step()` before `optimizer.step()`. In PyTorch 1.1.0 and later, you should call them in the opposite order: `optimizer.step()` before `lr_scheduler.step()`. Failure to do this will result in PyTorch skipping the first value of the learning rate schedule. See more details at https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate\n", + " warnings.warn(\"Detected call of `lr_scheduler.step()` before `optimizer.step()`. \"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train Loss: 0.5158 Acc: 0.7336\n", + "val Loss: 0.4568 Acc: 0.7778\n", + "\n", + "Epoch 2/10\n", + "----------\n", + "train Loss: 0.4562 Acc: 0.7869\n", + "val Loss: 0.2000 Acc: 0.9542\n", + "\n", + "Epoch 3/10\n", + "----------\n", + "train Loss: 0.5090 Acc: 0.7828\n", + "val Loss: 0.1858 Acc: 0.9477\n", + "\n", + "Epoch 4/10\n", + "----------\n", + "train Loss: 0.4266 Acc: 0.7992\n", + "val Loss: 0.2278 Acc: 0.9477\n", + "\n", + "Epoch 5/10\n", + "----------\n", + "train Loss: 0.5189 Acc: 0.7705\n", + "val Loss: 0.2774 Acc: 0.9020\n", + "\n", + "Epoch 6/10\n", + "----------\n", + "train Loss: 0.4524 Acc: 0.8074\n", + "val Loss: 0.2509 Acc: 0.9216\n", + "\n", + "Epoch 7/10\n", + "----------\n", + "train Loss: 0.4077 Acc: 0.8115\n", + "val Loss: 0.1791 Acc: 0.9412\n", + "\n", + "Epoch 8/10\n", + "----------\n", + "train Loss: 0.4013 Acc: 0.8402\n", + "val Loss: 0.1973 Acc: 0.9412\n", + "\n", + "Epoch 9/10\n", + "----------\n", + "train Loss: 0.3460 Acc: 0.8689\n", + "val Loss: 0.1996 Acc: 0.9412\n", + "\n", + "Epoch 10/10\n", + "----------\n", + "train Loss: 0.2655 Acc: 0.8893\n", + "val Loss: 0.1862 Acc: 0.9477\n", + "\n", + "Training complete in 8m 60s\n", + "Best val Acc: 0.954248\n", + "Evaluation of the model :\n", + "eval Loss: 0.2000 Acc: 0.9542\n" + ] + }, + { + "data": { + "text/plain": [ + "(0.19995229715615317, tensor(0.9542, dtype=torch.float64))" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -2043,34 +2202,33 @@ " transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n", " ]\n", " ),\n", + " \"eval\": transforms.Compose(\n", + " [\n", + " transforms.Resize(256),\n", + " transforms.CenterCrop(224),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n", + " ]\n", + " ),\n", "}\n", "\n", "\n", "data_dir = \"hymenoptera_data\"\n", "\n", - "\n", - "\n", - "# Create train, validation and test datasets and loaders\n", - "\n", - "train = datasets.ImageFolder(os.path.join(data_dir, \"train\"), data_transforms[\"train\"])\n", - "val = datasets.ImageFolder(os.path.join(data_dir, \"val\"), data_transforms[\"val\"])\n", - "\n", - "test = train_test_split(val, test_size = len(val)/2, random_state = 42)\n", - "\n", + "# Create train validation datasets and loaders\n", "image_datasets = {\n", - " \"train\" : train\n", - " \"val\" : val\n", - " \"test\" : test\n", + " x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])\n", + " for x in [\"train\", \"val\", \"eval\"]\n", "}\n", - "\n", "dataloaders = {\n", - " \"train\" : torch.utils.data.DataLoader(train, batch_size=4, shuffle=True, num_workers=4)\n", - " \"val\" : torch.utils.data.DataLoader(val, batch_size=4, shuffle=True, num_workers=4)\n", - " \"test\" : torch.utils.data.DataLoader(test, batch_size=4, shuffle=True, num_workers=4)\n", + " x: torch.utils.data.DataLoader(\n", + " image_datasets[x], batch_size=4, shuffle=True, num_workers=4\n", + " )\n", + " for x in [\"train\", \"val\", \"eval\"]\n", "}\n", "\n", "\n", - "dataset_sizes = {x: len(image_datasets[x]) for x in [\"train\", \"val\", \"test\"]}\n", + "dataset_sizes = {x: len(image_datasets[x]) for x in [\"train\", \"val\", \"eval\"]}\n", "class_names = image_datasets[\"train\"].classes\n", "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", "\n", @@ -2181,7 +2339,7 @@ "# Download a pre-trained ResNet18 model and freeze its weights\n", "model = torchvision.models.resnet18(pretrained=True)\n", "for param in model.parameters():\n", - " param.requires_grad = False\n", + " param.requires_grad = False \n", "\n", "# Replace the final fully connected layer\n", "# Parameters of newly constructed modules have requires_grad=True by default\n", @@ -2202,7 +2360,7 @@ "# The function eval_model evaluates the model on a different test set\n", "def eval_model(model, criterion):\n", "\n", - " phase = \"test\"\n", + " phase = \"eval\"\n", "\n", " model.eval()\n", "\n", @@ -2244,9 +2402,80 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + "----------\n", + "train Loss: 0.7083 Acc: 0.5984\n", + "val Loss: 0.5109 Acc: 0.7124\n", + "\n", + "Epoch 2/10\n", + "----------\n", + "train Loss: 0.5679 Acc: 0.6967\n", + "val Loss: 0.3589 Acc: 0.8758\n", + "\n", + "Epoch 3/10\n", + "----------\n", + "train Loss: 0.5573 Acc: 0.6762\n", + "val Loss: 0.3162 Acc: 0.8693\n", + "\n", + "Epoch 4/10\n", + "----------\n", + "train Loss: 0.6000 Acc: 0.6762\n", + "val Loss: 0.3620 Acc: 0.8497\n", + "\n", + "Epoch 5/10\n", + "----------\n", + "train Loss: 0.5870 Acc: 0.6721\n", + "val Loss: 0.2739 Acc: 0.9216\n", + "\n", + "Epoch 6/10\n", + "----------\n", + "train Loss: 0.4931 Acc: 0.6844\n", + "val Loss: 0.2464 Acc: 0.9216\n", + "\n", + "Epoch 7/10\n", + "----------\n", + "train Loss: 0.4539 Acc: 0.7787\n", + "val Loss: 0.2249 Acc: 0.9281\n", + "\n", + "Epoch 8/10\n", + "----------\n", + "train Loss: 0.5093 Acc: 0.7295\n", + "val Loss: 0.2308 Acc: 0.9477\n", + "\n", + "Epoch 9/10\n", + "----------\n", + "train Loss: 0.4690 Acc: 0.7500\n", + "val Loss: 0.2339 Acc: 0.9346\n", + "\n", + "Epoch 10/10\n", + "----------\n", + "train Loss: 0.4816 Acc: 0.7172\n", + "val Loss: 0.2278 Acc: 0.9281\n", + "\n", + "Training complete in 8m 6s\n", + "Best val Acc: 0.947712\n", + "Evaluation of the new model :\n", + "eval Loss: 0.2308 Acc: 0.9477\n" + ] + }, + { + "data": { + "text/plain": [ + "(0.23079453324716465, tensor(0.9477, dtype=torch.float64))" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Download a pre-trained ResNet18 model and freeze its weights\n", "model = torchvision.models.resnet18(pretrained=True)\n", @@ -2257,10 +2486,11 @@ "# Parameters of newly constructed modules have requires_grad=True by default\n", "num_ftrs = model.fc.in_features\n", "model.fc = nn.Sequential(\n", - " nn.Linear(num_ftrs, 256), # Adding a new fully connected layer\n", - " nn.ReLU(), # Applying ReLU activation function\n", - " nn.Dropout(0.5), # Dropout layer with p=0.5\n", - " nn.Linear(256, 2) # Final fully connected layer for binary classification\n", + " nn.Linear(num_ftrs, 256), # First fully connected layer\n", + " nn.ReLU(), # ReLU activation function after the first fully connected layer\n", + " nn.Dropout(0.5), # Dropout layer with p=0.5 after the first fully connected layer\n", + " nn.Linear(256, 2), # Second fully connected layer\n", + " nn.Dropout(0.5) # Dropout layer with p=0.5 after the second fully connected layer\n", ")\n", "# Send the model to the GPU\n", "model = model.to(device)\n", @@ -2273,7 +2503,107 @@ "model, epoch_time = train_model(\n", " model, criterion, optimizer_conv, exp_lr_scheduler, num_epochs=10\n", ")\n", - "\n" + "\n", + "# Now we can evaluate the model\n", + "print('Evaluation of the new model :')\n", + "eval_model(model, criterion)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model: int8 \t Size (KB): 45304.25\n" + ] + }, + { + "data": { + "text/plain": [ + "45304250" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print_size_of_model(model, \"int8\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model: int8 \t Size (KB): 44911.014\n" + ] + }, + { + "data": { + "text/plain": [ + "44911014" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import torch.quantization\n", + "\n", + "quantized_model = torch.quantization.quantize_dynamic(model, dtype=torch.qint8)\n", + "print_size_of_model(quantized_model, \"int8\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Evaluation of the quatized model :\n", + "eval Loss: 0.2306 Acc: 0.9477\n" + ] + }, + { + "data": { + "text/plain": [ + "(0.23059894524368585, tensor(0.9477, dtype=torch.float64))" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Now we can evaluate the model\n", + "print('Evaluation of the quatized model :')\n", + "eval_model(quantized_model, criterion)" ] }, {