Интегрированные градиенты

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть на GitHub Скачать блокнот См. модель концентратора TF

В этом руководстве показано, как реализовать интегрированные градиенты (IG) , метод объяснимого ИИ , представленный в статье « Аксиоматическая атрибуция для глубоких сетей» . IG стремится объяснить взаимосвязь между предсказаниями модели с точки зрения ее функций. Он имеет множество вариантов использования, включая понимание важности функций, выявление перекоса данных и отладку производительности модели.

IG стал популярным методом интерпретируемости благодаря его широкому применению к любой дифференцируемой модели (например, изображениям, тексту, структурированным данным), простоте реализации, теоретическим обоснованиям и вычислительной эффективности по сравнению с альтернативными подходами, что позволяет масштабировать его до больших сетей и функций. пространства, такие как изображения.

В этом руководстве вы шаг за шагом пройдёте реализацию IG, чтобы понять важность пиксельных функций классификатора изображений. В качестве примера рассмотрим это изображение пожарного катера, разбрызгивающего струи воды. Вы бы классифицировали это изображение как пожарную лодку и могли бы выделить пиксели, составляющие лодку и водометы, как важные для вашего решения. Ваша модель также классифицирует это изображение как пожарный катер позже в этом уроке; однако выделяет ли он те же пиксели как важные при объяснении своего решения?

На изображениях ниже, озаглавленных «Маска атрибуции IG» и «Исходное + наложение маски IG», вы можете видеть, что ваша модель вместо этого выделяет (фиолетовым цветом) пиксели, содержащие водяные пушки и струи воды лодки, как более важные, чем сама лодка для его решение. Как ваша модель будет обобщаться на новые пожарные катера? А пожарные катера без водометов? Читайте дальше, чтобы узнать больше о том, как работает IG и как применять IG к вашим моделям, чтобы лучше понять взаимосвязь между их прогнозами и базовыми функциями.

Выходное изображение 1

Настраивать

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

Загрузите предварительно обученный классификатор изображений с TF-Hub.

IG можно применить к любой дифференцируемой модели. В духе оригинальной статьи вы будете использовать предварительно обученную версию той же модели Inception V1, которую скачаете с 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
_________________________________________________________________

На странице модуля вам необходимо помнить следующее о Inception V1:

Входные данные: ожидаемая входная форма для модели (None, 224, 224, 3) . Это плотный 4D-тензор dtype float32 и shape (batch_size, height, width, RGB channels) , элементами которого являются значения цветов RGB пикселей, нормализованные к диапазону [0, 1]. Первый элемент — None , чтобы указать, что модель может принимать любой целочисленный размер пакета.

Выходы : tf.Tensor логитов в форме (batch_size, 1001) . Каждая строка представляет прогнозируемую оценку модели для каждого из 1001 класса из ImageNet. Для верхнего прогнозируемого индекса класса модели вы можете использовать tf.argmax(predictions, axis=-1) . Кроме того, вы также можете преобразовать выходные данные логита модели в предсказанные вероятности для всех классов, используя tf.nn.softmax(predictions, axis=-1) для количественной оценки неопределенности модели, а также изучить аналогичные предсказанные классы для отладки.

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

Загрузка и предварительная обработка изображений с помощью tf.image

Вы проиллюстрируете IG, используя два изображения из Wikimedia Commons : Fireboat и Giant Panda .

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

Классифицировать изображения

Давайте начнем с классификации этих изображений и отображения трех самых надежных прогнозов. Ниже приведена служебная функция для получения k лучших предсказанных меток и вероятностей.

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%

Вычислить интегрированные градиенты

