Website-Suche

Modellinterpretierbarkeit und -verständnis für PyTorch mit Captum


Einführung

Als direkte Folge der steigenden Modellkomplexität und der damit verbundenen Intransparenz haben Methoden der Modellinterpretierbarkeit in den letzten Jahren zunehmend an Bedeutung gewonnen. Das Verständnis von Modellen ist ein aktuelles Forschungsthema und ein Schwerpunktbereich für praktische Anwendungen, bei denen maschinelles Lernen in verschiedenen Sektoren zum Einsatz kommt.

Captum stellt Akademikern und Entwicklern modernste Techniken wie integrierte Farbverläufe zur Verfügung, die es einfach machen, die Elemente zu identifizieren, die zur Ausgabe eines Modells beitragen. Captum erleichtert ML-Forschern die Verwendung von PyTorch-Modellen zum Erstellen von Interpretierbarkeitsmethoden.

Durch die einfachere Identifizierung der vielen Elemente, die zur Ausgabe eines Modells beitragen, kann Captum Modellentwicklern dabei helfen, bessere Modelle zu erstellen und Modelle zu korrigieren, die unerwartete Ergebnisse liefern.

Algorithmusbeschreibungen

Captum ist eine Bibliothek, die die Implementierung verschiedener Interpretierbarkeitsansätze ermöglicht. Die Attributionsalgorithmen von Captum lassen sich in drei große Kategorien einteilen:

  • primäre Attribution: Bestimmt den Beitrag jedes Eingabemerkmals zur Ausgabe eines Modells.
  • Schichtenzuordnung: Jedes Neuron in einer bestimmten Schicht wird auf seinen Beitrag zur Modellausgabe hin bewertet.
  • Neuronattribution: Die Aktivierung eines versteckten Neurons wird durch die Bewertung des Beitrags jedes Eingabemerkmals bestimmt.

Im Folgenden finden Sie einen kurzen Überblick über die verschiedenen Methoden, die derzeit in Captum für die Primär-, Schicht- und Neuronenzuordnung implementiert sind. Außerdem ist eine Beschreibung des Geräuschtunnels enthalten, der zur Glättung der Ergebnisse jeder Attributionsmethode verwendet werden kann. Captum bietet zusätzlich zu seinen Attributionsalgorithmen Metriken zur Schätzung der Zuverlässigkeit von Modellerklärungen. Derzeit stellen sie Untreue- und Sensibilitätsmetriken bereit, die bei der Bewertung der Genauigkeit von Erklärungen helfen.

Primäre Attributionstechniken

Integrierte Farbverläufe

Nehmen wir an, wir haben eine formale Darstellung eines tiefen Netzwerks, F : Rn → [0, 1]. Sei x ∈ Rn die aktuelle Eingabe und x′ ∈ Rn die Basiseingabe. Die Basislinie in Bildnetzwerken könnte das schwarze Bild sein, während es in Textmodellen der Null-Einbettungsvektor sein könnte. Von der Grundlinie x′ bis zur Eingabe x berechnen wir Gradienten an allen Punkten entlang des geradlinigen Pfads (in Rn). Durch die Kumulierung dieser Gradienten lassen sich integrierte Gradienten erzeugen. Integrierte Gradienten werden als Pfadintegral von Gradienten entlang eines direkten Pfads von der Basislinie x′ zur Eingabe x definiert.

Die beiden Grundannahmen Sensitivität und Implementierungsinvarianz bilden die Grundlage dieser Methode. Weitere Informationen zu diesen Axiomen finden Sie im Originalpapier.

Verlaufsform

Shapley-Werte werden in der kooperativen Spieltheorie zur Berechnung von Gradient-SHAP-Werten verwendet, die mithilfe eines Gradientenansatzes berechnet werden. Gradient SHAP fügt jedem Eingabebeispiel mehrmals Gaußsches Rauschen hinzu und wählt dann einen zufälligen Punkt auf dem Pfad zwischen der Basislinie und der Eingabe aus, um den Gradienten der Ausgaben zu bestimmen. Infolgedessen stellen die endgültigen SHAP-Werte den erwarteten Wert der Gradienten dar. * (Eingaben – Basislinien). SHAP-Werte werden unter der Voraussetzung angenähert, dass Eingabemerkmale unabhängig sind und dass das erklärende Modell zwischen den Eingaben und den bereitgestellten Basislinien linear ist.

