【卷积神经网络可视化】之热度图可视化_visualizing heatmaps of class activation in an ima-CSDN博客
首先安装好对应的安装包,做这个的目的是为了可视化网络模型,查看每一个卷积之后得出的效果,可以通过改变网络模块来改进网络结构。这段代码只是计算最后一层的卷积输出热图。并没有计算每一层的梯度热图。
之后复制上面的代码,开始报错
raise RuntimeError("tf.gradients is not supported when eager execution " RuntimeError: tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.
搜了一下,
tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.-CSDN博客
放在前面。原图片
生成之后的图片
下面对代码进行解析
#导入模型和权重
model = VGG16(weights='imagenet')
这个模型是从keras里面导过来的。这段代码表示从keras的应用模块导入在imagenet数据集上训练好的模型与权重文件,这里训练好的模型有xception,vgg16,vgg19等。
from keras.applications.vgg16 import VGG16
应用 Applications - Keras 中文文档 (keras-zh.readthedocs.io)
我们转到keras中文文档中
ImageNet是一个大型可视化数据库,主要用于视觉对象识别软件的研究,ImageNet包含超过1400万的图像URL,这些URL被手动注释以指示图片中的对象。
并且还有很多模型可以使用
模型准确率
# 查看模型结构
model.summary()
这段代码效果
这里可以看到输入的大小,中间的层的输出大小以及参数。
图像入门 - 【布客】OpenCV 4.0.0 中文翻译 (apachecn.org)
cv.imread("E:/IRTC/ceshi/img.png")
返回的是一个numpy数组。形状会是 (height, width, 3)
# 模型预测
preds = model.predict(x)
返回
结果是预测的 Numpy 数组(或数组列表)
预测结果的形状取决于模型架构和输入数据的形状。例如,如果你的模型是一个用于分类的神经网络,并且你有一个包含 10 个类别的 softmax 输出层,那么对于每个输入样本,predict
方法将返回一个包含 10 个元素的一维数组,表示该样本属于每个类别的概率
模型预测输入可以是一个numpy数组。
# 将结果解码为元组列表 (class, description, probability)
# (一个列表代表批次中的一个样本)
print('Predicted:', decode_predictions(preds, top=3)[0])
# Predicted: [(u'n02504013', u'Indian_elephant', 0.82658225),(u'n01871265', u'tusker', 0.1122357),
top=3的意思是打印出前三个准确率高的结果,低的就别打印出来了。[0]表示
返回该批次中第一个图像的预测结果),而这里批次没有,只有一张图片。所以就[0],如果你写出[1],那么还会报错,list index out of range.
# 打印索引
print(np.argmax(preds[0]))
返回沿轴的最大值的索引。也就是返回预测的最大值对应的索引值。
最后的代码如下:我怕原up主删掉嘿嘿
# 这是预测向量中的“非洲象”条目
african_elephant_output = model.output[:, np.argmax(preds[0])]
这行代码是将对应的最大的索引的输出赋值给elephant_output ,output指定输出特定层数的张量,
# 获得VGG-16中的最后一个卷积层
last_conv_layer = model.get_layer('block4_conv3')
在文档中可以看到返回的是一个实例
chat说的很好,就是获取这一层的所有属性以及方法。试一下访问这些属性。不会用
# 求“非洲象”类相对于“block5_conv3”输出特征映射的梯度
grads = K.gradients(african_elephant_output, last_conv_layer.output)[0]
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
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
# 导入VGG-16模型和权重
model = VGG16(weights='imagenet')
# 查看模型结构
model.summary()
# model.get_config()
# 导入图片
src = cv.imread("E:/IRTC/ceshi/img.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('block4_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)