Поиск по сайту:

Интерпретируемость и понимание модели для PyTorch с использованием Captum


Введение

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

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

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

Описание алгоритмов

Captum — это библиотека, которая позволяет реализовать различные подходы к интерпретации. Алгоритмы атрибуции Captum можно разделить на три широкие категории:

  • Основная атрибуция: определяет вклад каждого входного признака в выходные данные модели.
  • Атрибуция слоя. Каждый нейрон в определенном слое оценивается на предмет его вклада в выходные данные модели.
  • Атрибуция нейрона. Активация скрытого нейрона определяется путем оценки вклада каждого входного признака.

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

Первичные методы атрибуции

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

Допустим, у нас есть формальное представление глубокой сети F : Rn → [0, 1]. Пусть x ∈ Rn будет текущим входом, а x′ ∈ Rn будет базовым входом. Базовой линией в сетях изображений может быть черное изображение, тогда как в текстовых моделях это может быть вектор нулевого внедрения. От базовой линии x' до входного x мы вычисляем градиенты во всех точках прямолинейного пути (в Rn). Суммируя эти градиенты, можно генерировать интегрированные градиенты. Интегрированные градиенты определяются как интеграл градиентов по прямому пути от базовой линии x' до входного сигнала x.

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

Градиент ШАП

Значения Шепли в теории кооперативных игр используются для вычисления значений градиента SHAP, которые вычисляются с использованием градиентного подхода. Градиент SHAP несколько раз добавляет гауссов шум к каждой входной выборке, а затем выбирает случайную точку на пути между базовой линией и входными данными, чтобы определить градиент выходных данных. В результате окончательные значения SHAP представляют собой ожидаемое значение градиентов. * (исходные данные – исходные данные). Значения SHAP аппроксимируются исходя из предпосылки, что входные объекты независимы и что объясняющая модель линейна между входными данными и предоставленными базовыми линиями.

ДипЛИФТ

Можно использовать DeepLIFT (метод обратного распространения данных) для описания входных изменений на основе различий между входными данными и их совпадающим эталоном (или базовым уровнем). DeepLIFT пытается объяснить несоответствие между выходными данными и эталоном, используя несоответствие между входными данными из эталона. DeepLIFT использует идею множителей, чтобы «винить» отдельные нейроны в разнице результатов. Для данного входного нейрона x с отличием от эталона ∆x и целевого нейрона t с отличием от эталона ∆t, вклад в который мы хотим вычислить, мы определяем множитель m∆x∆t как:

ДипЛИФТ ШАП

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

значимость

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

Входной градиент X

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

Управляемое обратное распространение ошибки и деконволюция

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

Управляемый GradCAM

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

Функция абляции

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

Перестановка функций

Перестановка признаков — это метод, основанный на возмущениях, в котором каждый признак в пакете переставляется случайным образом, а изменение выходных данных (или потерь) вычисляется в результате этой модификации. Элементы также могут быть сгруппированы вместе, а не по отдельности, как при удалении признаков. Обратите внимание, что в отличие от других алгоритмов, доступных в Captum, этот алгоритм является единственным, который может обеспечить правильную атрибуцию, когда он поставляется с пакетом из нескольких входных примеров. Другим алгоритмам на входе нужен только один пример.

Окклюзия

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

Выборка значений Шепли

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

Лайм

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

КернелШАП

Kernel SHAP — это метод расчета значений Шепли, использующий структуру LIME. Значения Шепли можно получить более эффективно в рамках LIME, установив функцию потерь, взвесив ядро и правильно регуляризировав члены.

Методы атрибуции слоев

Проводимость слоя

Layer Conductance — это метод, который создает более полную картину важности нейрона путем объединения активации нейрона с частными производными как нейрона по входу, так и по выходу по отношению к нейрону. Через скрытый нейрон проводимость основывается на потоке атрибуции интегрированных градиентов (IG). Полная проводимость скрытого нейрона y в оригинальной статье определяется следующим образом:

Внутреннее влияние

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