DeepLIFT

Es ist möglich, DeepLIFT (eine Backpropagation-Technik) zu verwenden, um Eingabeänderungen basierend auf den Unterschieden zwischen Eingaben und ihrer passenden Referenz (oder Basislinie) zuzuschreiben. DeepLIFT versucht, die Ungleichheit zwischen der Ausgabe aus der Referenz anhand der Ungleichheit zwischen den Eingaben aus der Referenz zu erklären. DeepLIFT nutzt die Idee von Multiplikatoren, um einzelnen Neuronen die Schuld für die Unterschiede in den Ausgaben zu geben. Für ein gegebenes Eingabeneuron x mit der Differenz zur Referenz ∆x und ein Zielneuron t mit der Differenz zur Referenz ∆t, zu dem wir den Beitrag berechnen möchten, definieren wir den Multiplikator m∆x∆t als:

DeepLIFT-FORM

DeepLIFT SHAP ist eine DeepLIFT-Erweiterung, die auf den in der kooperativen Spieltheorie etablierten Shapley-Werten basiert. DeepLIFT SHAP berechnet die DeepLIFT-Attribution für jedes Eingabe-Baseline-Paar und mittelt die resultierenden Attributionen pro Eingabebeispiel anhand einer Verteilung von Baselines. Die Nichtlinearitätsregeln von DeepLIFT helfen dabei, die nichtlinearen Funktionen des Netzwerks zu linearisieren, und die Approximation der SHAP-Werte durch die Methode gilt auch für das linearisierte Netzwerk. Bei dieser Methode wird ebenfalls davon ausgegangen, dass Eingabemerkmale unabhängig sind.

Ausprägung

Die Berechnung der Eingabezuordnung über die Ausprägung ist ein unkomplizierter Prozess, der den Gradienten der Ausgabe in Bezug auf die Eingabe ergibt. Als Eingabe wird eine Taylor-Netzwerkerweiterung erster Ordnung verwendet, und die Gradienten sind die Koeffizienten jedes Merkmals in der linearen Darstellung des Modells. Der absolute Wert dieser Koeffizienten kann verwendet werden, um die Relevanz eines Merkmals anzuzeigen. Weitere Informationen zum Salienzansatz finden Sie im Originalpapier.

Geben Sie den X-Gradienten ein

Eingabe-X-Gradient ist eine Erweiterung des Salienzansatzes, bei dem die Gradienten der Ausgabe in Bezug auf die Eingabe genommen und mit den Eingabemerkmalswerten multipliziert werden. Eine Intuition für diesen Ansatz geht von einem linearen Modell aus; Die Gradienten sind einfach die Koeffizienten jeder Eingabe, und das Produkt der Eingabe mit einem Koeffizienten entspricht dem Gesamtbeitrag des Merkmals zur Ausgabe des linearen Modells.

Geführte Backpropagation und Dekonvolution

Die Gradientenberechnung wird über geführte Backpropagation und Dekonvolution durchgeführt, obwohl die Backpropagation von ReLU-Funktionen außer Kraft gesetzt wird, sodass nur nicht negative Gradienten backpropagiert werden. Während die ReLU-Funktion bei der geführten Rückausbreitung auf die Eingabegradienten angewendet wird, wird sie bei der Entfaltung direkt auf die Ausgabegradienten angewendet. Es ist üblich, diese Methoden in Verbindung mit Faltungsnetzwerken einzusetzen, sie können jedoch auch in anderen Arten neuronaler Netzwerkarchitekturen verwendet werden.

Geführte GradCAM

Geführte Backpropagation-Attributionen berechnen das elementweise Produkt von geführten GradCAM-Attributionen (geführtes GradCAM) mit hochgetasteten (Schicht-)GradCAM-Attributionen. Die Attributionsberechnung wird für eine bestimmte Ebene durchgeführt und hochgesampelt, um sie an die Eingabegröße anzupassen. Der Schwerpunkt dieser Technik liegt auf Faltungs-Neuronalen Netzen. Es kann jedoch jede Ebene bereitgestellt werden, die räumlich an der Eingabe ausgerichtet werden kann. Normalerweise wird die letzte Faltungsschicht bereitgestellt.

