Dans un monde où les systèmes d’intelligence artificielle prennent des décisions critiques — en médecine, en justice, en finance ou en conduite autonome — il ne suffit plus qu’un modèle soit performant : il doit aussi être compréhensible. C’est l’objectif de l’IA explicable (Explainable AI ou XAI) : rendre les décisions des modèles transparentes, interprétables et dignes de confiance. Contrairement aux « boîtes noires » traditionnelles, les méthodes XAI cherchent à répondre à des questions essentielles : Pourquoi ce diagnostic ? Sur quoi le modèle s’appuie-t-il ? Quels éléments de l’entrée ont influencé la prédiction ? En vision par ordinateur, ces explications prennent souvent la forme de cartes de saillance qui mettent en évidence les régions d’une image pertinentes pour la décision. Grad-CAM s’inscrit précisément dans cette démarche.
Depuis que je travaille avec les réseaux de neurones convolutionnels, j’ai cherché à mieux comprendre comment ces modèles prennent leurs décisions. Une prédiction correcte ne suffit pas : il faut aussi s’assurer qu’elle repose sur des indices pertinents dans l’image, et non sur des biais ou des artefacts.
C’est dans cette optique que je me suis tourné vers l’XAI (Explainable AI), et plus précisément vers Grad-CAM (Gradient-weighted Class Activation Mapping). Cette méthode permet de générer une carte de chaleur indiquant quelles régions d’une image ont le plus contribué à la prédiction d’une classe donnée.
Contrairement à des approches plus anciennes comme CAM, Grad-CAM fonctionne sans modification de l’architecture du réseau : il suffit d’avoir accès aux activations et aux gradients de la dernière couche convolutionnelle. Dans cet article, je détaille son fonctionnement étape par étape, en développant chaque idée avec des paragraphes explicatifs et les formules essentielles.
Un réseau de neurones convolutionnel transforme progressivement une image brute en une représentation de plus en plus abstraite. Les premières couches détectent des motifs simples (bords, textures), tandis que les couches profondes combinent ces motifs pour former des concepts sémantiques (yeux, roues, ailes, etc.).
La dernière couche convolutionnelle occupe une position stratégique : elle est suffisamment profonde pour contenir des informations sémantiques riches, tout en conservant une structure spatiale sous forme de cartes d’activation. Contrairement aux couches entièrement connectées (fully connected), qui écrasent toute information de localisation, cette couche permet de savoir où dans l’image une caractéristique a été détectée.
C’est pourquoi Grad-CAM se concentre sur les activations de cette couche : elles offrent le meilleur compromis entre sémantique et localisation.
Soit \( x \in \mathbb{R}^{H \times W \times 3} \) une image d’entrée, et \( f \) un CNN pré-entraîné. Après propagation, la dernière couche convolutionnelle produit un tenseur d’activations :
\[ A = \{ A^k \}_{k=1}^K \quad \text{où} \quad A^k \in \mathbb{R}^{u \times v} \]Ici, \( K \) est le nombre de filtres (ou canaux) de la couche, et \( u \times v \) sa résolution spatiale (par exemple \( 7 \times 7 \) pour ResNet-50). Chaque \( A^k \) est une carte d’activation : elle indique, à chaque position \( (i,j) \), à quel point le filtre \( k \) a « réagi » à la présence d’une caractéristique apprise.
Soit \( y^c \) le logit (score avant softmax) associé à la classe cible \( c \). Ce score est une fonction non linéaire des activations \( A \), passant généralement par un global average pooling suivi d’une ou plusieurs couches fully connected.
L’objectif de Grad-CAM est de construire une carte \( L^c_{\text{Grad-CAM}} \in \mathbb{R}^{u \times v} \) qui reflète l’influence locale de chaque position dans \( A \) sur la valeur de \( y^c \).
Pour quantifier l’impact d’une activation sur la prédiction, Grad-CAM utilise les gradients de \( y^c \) par rapport à \( A \). Ces gradients sont calculés via la backpropagation et s’écrivent :
\[ \frac{\partial y^c}{\partial A^k_{i,j}} \]Intuitivement, cette dérivée partielle indique comment le score \( y^c \) changerait si l’on modifiait légèrement l’activation à la position \( (i,j) \) dans la carte \( k \). Un gradient positif signifie que cette activation soutient la classe \( c \) ; un gradient négatif, qu’elle la contredit.
Ces gradients sont essentiels : ils relient la sortie globale du réseau (le score d’une classe) à des éléments locaux dans les représentations internes. C’est cette connexion entre global et local qui rend Grad-CAM si puissant.
Pourquoi utiliser le logit et non la probabilité softmax ?
La fonction softmax compresse les logits dans \([0,1]\) et introduit des interactions entre classes (à cause de la normalisation). Cela peut atténuer ou déformer les gradients. En restant au niveau du logit, on obtient des gradients plus directs et plus stables.
Si l’on utilisait les gradients pixel par pixel, la carte finale serait très bruitée et difficile à interpréter. Grad-CAM adopte une stratégie plus robuste : moyenner les gradients spatialement pour chaque canal \( k \). Cela donne un poids scalaire :
\[ \alpha_k^c = \frac{1}{u v} \sum_{i=1}^{u} \sum_{j=1}^{v} \frac{\partial y^c}{\partial A^k_{i,j}} \]Ce poids \( \alpha_k^c \) représente l’importance moyenne du canal \( k \) pour la classe \( c \). Il joue le rôle d’un coefficient d’attention : plus il est élevé, plus le filtre \( k \) est pertinent pour reconnaître la classe cible.
Cette agrégation a deux avantages :
Une fois les poids \( \alpha_k^c \) calculés, on construit une carte composite en combinant linéairement les cartes d’activation :
\[ L^c(i,j) = \sum_{k=1}^{K} \alpha_k^c \cdot A^k_{i,j} \]Cette somme pondérée agrège, à chaque position \( (i,j) \), la contribution de tous les canaux, pondérée par leur pertinence pour la classe \( c \). Le résultat est une carte qui reflète l’activation globale utile à la prédiction.
Cependant, certaines régions peuvent avoir une influence négative sur \( y^c \) — par exemple, la présence d’un ciel bleu pourrait réduire la probabilité de « sous-marin ». Puisque l’on souhaite visualiser ce qui justifie la prédiction (et non ce qui la contredit), on applique la fonction ReLU :
\[ L^c_{\text{Grad-CAM}}(i,j) = \text{ReLU} \left( \sum_{k=1}^{K} \alpha_k^c \cdot A^k_{i,j} \right) \]La fonction ReLU, définie par \( \text{ReLU}(z) = \max(0, z) \), élimine toutes les contributions négatives. Cela garantit que la heatmap ne met en évidence que les régions qui ont positivement activé la classe cible — une exigence fondamentale pour une explication fidèle.
La carte \( L^c_{\text{Grad-CAM}} \) est de taille \( u \times v \), bien plus petite que l’image originale \( H \times W \). Pour la superposer visuellement, on effectue un upsampling (généralement bilinéaire) :
\[ \hat{L}^c = \text{Upsample}\left(L^c_{\text{Grad-CAM}}, \text{size}=(H, W)\right) \]Ensuite, on normalise la carte entre 0 et 1 pour faciliter l’affichage :
\[ \hat{L}^c_{\text{norm}} = \frac{\hat{L}^c - \min(\hat{L}^c)}{\max(\hat{L}^c) - \min(\hat{L}^c)} \]La carte normalisée est ensuite superposée en transparence sur l’image d’origine, souvent avec une colormap « hot » (noir → rouge → jaune). Le résultat est une visualisation intuitive : plus une zone est claire/chaude, plus elle a contribué à la décision.
L’ensemble du processus peut être résumé par la formule suivante :
\[ \boxed{ L^c_{\text{Grad-CAM}} = \text{ReLU} \left( \sum_{k=1}^{K} \left( \frac{1}{u v} \sum_{i=1}^{u} \sum_{j=1}^{v} \frac{\partial y^c}{\partial A^k_{i,j}} \right) A^k \right) } \]Cette expression incarne une idée puissante : l’explication d’une décision globale peut être construite à partir de contributions locales pondérées. Les gradients fournissent la pondération (sensibilité), les activations fournissent le support (représentation), et ReLU garantit la cohérence sémantique (seulement les contributions positives).
Bien que Grad-CAM soit robuste et largement applicable, il convient de garder à l’esprit quelques limites :
En pratique, il est recommandé de :
Grad-CAM est bien plus qu’un outil de visualisation : c’est une fenêtre sur le raisonnement spatial d’un CNN. En combinant de manière élégante les gradients (sensibilité) et les activations (représentation), il permet de transformer une décision opaque en une explication visuelle claire et exploitable.
Pour tout praticien du deep learning en vision, Grad-CAM constitue une première étape incontournable vers des systèmes plus transparents et fiables.
Dans le cadre de mon exploration, j’ai implémenté et testé Grad-CAM dans un environnement JAX/Flax, en l’appliquant à un classifieur CNN entraîné sur CIFAR-10.
Pour approfondir vos connaissances et explorer des outils avancés, voici quelques ressources :
Ma recommandation musicale du jour : à écouter sans modération !
Écouter sur YouTube