Grad-CAM可视化 图4 不同类别预测的注意力区域可视化
时间: 2025-06-24 09:41:00 浏览: 22
### Grad-CAM 可视化方法及其在不同类别预测中的应用
Grad-CAM(Gradient-weighted Class Activation Mapping)是一种用于解释卷积神经网络决策过程的技术,能够通过计算特定类别的梯度来生成热力图,从而突出显示输入图像中对模型预测贡献最大的区域[^1]。
#### 原理概述
Grad-CAM 的核心思想在于利用目标类别的得分 \( y_c \) 对最后一层卷积特征图的梯度进行加权平均。具体来说,对于给定的类别 \( c \),首先需要获取该类别对应的最终输出分数 \( y_c \)[^1]。接着,通过对 \( y_c \) 关于最后一个卷积层激活值 \( A_k^{ij} \) 计算梯度并取全局平均池化操作,可以得到每个通道的重要性权重:
\[
\alpha_k^c = \frac{1}{Z} \sum_{i,j} \frac{\partial y^c}{\partial A_k^{ij}}
\]
其中 \( Z \) 是空间维度大小,\( k \) 表示第 \( k \)-th 卷积核[^2]。随后,基于这些重要性权重和原始特征图重建热力图:
\[
L_{Grad-CAM}^c = ReLU\left( \sum_k \alpha_k^c A_k \right)
\]
此热力图经过双线性插值放大至原图尺寸后叠加到输入图片上即可完成可视化[^1]。
#### 实现步骤详解
以下是使用 PyTorch 实现 Grad-CAM 并针对多个类别分别提取其注意力区域的一个简单例子:
```python
import torch
from torchvision import models, transforms
from PIL import Image
import numpy as np
import cv2
class ActivationsAndGradients:
"""Class to store activations and gradients"""
def __init__(self, model, target_layer):
self.model = model
self.gradients = []
self.activations = []
target_layer.register_forward_hook(self.save_activation)
target_layer.register_backward_hook(self.save_gradient)
def save_activation(self, module, input, output):
self.activations.append(output.detach())
def save_gradient(self, module, grad_input, grad_output):
self.gradients.append(grad_output[0].detach())
def get_cam(feature_maps, grads):
alphas = grads.mean(dim=(2, 3), keepdim=True)
cam = (alphas * feature_maps).sum(dim=1, keepdim=True)
cam = torch.relu(cam)
cam -= cam.min()
cam /= cam.max() + 1e-8
return cam.squeeze().cpu().numpy()
model = models.resnet50(pretrained=True).eval()
target_layer = model.layer4[-1]
input_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
])
img_path = 'example.jpg'
image = Image.open(img_path).convert('RGB')
tensor_image = input_transform(image).unsqueeze(0)
act_grad_extractor = ActivationsAndGradients(model, target_layer)
output = act_grad_extractor(tensor_image)
_, predicted_class_indices = torch.topk(output.softmax(-1), 5)
predicted_classes = list(map(lambda idx: f'Class {idx}', predicted_class_indices.flatten()))
for class_idx in range(len(predicted_classes)):
one_hot_vector = torch.zeros_like(output)
one_hot_vector[:, class_idx] = 1.
model.zero_grad()
output.backward(one_hot_vector, retain_graph=True or class_idx != len(predicted_classes)-1 )
activation_maps = act_grad_extractor.activations.pop()
gradients = act_grad_extractor.gradients.pop()
cam_map = get_cam(activation_maps, gradients)
heatmap = cv2.applyColorMap(np.uint8(255 * cam_map), cv2.COLORMAP_JET)
fused_img = heatmap * 0.7 + np.array(image.resize((224, 224))) * 0.3
cv2.imwrite(f'{predicted_classes[class_idx]}_attention.png', fused_img.astype(int))
```
上述代码展示了如何加载预训练 ResNet 模型,并选取 `layer4` 中的最后一层作为目标层来进行 Grad-CAM 分析。它还演示了如何逐一对前五名可能类别生成相应的注意力建模结果[^2]。
#### 结果解读
每张生成的关注图都对应着某个具体的预测标签,颜色越亮表示相应位置对该分类的影响越大。因此,当比较同一幅图像下不同类别的关注图时,可以看到它们各自强调的不同部分——即所谓的“注意力区域”。
---
阅读全文
相关推荐
















