CNN - Réseaux convolutifs
L'architecture qui a révolutionné la vision par ordinateur
Les Convolutional Neural Networks (CNN) sont des réseaux spécialisés pour traiter des données avec une structure en grille, comme les images. Ils ont révolutionné la vision par ordinateur.
Pourquoi les CNN ?
Le problème des images
Une image 224×224 RGB = 150 528 pixels.
Avec un MLP classique :
150 528 entrées × 1000 neurones = 150 millions de poids !Problèmes :
- Trop de paramètres → overfitting
- Pas d'invariance spatiale
- Ignore la structure 2D
La solution : convolution
Les CNN exploitent trois idées clés :
- Connexions locales : chaque neurone ne voit qu'une petite région
- Partage des poids : les mêmes filtres s'appliquent partout
- Hiérarchie : des features simples aux features complexes
L'opération de convolution
Principe
Un filtre (kernel) glisse sur l'image et calcule une somme pondérée.
Image (5×5) Filtre (3×3) Feature Map (3×3)
┌─────────────────┐ ┌─────────┐ ┌─────────┐
│ 1 2 3 0 1 │ │ 1 0 1 │ │ 8 6 7 │
│ 0 1 2 3 1 │ * │ 0 1 0 │ = │ 5 7 9 │
│ 1 2 1 0 0 │ │ 1 0 1 │ │ 4 5 6 │
│ 0 1 2 1 1 │ └─────────┘ └─────────┘
│ 1 0 1 2 1 │
└─────────────────┘
Calcul d'une cellule :
1×1 + 2×0 + 3×1 + 0×0 + 1×1 + 2×0 + 1×1 + 2×0 + 1×1 = 8Paramètres importants
| Paramètre | Description |
|---|---|
| Kernel size | Taille du filtre (ex: 3×3, 5×5) |
| Stride | Pas de déplacement (1 = pixel par pixel) |
| Padding | Bordure ajoutée (préserve la taille) |
| Channels | Nombre de filtres (profondeur) |
Formule de taille de sortie
Output = (Input - Kernel + 2×Padding) / Stride + 1
Exemple : Image 32×32, kernel 3×3, stride 1, padding 1
Output = (32 - 3 + 2×1) / 1 + 1 = 32×32Détection de features
Chaque filtre détecte un type de pattern.
Exemples de filtres
Détection de bords verticaux Détection de bords horizontaux
┌─────────────┐ ┌─────────────┐
│ -1 0 1 │ │ -1 -1 -1 │
│ -1 0 1 │ │ 0 0 0 │
│ -1 0 1 │ │ 1 1 1 │
└─────────────┘ └─────────────┘
Flou (moyenne) Netteté
┌─────────────┐ ┌─────────────┐
│ 1/9 1/9 1/9 │ │ 0 -1 0 │
│ 1/9 1/9 1/9 │ │ -1 5 -1 │
│ 1/9 1/9 1/9 │ │ 0 -1 0 │
└─────────────┘ └─────────────┘En Deep Learning, les filtres sont appris automatiquement pendant l'entraînement, pas définis manuellement.
Pooling
Réduit la dimension spatiale tout en gardant les informations importantes.
Max Pooling
Garde la valeur maximale dans chaque région.
┌─────┬─────┐ ┌─────┐
│ 1 3 │ 2 1 │ │ 4 3 │
│ 4 2 │ 1 3 │ → │ 6 5 │
├─────┼─────┤ └─────┘
│ 5 6 │ 2 4 │
│ 3 2 │ 5 1 │
└─────┴─────┘
Max Pooling 2×2, stride 2Average Pooling
Calcule la moyenne de chaque région.
nn.MaxPool2d(kernel_size=2, stride=2)
nn.AvgPool2d(kernel_size=2, stride=2)Global Average Pooling
Réduit chaque feature map à une seule valeur (moyenne globale).
Feature Map 7×7 → GAP → 1 valeurUtilisé en fin de réseau pour remplacer les couches fully connected.
Architecture type d'un CNN
┌────────────────────────────────────────────────────────────────┐
│ ARCHITECTURE CNN │
├────────────────────────────────────────────────────────────────┤
│ │
│ Image → [Conv→ReLU→Pool] × N → Flatten → FC → Softmax │
│ │
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌─────┐ ┌──────────┐ │
│ │ Conv │ │ Conv │ │ Conv │ │ │ │ Dense │ │
│ │ 32 │→ │ 64 │→ │ 128 │→ │Flat │→ │ Softmax │ │
│ │filters│ │filters│ │filters│ │ │ │ │ │
│ └───────┘ └───────┘ └───────┘ └─────┘ └──────────┘ │
│ │
│ 224×224×3 112×112×32 56×56×64 28×28×128 1000 classes │
│ │
└────────────────────────────────────────────────────────────────┘Hiérarchie des features
Couche 1 : Bords, textures simples
┌───┐ ┌───┐ ┌───┐
│ / │ │ \ │ │ ─ │
└───┘ └───┘ └───┘
Couche 2 : Formes simples, coins
┌───┐ ┌───┐ ┌───┐
│ ◢ │ │ ◣ │ │ ○ │
└───┘ └───┘ └───┘
Couche 3 : Parties d'objets
┌───┐ ┌───┐ ┌───┐
│ 👁 │ │ 👃 │ │ 👂 │
└───┘ └───┘ └───┘
Couche 4 : Objets complets
┌───┐ ┌───┐ ┌───┐
│🐱│ │🐕│ │🚗│
└───┘ └───┘ └───┘Architectures célèbres
LeNet-5 (1998)
Premier CNN à succès (reconnaissance de chiffres).
Input → Conv → Pool → Conv → Pool → FC → FC → Output
32×32 6 2×2 16 2×2 120 84 10AlexNet (2012)
Victoire écrasante à ImageNet, lancement du Deep Learning moderne.
Innovations :
- ReLU au lieu de tanh
- Dropout
- Data augmentation
- Entraînement sur GPU
VGGNet (2014)
Architecture simple et profonde : que des conv 3×3.
# VGG-16 : 16 couches
# Répétition de blocs Conv-Conv-PoolResNet (2015)
Introduit les connexions résiduelles (skip connections).
┌───────────────────┐
│ │
↓ │
Input → Conv → BN → ReLU → Conv → BN → (+) → ReLU → Output
↑
│
Identity connectionFormule : F(x) + x au lieu de F(x)
Permet d'entraîner des réseaux très profonds (152+ couches).
# ResNet block
class ResBlock(nn.Module):
def __init__(self, channels):
super().__init__()
self.conv1 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn1 = nn.BatchNorm2d(channels)
self.conv2 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn2 = nn.BatchNorm2d(channels)
def forward(self, x):
residual = x
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += residual # Skip connection
return F.relu(out)EfficientNet (2019)
Scaling optimal de la profondeur, largeur et résolution.
Vision Transformer (ViT) (2020)
Applique l'architecture Transformer aux images (voir section Transformers).
Implémentation PyTorch
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
# Bloc convolutif 1
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.bn1 = nn.BatchNorm2d(32)
self.pool1 = nn.MaxPool2d(2, 2)
# Bloc convolutif 2
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.bn2 = nn.BatchNorm2d(64)
self.pool2 = nn.MaxPool2d(2, 2)
# Bloc convolutif 3
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.bn3 = nn.BatchNorm2d(128)
self.pool3 = nn.MaxPool2d(2, 2)
# Classificateur
self.global_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Linear(128, num_classes)
self.dropout = nn.Dropout(0.5)
def forward(self, x):
# Convolutions
x = self.pool1(F.relu(self.bn1(self.conv1(x))))
x = self.pool2(F.relu(self.bn2(self.conv2(x))))
x = self.pool3(F.relu(self.bn3(self.conv3(x))))
# Classification
x = self.global_pool(x)
x = x.view(x.size(0), -1)
x = self.dropout(x)
x = self.fc(x)
return x
# Utilisation
model = SimpleCNN(num_classes=10)
x = torch.randn(8, 3, 224, 224) # Batch de 8 images RGB 224×224
output = model(x) # Shape: (8, 10)Transfer Learning
Réutiliser un CNN pré-entraîné sur ImageNet.
import torchvision.models as models
# Charger un modèle pré-entraîné
resnet = models.resnet50(pretrained=True)
# Geler les poids
for param in resnet.parameters():
param.requires_grad = False
# Remplacer la dernière couche
resnet.fc = nn.Linear(resnet.fc.in_features, num_classes)
# Entraîner seulement la nouvelle couche
optimizer = optim.Adam(resnet.fc.parameters(), lr=0.001)Quand utiliser le Transfer Learning ?
| Données disponibles | Similarité avec ImageNet | Stratégie |
|---|---|---|
| Peu | Haute | Feature extraction (geler tout) |
| Peu | Basse | Feature extraction + fine-tuning léger |
| Beaucoup | Haute | Fine-tuning de tout le réseau |
| Beaucoup | Basse | Entraîner from scratch ou fine-tune |
Applications
Classification d'images
# Prédire la classe d'une image
output = model(image)
predicted_class = output.argmax(dim=1)Détection d'objets
Localiser et classifier plusieurs objets dans une image.
Architectures : YOLO, Faster R-CNN, SSD
Segmentation sémantique
Classifier chaque pixel de l'image.
Architectures : U-Net, DeepLab, Mask R-CNN
Autres applications
- Reconnaissance faciale
- Imagerie médicale
- Voitures autonomes
- Analyse de documents
- Super-résolution
Data Augmentation
Essentielle pour éviter l'overfitting.
from torchvision import transforms
train_transforms = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.RandomRotation(15),
transforms.ColorJitter(brightness=0.2, contrast=0.2),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])