9.10.2 EP09_02 🟢 Pooling manuel (Maximum et moyenne)
Entre les blocs convolutifs, l’architecture typique d’un CNN intercale des couches de pooling, qui réduisent la résolution spatiale de la carte de caractéristiques sans introduire de nouveaux paramètres entraînables — contrairement à la convolution, le pooling n’a pas de poids : il résume simplement chaque fenêtre de l’entrée à une seule valeur, par un maximum ou par une moyenne, exactement comme formalisé dans la section “Pooling”.
Vous êtes chargé d’implémenter cette opération à partir d’une fenêtre glissante carrée, sans chevauchement partiel sur les bords (uniquement des fenêtres complètes), en supportant les deux types les plus courants : max (préserve la valeur la plus saillante, typiquement utilisée pour retenir les bords et les textures fortes) et avg (lisse la région, préservant l’information d’intensité moyenne).
9.10.2.1 📋 Directives d’implémentation
Entrée : Lire les dimensions \(H \times W\) de la carte de caractéristiques d’entrée et ses \(H \times W\) valeurs réelles.
Fenêtre : Lire les entiers \(k\) (taille de la fenêtre carrée \(k \times k\)) et \(s\) (stride).
Type : Lire une chaîne de caractères, max ou avg, indiquant le type de pooling.
Sans remplissage : Cette opération n’utilise pas de padding ; les fenêtres qui dépasseraient le bord de l’entrée sont ignorées.
Calcul : Pour chaque position de sortie \((i,j)\), calculer le maximum ou la moyenne des \(k \times k\) valeurs de la fenêtre correspondante, commençant à \((i \cdot s,\, j \cdot s)\).
Dimensions de sortie :\(O_h = \lfloor (H - k)/s \rfloor + 1\) et \(O_w = \lfloor (W - k)/s \rfloor + 1\).
Sortie : Imprimer \(O_h\) et \(O_w\) sur la première ligne, suivis de \(O_h\) lignes avec \(O_w\) valeurs réelles chacune, formatées avec 4 décimales.
9.10.2.2 📌 Contraintes computationnelles
Fenêtre carrée :\(k \times k\), sans support pour les fenêtres rectangulaires dans cette version.
Sans padding : seules les fenêtres entièrement contenues dans l’entrée sont considérées — les dimensions “restantes” sont simplement ignorées.
avg utilise une division réelle : la moyenne est toujours \(\text{somme}/k^2\), même lorsque le résultat a de nombreuses décimales — arrondissez uniquement lors du formatage final, conformément à la directive générale du chapitre.
Formatage : toutes les valeurs de sortie avec exactement 4 décimales.
9.10.2.3 🧠 Fondement théorique
Élément
Rôle dans l’architecture
Pooling maximum
Préserve l’activation la plus forte de la fenêtre ; courant après les couches convolutives pour retenir les bords et les textures saillantes
Pooling moyen
Lisse la région, préservant l’intensité moyenne ; courant dans les couches finales (global average pooling)
Absence de paramètres
Différencie le pooling de la convolution : réduit la résolution spatiale sans coût supplémentaire d’entraînement
Réduction de résolution
Contribue à l’invariance aux petites translations et à la réduction du coût computationnel des couches suivantes
9.10.2.4 🧩 Méthodes de morph.py qui peuvent aider
Le morph.py n’implémente pas le pooling avec sous-échantillonnage directement, mais deux familles d’opérations montrent la même idée sous un autre angle, utile pour vérifier votre intuition :
mm.dil(f, Bc) / mm.dil0(f, B) — dilatation morphologique : remplace chaque pixel par le maximum de son voisinage défini par l’élément structurant \(B\) (ex. : mm.sebox(n) pour une fenêtre \((2n+1)\times(2n+1)\)). Conceptuellement, c’est un “max-pooling sans sous-échantillonnage” (produit une image de même taille, au lieu d’une image réduite).
mm.blur(f, N) — lissage par moyenne dans une fenêtre \(N \times N\), analogue au avg-pooling, également sans réduction de résolution.
mm.readImg(h, w, dtype='float') — utile pour lire la carte d’entrée en virgule flottante.
9.10.2.5 📦 Spécification d’entrée et de sortie (VPL)
🎮 Simulateur : Pooling manuel🟢 sans padding, fenêtres complètes
Entrée 4×4 fixe — ajustez la taille de la fenêtre (k), le stride (s) et le type, exactement les paramètres que l'EP09_02 lit en entrée, et voyez comment ils modifient la taille et les valeurs de la sortie.
Fenêtre (k)
Stride (s)
Type
(0,0)
Entrée X (4×4)
hors de la fenêtre fenêtre actuelle écarté (reste)
Sortie Y (pooling)
💡 Chaque position du curseur révèle une cellule de la matrice de sortie. Les cellules grises en pointillés sur l'entrée sont des « restes » qu'aucune fenêtre n'atteint — notez que cela se produit lorsque (H−k) n'est pas un multiple de s. Changer k, s ou le type réinitialise l'exploration.
Figure 9.44: Simulateur EP09_02 : Pooling manuel (maximum vs. moyenne, avec fenêtre k et pas s réglables)
%%writefile EP09_02.py# Code Python
Overwriting EP09_02.py
TestSuite("EP09_02.py").run()
✔️ EP09_02.cases existe déjà dans casos/
📋 4 cas chargé(s) depuis casos/EP09_02.cases
🔍 Test de Python : EP09_02.py
⚠️ EP09_02.py : fichier vide (moins de 3 lignes). Tests ignorés.