Aller au contenu principal

Module 10 — Interprétation : Grad-CAM et cartes de saillance

Le ResNet50 affiné du module 9 atteint 92 % de précision de validation sur les six catégories de déchets. C'est un bon score, mais ce chiffre seul ne dit pas sur quoi le modèle s'appuie pour décider. Peut-être regarde-t-il la bouteille, peut-être regarde-t-il l'ombre qu'elle projette sur le tapis. Un modèle qui obtient la bonne réponse pour la mauvaise raison échoue dès que le fond change. Ce module montre comment produire une carte visuelle de ce qu'un CNN a réellement utilisé pour sa prédiction, avec Grad-CAM comme outil principal, et se termine sur les limites méthodologiques que trop d'articles ignorent.

L'idée de Grad-CAM en trois pas

Grad-CAM — Selvaraju et al., 2017 — produit une heatmap superposable à l'image d'origine, indiquant où le modèle a puisé son évidence pour une classe donnée. La construction tient en trois pas :

  1. Choisir une couche cible : la dernière couche convolutive avant le sous-échantillonnage global. Ses cartes de caractéristiques ont encore une résolution spatiale suffisante et portent des concepts abstraits.
  2. Calculer les gradients de la sortie de la classe visée par rapport à chaque carte de cette couche. La moyenne spatiale de ces gradients donne un poids par carte, qui mesure l'importance de chaque canal pour cette prédiction.
  3. Combiner : la somme pondérée des cartes de caractéristiques (par leurs poids), suivie d'une ReLU, produit la heatmap. On la redimensionne à la taille de l'image et on la superpose.

Mathématiquement, pour la classe cc et la couche cible à KK cartes AkA^k de taille h×wh \times w :

αkc=1hwi,jycAijk,Lc=ReLU ⁣(kαkcAk).\alpha_k^c = \dfrac{1}{h \cdot w} \sum_{i,j} \dfrac{\partial y^c}{\partial A_{ij}^k}, \qquad L^c = \operatorname{ReLU}\!\left(\sum_k \alpha_k^c A^k\right).

La ReLU finale ne garde que les régions positivement liées à la classe : celles qui, en devenant plus actives, augmenteraient le score. Les régions qui iraient contre sont écartées.

Implémentation en Keras

Le code utilise tf.GradientTape (module 1 du cours 08) pour capturer les gradients à la volée.

import numpy as np
import tensorflow as tf
from tensorflow import keras

def grad_cam(modele, image, classe_id, nom_couche="conv5_block3_out"):
"""image de forme (1, H, W, 3), deja preprocessee."""
modele_grad = keras.Model(
modele.inputs,
[modele.get_layer(nom_couche).output, modele.output],
)
with tf.GradientTape() as ruban:
sortie_conv, predictions = modele_grad(image)
score_classe = predictions[:, classe_id]

gradients = ruban.gradient(score_classe, sortie_conv) # (1, h, w, K)
poids = tf.reduce_mean(gradients, axis=(0, 1, 2)) # (K,)
heatmap = tf.reduce_sum(sortie_conv[0] * poids, axis=-1) # (h, w)
heatmap = tf.maximum(heatmap, 0) # ReLU
heatmap = heatmap / (tf.reduce_max(heatmap) + 1e-8) # normaliser 0..1
return heatmap.numpy()

La superposition sur l'image d'origine se fait par redimensionnement au format de l'entrée, application d'une palette de couleurs — le jet de matplotlib est le classique — et mélange linéaire avec l'image d'origine à un poids de 0,4.

import cv2
import matplotlib.pyplot as plt

heatmap = grad_cam(modele, image_pretraitee, classe_id=2)
heatmap_couleur = cv2.applyColorMap(np.uint8(255 * cv2.resize(heatmap, (224, 224))),
cv2.COLORMAP_JET)
superposition = cv2.addWeighted(image_originale, 0.6, heatmap_couleur, 0.4, 0)
plt.imshow(cv2.cvtColor(superposition, cv2.COLOR_BGR2RGB))

Ce qu'on découvre sur le jeu de déchets

Passer Grad-CAM sur une centaine d'exemples du jeu de déchets à trier révèle plusieurs comportements du modèle. Trois cas classiques :

  • Sur une bouteille en verre correctement classée, la heatmap se concentre sur la silhouette du goulot et l'anneau caractéristique. C'est le comportement attendu.
  • Sur un carton correctement classé, la heatmap couvre les arêtes du carton et parfois le motif ondulé visible sur la tranche. Encore attendu.
  • Sur un plastique correctement classé, la heatmap se concentre parfois... sur le sol carrelé derrière l'objet. Le modèle a appris que les photos de plastique de ce jeu ont plus souvent été prises sur un carrelage particulier, et il utilise cet indice de fond comme raccourci.