Активация градиента слоя X

Активация Layer Gradient X — это сетевой эквивалент метода Input X Gradient для скрытых слоев в сети… Он умножает активацию слоя поэлементно на градиенты целевого вывода относительно указанного слоя.

ГрадКАМ

GradCAM — это метод атрибуции слоев сверточной нейронной сети, который обычно применяется к последнему сверточному слою. GradCAM вычисляет градиенты целевого вывода относительно указанного слоя, усредняет каждый выходной канал (выходное измерение 2) и умножает средний градиент для каждого канала на активации слоя. К выходным данным применяется ReLU, чтобы гарантировать, что из суммы результатов по всем каналам возвращаются только неотрицательные атрибуции.

Методы нейронной атрибуции

Проводимость нейронов

Проводимость сочетает в себе активацию нейрона с частными производными как нейрона по отношению к входу, так и по выходу по отношению к нейрону, чтобы обеспечить более полную картину значимости нейрона. Чтобы определить проводимость конкретного нейрона, исследуют поток атрибуции IG от каждого входа, проходящего через этот нейрон. Ниже приводится формальное определение проводимости нейрона y с учетом входного атрибута i, данное в оригинальной статье:

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

Нейронный градиент

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

Нейронные интегрированные градиенты

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

Нейрон ГрадиентSHAP

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

Нейрон DeepLIFT ШАП

Neuron DeepLIFT SHAP — это эквивалент DeepLIFT для конкретного нейрона. Используя распределение базовых показателей, алгоритм DeepLIFT SHAP вычисляет атрибуцию Neuron DeepLIFT для каждой пары входных данных и базовых данных и усредняет результирующие атрибуции для каждого входного примера.

Шумовой туннель

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

  • Сглаживание. Возвращается среднее значение выборочной атрибуции. Сглаживание указанного метода атрибуции с использованием ядра Гаусса является аппроксимацией этого процесса.
  • Сглаженный квадрат: возвращается среднее значение квадратов выборочных атрибуций.
  • Варград: возвращается дисперсия выборочных атрибуций.

Метрики

Неверность

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

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

Чувствительность

Чувствительность, которая определяется как степень объяснения изменения крошечных входных возмущений с использованием приближения на основе выборки Монте-Карло, измеряется следующим образом:

По умолчанию мы берем выборку из подпространства шара L-бесконечности с радиусом по умолчанию для приблизительной чувствительности. Пользователи могут изменить радиус шара и функцию выборки.

Интерпретация модели для предварительно обученной модели ResNet

В этом руководстве показано, как использовать методы интерпретации модели на предварительно обученной модели ResNet с выбранным изображением, а также визуализируются атрибуты для каждого пикселя путем наложения их на изображение. В этом уроке мы будем использовать алгоритмы интерпретации Integrated Gradients, GradientShape, Attribution with Layer GradCAM и Occlusion.

Прежде чем начать, у вас должна быть среда Python, которая включает в себя:

  • Python версии 3.6 или выше
  • PyTorch версии 1.2 или выше (рекомендуется последняя версия)
  • ТорчВижн версия 0
  • .6 или выше (рекомендуется последняя версия)
  • Captum (рекомендуется последняя версия)

В зависимости от того, используете ли вы виртуальную среду Anaconda или pip, следующие команды помогут вам настроить Captum:

С помощью conda:

conda install pytorch torchvision captum -c pytorch

С помощью pip:

pip install torch torchvision captum

Давайте импортируем библиотеки.

import torch
import torch.nn.functional as F

from PIL import Image

import os
import json
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
import os, sys
import json

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

import torchvision
from torchvision import models
from torchvision import transforms

from captum.attr import IntegratedGradients
from captum.attr import GradientShap
from captum.attr import Occlusion
from captum.attr import LayerGradCam
from captum.attr import NoiseTunnel
from captum.attr import visualization as viz
from captum.attr import LayerAttribution

Загружает предварительно обученную модель Resnet и устанавливает ее в режим оценки.