Merkmalsablation

Um die Attribution zu berechnen, verwendet eine als „Merkmalsablation“ bekannte Technik eine störungsbasierte Methode, die jedes Eingabemerkmal durch eine bekannte „Grundlinie“ oder einen „Referenzwert“ (z. B. 0) ersetzt, bevor die Ausgabedifferenz berechnet wird. Das Gruppieren und Abtragen von Eingabemerkmalen ist eine bessere Alternative als dies einzeln zu tun, und viele verschiedene Anwendungen können davon profitieren. Durch Gruppieren und Entfernen von Bildsegmenten können wir die relative Bedeutung des Segments bestimmen.

Feature-Permutation

Die Merkmalspermutation ist eine auf Störungen basierende Methode, bei der jedes Merkmal innerhalb eines Stapels zufällig permutiert wird und die Änderung der Ausgabe (oder des Verlusts) als Ergebnis dieser Änderung berechnet wird. Auf die gleiche Weise wie bei der Merkmalsablation können Merkmale statt einzeln auch gruppiert werden. Beachten Sie, dass dieser Algorithmus im Gegensatz zu den anderen in Captum verfügbaren Algorithmen der einzige ist, der ordnungsgemäße Zuordnungen liefern kann, wenn ihm ein Stapel mehrerer Eingabebeispiele bereitgestellt wird. Andere Algorithmen benötigen nur ein einziges Beispiel als Eingabe.

Okklusion

Okklusion ist ein störungsbasierter Ansatz zur Berechnung der Attribution, bei dem jeder zusammenhängende rechteckige Bereich durch eine bestimmte Grundlinie/Referenz ersetzt und der Unterschied in der Ausgabe berechnet wird. Für Features, die sich in mehreren Bereichen (Hyperrechtecke) befinden, werden die entsprechenden Ausgabeunterschiede gemittelt, um die Zuordnung für dieses Feature zu berechnen. Die Okklusion ist am nützlichsten in Fällen wie Bildern, in denen Pixel in einem zusammenhängenden rechteckigen Bereich wahrscheinlich stark korreliert sind.

Shapley Value Sampling

Die Attributionstechnik Shapley-Wert basiert auf der kooperativen Spieltheorie. Diese Technik nimmt jede Permutation der Eingabemerkmale und fügt sie einzeln zu einer angegebenen Basislinie hinzu. Der Unterschied in der Ausgabe nach dem Hinzufügen jedes Features entspricht seinem Beitrag, und diese Unterschiede werden über alle Permutationen hinweg summiert, um die Zuordnung zu bestimmen.

Kalk

Eine der am weitesten verbreiteten Interpretierbarkeitsmethoden ist Lime, die ein interpretierbares Ersatzmodell trainiert, indem sie Datenpunkte um ein Eingabebeispiel herum abtastet und Modellauswertungen an diesen Punkten verwendet, um ein einfacher interpretierbares „Ersatzmodell“ zu trainieren, beispielsweise ein lineares Modell.

KernelSHAP

Kernel SHAP ist eine Technik zur Berechnung von Shapley-Werten, die das LIME-Framework verwendet. Shapley-Werte können im LIME-Framework effizienter ermittelt werden, indem die Verlustfunktion festgelegt, der Kernel gewichtet und Terme ordnungsgemäß reguliert werden.

Techniken zur Ebenenzuordnung

Schichtleitfähigkeit

Layer Conductance ist eine Methode, die ein umfassenderes Bild der Bedeutung eines Neurons erstellt, indem sie die Aktivierung des Neurons mit den partiellen Ableitungen sowohl des Neurons in Bezug auf den Input als auch des Outputs in Bezug auf das Neuron kombiniert. Durch das verborgene Neuron baut die Leitfähigkeit auf dem Attributionsfluss von Integrated Gradients (IG) auf. Die Gesamtleitfähigkeit eines verborgenen Neurons ist in der Originalarbeit wie folgt definiert:

Interner Einfluss

Mithilfe des internen Einflusses kann man das Integral der Gradienten entlang des Pfads von einer Basiseingabe zur bereitgestellten Eingabe schätzen. Diese Technik ähnelt der Anwendung integrierter Farbverläufe, bei der der Farbverlauf in Bezug auf die Ebene (und nicht auf die Eingabe) integriert wird.

