分类网络中的类激活热力图 您所在的位置:网站首页 热力图的热力值是什么意思呀 分类网络中的类激活热力图

分类网络中的类激活热力图

2024-04-10 16:17| 来源: 网络整理| 查看: 265

1、背景

卷积神经网络是一种黑盒技术,通过理论推导,以及梯度传播,去不断逼近局部最优解。但神经网络究竟是怎么做出判断和决策的,需要不断地探究。近些年来有一些这方面的研究,类激活热力图(CAM)就是一个方面。

热力图通常是用来对类别进行划分的图像,它有点像红外成像图,温度高的地方就很红,温度低的部分就呈现蓝色。同理,我们使用热力图可以以权重的形式来展现,神经网络对图片的哪一部分激活值最大。比如输入到猫狗分类,如果卷积神经网络判别是猫,那它的热力图普遍分散在猫身上,而至于它是根据猫的哪一部分来判别,就利用了热力图的原理

2、原理

使用卷积神经网络进行分类,最后一层通常是softmax层,其最大值对应的就是分类网络预测的类别

我们从这个最大概率分类类别的节点出发,进行反向传播,对最后一层卷积层求得梯度,然后对每一张特征图求出均值,最后我们取出 最后一层卷积层的激活值,与前面我们对梯度特征图的均值进行相乘,这个过程可以理解为,每个通道的重要程度与我们卷积激活值进行相乘,就相当于是一个加权操作。最后根据这个乘积值生成一个热力图,与原图进行叠加,得到了可视化的CAM图。

3、代码

框架:keras

功能:cam热力图的实现

前提:已经训练完成了,得到了后缀名为.h5的模型文件

from keras import backend as K from keras.models import load_model from keras.preprocessing import image from keras.utils import plot_model from keras import Model import numpy as np import matplotlib.pyplot as plt from keras.applications.vgg16 import preprocess_input import cv2 def load_model_h5(model_file): """ 载入原始keras模型文件 :param model_file: 模型文件,h5类型 :return: 模型 """ return load_model(model_file) def load_img_preprocess(img_path, target_size): """ 加载图片并进行预处理 :param img_path: 图片文件名 target_size: 要加载图片的缩放大小 这是一个tuple元组类型 :return: 预处理过的图像文件 """ img = image.load_img(img_path, target_size=target_size) img = image.img_to_array(img) # 转换成数组形式 img = np.expand_dims(img, axis=0) # 为图片增加一维batchsize,直接设置为1 img = preprocess_input(img) # 对图像进行标准化 return img def gradient_compute(model, layername, img): """ 计算模型最后输出与你的layer的梯度 并将每个特征图的梯度进行平均 再将其与卷积层输出相乘 :param model: 模型 :param layername: 你想可视化热力的层名 :param img: 预处理后的图像 :return: 卷积层与平均梯度相乘的输出值 """ preds = model.predict(img) idx = np.argmax(preds[0]) # 返回预测图片最大可能性的index索引 output = model.output[:, idx] # 获取到我们对应索引的输出张量 last_layer = model.get_layer(layername) grads = K.gradients(output, last_layer.output)[0] pooled_grads = K.mean(grads, axis=(0, 1, 2)) # 对每张梯度特征图进行平均, # 返回的是一个大小是通道维数的张量 iterate = K.function([model.input], [pooled_grads, last_layer.output[0]]) pooled_grads_value, conv_layer_output_value = iterate([img]) for i in range(pooled_grads.shape[0]): conv_layer_output_value[:, :, i] *= pooled_grads_value[i] return conv_layer_output_value def plot_heatmap(conv_layer_output_value, img_in_path, img_out_path): """ 绘制热力图 :param conv_layer_output_value: 卷积层输出值 :param img_in_path: 输入图像的路径 :param img_out_path: 输出热力图的路径 :return: """ heatmap = np.mean(conv_layer_output_value, axis=-1) heatmap = np.maximum(heatmap, 0) heatmap /= np.max(heatmap) img = cv2.imread(img_in_path) heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) heatmap = np.uint8(255 * heatmap) heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) superimopsed_img = heatmap * 0.4 + img cv2.imwrite(img_out_path, superimopsed_img) img_path = r'./train_data/daisy/1.jpg' model_path = r'./five_flowers_categorical_vgg16.h5' layername = r'separable_conv2d_6' img = load_img_preprocess(img_path, (224, 224)) model = load_model_h5(model_path) conv_value = gradient_compute(model, layername, img) plot_heatmap(conv_value, img_path, './packagetest.jpg')

参考博客地址:https://blog.csdn.net/weixin_44106928/article/details/103323970?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-2-103323970.nonecase&utm_term=cam%E7%83%AD%E5%8A%9B%E5%9B%BE%E5%8F%AF%E8%A7%86%E5%8C%96&spm=1000.2123.3001.4430

 

后续我自己再完善和补充。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有