【卷积神经网络可视化】之热度图可视化

【卷积神经网络】之热度图可视化

一、内容

深度学习一直被人们称为**“黑盒子”**,即内部算法不可见。但是,卷积神经网络(CNN)却能够被可视化,通过可视化,人们能够了解CNN识别图像的过程。

介绍三种可视化方法 :
1.卷积核输出的可视化(Visualizing intermediate convnet outputs (intermediate activations),即可视化卷积核经过激活之后的结果。能够看到图像经过卷积之后结果,帮助理解卷积核的作用
2.卷积核的可视化(Visualizing convnets filters),帮助我们理解卷积核是如何感受图像的
3.热度图的可视化(Visualizing heatmaps of class activation in an image),通过热度图,了解图像分类问题中图像哪些部分起到了关键作用,同时可以定位图像中物体的位置

我们将先学习第三种可视化技术,这种技术有助于理解给定图像的哪些部分导致了卷积神经网络最终的分类决策。这有助于“调试”卷积神经网络的决策过程,特别是在分类错误的情况下。它还允许您在图像中定位特定的对象。
这类技术被称为**“类激活图”(CAM)可视化**,它包括在输入图像上生成“类激活”的热图。“类激活”热图是与特定输出类相关的2D分数网格,计算任何输入图像中的每个位置,表明每个位置相对于所考虑的类的重要性。它非常简单:它包含了给定一个输入图像的卷积层的输出特征图,并通过类相对于该通道的梯度来权衡该特征图中的每个通道。直观上,理解这个技巧的一种方法是,我们通过“每个通道对于类的重要性”来衡量“输入图像激活不同通道的强度”的空间图,从而得到“输入图像激活类的强度”的空间图。

在图像分类问题中,假设网络将一张图片识别成“猫”的概率是0.9,我想了解到底最后一层的卷积层对这0.9的概率的贡献是多少。换句话时候,假设最后一层卷积层有512个卷积核,我想了解这512个卷积核对该图片是”猫”分别投了几票。投票越多的卷积核,就越确信图片是“猫”,因为它们提取到的特征趋向猫的特征。

二、代码

from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import decode_predictions
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from keras import backend as K

# 导入VGG-16模型和权重
model = VGG16(weights='imagenet')
# 查看模型结构
model.summary()
# 导入图片
src = cv.imread("D:/vsprojects/images/elephant.png")
# 改变图片尺寸适应网络结构
img = cv.resize(src, (224, 224))
# 添加一个维度
x = np.expand_dims(img, 0)

# 模型预测
preds = model.predict(x)
# 打印出top3预测
print('Predicted:', decode_predictions(preds, top=3)[0])
# 打印索引
print(np.argmax(preds[0]))

# 这是预测向量中的“非洲象”条目
african_elephant_output = model.output[:, np.argmax(preds[0])]
# 获得VGG-16中的最后一个卷积层
last_conv_layer = model.get_layer('block5_conv3')
# 求“非洲象”类相对于“block5_conv3”输出特征映射的梯度
grads = K.gradients(african_elephant_output, last_conv_layer.output)[0]
# 改层是一个形状向量(512,),其中每个条目是特定feature map通道上梯度的平均强度
pooled_grads = K.mean(grads, axis=(0, 1, 2))

# 给定一个样本图像,获取输出
iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])
# 这些是这两个量的值,作为Numpy数组,给出了两个大象的样本图像
pooled_grads_value, conv_layer_output_value = iterate([x])

# 将feature map数组中的每个通道乘以关于elephant类的“这个通道有多重要”
for i in range(512):
    conv_layer_output_value[:, :, i] *= pooled_grads_value[i]
# 得到的特征图的通道平均是我们的类激活热图
heatmap = np.mean(conv_layer_output_value, axis=-1)
# 归一化处理
heatmap = np.maximum(heatmap, 0)
heatmap /= np.max(heatmap)
# 数组绘制成图像
plt.matshow(heatmap)
plt.show()

# 调整热图的大小,使其与原始图像大小相同
heatmap = cv.resize(heatmap, (src.shape[1], src.shape[0]))
# 将热图转换为RGB
heatmap = np.uint8(255 * heatmap)
# 转化为伪彩色图像
heatmap = cv.applyColorMap(heatmap, cv.COLORMAP_JET)
# 进行叠加
superimposed_img = heatmap * 0.5 + src
# 将预测结果添加
cv.putText(superimposed_img, decode_predictions(preds)[0][0][1],(50, 50), cv.FONT_HERSHEY_PLAIN, 2.0, (0, 0, 255), 2, 8)
# 保存叠加图像
cv.imwrite('D:/elephant.png', superimposed_img)

三、结果

1.输入

【卷积神经网络可视化】之热度图可视化_第1张图片

2.输出

【卷积神经网络可视化】之热度图可视化_第2张图片

3.拓展(乳腺肿瘤良恶性分析)

【卷积神经网络可视化】之热度图可视化_第3张图片
【卷积神经网络可视化】之热度图可视化_第4张图片

你可能感兴趣的:(【卷积神经网络可视化】之热度图可视化)