Ваша модель, Inception V1, представляет собой обучаемую функцию, которая описывает сопоставление между вашим пространством входных признаков, значениями пикселей изображения и пространством вывода, определяемым значениями вероятности класса ImageNet от 0 до 1. Ранние методы интерпретации для нейронных сетей присваивали оценки важности признаков, используя градиенты, которые говорят вам, какие пиксели имеют самую крутую локальную относительно предсказания вашей модели в заданной точке вдоль функции предсказания вашей модели. Однако градиенты описывают только локальные изменения в функции прогнозирования вашей модели относительно значений пикселей и не полностью описывают всю функцию прогнозирования модели. По мере того, как ваша модель полностью «узнает» взаимосвязь между диапазоном отдельного пикселя и правильным классом ImageNet, градиент для этого пикселя будет насыщаться , то есть становиться все меньше и даже стремиться к нулю. Рассмотрим простую модельную функцию ниже:

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

  • слева : градиенты вашей модели для пикселя x положительны между 0,0 и 0,8, но достигают 0,0 между 0,8 и 1,0. Pixel x явно оказывает значительное влияние на приближение вашей модели к прогнозируемой вероятности 80% для истинного класса. Имеет ли смысл, что важность пикселя x мала или прерывиста?

  • справа : интуиция, стоящая за IG, состоит в том, чтобы накапливать локальные градиенты пикселя x и приписывать их важность как оценку того, насколько он добавляет или вычитает общую вероятность выходного класса вашей модели. Вы можете разбить и вычислить IG на 3 части:

    1. интерполировать небольшие шаги вдоль прямой линии в пространстве признаков между 0 (базовая линия или начальная точка) и 1 (значение входного пикселя)
    2. вычислять градиенты на каждом шаге между прогнозами вашей модели относительно каждого шага
    3. аппроксимируйте интеграл между вашей базовой линией и вводом, накапливая (кумулятивное среднее) эти локальные градиенты.

Чтобы укрепить эту интуицию, вы пройдете через эти 3 части, применив IG к примеру изображения «Fireboat» ниже.

Установите базовый уровень

Базовая линия — это входное изображение, используемое в качестве отправной точки для расчета важности функции. Интуитивно вы можете думать о пояснительной роли базовой линии как о влиянии отсутствия каждого пикселя на прогноз «Пожарная шлюпка», чтобы контрастировать с его влиянием каждого пикселя на прогноз «Пожарная шлюпка», когда он присутствует во входном изображении. В результате выбор базовой линии играет центральную роль в интерпретации и визуализации важности особенностей пикселей. Дополнительные сведения о выборе базового плана см. в ресурсах в разделе «Дальнейшие шаги» в нижней части этого руководства. Здесь вы будете использовать черное изображение, все значения пикселей которого равны нулю.

Другие варианты, с которыми вы можете поэкспериментировать, включают полностью белое изображение или случайное изображение, которое вы можете создать с помощью 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

Распаковать формулы в код

Формула интегрированных градиентов выглядит следующим образом:

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

где:

