ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

LIME算法:图像分类解释器(代码实现)

2020-06-01 20:38:01  阅读:430  来源: 互联网

标签:解释器 image mask 算法 图像 import LIME


在上一篇博客LIME算法:模型的可解释性(代码实现)中,我整理了LIME算法的原理及在文本分类模型中的应用。在这篇笔记中,我记录了LIME算法在图像分类模型中的应用及过程中遇到的问题和解决方法。

一、算法简介

LIME算法是Marco Tulio Ribeiro2016年发表的论文《“Why Should I Trust You?” Explaining the Predictions of Any Classifier》中介绍的局部可解释性模型算法。该算法主要是用在文本类与图像类的模型中。
在这里插入图片描述
在日常测试图像分类模型时,常常会得到一些莫名其妙的预测结果。我拿我家小猫的照片做测试,得出的预测结果竟然有“纸箱、安全带”这样的分类:
在这里插入图片描述
我忍不住想知道,我家小猫到底哪部分长得像安全带?而要得到这个答案,就可以利用LIME解释器来帮助解释。

二、LIME解释器代码实现

要实现LIME解释器在图像分类模型中的应用,首先要有一个已经建模完成的图像分类模型,这里参考lime算法的GitHub实例,基于keras框架下载Google Inception net-v3深度神经网络模型。

#加载需要的包
import os
import keras
from keras.applications import inception_v3 as inc_net
from keras.preprocessing import image
from keras.applications.imagenet_utils import decode_predictions
from skimage.io import imread
import matplotlib.pyplot as plt
import numpy as np
print('Notebook run using keras:', keras.__version__)

#下载Google Inception net-v3深度神经网络模型
inet_model = inc_net.InceptionV3()

对待分类图像做数据预处理

def transform_img_fn(path_list):
    out = []
    for img_path in path_list:
        img = image.load_img(img_path, target_size=(299, 299))
        x = image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        x = inc_net.preprocess_input(x)
        out.append(x)
    return np.vstack(out)

读取图像,输出预测结果。

images = transform_img_fn([os.path.join('./','cat.jpg')])#加载图像后直接进行数据处理
plt.imshow(images[0] / 2 + 0.5)
preds = inet_model.predict(images)
for x in decode_predictions(preds)[0]:
    print(x)#输出预测结果

可以看到输出的预测结果TOP5,分别为埃及猫、猞猁、纸箱、窗口屏幕、安全带。
在这里插入图片描述

预测结果的最大概率”埃及猫“和实际猫咪是吻合的,但是为什么会预测出纸箱、安全带之类的结果,就让人一头雾水了。这样的情况通过LIME算法是可以得到解答的。

LIME模型的原理是,把原始图片转成可解释的特征表示,通过可解释的特征表示对样本进行扰动,得到N个扰动后的样本。然后再将这N个样本还原到原始特征空间,并把预测值作为真实值,用可解释的特征数据表示建立简单的数据表示,观察哪些超像素的系数较大。这部分的原理解释在上一篇博客中已经进行了详细的解释,这里主要关注代码的实现。

#加载lime包
import lime
from lime import lime_image

建立解释器,explain_instance的参数包括:

image:代解释图像
classifier_fn:分类器
labels:可解释标签
hide_color:隐藏颜色
top_labels:预测概率最高的K个标签生成解释
num_features:说明中出现的最大功能数
num_samples:学习线性模型的领域大小
batch_size:批处理大小
distance_metric:距离度量
model_regressor:模型回归器,默认为岭回归
segmentation_fn:分段,将图像分为多少个大小
random_seed:随机整数,用作分割算法的随机种子

explainer = lime_image.LimeImageExplainer()
x=images[0].astype(np.double) #lime要求numpy array
explanation = explainer.explain_instance(x, inet_model.predict, top_labels=5, hide_color=0, num_samples=1000)

解释器进度条跑完说明解释器运行完成。

在这里插入图片描述

对图像分类结果进行解释,首先看“埃及猫”的解释。

from skimage.segmentation import mark_boundaries
temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=True)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

显示出的图像是对分类结果最有力的部分。

在这里插入图片描述

可以调整参数hide_rest让图像的其他部分取消隐藏。

temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=False)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

在这里插入图片描述

还可以看到赞成部分和反对部分,赞成为绿色区域,反对为红色区域。

temp, mask = explanation.get_image_and_mask(explanation.top_labels[0], positive_only=True, num_features=5, hide_rest=False)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

在这里插入图片描述

以上是对预测结果为“埃及猫”的解释,还可以看看对预测结果为“安全带”的解释。

temp, mask = explanation.get_image_and_mask(explanation.top_labels[4], positive_only=True, num_features=5, hide_rest=True)
plt.imshow(mark_boundaries(temp / 2 + 0.5, mask))

在这里插入图片描述

可以看到模型对于图像中“不太像猫“的部分作出了”安全带“的分类。

由此,通过LIME算法可以对某张图像分类结果进行可视化的解释,使我们能更直观的看到模型的分类效果。

三、LIME算法的应用条件

在基于keras框架实现LIME算法之前,我是用pytorch自己建了神经网络图像分类模型来试用LIME算法。发现LIME算法中的skimage只能识别的tensor通道顺序为:NHWC,其中:
N:batch
H:height
W:width
C:channel

images = transform_img_fn([os.path.join('./','cat.jpg')])
images.shape

输出结果为:(1,299,299,3)
而pytorch中的tensor通道顺序为:NCHW,即为(1,3,299,299)。
所以如果是在pytorch框架下实现lime解释器,则考虑通道顺序问题,可以先对分类器进行封装。

def batch_model(images):
    model.eval()
    images=torch.FloatTensor(images).permute(0, 3, 1, 2)
    #通过permute改变通道顺序适用于pytorch,也就是(batches, channels, height, width)
    return model(images)

四、参考资料

1、https://github.com/marcotcr/lime

标签:解释器,image,mask,算法,图像,import,LIME
来源: https://blog.csdn.net/weixin_42347070/article/details/106455763

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有