Pooling : réduire les dimensions sans perdre l’essentiel
Le pooling (ou sous-échantillonnage) est une opération qui réduit les dimensions spatiales d’une feature map en agrégeant les valeurs d’une petite zone en une seule valeur, le plus souvent par maximum (max pooling) ou par moyenne (average pooling). C’est un composant historique des réseaux de neurones convolutifs (CNN) qui sert à diminuer la charge de calcul, limiter le surapprentissage et introduire une certaine invariance à la translation.
- Type
- Couche de réseau de neurones (non paramétrique)
- Rôle
- Réduction des dimensions spatiales (downsampling)
- Paramètres appris
- Aucun (opération fixe)
- Hyperparamètres
- Taille de la fenêtre (kernel), stride, padding
- Types courants
- Max pooling, average pooling, global average pooling (GAP)
- Configuration standard
- Fenêtre 2×2, stride 2 (divise les dimensions par 2)
- Alternative moderne
- Convolution avec stride (strided convolution)
Comment fonctionne le pooling ?
Le pooling fonctionne exactement comme la convolution, mais sans poids à apprendre. Une fenêtre glisse sur la feature map et, à chaque position, elle résume les valeurs capturées en un seul nombre. La fenêtre se déplace ensuite selon le stride défini.
Avec la configuration standard (fenêtre 2×2, stride 2), chaque feature map voit ses dimensions spatiales divisées par 2 dans chaque direction, ce qui élimine 75 % des activations. Le nombre de canaux reste inchangé : le pooling s’applique indépendamment à chaque canal.
La formule de la taille de sortie est identique à celle de la convolution :
Sortie = ⌊(Entrée + 2×Padding - Fenêtre) / Stride⌋ + 1
Exemple : feature map 32×32, fenêtre 2×2, stride 2, padding 0
Sortie = ⌊(32 + 0 - 2) / 2⌋ + 1 = 16×16
Point important : contrairement aux couches de convolution, les couches de pooling n’ont aucun paramètre entraînable. Ce sont des opérations mathématiques fixes qui ne contribuent pas au nombre total de paramètres du modèle.
Types de pooling
Max pooling
Le max pooling conserve la valeur maximale dans chaque fenêtre. C’est le type de pooling le plus utilisé dans les CNN classiques.
Feature map (4×4): Max pooling 2×2, stride 2:
1 3 2 1
5 6 8 4 → 6 8
2 4 7 3 4 7
1 2 3 1
Explication :
- Zone [1,3,5,6] → max = 6
- Zone [2,1,8,4] → max = 8
- Zone [2,4,1,2] → max = 4
- Zone [7,3,3,1] → max = 7
Le max pooling retient les caractéristiques les plus saillantes (les activations les plus fortes). Si un filtre de convolution a détecté un contour avec une forte activation dans une zone, le max pooling préserve cette détection tout en réduisant la résolution. Le résultat est une feature map plus nette et plus contrastée.
Avantages : capture les caractéristiques dominantes, introduit de l’invariance locale, très rapide à calculer.
Limites : ignore toutes les valeurs sauf le maximum, ce qui peut entraîner une perte d’information. Un bruit ou une valeur aberrante dans une seule activation peut fausser le résultat.
Average pooling
L’average pooling calcule la moyenne de toutes les valeurs dans la fenêtre :
Feature map (4×4): Average pooling 2×2, stride 2:
1 3 2 1
5 6 8 4 → 3.75 3.75
2 4 7 3 2.25 3.50
1 2 3 1
Explication :
- Zone [1,3,5,6] → moyenne = 3.75
- Zone [2,1,8,4] → moyenne = 3.75
- Zone [2,4,1,2] → moyenne = 2.25
- Zone [7,3,3,1] → moyenne = 3.50
L’average pooling produit des feature maps plus lisses car elle considère toutes les valeurs de la zone. Elle est plus robuste aux valeurs aberrantes mais capture moins bien les caractéristiques dominantes.
Avantages : conserve plus d’information globale, robuste au bruit, meilleure représentation des caractéristiques distribuées.
Limites : les transitions sont moins nettes, les caractéristiques fortes sont diluées par les valeurs faibles environnantes.
Global Average Pooling (GAP)
Le global average pooling réduit chaque canal entier à une seule valeur en calculant la moyenne de tous ses pixels. Une feature map de dimensions H×W×C est réduite à un vecteur de taille 1×1×C.
Introduit dans le papier « Network in Network » (2014), le GAP a transformé la conception des CNN. Avant le GAP, les CNN terminaient par une étape de « flatten » (aplatissement de toutes les feature maps en un vecteur) suivie de couches fully connected massives. AlexNet, par exemple, avait des couches fully connected de 4096 neurones, avec des millions de paramètres sujets au surapprentissage.
Le GAP élimine ce problème : il produit directement un vecteur de taille égale au nombre de canaux, sans paramètre supplémentaire. Ce vecteur est ensuite passé à une couche softmax pour la classification.
Global Max Pooling (GMP)
Même principe que le GAP, mais en conservant le maximum au lieu de la moyenne. Moins courant que le GAP en classification, il est utilisé dans certaines architectures de détection d’objets et dans les Vision Transformers (ViT).
Comparaison des types de pooling
| Type | Opération | Feature maps résultantes | Cas d’usage typique |
|---|---|---|---|
| Max pooling | Maximum de la zone | Nettes, contrastées | Couches intermédiaires des CNN, détection de features |
| Average pooling | Moyenne de la zone | Lisses, contextuelles | Couches profondes, tâches avec features distribuées |
| Global Average Pooling | Moyenne sur tout le canal | Vecteur 1D (1 valeur/canal) | Remplace flatten + FC avant classification |
| Global Max Pooling | Maximum sur tout le canal | Vecteur 1D (1 valeur/canal) | Détection d’objets, certains ViT |
| Adaptive pooling | Max ou average avec taille de sortie fixe | Dimensions fixées quelle que soit l’entrée | Entrées de taille variable, transfer learning |
Les quatre rôles du pooling dans un CNN
1. Réduction dimensionnelle
Le rôle le plus évident. En divisant les dimensions spatiales par 2 à chaque couche de pooling, le nombre de valeurs à traiter diminue exponentiellement. Après trois couches de pooling 2×2, une feature map 256×256 est réduite à 32×32, soit une réduction de 64× en nombre de pixels. Cela accélère le calcul et réduit l’empreinte mémoire.
2. Invariance locale à la translation
Le pooling introduit une certaine tolérance aux petits décalages dans la position des caractéristiques. Si un objet se déplace de quelques pixels dans l’image, le max pooling produit souvent le même résultat (le maximum de la zone reste le même). Cette propriété rend le modèle plus robuste aux légères variations de position.
Attention : cette invariance est locale (à l’échelle de la fenêtre de pooling) et non globale. Seul le global pooling en fin de réseau apporte une invariance complète à la translation.
3. Régularisation implicite
En réduisant le nombre de paramètres dans les couches suivantes, le pooling limite la capacité du modèle à mémoriser les données d’entraînement. C’est une forme de régularisation structurelle qui complète des techniques comme le dropout.
4. Élargissement du champ récepteur
Chaque neurone des couches suivantes « voit » une zone plus large de l’image originale après le pooling. Cela permet aux couches profondes de capturer des patterns plus globaux sans nécessiter des kernels de convolution énormes.
Le pooling dans les architectures classiques
L’utilisation du pooling a évolué avec les architectures CNN :
LeNet-5 (1998) : utilise l’average pooling (appelé « subsampling » à l’époque). Fenêtres 2×2 avec stride 2 après chaque couche de convolution.
AlexNet (2012) : adopte le max pooling, avec des fenêtres 3×3 et stride 2 (overlap pooling). L’overlap a montré de légères améliorations par rapport au pooling non chevauchant.
VGGNet (2014) : max pooling standard 2×2 avec stride 2 entre les blocs de convolution. Architecture très régulière.
GoogLeNet/Inception (2014) : introduit le Global Average Pooling en remplacement des couches fully connected finales. Réduction massive du nombre de paramètres.
ResNet (2015) : utilise une combinaison de convolutions stridées (stride 2 pour le downsampling entre stages) et de global average pooling final. Le pooling classique est moins présent.
ConvNeXt (2022) : n’utilise pas de max pooling du tout. Le downsampling est réalisé par des convolutions 2×2 avec stride 2, suivant la philosophie des Transformers. Seul le global average pooling est conservé avant la classification.
Le pooling est-il encore nécessaire ?
La question est légitime. Les architectures modernes tendent à remplacer les couches de pooling traditionnelles par des alternatives :
Convolutions stridées
Au lieu d’une couche de convolution (stride 1) suivie d’un pooling, on utilise une seule couche de convolution avec stride 2. Le résultat est similaire (division des dimensions par 2), mais avec l’avantage que le downsampling est appris : le réseau choisit quelles informations conserver et lesquelles éliminer.
Le papier « Striving for Simplicity: The All Convolutional Net » (Springenberg et al., 2015) a démontré que remplacer toutes les couches de pooling par des convolutions stridées pouvait améliorer les performances. Cette approche est adoptée par la majorité des architectures récentes.
Adaptive pooling
Le pooling adaptatif (disponible dans PyTorch via nn.AdaptiveAvgPool2d et nn.AdaptiveMaxPool2d) produit une sortie de taille fixe quelle que soit la taille d’entrée. Vous spécifiez la taille de sortie souhaitée, et la couche calcule automatiquement la taille de fenêtre et le stride nécessaires. C’est indispensable pour le transfer learning avec des images de tailles variées.
Attention pooling
Dans les Vision Transformers, le pooling est remplacé par des mécanismes d’attention qui décident quelles parties de l’image méritent le plus de « focus ». Le token [CLS] dans les ViT agit comme un pooling appris : il agrège l’information de tous les patches de l’image via l’attention.
Implémentation en PyTorch
import torch
import torch.nn as nn
# Max pooling 2x2 standard
maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
# Average pooling 2x2 standard
avgpool = nn.AvgPool2d(kernel_size=2, stride=2)
# Feature map simulée : batch=1, canaux=64, hauteur=32, largeur=32
x = torch.randn(1, 64, 32, 32)
out_max = maxpool(x) # → (1, 64, 16, 16)
out_avg = avgpool(x) # → (1, 64, 16, 16)
# Global Average Pooling
gap = nn.AdaptiveAvgPool2d(output_size=(1, 1))
out_gap = gap(x) # → (1, 64, 1, 1)
out_gap = out_gap.squeeze() # → (64,) : vecteur prêt pour classification
# Global Max Pooling
gmp = nn.AdaptiveMaxPool2d(output_size=(1, 1))
out_gmp = gmp(x) # → (1, 64, 1, 1)
# Adaptive pooling : sortie 7x7 quelle que soit l'entrée
adaptive = nn.AdaptiveAvgPool2d(output_size=(7, 7))
out_adapt = adaptive(x) # → (1, 64, 7, 7)
# Fonctionne aussi avec x de taille 64x64 ou 128x128
Guide pratique : quel pooling choisir ?
Classification d’images : global average pooling avant la couche de classification. C’est le standard depuis GoogLeNet. Ajoutez éventuellement un max pooling 2×2 dans les premières couches si vous suivez une architecture classique.
Détection d’objets : max pooling dans les couches d’extraction de features (backbone), combiné avec des pooling spécialisés comme le ROI pooling ou le ROI Align pour extraire les features des régions d’intérêt.
Segmentation sémantique : évitez le pooling agressif car la résolution spatiale est cruciale. Utilisez des convolutions dilatées ou des architectures encoder-decoder (U-Net) qui restaurent la résolution perdue.
Architecture moderne (ResNet, ConvNeXt) : remplacez le max pooling par des convolutions stridées pour le downsampling. Gardez le global average pooling final.
Déploiement mobile/embarqué : le pooling (sans paramètres) est plus économique que les convolutions stridées. Préférez le pooling quand chaque paramètre compte.
Le pooling au-delà de la vision : NLP et Transformers
Le pooling n’est pas réservé aux images. En NLP, il joue un rôle clé pour convertir une séquence de vecteurs de longueur variable en un vecteur de taille fixe :
Mean pooling sur les embeddings : dans les modèles de type Sentence-BERT, la moyenne de tous les vecteurs de tokens produit un embedding de phrase unique. C’est l’approche la plus courante pour la recherche sémantique et la similarité de texte.
Token [CLS] comme pooling : dans BERT et les Vision Transformers, le token spécial [CLS] agrège l’information de toute la séquence via le mécanisme d’self-attention. C’est une forme de pooling appris, plus expressive que le mean pooling classique.
Max pooling en classification de texte : les modèles TextCNN appliquent des convolutions 1D sur les embeddings de mots, puis un max pooling global pour extraire la caractéristique la plus saillante de chaque filtre. Rapide et efficace pour l’analyse de sentiment.
Questions fréquentes sur le pooling
Quelle est la différence entre max pooling et average pooling ?
Le max pooling conserve uniquement la valeur maximale de chaque zone, ce qui met en avant les caractéristiques les plus saillantes (contours forts, textures marquées). L’average pooling calcule la moyenne de la zone, produisant une représentation plus lisse qui conserve l’information globale. En pratique, le max pooling est préféré dans les couches intermédiaires des CNN car il capture mieux les features discriminantes. L’average pooling brille en fin de réseau (global average pooling) pour agréger l’information avant la classification.
Pourquoi les architectures modernes remplacent-elles le pooling par des convolutions stridées ?
Les convolutions stridées effectuent le downsampling tout en apprenant quelles informations conserver, grâce à leurs paramètres entraînables. Le pooling, lui, applique une règle fixe (max ou average) qui n’est pas toujours optimale. Des travaux comme « The All Convolutional Net » (2015) ont montré que cette substitution peut améliorer les performances. Cependant, le pooling reste pertinent dans certains contextes (déploiement embarqué, architectures légères) car il ne consomme aucun paramètre.
Le pooling a-t-il des paramètres entraînables ?
Non, les couches de pooling classiques (max, average, global) n’ont aucun paramètre entraînable. Ce sont des opérations déterministes appliquées aux feature maps. C’est à la fois un avantage (zéro coût en paramètres, pas de risque de surapprentissage lié au pooling) et une limite (le réseau ne peut pas apprendre la stratégie de downsampling optimale). Des recherches récentes proposent des variantes avec paramètres apprenables, mais elles restent marginales.
Qu’est-ce que le Global Average Pooling et pourquoi est-il si populaire ?
Le Global Average Pooling (GAP) calcule la moyenne de chaque canal de la dernière feature map, produisant un vecteur 1D de taille égale au nombre de canaux. Il remplace avantageusement la combinaison « flatten + couches fully connected » qui dominait les CNN avant 2014. Ses avantages : il élimine des millions de paramètres sujets au surapprentissage, il accepte des entrées de taille variable, et il crée une correspondance directe entre chaque canal et une caractéristique apprise. C’est le standard dans pratiquement toutes les architectures de classification modernes.
Le pooling provoque-t-il une perte d’information ?
Oui, par définition. Réduire une zone 2×2 à une seule valeur élimine 75 % des données. C’est d’ailleurs l’objectif : forcer le réseau à retenir l’essentiel. En pratique, cette perte est bénéfique pour la classification (généralisation, robustesse) mais problématique pour les tâches exigeant une résolution fine, comme la segmentation sémantique ou la super-résolution. C’est pourquoi les architectures de segmentation (U-Net, DeepLab) utilisent des mécanismes pour restaurer les détails perdus (skip connections, convolutions dilatées, upsampling).