model = models.resnet18(pretrained=True)
model = model.eval()

ResNet обучается на наборе данных ImageNet. Загружает и считывает список классов/меток набора данных ImageNet в памяти.

wget -P $HOME/.torch/models https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json
labels_path = os.getenv("HOME") + '/.torch/models/imagenet_class_index.json'
with open(labels_path) as json_data:
    idx_to_labels = json.load(json_data)

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

источник

Папка с изображениями должна содержать файл cat.jpg. Как мы видим ниже, Image.open() открывает и идентифицирует данный файл изображения, а np.asarry() преобразует его в массив.

test_img = Image.open('path/cat.jpg')
test_img_data = np.asarray(test_img)
plt.imshow(test_img_data)
plt.show()

В приведенном ниже коде мы определим преобразователи и функции нормализации изображения. Для обучения нашей модели ResNet мы использовали набор данных ImageNet, который требует, чтобы изображения имели определенный размер, а данные канала были нормализованы до определенного диапазона значений. Transforms.Compose() объединяет несколько преобразований и Transforms.Normalize() нормализует тензорное изображение со средним и стандартным отклонением.

# model expectation is 224x224 3-color image
transform = transforms.Compose([
 transforms.Resize(256),
 transforms.CenterCrop(224), #crop the given tensor image at the center
 transforms.ToTensor()
])ImageNet normalization
transform_normalize = transforms.Normalize(
     mean=[0.485, 0.456, 0.406],
     std=[0.229, 0.224, 0.225]
 )

img = Image.open('path/cat.jpg')

transformed_img = transform(img)

input = transform_normalize(transformed_img)
#unsqueeze returns a new tensor with a dimension of size one inserted at the #specified position.
input = input.unsqueeze(0)

Теперь мы предскажем класс входного изображения. Можно задать вопрос: «Что, по мнению нашей модели, представляет это изображение? »

#call our model
output = model(input)
## applied softmax() function
output = F.softmax(output, dim=1)
#torch.topk returns the k largest elements of the given input tensor along a given #dimension.K here is 1
prediction_score, pred_label_idx = torch.topk(output, 1)
pred_label_idx.squeeze_()
#convert into a dictionnary of keyvalues pair the predict label, convert it #into a string to get the predicted label
predicted_label = idx_to_labels[str(pred_label_idx.item())][1]
print('Predicted:', predicted_label, '(', prediction_score.squeeze().item(), ')')

выход :

Predicted: tabby ( 0.5530276298522949 )

Тот факт, что ResNet считает, что наше изображение кошки изображает настоящую кошку, подтвержден. Но что создает у модели впечатление, что это изображение кота? Чтобы получить ответ на этот вопрос, мы обратимся к Captum.

Атрибуция функций с помощью интегрированных градиентов

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

В нашем случае мы возьмем конкретный компонент выходного вектора — тот, который указывает на уверенность модели в выбранной категории — и будем использовать интегрированные градиенты, чтобы выяснить, какие аспекты входного изображения способствовали этому выводу. Это позволит нам определить, какие части изображения были наиболее важны для получения этого результата. После того, как мы получим карту важности из Integrated Gradients, мы будем использовать инструменты визуализации, полученные Captum, чтобы обеспечить четкое и понятное изображение карты важности.

Интегрированные градиенты будут определять интеграл градиентов выходных данных модели для прогнозируемого класса pred_label_idx по отношению к пикселям входного изображения на пути от черного изображения к нашему входному изображению.

print('Predicted:', predicted_label, '(', prediction_score.squeeze().item(), ')')
#Create IntegratedGradients object and get attributes
integrated_gradients = IntegratedGradients(model)
#Request the algorithm to assign our output target to
attributions_ig = integrated_gradients.attribute(input, target=pred_label_idx, n_steps=200)

Выход :

Predicted: tabby ( 0.5530276298522949 )

