"c:\\Users\\ZINEB\\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",
"Downloading: \"https://download.pytorch.org/models/resnet18-f37072fd.pth\" to C:\\Users\\ZINEB/.cache\\torch\\hub\\checkpoints\\resnet18-f37072fd.pth\n",
"c:\\Users\\ZINEB\\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.6227 Acc: 0.6680\n",
"val Loss: 0.3421 Acc: 0.8758\n",
"\n",
"Epoch 2/10\n",
"----------\n",
"train Loss: 0.7198 Acc: 0.7090\n",
"val Loss: 0.1835 Acc: 0.9477\n",
"\n",
"Epoch 3/10\n",
"----------\n",
"train Loss: 0.5178 Acc: 0.7746\n",
"val Loss: 0.1933 Acc: 0.9412\n",
"\n",
"Epoch 4/10\n",
"----------\n",
"train Loss: 0.4848 Acc: 0.8074\n",
"val Loss: 0.2029 Acc: 0.9281\n",
"\n",
"Epoch 5/10\n",
"----------\n",
"train Loss: 0.5139 Acc: 0.8074\n",
"val Loss: 0.2291 Acc: 0.9150\n",
"\n",
"Epoch 6/10\n",
"----------\n",
"train Loss: 0.5792 Acc: 0.8033\n",
"val Loss: 0.1806 Acc: 0.9412\n",
"\n",
"Epoch 7/10\n",
"----------\n",
"train Loss: 0.3262 Acc: 0.8607\n",
"val Loss: 0.2058 Acc: 0.9412\n",
"\n",
"Epoch 8/10\n",
"----------\n",
"train Loss: 0.3552 Acc: 0.8648\n",
"val Loss: 0.1882 Acc: 0.9412\n",
"\n",
"Epoch 9/10\n",
"----------\n",
"train Loss: 0.3464 Acc: 0.8484\n",
"val Loss: 0.1844 Acc: 0.9477\n",
"\n",
"Epoch 10/10\n",
"----------\n",
"train Loss: 0.3932 Acc: 0.8074\n",
"val Loss: 0.1730 Acc: 0.9412\n",
"\n",
"Training complete in 8m 30s\n",
"Best val Acc: 0.947712\n"
]
}
],
"source": [
"source": [
"import copy\n",
"import copy\n",
"import os\n",
"import os\n",
...
@@ -2152,6 +2235,171 @@
...
@@ -2152,6 +2235,171 @@
"Apply ther quantization (post and quantization aware) and evaluate impact on model size and accuracy."
"Apply ther quantization (post and quantization aware) and evaluate impact on model size and accuracy."
"c:\\Users\\ZINEB\\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\\ZINEB\\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\\ZINEB\\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"
The goal is to apply a Convolutional Neural Net (CNN) model on the CIFAR10 image dataset and test the accuracy of the model on the basis of image classification. Compare the Accuracy VS the neural network implemented during TD1.
The goal is to apply a Convolutional Neural Net (CNN) model on the CIFAR10 image dataset and test the accuracy of the model on the basis of image classification. Compare the Accuracy VS the neural network implemented during TD1.
Have a look at the following documentation to be familiar with PyTorch.
Have a look at the following documentation to be familiar with PyTorch.
On peut détecter un overfitting en surveillant les performances du modèle sur les données
On peut détecter un overfitting en surveillant les performances du modèle sur les données
d'entraînement et de test au fil du temps. Si les performances du modèle sur les données
d'entraînement et de test au fil du temps. Si les performances du modèle sur les données
d'entraînement continuent de s'améliorer tandis que celles sur les données de test diminuent,
d'entraînement continuent de s'améliorer tandis que celles sur les données de test diminuent,
cela indique un surapprentissage. Ici dans notre cas à partir de l'epoch 15, on remarque que la valeur de valid_loss commence à augmenter alors que train_loss diminue toujours.
cela indique un surapprentissage. Ici dans notre cas à partir de l'epoch 15, on remarque que la valeur de valid_loss commence à augmenter alors que train_loss diminue toujours.
%% Cell type:markdown id:11df8fd4 tags:
%% Cell type:markdown id:11df8fd4 tags:
Now loading the model with the lowest validation loss value
Now loading the model with the lowest validation loss value
For each class, compare the classification test accuracy of the initial model and the quantized model. Also give the overall test accuracy for both models.
For each class, compare the classification test accuracy of the initial model and the quantized model. Also give the overall test accuracy for both models.
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` python
``` python
import torch
import torch
import torch.nn as nn
import torch.nn as nn
from torchvision import datasets, transforms
from torchvision import datasets, transforms
from torch.utils.data.sampler import SubsetRandomSampler
from torch.utils.data.sampler import SubsetRandomSampler
import os
import os
import numpy as np
import numpy as np
```
```
%% Cell type:markdown id:a0a34b90 tags:
%% Cell type:markdown id:a0a34b90 tags:
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)
PyTorch offers several pre-trained models https://pytorch.org/vision/0.8/models.html
PyTorch offers several pre-trained models https://pytorch.org/vision/0.8/models.html
We will use ResNet50 trained on ImageNet dataset (https://www.image-net.org/index.php). Use the following code with the files `imagenet-simple-labels.json` that contains the imagenet labels and the image dog.png that we will use as test.
We will use ResNet50 trained on ImageNet dataset (https://www.image-net.org/index.php). Use the following code with the files `imagenet-simple-labels.json` that contains the imagenet labels and the image dog.png that we will use as test.
%% Cell type:code id:b4d13080 tags:
%% Cell type:code id:b4d13080 tags:
``` python
``` python
import json
import json
from PIL import Image
from PIL import Image
# Choose an image to pass through the model
# Choose an image to pass through the model
test_image = "dog.png"
test_image = "dog.png"
# Configure matplotlib for pretty inline plots
# Configure matplotlib for pretty inline plots
#%matplotlib inline
#%matplotlib inline
#%config InlineBackend.figure_format = 'retina'
#%config InlineBackend.figure_format = 'retina'
# Prepare the labels
# Prepare the labels
with open("imagenet-simple-labels.json") as f:
with open("imagenet-simple-labels.json") as f:
labels = json.load(f)
labels = json.load(f)
# First prepare the transformations: resize the image to what the model was trained on and convert it to a tensor
# First prepare the transformations: resize the image to what the model was trained on and convert it to a tensor
# Download the model if it's not there already. It will take a bit on the first run, after that it's fast
# Download the model if it's not there already. It will take a bit on the first run, after that it's fast
model = models.resnet50(pretrained=True)
model = models.resnet50(pretrained=True)
# Send the model to the GPU
# Send the model to the GPU
# model.cuda()
# model.cuda()
# Set layers such as dropout and batchnorm in evaluation mode
# Set layers such as dropout and batchnorm in evaluation mode
model.eval()
model.eval()
# Get the 1000-dimensional model output
# Get the 1000-dimensional model output
out = model(image)
out = model(image)
# Find the predicted class
# Find the predicted class
print("Predicted class is: {}".format(labels[out.argmax()]))
print("Predicted class is: {}".format(labels[out.argmax()]))
```
```
%% Output
%% Output
c:\Users\ZINEB\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.
c:\Users\ZINEB\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.
warnings.warn(
warnings.warn(
c:\Users\ZINEB\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=ResNet50_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet50_Weights.DEFAULT` to get the most up-to-date weights.
c:\Users\ZINEB\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=ResNet50_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet50_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/resnet50-0676ba61.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\resnet50-0676ba61.pth
Downloading: "https://download.pytorch.org/models/resnet50-0676ba61.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\resnet50-0676ba61.pth
# Set layers such as dropout and batchnorm in evaluation mode
# Set layers such as dropout and batchnorm in evaluation mode
model.eval()
model.eval()
# Get the 1000-dimensional model output
# Get the 1000-dimensional model output
out = model(image)
out = model(image)
# Find the predicted class
# Find the predicted class
print("Predicted class is: {}".format(labels[out.argmax()]))
print("Predicted class is: {}".format(labels[out.argmax()]))
```
```
%% Output
%% Output
c:\Users\ZINEB\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=AlexNet_Weights.IMAGENET1K_V1`. You can also use `weights=AlexNet_Weights.DEFAULT` to get the most up-to-date weights.
c:\Users\ZINEB\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=AlexNet_Weights.IMAGENET1K_V1`. You can also use `weights=AlexNet_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/alexnet-owt-7be5be79.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\alexnet-owt-7be5be79.pth
Downloading: "https://download.pytorch.org/models/alexnet-owt-7be5be79.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\alexnet-owt-7be5be79.pth
print("Predicted class is: {}".format(labels[out.argmax()]))
print("Predicted class is: {}".format(labels[out.argmax()]))
```
```
%% Output
%% Output
c:\Users\ZINEB\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=VGG16_Weights.IMAGENET1K_V1`. You can also use `weights=VGG16_Weights.DEFAULT` to get the most up-to-date weights.
c:\Users\ZINEB\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=VGG16_Weights.IMAGENET1K_V1`. You can also use `weights=VGG16_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/vgg16-397923af.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\vgg16-397923af.pth
Downloading: "https://download.pytorch.org/models/vgg16-397923af.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\vgg16-397923af.pth
For this work, we will use a pre-trained model (ResNet18) as a descriptor extractor and will refine the classification by training only the last fully connected layer of the network. Thus, the output layer of the pre-trained network will be replaced by a layer adapted to the new classes to be recognized which will be in our case ants and bees.
For this work, we will use a pre-trained model (ResNet18) as a descriptor extractor and will refine the classification by training only the last fully connected layer of the network. Thus, the output layer of the pre-trained network will be replaced by a layer adapted to the new classes to be recognized which will be in our case ants and bees.
Download and unzip in your working directory the dataset available at the address :
Download and unzip in your working directory the dataset available at the address :
imshow(out, title=[class_names[x] for x in classes])
imshow(out, title=[class_names[x] for x in classes])
```
```
%% Output
%% Output
%% Cell type:markdown id:bbd48800 tags:
%% Cell type:markdown id:bbd48800 tags:
Now, execute the following code which uses a pre-trained model ResNet18 having replaced the output layer for the ants/bees classification and performs the model training by only changing the weights of this output layer.
Now, execute the following code which uses a pre-trained model ResNet18 having replaced the output layer for the ants/bees classification and performs the model training by only changing the weights of this output layer.
%% Cell type:code id:572d824c tags:
%% Cell type:code id:572d824c tags:
``` python
``` python
import copy
import copy
import os
import os
import time
import time
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
import numpy as np
import numpy as np
import torch
import torch
import torch.nn as nn
import torch.nn as nn
import torch.optim as optim
import torch.optim as optim
import torchvision
import torchvision
from torch.optim import lr_scheduler
from torch.optim import lr_scheduler
from torchvision import datasets, transforms
from torchvision import datasets, transforms
# Data augmentation and normalization for training
# Data augmentation and normalization for training
# Just normalization for validation
# Just normalization for validation
data_transforms = {
data_transforms = {
"train": transforms.Compose(
"train": transforms.Compose(
[
[
transforms.RandomResizedCrop(
transforms.RandomResizedCrop(
224
224
), # ImageNet models were trained on 224x224 images
), # ImageNet models were trained on 224x224 images
transforms.RandomHorizontalFlip(), # flip horizontally 50% of the time - increases train set variability
transforms.RandomHorizontalFlip(), # flip horizontally 50% of the time - increases train set variability
transforms.ToTensor(), # convert it to a PyTorch tensor
transforms.ToTensor(), # convert it to a PyTorch tensor
c:\Users\ZINEB\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.
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/resnet18-f37072fd.pth" to C:\Users\ZINEB/.cache\torch\hub\checkpoints\resnet18-f37072fd.pth
c:\Users\ZINEB\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
warnings.warn("Detected call of `lr_scheduler.step()` before `optimizer.step()`. "
train Loss: 0.6227 Acc: 0.6680
val Loss: 0.3421 Acc: 0.8758
Epoch 2/10
----------
train Loss: 0.7198 Acc: 0.7090
val Loss: 0.1835 Acc: 0.9477
Epoch 3/10
----------
train Loss: 0.5178 Acc: 0.7746
val Loss: 0.1933 Acc: 0.9412
Epoch 4/10
----------
train Loss: 0.4848 Acc: 0.8074
val Loss: 0.2029 Acc: 0.9281
Epoch 5/10
----------
train Loss: 0.5139 Acc: 0.8074
val Loss: 0.2291 Acc: 0.9150
Epoch 6/10
----------
train Loss: 0.5792 Acc: 0.8033
val Loss: 0.1806 Acc: 0.9412
Epoch 7/10
----------
train Loss: 0.3262 Acc: 0.8607
val Loss: 0.2058 Acc: 0.9412
Epoch 8/10
----------
train Loss: 0.3552 Acc: 0.8648
val Loss: 0.1882 Acc: 0.9412
Epoch 9/10
----------
train Loss: 0.3464 Acc: 0.8484
val Loss: 0.1844 Acc: 0.9477
Epoch 10/10
----------
train Loss: 0.3932 Acc: 0.8074
val Loss: 0.1730 Acc: 0.9412
Training complete in 8m 30s
Best val Acc: 0.947712
%% Cell type:markdown id:bbd48800 tags:
%% Cell type:markdown id:bbd48800 tags:
Experiments:
Experiments:
Study the code and the results obtained.
Study the code and the results obtained.
Modify the code and add an "eval_model" function to allow
Modify the code and add an "eval_model" function to allow
the evaluation of the model on a test set (different from the learning and validation sets used during the learning phase). Study the results obtained.
the evaluation of the model on a test set (different from the learning and validation sets used during the learning phase). Study the results obtained.
Now modify the code to replace the current classification layer with a set of two layers using a "relu" activation function for the middle layer, and the "dropout" mechanism for both layers. Renew the experiments and study the results obtained.
Now modify the code to replace the current classification layer with a set of two layers using a "relu" activation function for the middle layer, and the "dropout" mechanism for both layers. Renew the experiments and study the results obtained.
Apply ther quantization (post and quantization aware) and evaluate impact on model size and accuracy.
Apply ther quantization (post and quantization aware) and evaluate impact on model size and accuracy.
c:\Users\ZINEB\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.
warnings.warn(
c:\Users\ZINEB\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.
warnings.warn(msg)
Epoch 1/10
----------
c:\Users\ZINEB\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
warnings.warn("Detected call of `lr_scheduler.step()` before `optimizer.step()`. "
Pytorch offers a framework to export a given CNN to your selfphone (either android or iOS). Have a look at the tutorial https://pytorch.org/mobile/home/
Pytorch offers a framework to export a given CNN to your selfphone (either android or iOS). Have a look at the tutorial https://pytorch.org/mobile/home/
The Exercise consists in deploying the CNN of Exercise 4 in your phone and then test it on live.
The Exercise consists in deploying the CNN of Exercise 4 in your phone and then test it on live.