Partie 2 · Voir
Construire un CNN
Dans un CNN, qu'est-ce qu'un neurone ? Pas un élément du filtre : c'est le calcul fait à une position de la fenêtre ; sa sortie est une case de la carte. Même calcul qu'en J1 (somme pondérée + biais, ReLU), mais deux choses changent.
| MLP (J1) | CNN | |
|---|---|---|
| Un neurone lit | tous les pixels (784) | une fenêtre : 9 pixels |
| Ses poids | à lui seul | le filtre, partagé par tous les neurones de la carte |
| Sa sortie | un nombre | une case de la carte |
Conséquence chiffrée : la couche 1 du CNN des organes a 16 cartes de 28 × 28, soit 12 544 neurones, mais seulement 16 × 10 = 160 paramètres. La couche 1 du MLP de J1 avait 128 neurones et 100 480 paramètres.
Un filtre par motif. Notre filtre ne voit que les bords verticaux. Un deuxième filtre (−1 en haut, +1 en bas) calcule bas − haut et répond au bord du haut. Une couche de convolution contient plusieurs filtres appliqués à la même entrée ; on empile leurs cartes, ce sont les canaux de la sortie (ici 2). Personne ne choisit les filtres dans un vrai CNN : leurs 9 poids et leur biais sont tirés au hasard, puis réglés par la descente de gradient, comme en J1.
Trois mots, trois choses :
- Filtre : un jeu de poids et un biais qui glisse sur l'entrée ; il produit une carte.
- Canal : une grille de nombres, une carte. Un carré de pixels : forme 1 × 6 × 6 (canaux × hauteur × largeur) ; après nos 2 filtres : 2 × 4 × 4 ; une photo couleur : 3 × 224 × 224.
- Couche : plusieurs filtres sur la même entrée ; k filtres donnent k canaux.
Et ils se combinent : un filtre de la couche suivante lit sa fenêtre au même endroit sur tous les canaux et en sort une seule carte. Sur nos 2 canaux : 3 × 3 × 2 = 18 poids + 1 biais ; sur 16 canaux : 3 × 3 × 16 = 144 poids + 1 biais ; sur une photo couleur : 27 poids + 1 biais.
paramètres d'une couche = filtres × (k × k × canaux d'entrée + 1)
À toi de coder
Un coin, c'est un bord vertical et un bord horizontal au même endroit. La couche 2 peut donc combiner les deux canaux de la couche 1 : un neurone qui additionne les deux cartes (poids 1 et 1), ajoute un biais de −3 et applique la ReLU ne garde que la case où la somme atteint 4, là où les deux bords sont présents. Première couche : des bords ; deuxième : des coins ; les suivantes : des formes plus grandes.
Le max pooling découpe la carte en zones de 2 × 2 cases et ne garde que le maximum de chacune. Trois bénéfices : (1) les petits décalages ne comptent plus (l'organe décalé d'un pixel donne le même résumé) ; (2) 4 fois moins de cases, donc moins de calculs ; (3) chaque case couvre 2 × 2 cases, le filtre 3 × 3 suivant voit une zone plus grande. Limite : seulement pour les petits décalages, et on perd la position exacte dans la zone (voulu).
À toi de coder
On enchaîne des étages « convolution, ReLU, pooling », puis la couche dense de J1 décide. Le CNN des 11 organes, forme = canaux × hauteur × largeur :
| Étape | Forme de la sortie |
|---|---|
| Entrée : une coupe | 1 × 28 × 28 |
| Convolution : 16 filtres 3 × 3, padding 1, ReLU | 16 × 28 × 28 |
| Max pooling 2 × 2 | 16 × 14 × 14 |
| Convolution : 32 filtres 3 × 3, padding 1, ReLU | 32 × 14 × 14 |
| Max pooling 2 × 2 | 32 × 7 × 7 |
| Flatten | 32 × 7 × 7 = 1 568 |
| Linear | 11 scores |
Pourquoi une couche dense à la fin ? Les 1 568 nombres disent chacun si un des 32 motifs est présent dans l'une des 7 × 7 zones. Chaque score d'organe doit les combiner tous : un neurone de J1 relié aux 1 568 nombres, nn.Linear(1568, 11). Pas de softmax à la fin : CrossEntropyLoss l'applique.
cnn = nn.Sequential( nn.Conv2d(1, 16, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(16, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Flatten(), nn.Linear(32 * 7 * 7, 11))
Les paquets ont la forme (64, 1, 28, 28), sans Flatten au début : le CNN lit l'image en 2D. La boucle d'entraînement, la perte et Adam (pas 0,001, paquets de 64, 10 époques) sont ceux de J1. À toi de compter les paramètres avec la démo : 22 059 contre 109 451.
À toi de coder