Давайте посмотрим на изображение и сопутствующие ему атрибуты, наложив последнее поверх изображения. Метод Visualize_image_attr(), предлагаемый Captum, предоставляет набор возможностей для адаптации представления данных атрибуции к вашим предпочтениям. Здесь мы передаем пользовательскую карту цветов Matplotlib (см. LinearSegmentedColormap()).

#result visualization with custom colormap
default_cmap = LinearSegmentedColormap.from_list('custom blue',
                                                 [(0, '#ffffff'),
                                                  (0.25, '#000000'),
                                                  (1, '#000000')], N=256)use visualize_image_attr helper method for visualization to show the #original image for comparison
_ = viz.visualize_image_attr(np.transpose(attributions_ig.squeeze().cpu().detach().numpy(), (1,2,0)),
                             np.transpose(transformed_img.squeeze().cpu().detach().numpy(), (1,2,0)),
                             method='heat_map',
                             cmap=default_cmap,
                             show_colorbar=True,
                             sign='positive',
                             outlier_perc=1)

Выход :

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

Давайте вычислим атрибуции с помощью интегрированных градиентов, а затем сгладим их по нескольким изображениям, созданным с помощью шумового туннеля. Последний изменяет входные данные, добавляя гауссов шум со стандартным отклонением, равным единице, в 10 раз (nt_samples=10). Подход smoothgrad_sq используется шумовым туннелем, чтобы сделать атрибуцию согласованной для всех nt_samples зашумленных выборок. Значение smoothgrad_sq представляет собой среднее значение квадратов атрибуции для выборок nt_samples. Visualize_image_attr_multiple() визуализирует атрибуцию для данного изображения путем нормализации значений атрибуции указанного знака (положительное, отрицательное, абсолютное значение или все), а затем отображает их на рисунке matplotlib с использованием выбранного режима.

noise_tunnel = NoiseTunnel(integrated_gradients)

attributions_ig_nt = noise_tunnel.attribute(input, nt_samples=10, nt_type='smoothgrad_sq', target=pred_label_idx)
_ = viz.visualize_image_attr_multiple(np.transpose(attributions_ig_nt.squeeze().cpu().detach().numpy(), (1,2,0)),
                                      np.transpose(transformed_img.squeeze().cpu().detach().numpy(), (1,2,0)),
                                      ["original_image", "heat_map"],
                                      ["all", "positive"],
                                      cmap=default_cmap,
                                      show_colorbar=True)

Выход :

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

Давайте закончим с использованием GradientShap. GradientShap — это градиентный подход, который можно использовать для вычисления значений SHAP, а также фантастический инструмент для изучения глобального поведения. Это модель линейного объяснения, которая объясняет предсказания модели с помощью распределения эталонных образцов. Он определяет ожидаемые градиенты для входных данных, выбранных случайным образом между входными данными и базовой линией. Базовый уровень выбирается случайным образом из предоставленного распределения базовых уровней.

torch.manual_seed(0)
np.random.seed(0)

gradient_shap = GradientShap(model)
Definition of baseline distribution of images
rand_img_dist = torch.cat([input * 0, input * 1])

attributions_gs = gradient_shap.attribute(input,
                                          n_samples=50,
                                          stdevs=0.0001,
                                          baselines=rand_img_dist,
                                          target=pred_label_idx)
_ = viz.visualize_image_attr_multiple(np.transpose(attributions_gs.squeeze().cpu().detach().numpy(), (1,2,0)),
                                      np.transpose(transformed_img.squeeze().cpu().detach().numpy(), (1,2,0)),
                                      ["original_image", "heat_map"],
                                      ["all", "absolute_value"],
                                      cmap=default_cmap,
                                      show_colorbar=True)

Выход :

Атрибуция слоев с помощью Layer GradCAM

Вы можете связать активность скрытых слоев внутри вашей модели с особенностями ваших входных данных с помощью атрибуции слоев. Мы применим алгоритм атрибуции слоев, чтобы исследовать активность одного из сверточных слоев, включенных в нашу модель. GradCAM отвечает за вычисление градиентов целевого вывода относительно указанного слоя. Затем эти градиенты усредняются для каждого выходного канала (выходное измерение 2), а активации слоев умножаются на средний градиент для каждого канала. Результаты суммируются по всем каналам. Поскольку активность сверточных слоев часто пространственно сопоставляется с входными данными, атрибуции GradCAM часто подвергаются повышающей дискретизации и используются для маскировки входных данных. Стоит отметить, что GradCAM специально разработан для сверточных нейронных сетей (коннетов). Атрибуция слоев настраивается так же, как атрибуция входных данных, за исключением того, что помимо модели необходимо предоставить скрытый слой внутри модели, которую вы хотите проанализировать. Подобно тому, что обсуждалось ранее, когда мы вызываем attribute(), мы указываем интересующий целевой класс.

layer_gradcam = LayerGradCam(model, model.layer3[1].conv2)
attributions_lgc = layer_gradcam.attribute(input, target=pred_label_idx)

_ = viz.visualize_image_attr(attributions_lgc[0].cpu().permute(1,2,0).detach().numpy(),
                             sign="all",
                             title="Layer 3 Block 1 Conv 2")

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

upsamp_attr_lgc = LayerAttribution.interpolate(attributions_lgc, input.shape[2:])

print(attributions_lgc.shape)
print(upsamp_attr_lgc.shape)
print(input.shape)

_ = viz.visualize_image_attr_multiple(upsamp_attr_lgc[0].cpu().permute(1,2,0).detach().numpy(),
                                      transformed_img.permute(1,2,0).numpy(),
                                      ["original_image","blended_heat_map","masked_image"],
                                      ["all","positive","positive"],
                                      show_colorbar=True,
                                      titles=["Original", "Positive Attribution", "Masked"],
                                      fig_size=(18, 6))

Выход :

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

Атрибуция функций с помощью окклюзии

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

Далее мы настроим атрибуцию окклюзии. Как и в случае с конфигурацией сверточной нейронной сети, вы можете выбрать размер целевой области и длину шага, которая определяет интервал между отдельными измерениями. Мы будем использовать функцию visualize_image_attr_multiple() для просмотра результатов нашей атрибуции окклюзии. Эта функция будет отображать тепловые карты как положительной, так и отрицательной атрибуции для каждого региона и маскировать исходное изображение регионами положительной атрибуции. Маскирование дает очень яркий взгляд на те области нашей фотографии кошки, которые модель определила как наиболее «кошачьи». »

occlusion = Occlusion(model)

attributions_occ = occlusion.attribute(input,
                                       target=pred_label_idx,
                                       strides=(3, 8, 8),
                                       sliding_window_shapes=(3,15, 15),
                                       baselines=0)

_ = viz.visualize_image_attr_multiple(np.transpose(attributions_occ.squeeze().cpu().detach().numpy(), (1,2,0)),
                                      np.transpose(transformed_img.squeeze().cpu().detach().numpy(), (1,2,0)),
                                      ["original_image", "heat_map", "heat_map", "masked_image"],
                                      ["all", "positive", "negative", "positive"],
                                      show_colorbar=True,
                                      titles=["Original", "Positive Attribution", "Negative Attribution", "Masked"],
                                      fig_size=(18, 6)
                                     )

Выход :

Часть изображения, содержащая кота, кажется, имеет более высокий уровень важности.

Заключение

Captum — это универсальная и простая библиотека интерпретируемости моделей для PyTorch. Он предлагает самые современные методы для понимания того, как конкретные нейроны и слои влияют на прогнозы. Он имеет три основных типа методов атрибуции: методы первичной атрибуции, методы атрибуции слоев и методы нейронной атрибуции.

Ссылки

https://pytorch.org/tutorials/beginner/introyt/captumyt.html https://gilberttanner.com/blog/interpreting-pytorch-models-with-captum/ https://arxiv.org/pdf/1805.12233.pdf https://arxiv.org/pdf/1704.02685.pdf

Статьи по данной тематике: