Aller au contenu
Apprendre.
  • M1 · toutes les matières15 matières : Préparation de données, API & sécurité, CI/CD, Docker, Merise, Dataviz, KNIME, ML appliqué : projet LoL, SQL & UML, SQL avancé, Machine Learning, Git, IA frugale & responsable, Qualité des données, MathématiquesAnnée
  • M2 · toutes les matières4 matières : Deep Learning, AI Act, Comex & Fundraising, Gouvernance & DataMeshAnnée
  • Deep LearningM2 · 4 modules · Réseaux de neurones, CNN, texte, modèles génératifs.Matière
  • Préparation de donnéesM1 · 3 modules · Nettoyer, transformer et fusionner des données avec Python.Matière
  • API & sécuritéM1 · 2 modules · Consommer, concevoir et sécuriser des API.Matière
  • CI/CDM1 · 1 module · Intégration et livraison continues.Matière
  • DockerM1 · 3 modules · Conteneurs, images, volumes, réseaux, Compose.Matière
  • MeriseM1 · 2 modules · Modéliser une base : MCD, MLD, MPD.Matière
  • DatavizM1 · 2 modules · Visualiser pour comprendre et décider.Matière
  • KNIMEM1 · 1 module · Explorer et nettoyer des données en workflow.Matière
  • ML appliqué : projet LoLM1 · 2 modules · Du besoin métier au POC de vision par ordinateur.Matière
  • SQL & UMLM1 · 3 modules · Modèles UML et requêtes SQL.Matière
  • SQL avancéM1 · 3 modules · Jointures, fenêtres, CTE, optimisation.Matière
  • Machine LearningM1 · 3 modules · Régression, classification, segmentation, projet.Matière

↑↓ naviguer↵ ouvre le résultat en surbrillanceesc fermer

Partie 1 · Voir

Repérer un motif partout

Hier, ton réseau lisait une coupe comme une liste de 784 nombres. Trois défauts, qu'on corrige aujourd'hui :

  • Les voisins : l'image est aplatie, deux pixels voisins comptent comme deux pixels quelconques.
  • Les décalages : d'un patient à l'autre, l'organe n'est pas au même endroit ; décalé de quelques pixels, c'est pour le MLP une tout autre liste de nombres.
  • La taille : une photo couleur de 224 × 224 donne plus de 19 millions de poids pour une seule couche de 128 neurones.

Pour tout calculer à la main, on zoome sur un carré de 6 × 6 pixels au coin d'un organe : 0 = sombre, 1 = clair. L'organe a un bord à gauche et un bord en haut. Un bord, c'est deux pixels voisins de valeurs nettement différentes. Comment le trouver par un calcul ?

Prends une seule ligne : les pixels n° 1 à 6 valent 0, 0, 0, 1, 1, 1. Le pixel 3 touche-t-il un bord ? On compare ses deux voisins : droite − gauche = 1 − 0 = 1 : oui. Deux voisins égaux donneraient 0 : pas de bord.

C'est une somme pondérée, comme dans un neurone de J1, avec les poids −1, 0, +1 : −1 retire le voisin de gauche, +1 ajoute celui de droite, 0 ignore le pixel du milieu. Les trois pixels lus forment la fenêtre. Calcul : (−1) × 0 + 0 × 0 + (+1) × 1 = 1.

À toi de le faire glisser sur toute la ligne : la fenêtre avance d'un pixel à la fois, et on range chaque réponse sous le pixel du milieu. Les pixels 1 et 6 n'ont qu'un voisin : pas de réponse pour eux.

À toi de coder

Faire glisser la fenêtre sur une ligne

Un neurone du MLP a un poids par pixel : si le bord se décale d'un pixel, il le manque (réponse 0). Ici, on garde les trois mêmes poids et on refait le calcul autour de chaque pixel : ils sont attachés à une place dans la fenêtre (gauche, milieu, droite), pas à un pixel. Complète convolution_ligne(ligne, w) : pour chaque pixel qui a ses deux voisins, elle calcule la somme pondérée de sa fenêtre de 3 pixels et range le résultat dans la liste reponses.

Puis applique-la à la ligne d'origine (reponses) et à la même ligne décalée d'un pixel (reponses_decalees) : tu dois retrouver le bord, là où il est maintenant.

Ctrl/⌘+Entrée

Sur l'image entière, on fait le même calcul avec une fenêtre de 3 × 3 pixels et 9 poids : chaque ligne des poids est notre −1, 0, +1. On multiplie chaque pixel par le poids placé au même endroit (case par case, ce n'est pas un produit de matrices), puis on additionne les 9 produits.

Exemple de la fenêtre qui chevauche le bord sur ses trois lignes : trois fois (1 − 0), donc 3. Un pixel isolé, plus clair par hasard, ne fait répondre qu'une ligne : 1. Trois lignes rendent donc la réponse plus forte pour un vrai bord que pour une tache. À toi : la fenêtre tout en haut, colonnes 2 à 4, donne 1 (le bord ne traverse qu'une ligne sur trois).