\(_{i}\) = функция
\(x\) = ввод
\(x'\) = базовый уровень
\(\alpha\) = постоянная интерполяции для искажения объектов на

На практике вычисление определенного интеграла не всегда возможно численно и может быть дорогостоящим, поэтому вы вычисляете следующее численное приближение:

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

где:

\(_{i}\) = особенность (отдельный пиксель)
\(x\) = ввод (тензор изображения)
\(x'\) = базовая линия (тензор изображения)
\(k\) = масштабированная постоянная возмущения объекта
\(m\) = количество шагов в приближении суммы Римана интеграла
\((x_{i}-x'_{i})\) = термин для отличия от базового уровня. Это необходимо для масштабирования интегрированных градиентов и сохранения их с точки зрения исходного изображения. Путь от базового изображения до входных данных находится в пространстве пикселей. Поскольку с IG вы интегрируете по прямой линии (линейное преобразование), это в конечном итоге примерно эквивалентно интегральному члену производной интерполированной функции изображения по отношению к \(\alpha\) с достаточным количеством шагов. Интеграл суммирует градиент каждого пикселя, умноженный на изменение пикселя вдоль пути. Проще реализовать эту интеграцию в виде единых шагов от одного изображения к другому, подставив \(x := (x' + \alpha(x-x'))\). Таким образом, замена переменных дает \(dx = (x-x')d\alpha\). \((x-x')\) является постоянным и выносится за скобки интеграла.

Интерполировать изображения

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

Во-первых, вы создадите линейную интерполяцию между базовой линией и исходным изображением. Вы можете думать об интерполированных изображениях как о небольших шагах в пространстве признаков между вашей базовой линией и входными данными, представленными \(\alpha\) в исходном уравнении.

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

Давайте используем приведенную выше функцию для создания интерполированных изображений вдоль линейного пути с альфа-интервалами между черным базовым изображением и примером изображения «Fireboat».

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

Давайте визуализируем интерполированные изображения. Примечание: другой способ думать о константе \(\alpha\) состоит в том, что она последовательно увеличивает интенсивность каждого интерполированного изображения.

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

Вычислить градиенты

Теперь давайте посмотрим, как рассчитать градиенты, чтобы измерить взаимосвязь между изменениями в функции и изменениями в прогнозах модели. В случае с изображениями градиент сообщает нам, какие пиксели оказывают наибольшее влияние на вероятности классов, предсказанные моделями.

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

где:
\(F()\) = функция предсказания вашей модели
\(\frac{\partial{F} }{\partial{x_i} }\) = градиент (вектор частных производных \(\partial\)) функции прогнозирования вашей модели F относительно каждой функции \(x_i\)

TensorFlow упрощает вычисление градиентов с помощью 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)

Давайте вычислим градиенты для каждого изображения вдоль пути интерполяции относительно правильного вывода. Вспомните, что ваша модель возвращает Tensor формы (1, 1001) с логитами, которые вы конвертируете в предсказанные вероятности для каждого класса. Вам нужно передать правильный индекс целевого класса ImageNet в функцию compute_gradients для вашего изображения.

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

Обратите внимание на выходную форму (n_interpolated_images, img_height, img_width, RGB) , которая дает нам градиент для каждого пикселя каждого изображения на пути интерполяции. Вы можете думать об этих градиентах как об измерении изменений в прогнозах вашей модели для каждого маленького шага в пространстве признаков.

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

Визуализация насыщенности градиента

Вспомните, что градиенты, которые вы только что вычислили выше, описывают локальные изменения предсказанной вашей моделью вероятности «Fireboat» и могут насыщать .

Эти концепции визуализируются с использованием градиентов, рассчитанных выше, на двух графиках ниже.

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

png

  • слева : этот график показывает, как уверенность вашей модели в классе «Fireboat» варьируется в зависимости от альфы. Обратите внимание, как градиенты или наклон линии в значительной степени выравниваются или насыщаются между 0,6 и 1,0, прежде чем установить окончательную предсказанную вероятность "Fireboat" около 40%.

  • right : Правый график более точно показывает средние величины градиентов по альфа-каналу. Обратите внимание, как значения резко приближаются и даже ненадолго опускаются ниже нуля. На самом деле, ваша модель больше всего «учится» на градиентах с более низкими значениями альфы перед насыщением. Интуитивно вы можете думать об этом, поскольку ваша модель изучила пиксели, например, водяные пушки, чтобы сделать правильный прогноз, отправляя градиенты этих пикселей к нулю, но все еще довольно неопределенно и фокусируясь на ложных пикселях моста или струи воды, когда значения альфа приближаются к исходное входное изображение.

Чтобы убедиться, что эти важные пиксели водяных пушек отражаются как важные для прогноза «Пожарная лодка», вы продолжите изучение ниже, чтобы узнать, как накапливать эти градиенты, чтобы точно оценить, как каждый пиксель влияет на вашу прогнозируемую вероятность «Пожарной лодки».

Накопление градиентов (интегральное приближение)

Существует множество различных способов вычисления численной аппроксимации интеграла для IG с различными компромиссами в отношении точности и сходимости для различных функций. Популярный класс методов называется суммами Римана . Здесь вы будете использовать правило трапеций (вы можете найти дополнительный код для изучения различных методов приближения в конце этого руководства).

$IntegratedGrads^{приблизительно} {i}(x)::=(x {i}-x' {i})\times \overbrace{\sum {k=1}^{m}}^\text{Sum m локальные градиенты} \text{градиенты (интерполированные изображения)} \times \overbrace{\frac{1}{m} }^\text{Разделить на m шагов}$

Из уравнения видно, что вы суммируете по m градиентам и делите на m шагов. Вы можете реализовать две операции вместе для части 3 как среднее значение локальных градиентов m интерполированных прогнозов и входных изображений .

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

Функция integral_approximation принимает градиенты прогнозируемой вероятности целевого класса по отношению к интерполированным изображениям между базовой линией и исходным изображением.

ig = integral_approximation(
    gradients=path_gradients)

Вы можете подтвердить, что усреднение по градиентам m интерполированных изображений возвращает интегрированный тензор градиентов той же формы, что и исходное изображение «Гигантская панда».

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

Собираем все вместе

Теперь вы объедините 3 предыдущие общие части вместе в функцию IntegratedGradients и используете декоратор @tf.function , чтобы скомпилировать его в высокопроизводительный вызываемый граф TensorFlow. Это реализовано в виде 5 небольших шагов ниже:

\(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. Сгенерировать альфы \(\alpha\)

  2. Генерировать интерполированные изображения = \((x' + \frac{k}{m}\times(x - x'))\)

  3. Вычислить градиенты между прогнозами выходных данных модели \(F\) по отношению к входным функциям = \(\frac{\partial F(\text{interpolated path inputs})}{\partial x_{i} }\)

  4. Интегральная аппроксимация через градиенты усреднения = \(\sum_{k=1}^m \text{gradients} \times \frac{1}{m}\)

  5. Масштабируйте интегрированные градиенты по отношению к исходному изображению = \((x_{i}-x'_{i}) \times \text{integrated gradients}\). Причина, по которой этот шаг необходим, заключается в том, чтобы убедиться, что значения атрибуции, накопленные для нескольких интерполированных изображений, выражены в одних и тех же единицах и точно отражают важность пикселей исходного изображения.

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)

Опять же, вы можете проверить, что атрибуты функции IG имеют ту же форму, что и входное изображение «Fireboat».

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

В документе предлагается количество шагов в диапазоне от 20 до 300 в зависимости от примера (хотя на практике это может быть больше 1000 для точной аппроксимации интеграла). Вы можете найти дополнительный код для проверки соответствующего количества шагов в ресурсах «Следующие шаги» в конце этого руководства.

Визуализируйте атрибуции

Вы готовы визуализировать атрибуты и наложить их на исходное изображение. Код ниже суммирует абсолютные значения интегрированных градиентов по цветовым каналам для создания маски атрибуции. Этот метод построения графика фиксирует относительное влияние пикселей на прогнозы модели.

Глядя на атрибуцию изображения «Fireboat», вы можете видеть, что модель идентифицирует водяные пушки и носики как способствующие ее правильному прогнозу.

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

На изображении «Гигантская панда» атрибуты подчеркивают текстуру, нос и мех на морде панды.

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

Использование и ограничения

Случаи применения

  • Использование таких методов, как интегрированные градиенты, перед развертыванием вашей модели может помочь вам развить интуицию в отношении того, как и почему она работает. Соответствуют ли особенности, выделенные этой техникой, вашей интуиции? Если нет, это может свидетельствовать об ошибке в вашей модели или наборе данных или о переоснащении.

Ограничения

  • Интегрированные градиенты обеспечивают важность функций для отдельных примеров, однако они не обеспечивают глобальную важность функций для всего набора данных.

  • Интегрированные градиенты обеспечивают важность отдельных функций, но не объясняют взаимодействия и комбинации функций.

Следующие шаги

В этом уроке представлена ​​базовая реализация интегрированных градиентов. В качестве следующего шага вы можете использовать этот блокнот, чтобы самостоятельно попробовать эту технику с различными моделями и изображениями.

Для заинтересованных читателей есть более длинная версия этого руководства (которая включает код для различных базовых линий, для вычисления интегральных приближений и для определения достаточного количества шагов), которую вы можете найти здесь .

Чтобы углубить свое понимание, ознакомьтесь с документом Axiomatic Attribution for Deep Networks и репозиторием Github , который содержит реализацию в предыдущей версии TensorFlow. Вы также можете изучить атрибуцию функций и влияние различных базовых показателей на distill.pub .

Заинтересованы во включении IG в ваши рабочие процессы машинного обучения для определения важности функций, анализа ошибок модели и мониторинга перекосов данных? Ознакомьтесь с продуктом объяснимого искусственного интеллекта Google Cloud, который поддерживает атрибуцию IG. Исследовательская группа Google AI PAIR также открыла инструмент What-if, который можно использовать для отладки моделей, включая визуализацию атрибутов функций IG.