Aide à protéger la Grande barrière de corail avec tensorflow sur Kaggle Rejoignez Défi

Dégradés intégrés

Voir sur TensorFlow.org Exécuter dans Google Colab Afficher sur GitHub Télécharger le cahier Voir le modèle TF Hub

Ce didacticiel montre comment implémenter les gradients intégrés (IG) , une technique d' IA explicable introduite dans l'article Attribution axiomatique pour les réseaux profonds . IG vise à expliquer la relation entre les prédictions d'un modèle en fonction de ses caractéristiques. Il a de nombreux cas d'utilisation, notamment la compréhension de l'importance des fonctionnalités, l'identification de l'asymétrie des données et le débogage des performances du modèle.

L'IG est devenue une technique d'interprétabilité populaire en raison de sa large applicabilité à tout modèle différentiable (par exemple, images, texte, données structurées), de sa facilité de mise en œuvre, de ses justifications théoriques et de son efficacité de calcul par rapport aux approches alternatives qui lui permettent de s'adapter à de grands réseaux et fonctionnalités. espaces tels que les images.

Dans ce didacticiel, vous allez parcourir une implémentation d'IG étape par étape pour comprendre l'importance des caractéristiques de pixel d'un classificateur d'image. À titre d'exemple, considérons cette image d'un bateau-pompe pulvérisant des jets d'eau. Vous classeriez cette image comme un bateau-pompe et pourriez mettre en évidence les pixels qui composent le bateau et les canons à eau comme étant importants pour votre décision. Votre modèle classera également cette image en tant que bateau-pompe plus tard dans ce didacticiel ; Cependant, met-il en évidence les mêmes pixels comme étant importants pour expliquer sa décision ?

Dans les images ci-dessous intitulées "IG Attribution Mask" et "Original + IG Mask Overlay", vous pouvez voir que votre modèle met en évidence (en violet) les pixels comprenant les canons à eau et les jets d'eau du bateau comme étant plus importants que le bateau lui-même pour sa décision. Comment votre modèle va-t-il se généraliser aux nouveaux bateaux-pompes ? Qu'en est-il des bateaux-pompes sans jets d'eau ? Poursuivez votre lecture pour en savoir plus sur le fonctionnement de l'IG et sur la manière de l'appliquer à vos modèles afin de mieux comprendre la relation entre leurs prédictions et les fonctionnalités sous-jacentes.

Image de sortie 1

Installer

import matplotlib.pylab as plt
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub

Télécharger un classificateur d'images pré-entraîné depuis TF-Hub

IG peut être appliqué à n'importe quel modèle différentiable. Dans l'esprit de l'article original, vous utiliserez une version pré-entraînée du même modèle, Inception V1, que vous téléchargerez depuis TensorFlow Hub .

model = tf.keras.Sequential([
    hub.KerasLayer(
        name='inception_v1',
        handle='https://tfhub.dev/google/imagenet/inception_v1/classification/4',
        trainable=False),
])
model.build([None, 224, 224, 3])
model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 inception_v1 (KerasLayer)   (None, 1001)              6633209   
                                                                 
=================================================================
Total params: 6,633,209
Trainable params: 0
Non-trainable params: 6,633,209
_________________________________________________________________

À partir de la page du module, vous devez garder à l'esprit ce qui suit concernant Inception V1 :

Entrées : la forme d'entrée attendue pour le modèle est (None, 224, 224, 3) . Il s'agit d'un tenseur 4D dense de type float32 et de forme (batch_size, height, width, RGB channels) dont les éléments sont des valeurs de couleur RVB de pixels normalisées à la plage [0, 1]. Le premier élément est None pour indiquer que le modèle peut accepter n'importe quelle taille de lot d'entiers.

Sorties : Un tf.Tensor de logits sous la forme de (batch_size, 1001) . Chaque ligne représente le score prévu du modèle pour chacune des 1 001 classes d'ImageNet. Pour l'index de classe prédit supérieur du modèle, vous pouvez utiliser tf.argmax(predictions, axis=-1) . En outre, vous pouvez également convertir la sortie logit du modèle en probabilités prédites dans toutes les classes à l'aide tf.nn.softmax(predictions, axis=-1) pour quantifier l'incertitude du modèle et explorer des classes prédites similaires pour le débogage.