En faisant glisser la fenêtre partout, on obtient une réponse par position : un tableau de 4 × 4 réponses, rangées à la place du pixel du milieu. Essaie toi-même.

L'image 6 × 6 du cours. Choisis le filtre, déplace la fenêtre (ligne, colonne) et change le biais : tu vois les 9 produits, la somme, puis la ReLU. Avec b = −1, la carte du bord vertical devient 0 0 0 0 / 0 1 1 0 / 0 2 2 0 / 0 2 2 0.

À toi de coder

La carte de convolution d'une image

Tu codes maintenant la convolution complète, sur des listes de listes. Pour une image de n × n pixels et un filtre de k × k, la fenêtre tient à n − k + 1 positions dans chaque sens : 4 × 4 réponses pour 6 × 6 pixels. La case carte[i][j] reçoit la somme pondérée de la fenêtre qui commence à la ligne i, colonne j.

Complète convolution(image, filtre), puis calcule carte_verticale et carte_horizontale avec les deux filtres du cours (le second calcule « bas − haut »). C'est le tableau de réponses des diapositives.

Ctrl/⌘+Entrée

On vient de construire une convolution. Trois mots à bien poser :

  • le filtre (ou noyau, kernel) : les 9 poids, qui fixent le motif cherché ;
  • la convolution : refaire le même calcul à chaque position de l'image ;
  • la carte (feature map) : le tableau des réponses, qui montre où est le motif.

Chaque case de la carte est la sortie d'un neurone de J1 qui ne lirait que 9 pixels voisins, et tous ces neurones ont les mêmes 9 poids : les poids sont partagés. Il manque deux ingrédients du neurone : le biais et l'activation. z = w₁x₁ + … + w₉x₉ + b, puis ReLU(z) = max(0, z). Avec b = −1 (choisi pour l'exemple, dans un vrai CNN il est appris), une case ne reste positive que si le bord traverse au moins deux lignes de la fenêtre. Un filtre 3 × 3 a 9 poids + 1 biais = 10 paramètres, quelle que soit l'image :

ImageUn neurone du MLPUn filtre 3 × 3
6 × 636 + 1 = 379 + 1 = 10
28 × 28784 + 1 = 7859 + 1 = 10
224 × 224 (gris)50 176 + 1 = 50 1779 + 1 = 10

Attention : peu de poids ne veut pas dire peu de calculs, le filtre refait sa somme à chaque position. Et le calcul ne sait pas ce qu'est un organe : un vaisseau ou du bruit répondent aussi.

Les pixels du bord de l'image. Un pixel du bord n'a pas de voisin de l'autre côté : la fenêtre ne peut pas se centrer sur lui, d'où 4 × 4 réponses pour 6 × 6 pixels, et une carte qui rétrécirait encore à chaque couche. Le padding entoure l'image d'un cadre de zéros : avec padding=1, les 36 pixels ont une réponse et la carte fait 6 × 6. Limite : ces voisins inventés valent 0, les réponses du bord sont un peu faussées.

Le stride. Avec un stride de 2, la fenêtre avance de deux pixels, en largeur et en hauteur : la carte 4 × 4 devient 2 × 2 (0 1 / 0 3), 4 fois moins de réponses. Utile pour réduire vite une grande image (ResNet le fait dès sa première couche).

Tout tient dans une formule, avec n la taille de l'image, k celle du filtre, p le padding et s le stride :

taille = ⌊(n + 2p − k) / s⌋ + 1

Notre carré : (6 + 0 − 3)/1 + 1 = 4. Avec padding 1 : (6 + 2 − 3)/1 + 1 = 6. Avec stride 2 : ⌊(6 + 0 − 3)/2⌋ + 1 = 2. Pour une coupe de 28 × 28 et un filtre 5 × 5 : 24 sans padding, et il faut p = 2 pour garder 28.

Règle n, k, p, s : le dessin montre l'image entourée de son cadre de zéros, la première fenêtre et les centres des réponses. Retrouve les cas du cours (6, 3, 0, 1 → 4 ; avec p = 1 → 6 ; avec s = 2 → 2) et le cas 28, 5, p = 2 → 28.

À toi de coder

Prévoir la taille d'une carte

Avant de construire un CNN, il faut prévoir la taille des cartes : c'est elle qui fixe le nombre d'entrées de la couche dense finale. Écris taille(n, k, p, s) avec la formule du cours. Le « arrondi à l'entier inférieur » est important : quand la fenêtre ne tombe pas juste (stride qui ne divise pas), la dernière position incomplète est abandonnée. En Python, la division entière est //.

Puis donne dans p5 le padding qui garde 28 × 28 avec un filtre 5 × 5 et un stride de 1 : règle (k − 1) / 2.

Ctrl/⌘+Entrée