使用 Partition 解释器解释 ResNet50

本笔记本演示了如何使用 SHAP 来解释图像分类模型。在这个例子中,我们解释了 ResNet50 模型对图像进行 1000 个 ImageNet 类别分类的输出。

[1]:
import json

from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input

import shap

加载模型和数据

[2]:
# load pre-trained model and data
model = ResNet50(weights="imagenet")
X, y = shap.datasets.imagenet50()
[3]:
# getting ImageNet 1000 class names
url = "https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json"
with open(shap.datasets.cache(url)) as file:
    class_names = [v[1] for v in json.load(file).values()]
# print("Number of ImageNet classes:", len(class_names))
# print("Class names:", class_names)

SHAP ResNet50 模型对图像的解释

使用以下内容构建一个分区解释器:- 模型(一个 Python 函数)- 掩码器(一个 Python 函数)- 输出名称(输出类名称的列表)

快速运行并进行少量评估

[4]:
# python function to get model output; replace this function with your own model function.
def f(x):
    tmp = x.copy()
    preprocess_input(tmp)
    return model(tmp)


# define a masker that is used to mask out partitions of the input image.
masker = shap.maskers.Image("inpaint_telea", X[0].shape)

# create an explainer with model and image masker
explainer = shap.Explainer(f, masker, output_names=class_names)

# here we explain two images using 500 evaluations of the underlying model to estimate the SHAP values
shap_values = explainer(
    X[1:3], max_evals=100, batch_size=50, outputs=shap.Explanation.argsort.flip[:4]
)
Partition explainer: 3it [00:10,  3.37s/it]

解释器选项:

  1. 上述图像遮罩器使用了一种称为“inpaint_telea”的模糊技术。还有其他可用于实验的遮罩选项,例如“inpaint_ns”和“blur(kernel_xsize, kernel_xsize)”。

  2. 推荐的评估次数为300-500次,以获得对超像素的解释,具有足够的粒度。评估次数越多,粒度越高,但运行时间也会增加。

    注意:在上面的代码中使用了 outputs=shap.Explanation.argsort.flip[:4] 来获取 SHAP 值,因为我们想要获取每张图像的前 4 个最可能的类别,即概率递减的前 4 个类别。因此,使用了翻转的 argsort 并切片为 4。

可视化 SHAP 值输出

[5]:
# output with shap values
shap.image_plot(shap_values)
../../../_images/example_notebooks_image_examples_image_classification_Explain_ResNet50_using_the_Partition_explainer_10_0.png
  1. 在第一个例子中,给定的鸟类图像被分类为美洲白鹭,其次是鹤、鹭和火烈鸟。正是鸟脖子上的“隆起”导致它被分类为美洲白鹭而不是鹤、鹭或火烈鸟。你可以看到鸟的颈部区域被适当的高亮显示为红色超像素。

  2. 在第二个例子中,是船的形状导致它被归类为快艇,而不是喷泉、救生艇或雪犁(红色超像素中适当突出显示)。

长时间的运行,包含多次评估

通过增加 max_evals 参数,我们让 SHAP 执行原始模型更多次,从而获得更细致的解释。我们还使用了模糊核,既为了演示它,也因为它的速度比修复快得多。请注意,如果您系统上没有使用现代GPU,这将需要一段时间。

[6]:
# python function to get model output; replace this function with your own model function.
def f(x):
    tmp = x.copy()
    preprocess_input(tmp)
    return model(tmp)


# define a masker that is used to mask out partitions of the input image.
masker_blur = shap.maskers.Image("blur(128,128)", X[0].shape)

# create an explainer with model and image masker
explainer_blur = shap.Explainer(f, masker_blur, output_names=class_names)

# here we explain two images using 500 evaluations of the underlying model to estimate the SHAP values
shap_values_fine = explainer_blur(
    X[1:3], max_evals=5000, batch_size=50, outputs=shap.Explanation.argsort.flip[:4]
)
Partition explainer: 3it [00:17,  5.87s/it]
[7]:
# output with shap values
shap.image_plot(shap_values_fine)
../../../_images/example_notebooks_image_examples_image_classification_Explain_ResNet50_using_the_Partition_explainer_14_0.png

有更多有用示例的想法吗?我们鼓励提交增加此文档笔记本的拉取请求!