"### **_Introduction au Machine Learning - Enise - Centrale Lyon_**\n",
"\n",
"2024-2025\n",
"\n",
"Emmanuel Dellandréa\t \n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "4c69d182",
"metadata": {},
"source": [
"# TD7 – Convolutional Neural Networks"
]
},
{
"cell_type": "markdown",
"id": "fa71eda4",
"metadata": {},
"source": [
"The objective of this tutorial is to use the PyTorch library for building, training, and evaluating CNN models."
]
},
{
"cell_type": "markdown",
"id": "23f266da",
"metadata": {},
"source": [
"## Sequence 1: Training a CNN to classify CIFAR10 images\n",
"\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. \n",
"\n",
"Be sure to check the PyTorch tutorials and documentation when needed:\n",
"\n",
"https://pytorch.org/tutorials/\n",
"\n",
"https://pytorch.org/docs/stable/index.html\n"
]
},
{
"cell_type": "markdown",
"id": "4ba1c82d",
"metadata": {},
"source": [
"You can test if GPU is available on your machine and thus train on it to speed up the process"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6e18f2fd",
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"\n",
"# check if CUDA is available\n",
"train_on_gpu = torch.cuda.is_available()\n",
"\n",
"if not train_on_gpu:\n",
" print(\"CUDA is not available. Training on CPU ...\")\n",
"else:\n",
" print(\"CUDA is available! Training on GPU ...\")"
"Build a new network with the following structure.\n",
"\n",
"- It has 3 convolutional layers of kernel size 3 and padding of 1.\n",
"- The first convolutional layer must output 16 channels, the second 32 and the third 64.\n",
"- At each convolutional layer output, we apply a ReLU activation then a MaxPool with kernel size of 2.\n",
"- Then, three fully connected layers, the first two being followed by a ReLU activation.\n",
"- The first fully connected layer will have an output size of 512.\n",
"- The second fully connected layer will have an output size of 64.\n",
"\n",
"Compare the results obtained with this new network to those obtained previously."
]
},
{
"cell_type": "markdown",
"id": "201470f9",
"metadata": {},
"source": [
"## Sequence 2: Working with pre-trained models.\n",
"\n",
"PyTorch offers several pre-trained models https://pytorch.org/vision/0.8/models.html \n",
"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.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b4d13080",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"from PIL import Image\n",
"from torchvision import models\n",
"\n",
"# Choose an image to pass through the model\n",
"test_image = \"dog.png\"\n",
"\n",
"# Configure matplotlib for pretty inline plots\n",
"# Download the model if it's not there already. It will take a bit on the first run, after that it's fast\n",
"model = models.resnet50(pretrained=True)\n",
"# Send the model to the GPU\n",
"# model.cuda()\n",
"# Set layers such as dropout and batchnorm in evaluation mode\n",
"model.eval()\n",
"\n",
"# Get the 1000-dimensional model output\n",
"out = model(image)\n",
"# Find the predicted class\n",
"print(\"Predicted class is: {}\".format(labels[out.argmax()]))"
]
},
{
"cell_type": "markdown",
"id": "184cfceb",
"metadata": {},
"source": [
"### Experiments:\n",
"\n",
"Study the code and the results obtained. Possibly add other images downloaded from the internet.\n",
"\n",
"Experiment with other pre-trained CNN models.\n",
"\n",
" \n"
]
},
{
"cell_type": "markdown",
"id": "5d57da4b",
"metadata": {},
"source": [
"## Sequence 3: Transfer Learning\n",
" \n",
" \n",
"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.\n",
"Download and unzip in your working directory the dataset available at the address :\n",
"imshow(out, title=[class_names[x] for x in classes])\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "bbd48800",
"metadata": {},
"source": [
"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."
"Modify the code and add an \"eval_model\" function to allow\n",
"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.\n",
"\n",
"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. Renew the experiments and study the results obtained.\n",
"\n",
"Experiment with other models and datasets."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.20"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
%% Cell type:markdown id:7edf7168 tags:
### **_Introduction au Machine Learning - Enise - Centrale Lyon_**
2024-2025
Emmanuel Dellandréa
%% Cell type:markdown id:4c69d182 tags:
# TD7 – Convolutional Neural Networks
%% Cell type:markdown id:fa71eda4 tags:
The objective of this tutorial is to use the PyTorch library for building, training, and evaluating CNN models.
%% Cell type:markdown id:23f266da tags:
## Sequence 1: Training a CNN to classify CIFAR10 images
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.
Be sure to check the PyTorch tutorials and documentation when needed:
https://pytorch.org/tutorials/
https://pytorch.org/docs/stable/index.html
%% Cell type:markdown id:4ba1c82d tags:
You can test if GPU is available on your machine and thus train on it to speed up the process
%% Cell type:code id:6e18f2fd tags:
``` python
importtorch
# check if CUDA is available
train_on_gpu=torch.cuda.is_available()
ifnottrain_on_gpu:
print("CUDA is not available. Training on CPU ...")
# forward pass: compute predicted outputs by passing inputs to the model
output=model(data)
# calculate the batch loss
loss=criterion(output,target)
# update test loss
test_loss+=loss.item()*data.size(0)
# convert output probabilities to predicted class
_,pred=torch.max(output,1)
# compare predictions to true label
correct_tensor=pred.eq(target.data.view_as(pred))
correct=(
np.squeeze(correct_tensor.numpy())
ifnottrain_on_gpu
elsenp.squeeze(correct_tensor.cpu().numpy())
)
# calculate test accuracy for each object class
foriinrange(batch_size):
label=target.data[i]
class_correct[label]+=correct[i].item()
class_total[label]+=1
# average test loss
test_loss=test_loss/len(test_loader)
print("Test Loss: {:.6f}\n".format(test_loss))
foriinrange(10):
ifclass_total[i]>0:
print(
"Test Accuracy of %5s: %2d%% (%2d/%2d)"
%(
classes[i],
100*class_correct[i]/class_total[i],
np.sum(class_correct[i]),
np.sum(class_total[i]),
)
)
else:
print("Test Accuracy of %5s: N/A (no training examples)"%(classes[i]))
print(
"\nTest Accuracy (Overall): %2d%% (%2d/%2d)"
%(
100.0*np.sum(class_correct)/np.sum(class_total),
np.sum(class_correct),
np.sum(class_total),
)
)
```
%% Cell type:markdown id:944991a2 tags:
### Experiments:
Build a new network with the following structure.
- It has 3 convolutional layers of kernel size 3 and padding of 1.
- The first convolutional layer must output 16 channels, the second 32 and the third 64.
- At each convolutional layer output, we apply a ReLU activation then a MaxPool with kernel size of 2.
- Then, three fully connected layers, the first two being followed by a ReLU activation.
- The first fully connected layer will have an output size of 512.
- The second fully connected layer will have an output size of 64.
Compare the results obtained with this new network to those obtained previously.
%% Cell type:markdown id:201470f9 tags:
## Sequence 2: Working with pre-trained models.
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.
%% Cell type:code id:b4d13080 tags:
``` python
importjson
fromPILimportImage
fromtorchvisionimportmodels
# Choose an image to pass through the model
test_image="dog.png"
# Configure matplotlib for pretty inline plots
#%matplotlib inline
#%config InlineBackend.figure_format = 'retina'
# Prepare the labels
withopen("imagenet-simple-labels.json")asf:
labels=json.load(f)
# 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
model=models.resnet50(pretrained=True)
# Send the model to the GPU
# model.cuda()
# Set layers such as dropout and batchnorm in evaluation mode
model.eval()
# Get the 1000-dimensional model output
out=model(image)
# Find the predicted class
print("Predicted class is: {}".format(labels[out.argmax()]))
```
%% Cell type:markdown id:184cfceb tags:
### Experiments:
Study the code and the results obtained. Possibly add other images downloaded from the internet.
Experiment with other pre-trained CNN models.
%% Cell type:markdown id:5d57da4b tags:
## Sequence 3: Transfer Learning
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 :
plt.pause(0.001)# pause a bit so that plots are updated
plt.show()
# Get a batch of training data
inputs,classes=next(iter(dataloaders["train"]))
# Make a grid from batch
out=torchvision.utils.make_grid(inputs)
imshow(out,title=[class_names[x]forxinclasses])
```
%% 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.
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.
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. Renew the experiments and study the results obtained.