Gradientes integrados

Ver en TensorFlow.org Ejecutar en Google Colab Ver en GitHub Descargar libreta Ver modelo TF Hub

Este tutorial demuestra cómo implementar gradientes integrados (IG) , una técnica de IA explicable presentada en el artículo Atribución axiomática para redes profundas . IG tiene como objetivo explicar la relación entre las predicciones de un modelo en términos de sus características. Tiene muchos casos de uso, incluida la comprensión de la importancia de las funciones, la identificación de sesgos de datos y la depuración del rendimiento del modelo.

IG se ha convertido en una técnica de interpretabilidad popular debido a su amplia aplicabilidad a cualquier modelo diferenciable (por ejemplo, imágenes, texto, datos estructurados), facilidad de implementación, justificaciones teóricas y eficiencia computacional en relación con enfoques alternativos que le permiten escalar a grandes redes y funciones. espacios como las imágenes.

En este tutorial, recorrerá una implementación de IG paso a paso para comprender la importancia de las características de píxeles de un clasificador de imágenes. Como ejemplo, considere esta imagen de un barco de bomberos rociando chorros de agua. Clasificaría esta imagen como un barco de bomberos y podría resaltar los píxeles que forman el barco y los cañones de agua como importantes para su decisión. Su modelo también clasificará esta imagen como un barco de bomberos más adelante en este tutorial; sin embargo, ¿resalta los mismos píxeles como importantes al explicar su decisión?

En las imágenes a continuación tituladas "Máscara de atribución de IG" y "Original + Superposición de máscara de IG", puede ver que su modelo resalta (en púrpura) los píxeles que comprenden los cañones de agua y los chorros de agua del barco como más importantes que el propio barco para su decisión. ¿Cómo se generalizará su modelo a los nuevos barcos de bomberos? ¿Qué pasa con los barcos de bomberos sin chorros de agua? Siga leyendo para obtener más información sobre cómo funciona IG y cómo aplicar IG a sus modelos para comprender mejor la relación entre sus predicciones y las características subyacentes.

Imagen de salida 1

Configuración

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

Descargue un clasificador de imágenes preentrenado de TF-Hub

IG se puede aplicar a cualquier modelo diferenciable. En el espíritu del documento original, utilizará una versión preentrenada del mismo modelo, Inception V1, que descargará de 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
_________________________________________________________________

Desde la página del módulo, debe tener en cuenta lo siguiente sobre Inception V1:

Entradas : la forma de entrada esperada para el modelo es (None, 224, 224, 3) . Este es un tensor 4D denso de dtype float32 y forma (batch_size, height, width, RGB channels) cuyos elementos son valores de color RGB de píxeles normalizados al rango [0, 1]. El primer elemento es None para indicar que el modelo puede tomar cualquier tamaño de lote entero.

Salidas : Un tf.Tensor de logits en forma de (batch_size, 1001) . Cada fila representa la puntuación predicha del modelo para cada una de las 1001 clases de ImageNet. Para el índice de clase predicho superior del modelo, puede usar tf.argmax(predictions, axis=-1) . Además, también puede convertir la salida logit del modelo en probabilidades pronosticadas en todas las clases usando tf.nn.softmax(predictions, axis=-1) para cuantificar la incertidumbre del modelo y explorar clases pronosticadas similares para la depuración.

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')

Cargue y preprocese imágenes con tf.image

Ilustrará IG usando dos imágenes de Wikimedia Commons : un barco de bomberos y un panda gigante .

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

Clasificar imágenes

Comencemos clasificando estas imágenes y mostrando las 3 predicciones más seguras. A continuación se muestra una función de utilidad para recuperar las k etiquetas y probabilidades principales predichas.

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%

Calcular gradientes integrados