def load_imagenet_labels(file_path):
  labels_file = tf.keras.utils.get_file('ImageNetLabels.txt', file_path)
  with open(labels_file) as reader:
    f = reader.read()
    labels = f.splitlines()
  return np.array(labels)
imagenet_labels = load_imagenet_labels('https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt
16384/10484 [==============================================] - 0s 0us/step
24576/10484 [======================================================================] - 0s 0us/step

Charger et prétraiter les images avec tf.image

Vous illustrerez IG en utilisant deux images de Wikimedia Commons : un bateau- pompe et un panda géant .

def read_image(file_name):
  image = tf.io.read_file(file_name)
  image = tf.io.decode_jpeg(image, channels=3)
  image = tf.image.convert_image_dtype(image, tf.float32)
  image = tf.image.resize_with_pad(image, target_height=224, target_width=224)
  return image
img_url = {
    'Fireboat': 'http://storage.googleapis.com/download.tensorflow.org/example_images/San_Francisco_fireboat_showing_off.jpg',
    'Giant Panda': 'http://storage.googleapis.com/download.tensorflow.org/example_images/Giant_Panda_2.jpeg',
}

img_paths = {name: tf.keras.utils.get_file(name, url) for (name, url) in img_url.items()}
img_name_tensors = {name: read_image(img_path) for (name, img_path) in img_paths.items()}
Downloading data from http://storage.googleapis.com/download.tensorflow.org/example_images/San_Francisco_fireboat_showing_off.jpg
3956736/3954129 [==============================] - 0s 0us/step
3964928/3954129 [==============================] - 0s 0us/step
Downloading data from http://storage.googleapis.com/download.tensorflow.org/example_images/Giant_Panda_2.jpeg
811008/802859 [==============================] - 0s 0us/step
819200/802859 [==============================] - 0s 0us/step
plt.figure(figsize=(8, 8))
for n, (name, img_tensors) in enumerate(img_name_tensors.items()):
  ax = plt.subplot(1, 2, n+1)
  ax.imshow(img_tensors)
  ax.set_title(name)
  ax.axis('off')
plt.tight_layout()

png

Classer les images

Commençons par classer ces images et afficher les 3 prédictions les plus fiables. Voici une fonction utilitaire pour récupérer les top k étiquettes et probabilités prédites.

def top_k_predictions(img, k=3):
  image_batch = tf.expand_dims(img, 0)
  predictions = model(image_batch)
  probs = tf.nn.softmax(predictions, axis=-1)
  top_probs, top_idxs = tf.math.top_k(input=probs, k=k)
  top_labels = imagenet_labels[tuple(top_idxs)]
  return top_labels, top_probs[0]
for (name, img_tensor) in img_name_tensors.items():
  plt.imshow(img_tensor)
  plt.title(name, fontweight='bold')
  plt.axis('off')
  plt.show()

  pred_label, pred_prob = top_k_predictions(img_tensor)
  for label, prob in zip(pred_label, pred_prob):
    print(f'{label}: {prob:0.1%}')

png

fireboat: 32.6%
pier: 12.7%
suspension bridge: 5.7%

png

giant panda: 89.4%
teddy: 0.3%
gibbon: 0.3%

Calculer les dégradés intégrés

Votre modèle, Inception V1, est une fonction apprise qui décrit un mappage entre votre espace de caractéristiques d'entrée, les valeurs de pixels d'image et un espace de sortie défini par les valeurs de probabilité de classe ImageNet entre 0 et 1. Les premières méthodes d'interprétabilité pour les réseaux de neurones ont attribué des scores d'importance des caractéristiques à l'aide les gradients, qui vous indiquent quels pixels ont le local le plus raide par rapport à la prédiction de votre modèle à un point donné le long de la fonction de prédiction de votre modèle. Cependant, les gradients ne décrivent que les modifications locales de la fonction de prédiction de votre modèle en ce qui concerne les valeurs de pixel et ne décrivent pas entièrement la fonction de prédiction de votre modèle dans son intégralité. Au fur et à mesure que votre modèle "apprend" complètement la relation entre la plage d'un pixel individuel et la classe ImageNet correcte, le dégradé de ce pixel saturera , ce qui signifie qu'il deviendra de plus en plus petit et qu'il ira même jusqu'à zéro. Considérez la fonction de modèle simple ci-dessous :

def f(x):
  """A simplified model function."""
  return tf.where(x < 0.8, x, 0.8)

def interpolated_path(x):
  """A straight line path."""
  return tf.zeros_like(x)

x = tf.linspace(start=0.0, stop=1.0, num=6)
y = f(x)

png

  • gauche : Les gradients de votre modèle pour le pixel x sont positifs entre 0.0 et 0.8 mais passent à 0.0 entre 0.8 et 1.0. Le pixel x a clairement un impact significatif sur la poussée de votre modèle vers une probabilité prédite de 80 % sur la vraie classe. Est-il logique que l'importance du pixel x soit faible ou discontinue ?

  • à droite : l'intuition derrière IG est d'accumuler les gradients locaux du pixel x et d'attribuer son importance en tant que score pour combien il ajoute ou soustrait à la probabilité globale de classe de sortie de votre modèle. Vous pouvez décomposer et calculer IG en 3 parties :

    1. interpoler de petits pas le long d'une ligne droite dans l'espace des caractéristiques entre 0 (une ligne de base ou un point de départ) et 1 (la valeur du pixel d'entrée)
    2. calculer les gradients à chaque étape entre les prédictions de votre modèle par rapport à chaque étape
    3. approximez l'intégrale entre votre ligne de base et votre entrée en accumulant (moyenne cumulée) ces gradients locaux.

Pour renforcer cette intuition, vous parcourrez ces 3 parties en appliquant IG à l'exemple d'image "Fireboat" ci-dessous.

Établir une ligne de base

Une ligne de base est une image d'entrée utilisée comme point de départ pour calculer l'importance des caractéristiques. Intuitivement, vous pouvez considérer le rôle explicatif de la ligne de base comme représentant l'impact de l'absence de chaque pixel sur la prédiction "Fireboat" pour contraster avec son impact de chaque pixel sur la prédiction "Fireboat" lorsqu'il est présent dans l'image d'entrée. Par conséquent, le choix de la ligne de base joue un rôle central dans l'interprétation et la visualisation de l'importance des caractéristiques des pixels. Pour une discussion supplémentaire sur la sélection de la ligne de base, consultez les ressources de la section « Étapes suivantes » au bas de ce didacticiel. Ici, vous allez utiliser une image noire dont les valeurs de pixel sont toutes nulles.

D'autres choix que vous pouvez expérimenter incluent une image entièrement blanche ou une image aléatoire, que vous pouvez créer avec tf.random.uniform(shape=(224,224,3), minval=0.0, maxval=1.0) .

baseline = tf.zeros(shape=(224,224,3))
plt.imshow(baseline)
plt.title("Baseline")
plt.axis('off')
plt.show()

png

Déballer les formules dans le code

La formule des dégradés intégrés est la suivante :

\(IntegratedGradients_{i}(x) ::= (x_{i} - x'_{i})\times\int_{\alpha=0}^1\frac{\partial F(x'+\alpha \times (x - x'))}{\partial x_i}{d\alpha}\)

où:

\(_{i}\) = fonctionnalité
\(x\) = entrée
\(x'\) = ligne de base
\(\alpha\) = constante d'interpolation pour perturber les caractéristiques par

En pratique, le calcul d'une intégrale définie n'est pas toujours numériquement possible et peut être coûteux en calcul, vous calculez donc l'approximation numérique suivante :

\(IntegratedGrads^{approx}_{i}(x)::=(x_{i}-x'_{i})\times\sum_{k=1}^{m}\frac{\partial F(x' + \frac{k}{m}\times(x - x'))}{\partial x_{i} } \times \frac{1}{m}\)

où:

\(_{i}\) = caractéristique (pixel individuel)
\(x\) = entrée (tenseur d'image)
\(x'\) = ligne de base (tenseur d'image)
\(k\) = constante de perturbation de caractéristique mise à l'échelle
\(m\) = nombre d'étapes dans l'approximation de la somme de Riemann de l'intégrale
\((x_{i}-x'_{i})\) = un terme pour la différence par rapport à la ligne de base. Cela est nécessaire pour mettre à l'échelle les dégradés intégrés et les conserver en fonction de l'image d'origine. Le chemin de l'image de base à l'entrée est dans l'espace pixel. Puisqu'avec IG vous intégrez en ligne droite (transformation linéaire), cela finit par être à peu près équivalent au terme intégral de la dérivée de la fonction d'image interpolée par rapport à \(\alpha\) avec suffisamment de pas. L'intégrale additionne le gradient de chaque pixel multiplié par la variation du pixel le long du chemin. Il est plus simple d'implémenter cette intégration sous forme d'étapes uniformes d'une image à l'autre, en remplaçant \(x := (x' + \alpha(x-x'))\). Ainsi, le changement de variables donne \(dx = (x-x')d\alpha\). Le terme \((x-x')\) est constant et est factorisé hors de l'intégrale.

Interpoler des images

\(IntegratedGrads^{approx}_{i}(x)::=(x_{i}-x'_{i})\times\sum_{k=1}^{m}\frac{\partial F(\overbrace{x' + \frac{k}{m}\times(x - x')}^\text{interpolate m images at k intervals})}{\partial x_{i} } \times \frac{1}{m}\)

Tout d'abord, vous allez générer une interpolation linéaire entre la ligne de base et l'image d'origine. Vous pouvez considérer les images interpolées comme de petites étapes dans l'espace des caractéristiques entre votre ligne de base et l'entrée, représentées par \(\alpha\) dans l'équation d'origine.

m_steps=50
alphas = tf.linspace(start=0.0, stop=1.0, num=m_steps+1) # Generate m_steps intervals for integral_approximation() below.
def interpolate_images(baseline,
                       image,
                       alphas):
  alphas_x = alphas[:, tf.newaxis, tf.newaxis, tf.newaxis]
  baseline_x = tf.expand_dims(baseline, axis=0)
  input_x = tf.expand_dims(image, axis=0)
  delta = input_x - baseline_x
  images = baseline_x +  alphas_x * delta
  return images

Utilisons la fonction ci-dessus pour générer des images interpolées le long d'un chemin linéaire à des intervalles alpha entre une image de base noire et l'exemple d'image "Fireboat".

interpolated_images = interpolate_images(
    baseline=baseline,
    image=img_name_tensors['Fireboat'],
    alphas=alphas)

Visualisons les images interpolées. Remarque : une autre façon de penser à la constante \(\alpha\) est qu'elle augmente constamment l'intensité de chaque image interpolée.

fig = plt.figure(figsize=(20, 20))

i = 0
for alpha, image in zip(alphas[0::10], interpolated_images[0::10]):
  i += 1
  plt.subplot(1, len(alphas[0::10]), i)
  plt.title(f'alpha: {alpha:.1f}')
  plt.imshow(image)
  plt.axis('off')

plt.tight_layout();

png

Calculer les gradients

Voyons maintenant comment calculer les gradients afin de mesurer la relation entre les modifications d'une caractéristique et les modifications des prédictions du modèle. Dans le cas des images, le gradient nous indique quels pixels ont le plus fort effet sur les probabilités de classe prédites par les modèles.

\(IntegratedGrads^{approx}_{i}(x)::=(x_{i}-x'_{i})\times\sum_{k=1}^{m}\frac{\overbrace{\partial F(\text{interpolated images})}^\text{compute gradients} }{\partial x_{i} } \times \frac{1}{m}\)

où:
\(F()\) = la fonction de prédiction de votre modèle
\(\frac{\partial{F} }{\partial{x_i} }\) = gradient (vecteur de dérivées partielles \(\partial\)) de la fonction de prédiction de votre modèle F par rapport à chaque caractéristique \(x_i\)

TensorFlow vous facilite le calcul des gradients avec un tf.GradientTape .

def compute_gradients(images, target_class_idx):
  with tf.GradientTape() as tape:
    tape.watch(images)
    logits = model(images)
    probs = tf.nn.softmax(logits, axis=-1)[:, target_class_idx]
  return tape.gradient(probs, images)

Calculons les gradients pour chaque image le long du chemin d'interpolation par rapport à la sortie correcte. Rappelez-vous que votre modèle renvoie un tenseur de forme (1, 1001) avec des Tensor que vous convertissez en probabilités prédites pour chaque classe. Vous devez transmettre l'index de classe cible ImageNet correct à la fonction compute_gradients pour votre image.

path_gradients = compute_gradients(
    images=interpolated_images,
    target_class_idx=555)

Notez la forme de sortie de (n_interpolated_images, img_height, img_width, RGB) , qui nous donne le gradient pour chaque pixel de chaque image le long du chemin d'interpolation. Vous pouvez considérer ces gradients comme mesurant le changement dans les prédictions de votre modèle pour chaque petite étape dans l'espace des caractéristiques.

print(path_gradients.shape)
(51, 224, 224, 3)

Visualisation de la saturation des dégradés

Rappelez-vous que les gradients que vous venez de calculer ci-dessus décrivent les changements locaux de la probabilité prédite de votre modèle de "Fireboat" et peuvent saturer .

Ces concepts sont visualisés à l'aide des gradients que vous avez calculés ci-dessus dans les 2 tracés ci-dessous.

pred = model(interpolated_images)
pred_proba = tf.nn.softmax(pred, axis=-1)[:, 555]

png

  • gauche : ce graphique montre comment la confiance de votre modèle dans la classe "Fireboat" varie selon les alphas. Remarquez comment les gradients, ou la pente de la ligne, s'aplatissent ou saturent en grande partie entre 0,6 et 1,0 avant de se stabiliser à la probabilité prédite finale "Fireboat" d'environ 40 %.

  • droite : Le graphique de droite montre plus directement les magnitudes moyennes des gradients sur alpha. Notez comment les valeurs s'approchent brusquement et plongent même brièvement en dessous de zéro. En fait, votre modèle "apprend" le plus des gradients à des valeurs inférieures d'alpha avant de saturer. Intuitivement, vous pouvez penser à cela car votre modèle a appris les pixels, par exemple les canons à eau, pour faire la prédiction correcte, en envoyant ces gradients de pixels à zéro, mais il est encore assez incertain et concentré sur de faux pixels de pont ou de jet d'eau lorsque les valeurs alpha se rapprochent de la image d'entrée d'origine.

Pour vous assurer que ces pixels de canon à eau importants sont reflétés comme importants pour la prédiction "Fireboat", vous continuerez ci-dessous pour apprendre comment accumuler ces gradients pour approximer avec précision l'impact de chaque pixel sur votre probabilité prédite "Fireboat".

Accumuler des gradients (approximation intégrale)

Il existe de nombreuses façons différentes de calculer l'approximation numérique d'une intégrale pour IG avec différents compromis en termes de précision et de convergence entre différentes fonctions. Une classe populaire de méthodes s'appelle les sommes de Riemann . Ici, vous utiliserez la règle trapézoïdale (vous pouvez trouver du code supplémentaire pour explorer différentes méthodes d'approximation à la fin de ce didacticiel).

$IntegratedGrads^{approx} {i}(x)::=(x {i}-x' {i})\times \overbrace{\sum {k=1}^{m} }^\text{Sum m gradients locaux} \text{gradients(images interpolées)} \times \overbrace{\frac{1}{m} }^\text{Divide by m steps}$

À partir de l'équation, vous pouvez voir que vous additionnez sur m gradients et que vous divisez par m pas. Vous pouvez implémenter les deux opérations ensemble pour la partie 3 en tant que moyenne des gradients locaux de m prédictions interpolées et images d'entrée .

def integral_approximation(gradients):
  # riemann_trapezoidal
  grads = (gradients[:-1] + gradients[1:]) / tf.constant(2.0)
  integrated_gradients = tf.math.reduce_mean(grads, axis=0)
  return integrated_gradients

La fonction integral_approximation prend les gradients de la probabilité prédite de la classe cible par rapport aux images interpolées entre la ligne de base et l'image d'origine.

ig = integral_approximation(
    gradients=path_gradients)

Vous pouvez confirmer que la moyenne sur les gradients de m images interpolées renvoie un tenseur de gradients intégré avec la même forme que l'image "Giant Panda" originale.

print(ig.shape)
(224, 224, 3)

Mettre tous ensemble

Vous allez maintenant combiner les 3 parties générales précédentes dans une fonction IntegratedGradients et utiliser un décorateur @tf.function pour le compiler dans un graphique TensorFlow appelable haute performance. Ceci est mis en œuvre en 5 étapes plus petites ci-dessous :

\(IntegratedGrads^{approx}_{i}(x)::=\overbrace{(x_{i}-x'_{i})}^\text{5.}\times \overbrace{\sum_{k=1}^{m} }^\text{4.} \frac{\partial \overbrace{F(\overbrace{x' + \overbrace{\frac{k}{m} }^\text{1.}\times(x - x'))}^\text{2.} }^\text{3.} }{\partial x_{i} } \times \overbrace{\frac{1}{m} }^\text{4.}\)

  1. Générer des alphas \(\alpha\)

  2. Générer des images interpolées = \((x' + \frac{k}{m}\times(x - x'))\)

  3. Calculer les gradients entre les prédictions de sortie du modèle \(F\) par rapport aux caractéristiques d'entrée = \(\frac{\partial F(\text{interpolated path inputs})}{\partial x_{i} }\)

  4. Approximation intégrale par gradients de moyenne = \(\sum_{k=1}^m \text{gradients} \times \frac{1}{m}\)

  5. Mettre à l'échelle les dégradés intégrés par rapport à l'image d'origine = \((x_{i}-x'_{i}) \times \text{integrated gradients}\). La raison pour laquelle cette étape est nécessaire est de s'assurer que les valeurs d'attribution accumulées sur plusieurs images interpolées sont dans les mêmes unités et représentent fidèlement l'importance des pixels sur l'image d'origine.

def integrated_gradients(baseline,
                         image,
                         target_class_idx,
                         m_steps=50,
                         batch_size=32):
  # Generate alphas.
  alphas = tf.linspace(start=0.0, stop=1.0, num=m_steps+1)

  # Collect gradients.    
  gradient_batches = []

  # Iterate alphas range and batch computation for speed, memory efficiency, and scaling to larger m_steps.
  for alpha in tf.range(0, len(alphas), batch_size):
    from_ = alpha
    to = tf.minimum(from_ + batch_size, len(alphas))
    alpha_batch = alphas[from_:to]

    gradient_batch = one_batch(baseline, image, alpha_batch, target_class_idx)
    gradient_batches.append(gradient_batch)

  # Stack path gradients together row-wise into single tensor.
  total_gradients = tf.stack(gradient_batch)

  # Integral approximation through averaging gradients.
  avg_gradients = integral_approximation(gradients=total_gradients)

  # Scale integrated gradients with respect to input.
  integrated_gradients = (image - baseline) * avg_gradients

  return integrated_gradients
@tf.function
def one_batch(baseline, image, alpha_batch, target_class_idx):
    # Generate interpolated inputs between baseline and input.
    interpolated_path_input_batch = interpolate_images(baseline=baseline,
                                                       image=image,
                                                       alphas=alpha_batch)

    # Compute gradients between model outputs and interpolated inputs.
    gradient_batch = compute_gradients(images=interpolated_path_input_batch,
                                       target_class_idx=target_class_idx)
    return gradient_batch
ig_attributions = integrated_gradients(baseline=baseline,
                                       image=img_name_tensors['Fireboat'],
                                       target_class_idx=555,
                                       m_steps=240)

Encore une fois, vous pouvez vérifier que les attributions d'entités IG ont la même forme que l'image d'entrée "Fireboat".

print(ig_attributions.shape)
(224, 224, 3)

Le document suggère que le nombre d'étapes se situe entre 20 et 300 selon l'exemple (bien qu'en pratique, cela puisse être plus élevé dans les milliers pour se rapprocher avec précision de l'intégrale). Vous pouvez trouver du code supplémentaire pour vérifier le nombre approprié d'étapes dans les ressources "Étapes suivantes" à la fin de ce didacticiel.

Visualisez les attributions

Vous êtes prêt à visualiser les attributions et à les superposer sur l'image d'origine. Le code ci-dessous additionne les valeurs absolues des dégradés intégrés sur les canaux de couleur pour produire un masque d'attribution. Cette méthode de traçage capture l'impact relatif des pixels sur les prédictions du modèle.

En regardant les attributions sur l'image "Fireboat", vous pouvez voir que le modèle identifie les canons à eau et les becs comme contribuant à sa prédiction correcte.

_ = plot_img_attributions(image=img_name_tensors['Fireboat'],
                          baseline=baseline,
                          target_class_idx=555,
                          m_steps=240,
                          cmap=plt.cm.inferno,
                          overlay_alpha=0.4)

png

Sur l'image "Giant Panda", les attributions mettent en évidence la texture, le nez et la fourrure du visage du Panda.

_ = plot_img_attributions(image=img_name_tensors['Giant Panda'],
                          baseline=baseline,
                          target_class_idx=389,
                          m_steps=55,
                          cmap=plt.cm.viridis,
                          overlay_alpha=0.5)

png

Utilisations et limites

Cas d'utilisation

  • L'utilisation de techniques telles que les dégradés intégrés avant de déployer votre modèle peut vous aider à développer une intuition sur comment et pourquoi cela fonctionne. Les traits mis en évidence par cette technique correspondent-ils à votre intuition ? Si ce n'est pas le cas, cela peut indiquer un bogue dans votre modèle ou votre jeu de données, ou un surajustement.

Limites

  • Les dégradés intégrés fournissent des importances de fonctionnalités sur des exemples individuels, cependant, ils ne fournissent pas d'importances de fonctionnalités globales sur l'ensemble d'un ensemble de données.

  • Les dégradés intégrés fournissent des importances de fonctionnalités individuelles, mais n'expliquent pas les interactions et les combinaisons de fonctionnalités.

Prochaines étapes

Ce didacticiel a présenté une implémentation de base des dégradés intégrés. Dans une prochaine étape, vous pouvez utiliser ce cahier pour essayer vous-même cette technique avec différents modèles et images.

Pour les lecteurs intéressés, il existe une version plus longue de ce didacticiel (qui inclut du code pour différentes lignes de base, pour calculer des approximations intégrales et pour déterminer un nombre suffisant d'étapes) que vous pouvez trouver ici .

Pour approfondir votre compréhension, consultez l'article Axiomatic Attribution for Deep Networks and Github repository , qui contient une implémentation dans une version précédente de TensorFlow. Vous pouvez également explorer l'attribution des fonctionnalités et l'impact de différentes lignes de base sur distill.pub .

Intéressé par l'intégration de l'IG dans vos workflows d'apprentissage automatique de production pour l'importance des fonctionnalités, l'analyse des erreurs de modèle et la surveillance de l'asymétrie des données ? Découvrez le produit d' IA Explicable de Google Cloud qui prend en charge les attributions IG. Le groupe de recherche Google AI PAIR a également ouvert l' outil What-if qui peut être utilisé pour le débogage de modèles, y compris la visualisation des attributions de fonctionnalités IG.