diff --git a/TD2 Deep Learning.ipynb b/TD2 Deep Learning.ipynb index beeedead715e6462decd75a7c9889807ae984cc7..8818c875f24c4e07041b5ba48f31197392915c10 100644 --- a/TD2 Deep Learning.ipynb +++ b/TD2 Deep Learning.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 2, "id": "330a42f5", "metadata": {}, "outputs": [ @@ -53,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -72,7 +72,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 4, "id": "b1950f0a", "metadata": {}, "outputs": [ @@ -80,40 +80,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "tensor([[ 1.1058e+00, 1.7336e+00, 1.6643e+00, 4.8814e-01, 1.0503e+00,\n", - " 3.3081e-01, 4.2909e-01, 2.5513e-01, 4.4685e-01, 1.2261e+00],\n", - " [ 1.6754e+00, 2.5322e-01, -3.2846e-01, 8.9585e-01, -1.3316e+00,\n", - " 2.3624e-01, 5.5837e-01, 9.2219e-01, 5.8599e-01, 8.2756e-01],\n", - " [-5.0919e-04, 5.2701e-01, 1.6103e+00, -1.1456e+00, -3.3717e-01,\n", - " -1.9402e-01, 8.6480e-01, -1.5003e+00, 8.3813e-01, -1.2842e-01],\n", - " [ 2.1325e+00, 4.6389e-02, 3.8270e-01, -4.7796e-01, 6.9516e-01,\n", - " 4.3799e-01, 1.4166e+00, -9.7244e-01, -4.0094e-02, -2.5280e+00],\n", - " [-1.2872e+00, -3.9930e-01, -8.1700e-01, -1.0437e+00, -1.0481e+00,\n", - " 1.7232e+00, -1.6563e+00, -4.3769e-01, 1.3422e+00, -7.3623e-01],\n", - " [-7.6558e-01, -8.4420e-01, 1.0399e-01, -2.7014e-01, -2.8180e-02,\n", - " -9.6759e-01, -1.1035e-01, 6.1477e-01, -9.9411e-02, -1.2770e+00],\n", - " [ 1.7107e-01, -1.4533e+00, -1.0981e-01, 9.6294e-01, 1.8770e-01,\n", - " 2.1585e-01, 8.4826e-01, 8.2598e-01, 5.2848e-01, -6.2572e-01],\n", - " [-6.8073e-01, 1.5341e+00, 5.4558e-01, 1.1158e+00, 9.1971e-01,\n", - " -1.0714e+00, 1.1650e-01, 5.2230e-01, -9.3863e-01, 5.0782e-01],\n", - " [-8.9026e-02, 1.3079e-01, -1.3377e+00, 7.9199e-01, 1.4043e+00,\n", - " -7.5685e-01, 8.6716e-01, 6.6349e-01, -4.2035e-01, -8.4952e-01],\n", - " [ 3.0876e-01, 1.6299e+00, 1.0647e+00, -6.7523e-01, -2.7187e-01,\n", - " 6.6396e-01, 3.1289e-01, -1.8232e-01, -6.1341e-01, -3.0799e-01],\n", - " [ 1.5986e-01, 4.0908e-01, -1.9692e-02, 1.2336e+00, 1.0539e-01,\n", - " 1.4811e+00, -1.7229e+00, 5.4524e-01, 3.1768e-01, -6.7840e-01],\n", - " [-1.5905e-01, -1.8926e-01, 3.9945e-01, 2.6893e-01, 2.3556e-01,\n", - " 1.1111e+00, 4.4930e-01, -2.0415e-02, 9.0348e-01, 6.3381e-02],\n", - " [-1.3243e+00, 6.9054e-01, 2.4535e-01, 1.2984e+00, -6.0229e-01,\n", - " -8.0071e-01, 4.5005e-02, 1.3536e+00, 5.6984e-01, -1.2901e+00],\n", - " [ 5.6000e-01, 1.6408e-01, 1.2537e+00, -1.4064e+00, 1.0504e+00,\n", - " 5.6275e-01, -1.2924e-01, -4.2453e-01, 1.2955e+00, -1.0917e-01]])\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "tensor([[-1.8074e-01, 1.5241e+00, -1.3546e-01, -1.2838e+00, 2.2640e-01,\n", + " -1.2553e-01, -1.6809e+00, 3.9784e-01, -9.4289e-02, 3.5530e-01],\n", + " [-2.2709e-01, 7.5171e-01, -1.8169e+00, 6.3701e-01, -7.9855e-01,\n", + " 1.5751e+00, -9.2336e-01, -1.8218e-01, -6.2022e-02, -2.6735e+00],\n", + " [-2.3175e-01, 1.2065e-01, 9.2158e-01, 4.0761e-01, 5.0920e-01,\n", + " -2.0830e-01, 5.9477e-01, -2.4526e+00, 1.5291e+00, 1.2228e-01],\n", + " [ 6.3699e-02, 8.3339e-01, -2.4348e-01, -2.7755e+00, -3.5887e-02,\n", + " 4.2460e-01, 1.1398e-01, -8.2430e-01, -6.5116e-01, -1.5914e+00],\n", + " [ 1.8005e+00, 1.0883e+00, 1.3797e+00, -1.8554e-01, 9.3593e-02,\n", + " -4.3051e-01, 2.5463e-01, 2.0544e+00, -2.0729e-01, -1.1623e+00],\n", + " [-2.8985e-01, 2.0965e+00, 9.4812e-01, 5.9547e-01, -1.7109e+00,\n", + " -4.6174e-01, 4.5153e-01, -6.9997e-01, -1.5717e+00, 1.0125e+00],\n", + " [-4.8650e-01, 4.6680e-01, 1.5609e+00, 4.5947e-01, 5.7850e-01,\n", + " -2.8709e-01, -2.5730e-01, 1.0270e+00, -1.7424e+00, 1.7485e+00],\n", + " [ 1.1762e+00, 5.2229e-01, -3.9036e-01, 1.1959e+00, -1.7538e+00,\n", + " -4.4158e-01, -7.4067e-01, 3.9571e-01, 2.0077e+00, -8.1235e-01],\n", + " [-1.6999e+00, -4.1551e-02, 1.3648e+00, -1.2220e+00, -2.0506e-01,\n", + " 7.1548e-01, 3.5882e-01, -1.5645e-01, -5.0942e-01, -6.1326e-02],\n", + " [ 1.6581e+00, -8.4809e-01, 4.7475e-01, -2.2561e+00, 3.8582e-02,\n", + " -1.0277e+00, -6.0917e-01, 1.5007e+00, 1.9578e+00, 2.0218e-01],\n", + " [ 1.4928e+00, 2.2087e-01, 5.0907e-01, -1.5857e+00, -8.4575e-01,\n", + " 8.6924e-01, -8.6839e-01, 6.0105e-01, -3.6015e-01, -6.4565e-01],\n", + " [ 9.0478e-01, -2.6878e-01, -2.1540e-02, 1.2220e+00, 8.8916e-02,\n", + " 7.9812e-01, -1.0435e+00, -4.6728e-01, -1.9995e+00, 1.3223e+00],\n", + " [-8.4984e-01, -3.3195e-01, 1.2790e+00, 2.2619e-02, -1.0025e+00,\n", + " -1.9617e-01, 2.2083e-01, 1.0495e-03, -2.6835e+00, -9.3611e-01],\n", + " [ 1.7703e-01, -1.7832e+00, 2.5483e+00, -2.5165e+00, -2.1459e-01,\n", + " -1.1852e+00, 3.9559e-01, -1.2278e+00, 1.0694e-01, 4.8980e-02]])\n", "AlexNet(\n", " (features): Sequential(\n", " (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))\n", @@ -183,7 +177,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 5, "id": "6e18f2fd", "metadata": {}, "outputs": [ @@ -217,7 +211,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 6, "id": "462666a2", "metadata": {}, "outputs": [ @@ -298,7 +292,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 7, "id": "317bf070", "metadata": {}, "outputs": [ @@ -362,7 +356,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 8, "id": "4b53f229", "metadata": {}, "outputs": [ @@ -370,25 +364,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 0 \tTraining Loss: 45.068168 \tValidation Loss: 41.658336\n", - "Validation loss decreased (inf --> 41.658336). Saving model ...\n", - "Epoch: 1 \tTraining Loss: 36.543189 \tValidation Loss: 33.181536\n", - "Validation loss decreased (41.658336 --> 33.181536). Saving model ...\n", - "Epoch: 2 \tTraining Loss: 31.468431 \tValidation Loss: 29.895601\n", - "Validation loss decreased (33.181536 --> 29.895601). Saving model ...\n", - "Epoch: 3 \tTraining Loss: 28.879008 \tValidation Loss: 27.669525\n", - "Validation loss decreased (29.895601 --> 27.669525). Saving model ...\n", - "Epoch: 4 \tTraining Loss: 26.925435 \tValidation Loss: 26.301845\n", - "Validation loss decreased (27.669525 --> 26.301845). Saving model ...\n", - "Epoch: 5 \tTraining Loss: 25.447193 \tValidation Loss: 25.830709\n", - "Validation loss decreased (26.301845 --> 25.830709). Saving model ...\n", - "Epoch: 6 \tTraining Loss: 24.231406 \tValidation Loss: 24.478850\n", - "Validation loss decreased (25.830709 --> 24.478850). Saving model ...\n", - "Epoch: 7 \tTraining Loss: 23.158099 \tValidation Loss: 25.051581\n", - "Epoch: 8 \tTraining Loss: 22.216344 \tValidation Loss: 23.490295\n", - "Validation loss decreased (24.478850 --> 23.490295). Saving model ...\n", - "Epoch: 9 \tTraining Loss: 21.386869 \tValidation Loss: 22.800535\n", - "Validation loss decreased (23.490295 --> 22.800535). Saving model ...\n" + "Couldn't find program: 'false'\n" ] } ], @@ -398,8 +374,8 @@ "criterion = nn.CrossEntropyLoss() # specify loss function\n", "optimizer = optim.SGD(model.parameters(), lr=0.01) # specify optimizer\n", "\n", - "n_epochs = 10 # number of epochs to train the model\n", - "train_loss_list = [] # list to store loss to visualize\n", + "n_epochs = 20 # number of epochs to train the model\n", + "train_loss_list_Net = [] # 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", @@ -442,7 +418,7 @@ " # 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", + " train_loss_list_Net.append(train_loss)\n", "\n", " # Print training/validation statistics\n", " print(\n", @@ -472,25 +448,22 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 10, "id": "d39df818", "metadata": {}, "outputs": [ { - "data": { - "image/png": "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", - "text/plain": [ - "<Figure size 640x480 with 1 Axes>" - ] - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "Couldn't find program: 'false'\n" + ] } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", - "plt.plot(range(n_epochs), train_loss_list)\n", + "plt.plot(range(n_epochs), train_loss_list_Net)\n", "plt.xlabel(\"Epoch\")\n", "plt.ylabel(\"Loss\")\n", "plt.title(\"Performance of Model 1\")\n", @@ -507,7 +480,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 12, "id": "e93efdfc", "metadata": {}, "outputs": [ @@ -533,12 +506,12 @@ } ], "source": [ - "model.load_state_dict(torch.load(\"./model_cifar.pt\"))\n", + "model.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", + "class_correct_NET = list(0.0 for i in range(10))\n", + "class_total_NET = list(0.0 for i in range(10))\n", "\n", "import torch.optim as optim\n", "\n", @@ -570,22 +543,22 @@ " # 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", + " class_correct_NET[label] += correct[i].item()\n", + " class_total_NET[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", + " if class_total_NET[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", + " 100 * class_correct_NET[i] / class_total_NET[i],\n", + " np.sum(class_correct_NET[i]),\n", + " np.sum(class_total_NET[i]),\n", " )\n", " )\n", " else:\n", @@ -594,9 +567,9 @@ "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", + " 100.0 * np.sum(class_correct_NET) / np.sum(class_total_NET),\n", + " np.sum(class_correct_NET),\n", + " np.sum(class_total_NET),\n", " )\n", ")" ] @@ -620,7 +593,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -652,49 +625,14 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "newNet(\n", - " (conv1): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1))\n", - " (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n", - " (conv2): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1))\n", - " (conv3): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))\n", - " (fc1): Linear(in_features=256, 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.5, inplace=False)\n", - ")\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch: 0 \tTraining Loss: 45.997170 \tValidation Loss: 45.813581\n", - "Validation loss decreased (inf --> 45.813581). Saving model ...\n", - "Epoch: 1 \tTraining Loss: 43.447996 \tValidation Loss: 39.434123\n", - "Validation loss decreased (45.813581 --> 39.434123). Saving model ...\n", - "Epoch: 2 \tTraining Loss: 37.817678 \tValidation Loss: 33.835315\n", - "Validation loss decreased (39.434123 --> 33.835315). Saving model ...\n", - "Epoch: 3 \tTraining Loss: 34.411652 \tValidation Loss: 32.083492\n", - "Validation loss decreased (33.835315 --> 32.083492). Saving model ...\n", - "Epoch: 4 \tTraining Loss: 32.522201 \tValidation Loss: 29.788260\n", - "Validation loss decreased (32.083492 --> 29.788260). Saving model ...\n", - "Epoch: 5 \tTraining Loss: 30.807354 \tValidation Loss: 28.055189\n", - "Validation loss decreased (29.788260 --> 28.055189). Saving model ...\n", - "Epoch: 6 \tTraining Loss: 29.412794 \tValidation Loss: 27.665930\n", - "Validation loss decreased (28.055189 --> 27.665930). Saving model ...\n", - "Epoch: 7 \tTraining Loss: 28.139727 \tValidation Loss: 25.605682\n", - "Validation loss decreased (27.665930 --> 25.605682). Saving model ...\n", - "Epoch: 8 \tTraining Loss: 27.044169 \tValidation Loss: 25.173172\n", - "Validation loss decreased (25.605682 --> 25.173172). Saving model ...\n", - "Epoch: 9 \tTraining Loss: 25.927621 \tValidation Loss: 23.948350\n", - "Validation loss decreased (25.173172 --> 23.948350). Saving model ...\n" + "Couldn't find program: 'false'\n" ] } ], @@ -712,8 +650,8 @@ " criterion = nn.CrossEntropyLoss() # specify loss function\n", " optimizer = optim.SGD(model.parameters(), lr=0.01) # specify optimizer\n", "\n", - " n_epochs = 10 # number of epochs to train the model\n", - " train_loss_list = [] # list to store loss to visualize\n", + " n_epochs = 20 # number of epochs to train the model\n", + " train_loss_list_newNet = [] # 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", @@ -756,7 +694,7 @@ " # 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", + " train_loss_list_newNet.append(train_loss)\n", "\n", " # Print training/validation statistics\n", " print(\n", @@ -778,37 +716,91 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Test Loss: 23.851512\n", - "\n", - "Test Accuracy of airplane: 53% (537/1000)\n", - "Test Accuracy of automobile: 65% (658/1000)\n", - "Test Accuracy of bird: 41% (413/1000)\n", - "Test Accuracy of cat: 43% (439/1000)\n", - "Test Accuracy of deer: 33% (338/1000)\n", - "Test Accuracy of dog: 39% (395/1000)\n", - "Test Accuracy of frog: 82% (826/1000)\n", - "Test Accuracy of horse: 57% (575/1000)\n", - "Test Accuracy of ship: 76% (769/1000)\n", - "Test Accuracy of truck: 76% (762/1000)\n", - "\n", - "Test Accuracy (Overall): 57% (5712/10000)\n" + "Couldn't find program: 'false'\n" ] } ], "source": [ - "model.load_state_dict(torch.load(\"./my_model_cifar.pt\"))\n", + "import matplotlib.pyplot as plt\n", + "\n", + "plt.plot(range(n_epochs), train_loss_list_Net,label='Net')\n", + "plt.plot(range(n_epochs), train_loss_list_newNet,label='newNet')\n", + "plt.xlabel(\"Epoch\")\n", + "plt.ylabel(\"Loss\")\n", + "plt.title(\"Performance of Model 1\")\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAdwAAAGFCAYAAABXIkLKAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAACAaUlEQVR4nOzdd3hUZdrH8e+ZnplMeu8dQiAQei8KCAhYsGLX3VVfu7vuuta1oau7rmsva18LiCgqKr0J0nsJgZAQSO89k8zMef84JAsCSglp3J/rmkuZzJx5ZiaZ3zzl3I+iqqqKEEIIIc4qXXs3QAghhDgXSOAKIYQQbUACVwghhGgDErhCCCFEG5DAFUIIIdqABK4QQgjRBiRwhRBCiDYggSuEEEK0AQlcIYQQog1I4AohhBBtQAJXCCGEaAMSuEIIIUQbkMAVQggh2oAErhBCCNEGJHCFEEKINiCBK4QQQrQBCVzRJTidTqqrq1suNTU1NDQ04Ha7z+i4LpeLl156if79+zNgwABWrVrVSi3umlRVJTMzk9tuu42UlBQmTJhAfX39Ubdxu93U1dVRXV2N0+k85v41NTXU1NQc87NTUVBQwLBhw1i9evVJ3b6wsJC0tDSWL19+wts0Nja2tLuuru6Mf7fEuUcCV3QJy5YtIyYmhp49e9KvXz+GDRvG1VdfzerVq8/og3HlypXMmDGDq6++mueee47u3bu3Yqu7HofDwQcffMCuXbt4+OGHeeSRRzCZTEfd5uDBg1x++eV4e3sze/ZsVFVt+VlpaSmxsbGkpKSwaNGi026Hy+WiuLiYxsbGk759UVHRr95+xowZTJgwgfj4eC699FIOHTp02u0T5yZDezdAiNZiNBp5/vnniY6OpqCggFdffZU777yTb7/9lsjIyFM6VnNIb9u2DavVyr333oterz/lNqmqitvtRqfToSjKKd+/s6muriY7O5sLLriASy+9FIvFcsLbRkRE8Pnnn3PFFVe0vDY//PADOp0ODw+Po4K4I3A4HIwcOZKoqChKSkrauzmiE5LAFV2GTqejZ8+epKSkANDU1MTdd9/Njh07iIyMZNu2bcyePZvc3FzCwsK4/PLLSUlJQa/Xs2nTJr766isuuugivv/+e2pqajAajfzwww+UlpZyww030Lt3b2666Sa8vb2ZNWsWq1evRlVVBgwYwPTp0zGbzQC89tprNDY2kpqayrfffktycjIDBw7ko48+YurUqaxZs4asrCwGDBjAtddey+7du/niiy8oKytj0qRJTJ48Gb1ej9vtZsGCBfz0008UFBTg5eXF1KlTGT16dMtzfvzxx4mKiiIwMJD58+djNBq55pprGDBgAKAFfnl5OZ999hnbt29Hp9ORmprKddddh81mw+VysWjRIn788UdqampITk5m+vTpBAcHn/ALwv79+5k9ezZ79uwhMDCQqVOnMmDAAJqamnj22WdZsWIFO3fuZPfu3Vx88cVcdtllxz3OpEmT+PHHH8nMzCQxMRGXy8XMmTOZMGECW7dubbmdqqpkZ2czc+ZM9u3bh7+/PxdffDGDBw9GURRUVaWsrIyPPvqI3bt3Ex0dzeTJk496rOah7lmzZrF//358fX257LLLGDRo0En/fj366KOYTCbee+895syZc9L3E6KZDCmLLqe5V+lwOFAUBb1ez6pVq7jtttvYvXs3YWFhbN68md/97ndkZ2ejqiqHDh1i9uzZ/P73v6ewsJCwsDAiIyMJCQnBbDbTu3dv4uLiMBqN/P3vf+fRRx9tmSN++umn+dvf/tbSI1u1ahXvvPMOTz75JB4eHnh5eVFUVMS7777LjBkzOHjwIIqi8NRTT/HXv/6VV199FZfLRUlJCY899ljLvKPL5eKNN96grKyM8PBwsrKyuP3221myZEnLc/3+++95+eWXeffdd/Hx8WHTpk3cfffd5OfnA1BfX89NN93E66+/jtlsxtvbm++++46CggLcbjfvvvsuf/zjH2loaMDf358vvviCe+6555h51+bXdf/+/TzwwAPMmjWLwMBA0tPTue2221i7di06nY7Y2Fh8fHwICwujV69ehISEnPB96tmzJ3FxcXz33XeoqsqOHTtIT0/niiuuOOoxS0pKuO222/jmm2/w8/Nj586d3HHHHSxatAhVVXG5XPz1r3/lP//5D2azmT179vDHP/7xqMc6dOgQ1113HatWrSI0NJT9+/dz6623snz58pPuSVut1nNilEKcRaoQXcDChQvV4OBg9fPPP1dXr16tfvzxx2pKSoo6cuRINTs7W73pppvUu+++W62qqlIdDoeal5enXnDBBeoDDzygut1ude7cuWpISIj67LPPqg6HQ3U6narL5VKfeeYZNS4uTnW5XKrL5VLT09PVqKgo9YUXXlCb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y4WqqhQWFuLt7d2uK/dVVSUvL69lo4JnnnnmhPOyR74XzXOHDQ0NHeL9OLJtNpsNl8t11NkFoI3yhISEkJ6eDmjPfd++fcTFxbVHk48xf/583G4348ePP+ECriOfp16vx2q1dqhRw9YigXuY1Wpl0KBBzJo1i927d/Pf//6XkpISRowYwZIlS/jggw9wOp3ExMRgsVj4+uuv2bdvH19++SVGo7FdF0yBNif40ksvsXv3bm6++WbsdjtVVVUt33o/+eQTvvrqKwC2bt3K6tWrycvLY926dcyZM4fk5OSzvsDl19TV1fH111+TlZVFZmYmL730Enq9nh49ejB//nw++ugj3G43SUlJuN3uo15/Ly+vDjP0pKoqM2fOZNiwYS29WIAPPviA7777DtACee3ateTl5bF69Wq+/fZb+vTp0y4L1xobGzl48CCHDh3C4XBw6NAhCgsLCQ4OJjY2ls8//5yMjAzefPNNzGZzyyrSN954gyVLlqDT6Rg2bBgbNmxg6dKlbN26lXnz5tG/f/826a03NjaSk5NDbm4uDQ0NLe2vqKjg2WefpaKigptuugmDwdDy5Qzg1VdfZdmyZQCsXbuWtWvXkp+fz7Jly5g/fz59+vRps4VT9fX1ZGVlUVJSQlVVFQcOHKCkpIR9+/axdOlS8vLy2LRpE++99x4JCQkEBATgdDp5/vnn2bZtGzqdjmnTpvHf//6XdevWsXjxYlatWsXUqVPbtP2lpaUt7S8rKwO092fmzJlMnToVf3//lvs0NjbywgsvsGPHDgC++eYbdu3axaFDh5g1axY7d+48amSry1CFqqqq6na71T179qg33nij2rNnT3XMmDHq4sWLVZfLpb7yyivqTTfdpDY0NKhOp1NdvXq1Om3aNDUlJUWdNm2a+vPPP6sul6td219SUqL6+fmpAQEBanx8vJqYmKiOHj1a3bhxo6qqqnr77berDz30kKqqqjpv3jx1woQJakpKijp8+HD1b3/7m3rw4EHV7Xa3W/vLy8vVadOmqb1791b79eunXnPNNermzZtVl8ulPv/88+rvfvc7tampSXU6neqyZcvUqVOnqikpKepVV12lbtiwod1f/2ZZWVnqsGHD1OXLlx/1et50003qE088oaqqqn755Zfq2LFj1ZSUFHXEiBHqM888o+bn57fL67937151xIgRalRUlGq329Wo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", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import matplotlib.image as mpimg\n", + "\n", + "# Chemin vers l'image\n", + "image_path = \"result/comparaison_loss_models.png\"\n", + "\n", + "# Charger l'image avec Matplotlib\n", + "img = mpimg.imread(image_path)\n", "\n", + "# Afficher l'image\n", + "plt.imshow(img)\n", + "plt.axis('off') # Masquer les axes\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Attempting to deserialize object on a CUDA device but torch.cuda.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Users\\Utilisateur\\Documents\\GitHub\\image-classification\\TD2 Deep Learning.ipynb Cell 26\u001b[0m line \u001b[0;36m1\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X32sZmlsZQ%3D%3D?line=0'>1</a>\u001b[0m model\u001b[39m.\u001b[39mload_state_dict(torch\u001b[39m.\u001b[39mload(\u001b[39m\"\u001b[39m\u001b[39mmy_model_cifar.pt\u001b[39m\u001b[39m\"\u001b[39m))\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X32sZmlsZQ%3D%3D?line=1'>2</a>\u001b[0m \u001b[39m# track test loss\u001b[39;00m\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X32sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m test_loss \u001b[39m=\u001b[39m \u001b[39m0.0\u001b[39m\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:1014\u001b[0m, in \u001b[0;36mload\u001b[1;34m(f, map_location, pickle_module, weights_only, mmap, **pickle_load_args)\u001b[0m\n\u001b[0;32m 1012\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[0;32m 1013\u001b[0m \u001b[39mraise\u001b[39;00m pickle\u001b[39m.\u001b[39mUnpicklingError(UNSAFE_MESSAGE \u001b[39m+\u001b[39m \u001b[39mstr\u001b[39m(e)) \u001b[39mfrom\u001b[39;00m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m-> 1014\u001b[0m \u001b[39mreturn\u001b[39;00m _load(opened_zipfile,\n\u001b[0;32m 1015\u001b[0m map_location,\n\u001b[0;32m 1016\u001b[0m pickle_module,\n\u001b[0;32m 1017\u001b[0m overall_storage\u001b[39m=\u001b[39moverall_storage,\n\u001b[0;32m 1018\u001b[0m \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mpickle_load_args)\n\u001b[0;32m 1019\u001b[0m \u001b[39mif\u001b[39;00m mmap:\n\u001b[0;32m 1020\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39mmmap can only be used with files saved with \u001b[39m\u001b[39m\"\u001b[39m,\n\u001b[0;32m 1021\u001b[0m \u001b[39m\"\u001b[39m\u001b[39m`torch.save(_use_new_zipfile_serialization=True), \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 1022\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mplease torch.save your checkpoint with this option in order to use mmap.\u001b[39m\u001b[39m\"\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:1422\u001b[0m, in \u001b[0;36m_load\u001b[1;34m(zip_file, map_location, pickle_module, pickle_file, overall_storage, **pickle_load_args)\u001b[0m\n\u001b[0;32m 1420\u001b[0m unpickler \u001b[39m=\u001b[39m UnpicklerWrapper(data_file, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mpickle_load_args)\n\u001b[0;32m 1421\u001b[0m unpickler\u001b[39m.\u001b[39mpersistent_load \u001b[39m=\u001b[39m persistent_load\n\u001b[1;32m-> 1422\u001b[0m result \u001b[39m=\u001b[39m unpickler\u001b[39m.\u001b[39mload()\n\u001b[0;32m 1424\u001b[0m torch\u001b[39m.\u001b[39m_utils\u001b[39m.\u001b[39m_validate_loaded_sparse_tensors()\n\u001b[0;32m 1425\u001b[0m torch\u001b[39m.\u001b[39m_C\u001b[39m.\u001b[39m_log_api_usage_metadata(\n\u001b[0;32m 1426\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mtorch.load.metadata\u001b[39m\u001b[39m\"\u001b[39m, {\u001b[39m\"\u001b[39m\u001b[39mserialization_id\u001b[39m\u001b[39m\"\u001b[39m: zip_file\u001b[39m.\u001b[39mserialization_id()}\n\u001b[0;32m 1427\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:1392\u001b[0m, in \u001b[0;36m_load.<locals>.persistent_load\u001b[1;34m(saved_id)\u001b[0m\n\u001b[0;32m 1390\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 1391\u001b[0m nbytes \u001b[39m=\u001b[39m numel \u001b[39m*\u001b[39m torch\u001b[39m.\u001b[39m_utils\u001b[39m.\u001b[39m_element_size(dtype)\n\u001b[1;32m-> 1392\u001b[0m typed_storage \u001b[39m=\u001b[39m load_tensor(dtype, nbytes, key, _maybe_decode_ascii(location))\n\u001b[0;32m 1394\u001b[0m \u001b[39mreturn\u001b[39;00m typed_storage\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:1366\u001b[0m, in \u001b[0;36m_load.<locals>.load_tensor\u001b[1;34m(dtype, numel, key, location)\u001b[0m\n\u001b[0;32m 1361\u001b[0m storage\u001b[39m.\u001b[39mbyteswap(dtype)\n\u001b[0;32m 1363\u001b[0m \u001b[39m# TODO: Once we decide to break serialization FC, we can\u001b[39;00m\n\u001b[0;32m 1364\u001b[0m \u001b[39m# stop wrapping with TypedStorage\u001b[39;00m\n\u001b[0;32m 1365\u001b[0m typed_storage \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mstorage\u001b[39m.\u001b[39mTypedStorage(\n\u001b[1;32m-> 1366\u001b[0m wrap_storage\u001b[39m=\u001b[39mrestore_location(storage, location),\n\u001b[0;32m 1367\u001b[0m dtype\u001b[39m=\u001b[39mdtype,\n\u001b[0;32m 1368\u001b[0m _internal\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n\u001b[0;32m 1370\u001b[0m \u001b[39mif\u001b[39;00m typed_storage\u001b[39m.\u001b[39m_data_ptr() \u001b[39m!=\u001b[39m \u001b[39m0\u001b[39m:\n\u001b[0;32m 1371\u001b[0m loaded_storages[key] \u001b[39m=\u001b[39m typed_storage\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:381\u001b[0m, in \u001b[0;36mdefault_restore_location\u001b[1;34m(storage, location)\u001b[0m\n\u001b[0;32m 379\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdefault_restore_location\u001b[39m(storage, location):\n\u001b[0;32m 380\u001b[0m \u001b[39mfor\u001b[39;00m _, _, fn \u001b[39min\u001b[39;00m _package_registry:\n\u001b[1;32m--> 381\u001b[0m result \u001b[39m=\u001b[39m fn(storage, location)\n\u001b[0;32m 382\u001b[0m \u001b[39mif\u001b[39;00m result \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m 383\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:274\u001b[0m, in \u001b[0;36m_cuda_deserialize\u001b[1;34m(obj, location)\u001b[0m\n\u001b[0;32m 272\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_cuda_deserialize\u001b[39m(obj, location):\n\u001b[0;32m 273\u001b[0m \u001b[39mif\u001b[39;00m location\u001b[39m.\u001b[39mstartswith(\u001b[39m'\u001b[39m\u001b[39mcuda\u001b[39m\u001b[39m'\u001b[39m):\n\u001b[1;32m--> 274\u001b[0m device \u001b[39m=\u001b[39m validate_cuda_device(location)\n\u001b[0;32m 275\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mgetattr\u001b[39m(obj, \u001b[39m\"\u001b[39m\u001b[39m_torch_load_uninitialized\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39mFalse\u001b[39;00m):\n\u001b[0;32m 276\u001b[0m \u001b[39mwith\u001b[39;00m torch\u001b[39m.\u001b[39mcuda\u001b[39m.\u001b[39mdevice(device):\n", + "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\serialization.py:258\u001b[0m, in \u001b[0;36mvalidate_cuda_device\u001b[1;34m(location)\u001b[0m\n\u001b[0;32m 255\u001b[0m device \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mcuda\u001b[39m.\u001b[39m_utils\u001b[39m.\u001b[39m_get_device_index(location, \u001b[39mTrue\u001b[39;00m)\n\u001b[0;32m 257\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m torch\u001b[39m.\u001b[39mcuda\u001b[39m.\u001b[39mis_available():\n\u001b[1;32m--> 258\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m'\u001b[39m\u001b[39mAttempting to deserialize object on a CUDA \u001b[39m\u001b[39m'\u001b[39m\n\u001b[0;32m 259\u001b[0m \u001b[39m'\u001b[39m\u001b[39mdevice but torch.cuda.is_available() is False. \u001b[39m\u001b[39m'\u001b[39m\n\u001b[0;32m 260\u001b[0m \u001b[39m'\u001b[39m\u001b[39mIf you are running on a CPU-only machine, \u001b[39m\u001b[39m'\u001b[39m\n\u001b[0;32m 261\u001b[0m \u001b[39m'\u001b[39m\u001b[39mplease use torch.load with map_location=torch.device(\u001b[39m\u001b[39m\\'\u001b[39;00m\u001b[39mcpu\u001b[39m\u001b[39m\\'\u001b[39;00m\u001b[39m) \u001b[39m\u001b[39m'\u001b[39m\n\u001b[0;32m 262\u001b[0m \u001b[39m'\u001b[39m\u001b[39mto map your storages to the CPU.\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 263\u001b[0m device_count \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mcuda\u001b[39m.\u001b[39mdevice_count()\n\u001b[0;32m 264\u001b[0m \u001b[39mif\u001b[39;00m device \u001b[39m>\u001b[39m\u001b[39m=\u001b[39m device_count:\n", + "\u001b[1;31mRuntimeError\u001b[0m: Attempting to deserialize object on a CUDA device but torch.cuda.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU." + ] + } + ], + "source": [ + "model.load_state_dict(torch.load(\"my_model_cifar.pt\"))\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", + "class_correct_newNET = list(0.0 for i in range(10))\n", + "class_total_newNET = list(0.0 for i in range(10))\n", "\n", "import torch.optim as optim\n", "\n", @@ -840,22 +832,22 @@ " # 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", + " class_correct_newNET[label] += correct[i].item()\n", + " class_total_newNET[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", + " if class_total_newNET[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", + " 100 * class_correct_newNET[i] / class_total_newNET[i],\n", + " np.sum(class_correct_newNET[i]),\n", + " np.sum(class_total_newNET[i]),\n", " )\n", " )\n", " else:\n", @@ -864,100 +856,39 @@ "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", + " 100.0 * np.sum(class_correct_newNET) / np.sum(class_total_newNET),\n", + " np.sum(class_correct_newNET),\n", + " np.sum(class_total_newNET),\n", " )\n", ")" ] }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 25, "metadata": {}, "outputs": [ { - "ename": "RuntimeError", - "evalue": "Error(s) in loading state_dict for newNet:\n\tMissing key(s) in state_dict: \"conv3.weight\", \"conv3.bias\". \n\tsize mismatch for conv1.weight: copying a param with shape torch.Size([6, 3, 5, 5]) from checkpoint, the shape in current model is torch.Size([16, 3, 3, 3]).\n\tsize mismatch for conv1.bias: copying a param with shape torch.Size([6]) from checkpoint, the shape in current model is torch.Size([16]).\n\tsize mismatch for conv2.weight: copying a param with shape torch.Size([16, 6, 5, 5]) from checkpoint, the shape in current model is torch.Size([32, 16, 3, 3]).\n\tsize mismatch for conv2.bias: copying a param with shape torch.Size([16]) from checkpoint, the shape in current model is torch.Size([32]).\n\tsize mismatch for fc1.weight: copying a param with shape torch.Size([120, 400]) from checkpoint, the shape in current model is torch.Size([512, 256]).\n\tsize mismatch for fc1.bias: copying a param with shape torch.Size([120]) from checkpoint, the shape in current model is torch.Size([512]).\n\tsize mismatch for fc2.weight: copying a param with shape torch.Size([84, 120]) from checkpoint, the shape in current model is torch.Size([64, 512]).\n\tsize mismatch for fc2.bias: copying a param with shape torch.Size([84]) from checkpoint, the shape in current model is torch.Size([64]).\n\tsize mismatch for fc3.weight: copying a param with shape torch.Size([10, 84]) from checkpoint, the shape in current model is torch.Size([10, 64]).", + "ename": "NameError", + "evalue": "name 'class_correct_newNET' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32mc:\\Users\\Utilisateur\\Documents\\GitHub\\image-classification\\TD2 Deep Learning.ipynb Cell 25\u001b[0m line \u001b[0;36m1\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X56sZmlsZQ%3D%3D?line=10'>11</a>\u001b[0m model1 \u001b[39m=\u001b[39m newNet() \u001b[39m# Remplacez Net par le type de modèle que vous utilisez\u001b[39;00m\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X56sZmlsZQ%3D%3D?line=11'>12</a>\u001b[0m model2 \u001b[39m=\u001b[39m newNet() \u001b[39m# Assurez-vous que les deux modèles ont la même architecture\u001b[39;00m\n\u001b[1;32m---> <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X56sZmlsZQ%3D%3D?line=13'>14</a>\u001b[0m model1\u001b[39m.\u001b[39mload_state_dict(torch\u001b[39m.\u001b[39mload(model_path1))\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X56sZmlsZQ%3D%3D?line=14'>15</a>\u001b[0m model2\u001b[39m.\u001b[39mload_state_dict(torch\u001b[39m.\u001b[39mload(model_path2))\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X56sZmlsZQ%3D%3D?line=16'>17</a>\u001b[0m \u001b[39m# Mettez les modèles en mode évaluation\u001b[39;00m\n", - "File \u001b[1;32mc:\\Users\\Utilisateur\\anaconda3\\Lib\\site-packages\\torch\\nn\\modules\\module.py:2152\u001b[0m, in \u001b[0;36mModule.load_state_dict\u001b[1;34m(self, state_dict, strict, assign)\u001b[0m\n\u001b[0;32m 2147\u001b[0m error_msgs\u001b[39m.\u001b[39minsert(\n\u001b[0;32m 2148\u001b[0m \u001b[39m0\u001b[39m, \u001b[39m'\u001b[39m\u001b[39mMissing key(s) in state_dict: \u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m. \u001b[39m\u001b[39m'\u001b[39m\u001b[39m.\u001b[39mformat(\n\u001b[0;32m 2149\u001b[0m \u001b[39m'\u001b[39m\u001b[39m, \u001b[39m\u001b[39m'\u001b[39m\u001b[39m.\u001b[39mjoin(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m{\u001b[39;00mk\u001b[39m}\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m'\u001b[39m \u001b[39mfor\u001b[39;00m k \u001b[39min\u001b[39;00m missing_keys)))\n\u001b[0;32m 2151\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(error_msgs) \u001b[39m>\u001b[39m \u001b[39m0\u001b[39m:\n\u001b[1;32m-> 2152\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m'\u001b[39m\u001b[39mError(s) in loading state_dict for \u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m:\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m{}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m.\u001b[39mformat(\n\u001b[0;32m 2153\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__class__\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mjoin(error_msgs)))\n\u001b[0;32m 2154\u001b[0m \u001b[39mreturn\u001b[39;00m _IncompatibleKeys(missing_keys, unexpected_keys)\n", - "\u001b[1;31mRuntimeError\u001b[0m: Error(s) in loading state_dict for newNet:\n\tMissing key(s) in state_dict: \"conv3.weight\", \"conv3.bias\". \n\tsize mismatch for conv1.weight: copying a param with shape torch.Size([6, 3, 5, 5]) from checkpoint, the shape in current model is torch.Size([16, 3, 3, 3]).\n\tsize mismatch for conv1.bias: copying a param with shape torch.Size([6]) from checkpoint, the shape in current model is torch.Size([16]).\n\tsize mismatch for conv2.weight: copying a param with shape torch.Size([16, 6, 5, 5]) from checkpoint, the shape in current model is torch.Size([32, 16, 3, 3]).\n\tsize mismatch for conv2.bias: copying a param with shape torch.Size([16]) from checkpoint, the shape in current model is torch.Size([32]).\n\tsize mismatch for fc1.weight: copying a param with shape torch.Size([120, 400]) from checkpoint, the shape in current model is torch.Size([512, 256]).\n\tsize mismatch for fc1.bias: copying a param with shape torch.Size([120]) from checkpoint, the shape in current model is torch.Size([512]).\n\tsize mismatch for fc2.weight: copying a param with shape torch.Size([84, 120]) from checkpoint, the shape in current model is torch.Size([64, 512]).\n\tsize mismatch for fc2.bias: copying a param with shape torch.Size([84]) from checkpoint, the shape in current model is torch.Size([64]).\n\tsize mismatch for fc3.weight: copying a param with shape torch.Size([10, 84]) from checkpoint, the shape in current model is torch.Size([10, 64])." + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Users\\Utilisateur\\Documents\\GitHub\\image-classification\\TD2 Deep Learning.ipynb Cell 27\u001b[0m line \u001b[0;36m8\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m \u001b[39m# Plotting\u001b[39;00m\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m labels \u001b[39m=\u001b[39m [\u001b[39m\"\u001b[39m\u001b[39mModel 1\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mModel 2\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=5'>6</a>\u001b[0m accuracy_overall \u001b[39m=\u001b[39m [\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=6'>7</a>\u001b[0m \u001b[39m100.0\u001b[39m \u001b[39m*\u001b[39m np\u001b[39m.\u001b[39msum(class_correct_NET) \u001b[39m/\u001b[39m np\u001b[39m.\u001b[39msum(class_total_NET),\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=7'>8</a>\u001b[0m \u001b[39m100.0\u001b[39m \u001b[39m*\u001b[39m np\u001b[39m.\u001b[39msum(class_correct_newNET) \u001b[39m/\u001b[39m np\u001b[39m.\u001b[39msum(class_total_newNET),\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=8'>9</a>\u001b[0m ]\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=10'>11</a>\u001b[0m plt\u001b[39m.\u001b[39mbar(labels, accuracy_overall)\n\u001b[0;32m <a href='vscode-notebook-cell:/c%3A/Users/Utilisateur/Documents/GitHub/image-classification/TD2%20Deep%20Learning.ipynb#X33sZmlsZQ%3D%3D?line=11'>12</a>\u001b[0m plt\u001b[39m.\u001b[39mxlabel(\u001b[39m\"\u001b[39m\u001b[39mModels\u001b[39m\u001b[39m\"\u001b[39m)\n", + "\u001b[1;31mNameError\u001b[0m: name 'class_correct_newNET' is not defined" ] } ], "source": [ - "import torch\n", - "import torch.nn as nn\n", - "import torch.optim as optim\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "# Charger les modèles\n", - "model_path1 = \"./model_cifar.pt\"\n", - "model_path2 = \"./my_model_cifar.pt\"\n", - "\n", - "model1 = Net() # Remplacez Net par le type de modèle que vous utilisez\n", - "model2 = newNet() # Assurez-vous que les deux modèles ont la même architecture\n", - "\n", - "model1.load_state_dict(torch.load(model_path1))\n", - "model2.load_state_dict(torch.load(model_path2))\n", - "\n", - "# Mettez les modèles en mode évaluation\n", - "model1.eval()\n", - "model2.eval()\n", - "\n", - "# Initialiser les variables pour le suivi des performances\n", - "test_loss = [0.0, 0.0] # Liste pour stocker les pertes de test pour chaque modèle\n", - "class_correct = [list(0.0 for i in range(10)), list(0.0 for i in range(10))]\n", - "class_total = [list(0.0 for i in range(10)), list(0.0 for i in range(10))]\n", - "\n", - "# Définir le critère et l'optimiseur\n", - "criterion = nn.CrossEntropyLoss()\n", - "\n", - "# Boucle sur le jeu de données de test\n", - "for model_num, model in enumerate([model1, model2]):\n", - " for data, target in test_loader:\n", - " if train_on_gpu:\n", - " data, target = data.cuda(), target.cuda()\n", - " output = model(data)\n", - " loss = criterion(output, target)\n", - " test_loss[model_num] += loss.item() * data.size(0)\n", - "\n", - " _, pred = torch.max(output, 1)\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", - "\n", - " for i in range(batch_size):\n", - " label = target.data[i]\n", - " class_correct[model_num][label] += correct[i].item()\n", - " class_total[model_num][label] += 1\n", - "\n", - " test_loss[model_num] = test_loss[model_num] / len(test_loader)\n", - "\n", - "# Afficher les performances de chaque modèle\n", - "for model_num, model in enumerate([\"Model 1\", \"Model 2\"]):\n", - " print(f\"\\n{model} Test Loss: {test_loss[model_num]:.6f}\\n\")\n", - " for i in range(10):\n", - " if class_total[model_num][i] > 0:\n", - " print(\n", - " f\"Test Accuracy of {classes[i]}: {100 * class_correct[model_num][i] / class_total[model_num][i]:.2f}%\"\n", - " )\n", - " else:\n", - " print(f\"Test Accuracy of {classes[i]}: N/A (no training examples)\")\n", - "\n", "# Plotting\n", "labels = [\"Model 1\", \"Model 2\"]\n", "accuracy_overall = [\n", - " 100.0 * np.sum(class_correct[0]) / np.sum(class_total[0]),\n", - " 100.0 * np.sum(class_correct[1]) / np.sum(class_total[1]),\n", + " 100.0 * np.sum(class_correct_NET) / np.sum(class_total_NET),\n", + " 100.0 * np.sum(class_correct_newNET) / np.sum(class_total_newNET),\n", "]\n", "\n", "plt.bar(labels, accuracy_overall)\n", @@ -969,7 +900,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -987,7 +918,7 @@ "model_path1 = \"./model_cifar.pt\"\n", "model_path2 = \"./my_model_cifar.pt\"\n", "\n", - "model1 = newNet() # Remplacez Net par le type de modèle que vous utilisez\n", + "model1 = Net() # Remplacez Net par le type de modèle que vous utilisez\n", "model1.load_state_dict(torch.load(model_path1))\n", "\n", "\n", diff --git a/result/comparaison_loss_models.png b/result/comparaison_loss_models.png new file mode 100644 index 0000000000000000000000000000000000000000..f3507aeab18f8210449bdad028ceb1fc7974f7e9 Binary files /dev/null and b/result/comparaison_loss_models.png differ