[视觉工具]如何使用热力图可视化模型

本文介绍了如何利用热力图(heatmap)作为工具,通过Grad-CAM方法来可视化人工智能模型,尤其是计算机视觉模型的内部工作原理,帮助理解模型的图像识别偏好和潜在偏差。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.背景

热力图(heatmap)可以帮我们可视化模型,方便我们知道模型是如何看待图片的,也方便我们检测出模型的偏向(bias).

 

二.工具

Grad-CAM

 

三.代码(法1)

# USAGE
# python apply_gradcam.py --image images/space_shuttle.jpg
# python apply_gradcam.py --image images/beagle.jpg
# python apply_gradcam.py --image images/soccer_ball.jpg --model resnet

# import the necessary packages
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.applications import VGG16
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.applications import imagenet_utils
import numpy as np
import argparse
import imutils
import cv2
from tensorflow.keras.models import Model
import tensorflow as tf

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
        help="path to the input image")
ap.add_argument("-m", "--model", type=str, default="vgg",
        choices=("vgg", "resnet"),
        help="model to be used")
args = vars(ap.parse_args())

# initialize the model to be VGG16
Model = VGG16

# check to see if we are using ResNet
if args["model"] == "resnet":
        Model = ResNet50

# gradcam
class GradCAM:
	def __init__(self, model, classIdx, layerName=None):
		# store the model, the class index used to measure the class
		# activation map, and the layer to be used when visualizing
		# the class activation map
		self.model = model
		self.classIdx = classIdx
		self.layerName = layerName

		# if the layer name is None, attempt to automatically find
		# the target output layer
		if self.layerName is None:
			self.layerName = self.find_target_layer()

	def find_target_layer(self):
		# attempt to find the final convolutional layer in the network
		# by looping over the layers of the network in reverse order
		for layer in reversed(self.model.layers):
			# check to see if the layer has a 4D output
			if len(layer.output_shape) == 4:
				return layer.name

		# otherwise, we could not find a 4D layer so the GradCAM
		# algorithm cannot be applied
		raise ValueError("Could not find 4D layer. Cannot apply GradCAM.")

	def compute_heatmap(self, image, eps=1e-8):
		# construct our gradient model by supplying (1) the inputs
		# to our pre-trained model, (2) the output of the (presumably)
		# final 4D layer in the network, and (3) the output of the
		# softmax activations from the model
		gradModel = Model(
			inputs=[self.model.inputs],
			outputs=[self.model.get_layer(self.layerName).output, 
				self.model.output])

		# record operations for automatic differentiation
		with tf.GradientTape() as tape:
			# cast the image tensor to a float-32 data type, pass the
			# image
### 关于像分类中 Heatmap 的实现与应用 Heatmap 是一种可视化工具,能够展示卷积神经网络(CNN)在进行预测时关注的区域。通过生成可以直观理解模型决策依据,有助于提高模型透明性和可解释性。 #### 使用 Grad-CAM 方法生成 Heatmap Grad-CAM (Gradient-weighted Class Activation Mapping) 是目前最常用的生成 heatmap 技术之一。该方法利用目标类别的梯度信息来加权最后特征层上的通道响应,从而得到输入空间上重要性的映射[^1]。 具体步骤如下: - **获取最后一层卷积输出**:提取经过训练后的 CNN 中最后一个卷积层的结果作为基础特征。 - **计算类别得分相对于这些激活值的导数**:对于给定的目标类别 y,在反向传播过程中收集其对应损失函数 L 对上述特征 F 上各位置 j 处单元格 f_j 的偏导 dL/dF_j 。 - **权重 w_kc 计算**:对每个过滤器 k 和类别 c ,w_kc 表示为所有位置处相应偏导之平均值 \(\frac{1}{Z}\sum_{j}dL/dF_j\) ,其中 Z 是空间维度大小。 - **构建 CAM** :将所有滤波器按各自权重求和形成粗略 cam \(CAM(x,y)=ReLU\left (\sum_kw^{kc}_{k}(x,y)\right )\) 并将其 resize 到原始片尺寸。 以下是 Python 实现代码片段: ```python import numpy as np from tensorflow.keras import backend as K from tensorflow.keras.preprocessing.image import load_img, img_to_array from matplotlib import pyplot as plt from scipy.ndimage.interpolation import zoom def get_heatmap(model, image_path, last_conv_layer_name='block5_conv3', pred_index=None): # 加载并预处理像 img = preprocess_image(image_path) # 构建用于计算梯度的张量 grad_model = Model([model.inputs], [model.get_layer(last_conv_layer_name).output, model.output]) with tf.GradientTape() as tape: conv_outputs, predictions = grad_model(np.array([img])) loss = predictions[:, pred_index] # 获取指定类别的梯度 output = conv_outputs[0] grads = tape.gradient(loss, conv_outputs)[0] # 应用全局平均池化获得权重矩阵 weights = np.mean(grads, axis=(0, 1)) # 创建cam cam = np.ones(output.shape[0:2], dtype=np.float32) for i, w in enumerate(weights): cam += w * output[:, :, i] # ReLU操作以及resize回原大小 cam = cv2.resize(cam.numpy(), (img.shape[1], img.shape[0]), interpolation=cv2.INTER_LINEAR) cam = np.maximum(cam, 0) heatmap = cam / np.max(cam) return heatmap def show_heatmap(img_path, heatmap): original_img = cv2.imread(img_path) heatmap = np.uint8(255 * heatmap) jet_colormap = cv2.applyColorMap(cv2.cvtColor((heatmap*255).astype('uint8'),cv2.COLOR_GRAY2BGR), cv2.COLORMAP_JET) superimposed_img = cv2.addWeighted(original_img, 0.6, jet_colormap, 0.4, 0) fig, ax = plt.subplots() ax.imshow(superimposed_img) plt.show() ``` 此段代码实现了基于 TensorFlow/Keras 框架下的 Grad-CAM 算法,可用于任何已训练好的 CNN 模型之上。注意这里假设 `last_conv_layer_name` 已知;如果不确定,则需查阅所使用的特定架构文档找到合适的名称[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值