Aktivierung des Ebenenverlaufs X

Layer Gradient X Activation ist das Netzwerkäquivalent der Input Es multipliziert die Aktivierung der Ebene Element für Element mit den Farbverläufen der Zielausgabe in Bezug auf die angegebene Ebene.

GradCAM

GradCAM ist eine Faltungsschichtzuordnungstechnik für neuronale Netzwerke, die typischerweise auf die letzte Faltungsschicht angewendet wird. GradCAM berechnet die Gradienten der Zielausgabe in Bezug auf die angegebene Ebene, mittelt jeden Ausgabekanal (Ausgabedimension 2) und multipliziert den durchschnittlichen Gradienten für jeden Kanal mit den Ebenenaktivierungen. Auf die Ausgabe wird eine ReLU angewendet, um sicherzustellen, dass aus der Summe der Ergebnisse über alle Kanäle nur nicht negative Attributionen zurückgegeben werden.

Neuronen-Attributionstechniken

Neuronenleitfähigkeit

Die Leitfähigkeit kombiniert die Neuronenaktivierung mit partiellen Ableitungen sowohl des Neurons in Bezug auf den Input als auch des Outputs in Bezug auf das Neuron, um ein umfassenderes Bild der Neuronenrelevanz zu liefern. Um die Leitfähigkeit eines bestimmten Neurons zu bestimmen, untersucht man den Fluss der IG-Attribution von jedem Eingang, der dieses Neuron passiert. Das Folgende ist die formale Definition der Leitfähigkeit von Neuronen bei gegebener Eingabezuordnung i im Originalpapier:

Gemäß dieser Definition ist zu beachten, dass die Summierung der Leitfähigkeit eines Neurons (über alle Eingabemerkmale hinweg) immer gleich der Leitfähigkeit der Schicht ist, in der sich dieses spezifische Neuron befindet.

Neuronengradient

Der Neuronengradientenansatz ist die Äquivalenz der Salienzmethode für ein einzelnes Neuron im Netzwerk. Es berechnet einfach den Gradienten der Neuronenausgabe relativ zur Modelleingabe. Man kann sich diese Methode wie Saliency als eine Taylor-Erweiterung erster Ordnung des Neuronenausgangs am gegebenen Eingang vorstellen, wobei die Gradienten den Koeffizienten jedes Merkmals in der linearen Darstellung des Modells entsprechen.

Neuronenintegrierte Gradienten

Mit einer Technik namens „Neuron Integrated Gradients“ ist es möglich, das Integral von Eingabegradienten in Bezug auf ein bestimmtes Neuron über den gesamten Pfad von einer Basiseingabe bis zur interessierenden Eingabe abzuschätzen. „Integrale Gradienten entsprechen dieser Methode, vorausgesetzt, dass die Ausgabe nur die des identifizierten Neurons ist. Weitere Informationen zum integrierten Gradientenansatz finden Sie im Originalpapier hier.

Neuronen-GradientSHAP

Neuron GradientSHAP ist das Äquivalent von GradientSHAP für ein bestimmtes Neuron. Neuron GradientSHAP fügt jeder Eingabeprobe mehrmals Gaußsches Rauschen hinzu, wählt einen zufälligen Punkt entlang des Pfads zwischen Grundlinie und Eingabe und berechnet den Gradienten des Zielneurons in Bezug auf jeden zufällig ausgewählten Punkt. Die resultierenden SHAP-Werte liegen nahe an den vorhergesagten Gradientenwerten *. (Eingaben – Grundlinien).

Neuron DeepLIFT SHAP

Neuron DeepLIFT SHAP ist das Äquivalent von DeepLIFT für ein bestimmtes Neuron. Mithilfe der Verteilung der Basislinien berechnet der DeepLIFT SHAP-Algorithmus die Neuron DeepLIFT-Attribution für jedes Eingabe-Baseline-Paar und mittelt die resultierenden Zuordnungen pro Eingabebeispiel.

Lärmtunnel