Ce troisième cas est le motif « biais de fond », documenté à répétition depuis Ribeiro et al. (2016) sur les huskies vs loups (le modèle regardait la neige). Sans Grad-CAM, il passe complètement inaperçu : la précision de validation est élevée parce que la validation partage la même distribution de fonds que l'entraînement. En production, dès qu'on change de tapis, la précision s'effondre.

Grad-CAM sert d'audit, pas de rapport final

Un modèle qui produit de belles heatmaps sur 20 exemples bien choisis n'est pas un modèle audité. Il faut échantillonner aléatoirement, y compris sur les erreurs, et en particulier sur les faux positifs. Le biais de fond n'apparaît que sur les cas où le fond porte l'information — les faux positifs en sont souvent des exemples pédagogiques.

Cartes de saillance : la génération précédente

Grad-CAM n'est pas la première méthode. Les cartes de saillance (Simonyan et al., 2013) calculent directement le gradient du score de classe par rapport aux pixels d'entrée, puis en prennent la valeur absolue ou la norme par canal.

def saillance(modele, image, classe_id):
image_tf = tf.Variable(image)
with tf.GradientTape() as ruban:
predictions = modele(image_tf)
score = predictions[:, classe_id]
gradients = ruban.gradient(score, image_tf)
return tf.reduce_max(tf.abs(gradients[0]), axis=-1).numpy()

Ces cartes sont plus fines que Grad-CAM — un pixel par pixel — mais aussi beaucoup plus bruitées. Elles s'accompagnent facilement d'artefacts liés aux gradients non-lisses des ReLU. Grad-CAM++, SmoothGrad, Integrated Gradients sont autant de raffinements qui atténuent le bruit et sont aujourd'hui la référence pour un audit sérieux.

Le choix : Grad-CAM pour comprendre quelle région compte, saillance et ses variantes pour comprendre quels pixels précis comptent.

Les limites qu'on ne dit pas assez

L'interprétation visuelle des CNN est un outil précieux, mais fragile. Plusieurs travaux ont montré ses limites, à connaître avant de faire reposer une décision réglementaire dessus.

  • Sanity checks (Adebayo et al., 2018) : plusieurs méthodes de saillance produisent des cartes qui ne changent pas quand on randomise les poids du modèle, ce qui signifie qu'elles reflètent surtout la structure de l'image d'entrée, pas ce que le modèle a appris.
  • Manipulation adverse (Ghorbani et al., 2019) : on peut produire deux images visuellement identiques pour un humain qui donnent des heatmaps Grad-CAM complètement différentes. L'interprétation n'est pas invariante à des perturbations imperceptibles.
  • Résolution limitée : la couche cible de Grad-CAM a typiquement 7x7 pixels sur ResNet50 en 224x224. Une heatmap redimensionnée à 224x224 par interpolation bilinéaire donne l'illusion d'une précision qu'elle n'a pas.
L'interprétation est un test de plausibilité, pas une preuve

Une heatmap qui cible l'objet renforce la confiance ; une heatmap qui cible le fond signale un problème à investiguer. Mais une heatmap qui semble bonne ne prouve pas que le modèle est bon : elle n'exclut pas qu'il utilise d'autres indices non visibles à ce niveau de résolution. Traiter Grad-CAM comme un filet de sécurité, pas comme un rapport de fiabilité.

Vers un pipeline d'audit visuel

Un audit sérieux d'un modèle de vision — c'est ce que ferait un responsable qualité du tri de déchets avant de mettre le modèle en production — combine :

  1. Grad-CAM sur 200 exemples aléatoires, tirés à parts égales entre bonnes et mauvaises prédictions.
  2. Grad-CAM sur les 30 faux positifs les plus confiants, où le biais de fond apparaît le plus.
  3. Test d'occlusion : remplacer une région rectangulaire par du gris et mesurer la chute du score de la classe prédite ; croiser avec la heatmap.
  4. Test de fond : changer le fond à luminosité et contraste équivalents, mesurer la stabilité de la prédiction.

Ces quatre étapes prennent une demi-journée sur un jeu de test, et cadrent le modèle beaucoup mieux qu'un simple score de validation.

En résumé

  • Grad-CAM produit une heatmap superposable à l'image, calculée à partir des gradients de la sortie par rapport aux cartes de la dernière couche convolutive.
  • Le principal usage est de détecter les biais de fond — un modèle qui regarde le tapis plutôt que la bouteille — invisibles dans la précision de validation quand la validation partage la distribution de l'entraînement.
  • Les cartes de saillance au pixel sont plus fines mais plus bruitées ; Grad-CAM++ et SmoothGrad les rendent plus fiables.
  • L'interprétation visuelle est un test de plausibilité, pas une preuve : plusieurs cartes ne changent pas quand on randomise les poids, et des manipulations adverses invisibles peuvent renverser la heatmap.

Ce module clôt la partie technique du cours. Le récapitulatif suivant synthétise les onze modules et annonce l'examen final.