Su modelo, Inception V1, es una función aprendida que describe un mapeo entre su espacio de características de entrada, los valores de píxeles de la imagen y un espacio de salida definido por los valores de probabilidad de clase de ImageNet entre 0 y 1. Los primeros métodos de interpretación para las redes neuronales asignaban puntajes de importancia de características usando gradientes, que le indican qué píxeles tienen el local más inclinado en relación con la predicción de su modelo en un punto determinado a lo largo de la función de predicción de su modelo. Sin embargo, los gradientes solo describen los cambios locales en la función de predicción de su modelo con respecto a los valores de píxel y no describen completamente la función de predicción de su modelo en su totalidad. A medida que su modelo "aprende" por completo la relación entre el rango de un píxel individual y la clase ImageNet correcta, el gradiente de este píxel se saturará , lo que significa que se volverá cada vez más pequeño e incluso llegará a cero. Considere la siguiente función de modelo simple:

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

  • izquierda : los gradientes de su modelo para el píxel x son positivos entre 0,0 y 0,8, pero van a 0,0 entre 0,8 y 1,0. Pixel x claramente tiene un impacto significativo en empujar su modelo hacia el 80% de probabilidad prevista en la clase real. ¿Tiene sentido que la importancia del píxel x sea ​​pequeña o discontinua?

  • derecha : la intuición detrás de IG es acumular los gradientes locales del píxel x y atribuir su importancia como una puntuación de cuánto agrega o resta a la probabilidad de clase de salida general de su modelo. Puede desglosar y calcular IG en 3 partes:

    1. interpolar pequeños pasos a lo largo de una línea recta en el espacio de características entre 0 (una línea base o punto de inicio) y 1 (valor de píxel de entrada)
    2. calcule gradientes en cada paso entre las predicciones de su modelo con respecto a cada paso
    3. aproxime la integral entre su línea de base y la entrada acumulando (promedio acumulativo) estos gradientes locales.

Para reforzar esta intuición, recorrerá estas 3 partes aplicando IG a la imagen de ejemplo "Fireboat" a continuación.

Establecer una línea de base

Una línea de base es una imagen de entrada que se utiliza como punto de partida para calcular la importancia de las características. Intuitivamente, puede pensar en el papel explicativo de la línea de base como una representación del impacto de la ausencia de cada píxel en la predicción "Fireboat" para contrastar con su impacto de cada píxel en la predicción "Fireboat" cuando está presente en la imagen de entrada. Como resultado, la elección de la línea de base juega un papel central en la interpretación y visualización de la importancia de las características de los píxeles. Para una discusión adicional sobre la selección de la línea de base, consulte los recursos en la sección "Pasos siguientes" al final de este tutorial. Aquí, utilizará una imagen negra cuyos valores de píxel son todos cero.

Otras opciones con las que puede experimentar incluyen una imagen completamente blanca o una imagen aleatoria, que puede crear con 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

Desempaquetar fórmulas en código

La fórmula para Gradientes Integrados es la siguiente:

\(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}\)

donde:

\(_{i}\) = función
\(x\) = entrada
\(x'\) = línea de base
\(\alpha\) = constante de interpolación para perturbar características por

En la práctica, calcular una integral definida no siempre es numéricamente posible y puede ser costoso desde el punto de vista computacional, por lo que calcula la siguiente aproximación numérica:

\(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}\)

donde:

\(_{i}\) = función (píxel individual)
\(x\) = entrada (tensor de imagen)
\(x'\) = línea base (tensor de imagen)
\(k\) = constante de perturbación de entidad escalada
\(m\) = número de pasos en la aproximación de suma de Riemann de la integral
\((x_{i}-x'_{i})\) = un término para la diferencia con respecto a la línea de base. Esto es necesario para escalar los degradados integrados y mantenerlos en términos de la imagen original. La ruta desde la imagen de línea de base hasta la entrada está en el espacio de píxeles. Dado que con IG está integrando en línea recta (transformación lineal), esto termina siendo aproximadamente equivalente al término integral de la derivada de la función de imagen interpolada con respecto a \(\alpha\) con suficientes pasos. La integral suma el gradiente de cada píxel multiplicado por el cambio en el píxel a lo largo de la ruta. Es más sencillo implementar esta integración como pasos uniformes de una imagen a otra, sustituyendo \(x := (x' + \alpha(x-x'))\). Entonces el cambio de variables da \(dx = (x-x')d\alpha\). El término \((x-x')\) es constante y se factoriza fuera de la integral.

Interpolar imágenes

\(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}\)

Primero, generará una interpolación lineal entre la línea base y la imagen original. Puede pensar en las imágenes interpoladas como pequeños pasos en el espacio de características entre su línea de base y la entrada, representado por \(\alpha\) en la ecuación original.

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

Usemos la función anterior para generar imágenes interpoladas a lo largo de una ruta lineal en intervalos alfa entre una imagen de línea de base negra y la imagen de ejemplo "Fireboat".

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

Visualicemos las imágenes interpoladas. Nota: otra forma de pensar acerca de la constante \(\alpha\) es que aumenta constantemente la intensidad de cada imagen interpolada.

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

Calcular gradientes

Ahora echemos un vistazo a cómo calcular gradientes para medir la relación entre los cambios en una característica y los cambios en las predicciones del modelo. En el caso de las imágenes, el gradiente nos dice qué píxeles tienen el efecto más fuerte en las probabilidades de clase previstas por los modelos.

\(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}\)

donde:
\(F()\) = la función de predicción de su modelo
\(\frac{\partial{F} }{\partial{x_i} }\) = gradiente (vector de derivadas parciales \(\partial\)) de la función de predicción de su modelo F relativa a cada característica \(x_i\)

TensorFlow facilita la computación de gradientes con 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)

Calculemos los gradientes de cada imagen a lo largo de la ruta de interpolación con respecto a la salida correcta. Recuerda que tu modelo devuelve un Tensor con forma (1, 1001) con logits que conviertes en probabilidades pronosticadas para cada clase. Debe pasar el índice de clase de destino de ImageNet correcto a la función compute_gradients para su imagen.

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

Tenga en cuenta la forma de salida de (n_interpolated_images, img_height, img_width, RGB) , que nos proporciona el degradado de cada píxel de cada imagen a lo largo de la ruta de interpolación. Puede pensar en estos gradientes como una medida del cambio en las predicciones de su modelo para cada pequeño paso en el espacio de características.

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

Visualización de la saturación de gradiente

Recuerde que los gradientes que acaba de calcular describen cambios locales en la probabilidad prevista de su modelo de "Fireboat" y pueden saturar .

Estos conceptos se visualizan utilizando los gradientes que calculó anteriormente en las 2 gráficas a continuación.

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

png

  • izquierda : Este gráfico muestra cómo la confianza de su modelo en la clase "Fireboat" varía entre alfas. Observe cómo los gradientes, o la pendiente de la línea, se aplanan o saturan en gran medida entre 0,6 y 1,0 antes de establecerse en la probabilidad final predicha de "Fireboat" de alrededor del 40 %.

  • derecha : El diagrama de la derecha muestra las magnitudes de los gradientes promedio sobre alfa más directamente. Observe cómo los valores se acercan bruscamente e incluso caen brevemente por debajo de cero. De hecho, su modelo "aprende" más de los gradientes en valores más bajos de alfa antes de saturarse. Intuitivamente, puede pensar en esto ya que su modelo ha aprendido los píxeles, por ejemplo, cañones de agua para hacer la predicción correcta, enviando estos gradientes de píxeles a cero, pero aún es bastante incierto y se enfoca en puentes falsos o píxeles de chorro de agua a medida que los valores alfa se acercan al imagen de entrada original.

Para asegurarse de que estos píxeles importantes del cañón de agua se reflejen como importantes para la predicción del "Bote de bomberos", continuará a continuación para aprender cómo acumular estos gradientes para aproximar con precisión cómo cada píxel afecta su probabilidad predicha de "Bote de bomberos".

Gradientes acumulados (aproximación integral)

Hay muchas maneras diferentes de calcular la aproximación numérica de una integral para IG con diferentes compensaciones en precisión y convergencia a través de funciones variables. Una clase popular de métodos se llama sumas de Riemann . Aquí, utilizará la regla trapezoidal (puede encontrar código adicional para explorar diferentes métodos de aproximación al final de este tutorial).

$IntegratedGrads^{aprox.} {i}(x)::=(x {i}-x' {i})\times \overbrace{\sum {k=1}^{m} }^\text{Suma m gradientes locales} \text{gradientes(imágenes interpoladas)} \times \overbrace{\frac{1}{m} }^\text{Dividir por m pasos}$

A partir de la ecuación, puede ver que está sumando m gradientes y dividiendo por m pasos. Puede implementar las dos operaciones juntas para la parte 3 como un promedio de los gradientes locales de m predicciones interpoladas e imágenes de entrada .

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 función integral_approximation toma los gradientes de la probabilidad predicha de la clase objetivo con respecto a las imágenes interpoladas entre la línea de base y la imagen original.

ig = integral_approximation(
    gradients=path_gradients)

Puede confirmar que el promedio de los gradientes de m imágenes interpoladas devuelve un tensor de gradientes integrado con la misma forma que la imagen original del "panda gigante".

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

Poniendolo todo junto

Ahora combinará las 3 partes generales anteriores en una función IntegratedGradients y utilizará un decorador @tf.function para compilarlo en un gráfico TensorFlow invocable de alto rendimiento. Esto se implementa como 5 pasos más pequeños a continuación:

\(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. Generar alfas \(\alpha\)

  2. Generar imágenes interpoladas = \((x' + \frac{k}{m}\times(x - x'))\)

  3. Calcule los gradientes entre las predicciones de salida del modelo \(F\) con respecto a las características de entrada = \(\frac{\partial F(\text{interpolated path inputs})}{\partial x_{i} }\)

  4. Aproximación integral a través de promedio de gradientes = \(\sum_{k=1}^m \text{gradients} \times \frac{1}{m}\)

  5. Escale los degradados integrados con respecto a la imagen original = \((x_{i}-x'_{i}) \times \text{integrated gradients}\). La razón por la que este paso es necesario es para asegurarse de que los valores de atribución acumulados en múltiples imágenes interpoladas estén en las mismas unidades y representen fielmente la importancia de los píxeles en la imagen original.

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)

Nuevamente, puede verificar que las atribuciones de características de IG tengan la misma forma que la imagen de entrada "Fireboat".

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

El documento sugiere que el número de pasos oscile entre 20 y 300 según el ejemplo (aunque en la práctica puede ser más alto en los 1000 para aproximar con precisión la integral). Puede encontrar código adicional para verificar la cantidad adecuada de pasos en los recursos "Pasos siguientes" al final de este tutorial.

Visualizar atribuciones

Está listo para visualizar las atribuciones y superponerlas en la imagen original. El siguiente código suma los valores absolutos de los degradados integrados en los canales de color para producir una máscara de atribución. Este método de trazado captura el impacto relativo de los píxeles en las predicciones del modelo.

Si observa las atribuciones en la imagen "Fireboat", puede ver que el modelo identifica los cañones de agua y los surtidores que contribuyen a su predicción correcta.

_ = 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

En la imagen del "Panda Gigante", las atribuciones resaltan la textura, la nariz y el pelaje de la cara del 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

Usos y limitaciones

casos de uso

  • Emplear técnicas como los degradados integrados antes de implementar su modelo puede ayudarlo a desarrollar la intuición de cómo y por qué funciona. ¿Las características resaltadas por esta técnica coinciden con su intuición? De lo contrario, eso puede ser indicativo de un error en su modelo o conjunto de datos, o sobreajuste.

Limitaciones

  • Los degradados integrados proporcionan la importancia de las características en ejemplos individuales; sin embargo, no proporciona la importancia de las características globales en un conjunto de datos completo.

  • Los degradados integrados proporcionan la importancia de las funciones individuales, pero no explican las interacciones y combinaciones de funciones.

Próximos pasos

Este tutorial presentó una implementación básica de gradientes integrados. Como siguiente paso, puedes utilizar este cuaderno para probar tú mismo esta técnica con diferentes modelos e imágenes.

Para los lectores interesados, hay una versión más larga de este tutorial (que incluye código para diferentes líneas base, para calcular aproximaciones integrales y para determinar una cantidad suficiente de pasos) que puede encontrar aquí .

Para profundizar su comprensión, consulte el documento Axiomatic Attribution for Deep Networks and Github repository , que contiene una implementación en una versión anterior de TensorFlow. También puede explorar la atribución de características y el impacto de diferentes líneas de base en destilar.pub .

¿Está interesado en incorporar IG en sus flujos de trabajo de aprendizaje automático de producción para la importancia de las funciones, el análisis de errores del modelo y el control de la asimetría de datos? Consulte el producto de IA explicable de Google Cloud que admite atribuciones de IG. El grupo de investigación Google AI PAIR también abrió la herramienta What-if que se puede usar para la depuración de modelos, incluida la visualización de las atribuciones de funciones de IG.