Noise Tunnel ist eine Attributionstechnik, die in Verbindung mit anderen Methoden verwendet werden kann. Der Rauschtunnel berechnet die Attribution mehrmals, fügt der Eingabe jedes Mal Gaußsches Rauschen hinzu und führt dann die resultierenden Attributionen abhängig vom gewählten Typ zusammen. Die folgenden Geräuschtunneltypen werden unterstützt:

  • Smoothgrad: Der Mittelwert der Stichprobenzuordnungen wird zurückgegeben. Die Glättung der angegebenen Attributionstechnik mithilfe eines Gaußschen Kernels ist eine Annäherung an diesen Prozess.
  • Smoothgrad Squared: Der Mittelwert der quadrierten Stichprobenzuordnungen wird zurückgegeben.
  • Vargrad: Die Varianz der Stichprobenattribute wird zurückgegeben.

Metriken

Untreue

Untreue misst den mittleren quadratischen Fehler zwischen Modellerklärungen in den Größen der Eingabestörungen und den Änderungen der Prädiktorfunktion an diesen Eingabestörungen. Untreue wird wie folgt definiert:

Von bekannten Attributionstechniken wie dem integrierten Gradienten ist dies ein rechnerisch effizienteres und erweitertes Konzept von Sensitivy-n. Letzterer analysiert die Korrelationen zwischen der Summe der Attributionen und den Unterschieden der Prädiktorfunktion an ihrem Eingang und einer vordefinierten Basislinie.

Empfindlichkeit

Die Empfindlichkeit, die als Grad der Erklärungsänderung bei winzigen Eingangsstörungen unter Verwendung einer auf Monte-Carlo-Stichproben basierenden Näherung definiert ist, wird wie folgt gemessen:

Standardmäßig nehmen wir Stichproben aus einem Unterraum einer L-Infinity-Kugel mit einem Standardradius zur ungefähren Empfindlichkeit. Benutzer können den Radius des Balls und die Beispielfunktion ändern.

Modellinterpretation für vorab trainiertes ResNet-Modell

Dieses Tutorial zeigt, wie Sie Modellinterpretierbarkeitsmethoden für ein vorab trainiertes ResNet-Modell mit einem ausgewählten Bild verwenden und visualisiert die Zuordnungen für jedes Pixel, indem es sie auf dem Bild überlagert. In diesem Tutorial verwenden wir die Interpretationsalgorithmen Integrated Gradients, GradientShape, Attribution with Layer GradCAM und Occlusion.

Bevor Sie beginnen, müssen Sie über eine Python-Umgebung verfügen, die Folgendes umfasst:

  • Python-Version 3.6 oder höher
  • PyTorch Version 1.2 oder höher (die neueste Version wird empfohlen)
  • TorchVision Version 0
  • .6 oder höher (die neueste Version wird empfohlen)
  • Captum (die neueste Version wird empfohlen)

Je nachdem, ob Sie die virtuelle Anaconda- oder Pip-Umgebung verwenden, helfen Ihnen die folgenden Befehle bei der Einrichtung von Captum:

Mit conda:

conda install pytorch torchvision captum -c pytorch

Mit pip:

pip install torch torchvision captum

Lassen Sie uns Bibliotheken importieren.

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

Lädt das vorab trainierte Resnet-Modell und versetzt es in den Bewertungsmodus

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

Das ResNet wird auf dem ImageNet-Datensatz trainiert. Lädt die Liste der ImageNet-Dataset-Klassen/Labels im Speicher herunter und liest sie.

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)

Nachdem wir das Modell fertiggestellt haben, können wir das Bild zur Analyse herunterladen. In meinem Fall habe ich ein Katzenbild gewählt.

Quelle

Ihr Bildordner muss die Datei cat.jpg enthalten. Wie wir unten sehen können, öffnet und identifiziert Image.open() die angegebene Bilddatei und np.asarry() konvertiert sie in ein Array.

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

Im folgenden Code definieren wir Transformatoren und Normalisierungsfunktionen für das Bild. Um unser ResNet-Modell zu trainieren, haben wir den ImageNet-Datensatz verwendet, der erfordert, dass Bilder eine bestimmte Größe haben und die Kanaldaten auf einen bestimmten Wertebereich normalisiert sind. transforms.Compose() setzt mehrere Transformationen zusammen und transforms.Normalize() normalisiert ein Tensorbild mit Mittelwert und Standardabweichung.

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

Jetzt werden wir die Klasse des Eingabebildes vorhersagen. Die Frage, die gestellt werden kann, lautet: „Was stellt dieses Bild für unser Modell dar?“ ”

#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(), ')')

Ausgabe :

Predicted: tabby ( 0.5530276298522949 )

Die Tatsache, dass ResNet glaubt, dass unser Bild einer Katze eine tatsächliche Katze darstellt, ist bestätigt. Aber was vermittelt dem Model den Eindruck, dass es sich um das Bild einer Katze handelt? Um die Lösung dieser Frage zu finden, werden wir Captum konsultieren.

Merkmalszuordnung mit integrierten Farbverläufen

Eine der verschiedenen Techniken zur Merkmalszuordnung in Captum sind integrierte Farbverläufe. Integrierte Gradienten verleihen jedem Eingabemerkmal einen Relevanzwert, indem das Integral der Gradienten der Modellausgabe in Bezug auf die Eingaben geschätzt wird.

In unserem Fall nehmen wir eine bestimmte Komponente des Ausgabevektors – diejenige, die das Vertrauen des Modells in seine ausgewählte Kategorie angibt – und verwenden integrierte Farbverläufe, um herauszufinden, welche Aspekte des Eingabebilds zu dieser Ausgabe beigetragen haben. Dadurch können wir feststellen, welche Teile des Bildes für die Erzielung dieses Ergebnisses am wichtigsten waren. Nachdem wir die Wichtigkeitskarte von Integrated Gradients erhalten haben, werden wir die von Captum erfassten Visualisierungstools verwenden, um eine klare und verständliche Darstellung der Wichtigkeitskarte bereitzustellen.

Integrierte Gradienten bestimmen das Integral der Gradienten der Ausgabe des Modells für die vorhergesagte Klasse pred_label_idx in Bezug auf die Eingabebildpixel entlang des Pfads vom schwarzen Bild zu unserem Eingabebild.

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)

Ausgabe :

Predicted: tabby ( 0.5530276298522949 )

Sehen wir uns das Bild und die dazugehörigen Zuschreibungen an, indem wir diese über das Bild legen. Die von Captum angebotene Methode visualize_image_attr() bietet eine Reihe von Möglichkeiten, die Darstellung der Attributionsdaten an Ihre Vorlieben anzupassen. Hier übergeben wir eine benutzerdefinierte Matplotlib-Farbkarte (siehe 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)

Ausgabe :

Sie sollten in dem Bild, das wir oben gezeigt haben, erkennen können, dass der Bereich um die Katze im Bild der Ort ist, an dem der Integrated Gradients-Algorithmus uns das stärkste Signal liefert.

Lassen Sie uns Attributionen mithilfe integrierter Farbverläufe berechnen und sie dann über mehrere Bilder glätten, die von einem Rauschtunnel erzeugt wurden. Letzterer modifiziert die Eingabe, indem er Gaußsches Rauschen mit einer Standardabweichung von eins, zehnmal hinzufügt (nt_samples=10). Der smoothgrad_sq-Ansatz wird von Noise Tunnel verwendet, um die Zuordnungen über alle nt_samples verrauschter Samples konsistent zu machen. Der Wert von smoothgrad_sq ist der Mittelwert der quadrierten Zuordnungen über nt_samples-Stichproben. visualize_image_attr_multiple() visualisiert die Attribution für ein bestimmtes Bild, indem es die Attributionswerte des angegebenen Zeichens (positiv, negativ, absoluter Wert oder alle) normalisiert und sie dann im ausgewählten Modus in einer Matplotlib-Abbildung anzeigt.

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)

Ausgabe :

Auf den Bildern oben kann ich sehen, dass sich das Modell auf den Kopf der Katze konzentriert.

Zum Abschluss verwenden wir GradientShap. GradientShap ist ein Gradientenansatz, der zur Berechnung von SHAP-Werten verwendet werden kann und außerdem ein fantastisches Werkzeug ist, um Einblicke in das globale Verhalten zu gewinnen. Es handelt sich um ein lineares Erklärungsmodell, das die Vorhersagen des Modells anhand einer Verteilung von Referenzstichproben erklärt. Es bestimmt die erwarteten Gradienten für eine Eingabe, die zufällig zwischen der Eingabe und einer Grundlinie ausgewählt wird. Die Basislinie wird zufällig aus der bereitgestellten Verteilung der Basislinien ausgewählt.

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)

Ausgabe :

Layer-Attribution mit Layer GradCAM

Mithilfe der Layer-Attribution können Sie die Aktivität verborgener Ebenen in Ihrem Modell mit Merkmalen Ihrer Eingabe in Beziehung setzen. Wir werden einen Algorithmus zur Schichtzuordnung anwenden, um die Aktivität einer der in unserem Modell enthaltenen Faltungsschichten zu untersuchen. GradCAM ist für die Berechnung der Farbverläufe der Zielausgabe in Bezug auf die angegebene Ebene verantwortlich. Diese Gradienten werden dann für jeden Ausgabekanal gemittelt (Dimension 2 der Ausgabe) und die Ebenenaktivierungen werden mit dem durchschnittlichen Gradienten für jeden Kanal multipliziert. Die Ergebnisse werden über alle Kanäle hinweg summiert. Da die Aktivität von Faltungsschichten häufig räumlich auf die Eingabe abgebildet wird, werden GradCAM-Zuordnungen häufig hochgetastet und zum Maskieren der Eingabe verwendet. Es ist erwähnenswert, dass GradCAM explizit für Faltungs-Neuronale Netze (Convnets) entwickelt wurde. Die Ebenenzuordnung wird auf die gleiche Weise wie die Eingabezuordnung eingerichtet, mit der Ausnahme, dass Sie zusätzlich zum Modell eine verborgene Ebene innerhalb des Modells bereitstellen müssen, das Sie analysieren möchten. Ähnlich wie zuvor besprochen geben wir beim Aufruf von attribute() die interessierende Zielklasse an.

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

Um einen genaueren Vergleich zwischen dem Eingabebild und diesen Attributionsdaten zu ermöglichen, werden wir diese mit Hilfe der Funktion interpolate() hochskalieren, die sich in der LayerAttribution-Basisklasse befindet.

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

Ausgabe :

Visualisierungen wie diese haben das Potenzial, Ihnen einzigartige Erkenntnisse darüber zu liefern, wie Ihre verborgenen Ebenen auf die von Ihnen bereitgestellten Eingaben reagieren.

Merkmalszuordnung mit Okklusion

Auf Gradienten basierende Methoden helfen dabei, das Modell im Hinblick auf die direkte Berechnung der Änderungen in der Ausgabe in Bezug auf die Eingabe zu verstehen. Die als störungsbasierte Attribution bekannte Technik geht dieses Problem direkter an, indem sie Änderungen an der Eingabe vornimmt, um die Auswirkungen solcher Änderungen auf die Ausgabe zu quantifizieren. Eine solche Strategie wird Okklusion genannt. Dabei werden Teile des Eingangsbildes ausgetauscht und analysiert, wie sich diese Änderung auf das am Ausgang erzeugte Signal auswirkt.

Im Folgenden konfigurieren wir die Okklusionsattribution. Wie bei der Konfiguration eines Faltungs-Neuronalen Netzwerks können Sie die Größe der Zielregion und eine Schrittlänge wählen, die den Abstand der einzelnen Messungen bestimmt. Wir werden die Funktion visualize_image_attr_multiple() verwenden, um die Ergebnisse unserer Occlusion-Attribution anzuzeigen. Diese Funktion zeigt Heatmaps sowohl der positiven als auch der negativen Attribution pro Region an und maskiert das Originalbild mit den Regionen mit positiver Attribution. Die Maskierung ermöglicht einen sehr aufschlussreichen Blick auf die Bereiche unseres Katzenfotos, die das Modell als am „katzenähnlichsten“ identifiziert hat. ”

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

Ausgabe :

Dem Teil des Bildes, der die Katze zeigt, scheint eine höhere Bedeutung beigemessen zu werden.

Abschluss

Captum ist eine vielseitige und einfache Modellinterpretierbarkeitsbibliothek für PyTorch. Es bietet modernste Techniken zum Verständnis, wie sich bestimmte Neuronen und Schichten auf Vorhersagen auswirken. Es gibt drei Haupttypen von Attributionstechniken: primäre Attributionstechniken, Schichtattributionstechniken und Neuronenattributionstechniken.

Referenzen

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

Verwandte Artikel: