Grad-CAM(Gradient-weighted Class Activation Mapping)热力图(内含示例代码)

news/2024/7/10 2:34:18 标签: pytorch, 计算机视觉, 目标检测, python

Grad-CAM(Gradient-weighted Class Activation Mapping)是一种用于可视化卷积神经网络(CNN)中特定类别的激活区域的技术。Grad-CAM帮助我们理解神经网络在分类任务中的决策过程,特别是它关注哪些图像区域以及这些区域对最终分类结果的影响。

具体来说,Grad-CAM使用神经网络的梯度信息来生成权重,这些权重用于对特定类别的激活区域进行加权。通过将这些权重与卷积层的输出相乘,然后对结果进行求和,可以生成一个热力图,显示了哪些图像区域对于网络分类特定类别最为重要。

Grad-CAM的优势之一是它可以应用于任何使用全局平均池化(global average pooling)的CNN模型,而不需要对网络结构进行修改。这使得Grad-CAM成为一种在解释深度学习模型决策时广泛使用的工具。Grad-CAM的应用包括图像分类、目标检测等领域。

以下是一个简单的示例:

python">import torch
import torch.nn as nn
from torchvision import models, transforms
from torch.autograd import Variable
from PIL import Image
import matplotlib.pyplot as plt
import cv2
import numpy as np

# 加载预训练的ResNet模型
model = models.resnet50(pretrained=True)
model.eval()

# 选择模型的中间层作为特征提取层,这里以layer3中的第一个卷积层为例
target_layer = model.layer3[0].conv1

# 图像预处理
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 读取并预处理图像
img_path = 'path/to/your/image.jpg'
img = Image.open(img_path).convert('RGB')
img_tensor = transform(img)
img_tensor = Variable(img_tensor.unsqueeze(0))

# 前向传播获取预测分数
logits = model(img_tensor)
pred_class = torch.argmax(logits, dim=1)

# 计算梯度
model.zero_grad()
logits[0, pred_class].backward()

# 获取目标层的梯度
grads = target_layer.weight.grad

# 对梯度进行全局平均池化
pooled_grads = torch.mean(grads, dim=[2, 3])

# 获取目标层的输出特征图
target = target_layer(img_tensor)

# 将梯度与目标层的输出特征图相乘
for i in range(pooled_grads.shape[1]):
    target[0, i, :, :] *= pooled_grads[0, i]

# 计算热力图
heatmap = torch.mean(target, dim=1).squeeze()

# 使用ReLU将负值置零
heatmap = np.maximum(heatmap.detach().numpy(), 0)

# 归一化热力图
heatmap /= torch.max(heatmap)

# 使用OpenCV将热力图叠加到原始图像上
img_array = cv2.imread(img_path)
heatmap = cv2.resize(heatmap, (img_array.shape[1], img_array.shape[0]))
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
superimposed_img = cv2.addWeighted(img_array, 0.6, heatmap, 0.4, 0)

# 显示结果
plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()

目标检测算法中,通常使用的是卷积神经网络(CNN)作为特征提取器,其输出被传递给目标检测头部。你可以选择目标检测头部之前的中间层来进行 Grad-CAM 可视化。

以下是一个简单的示例代码,假设你使用的目标检测模型是 Faster R-CNN,并且你想在 RoI pooling 层之前的中间层上应用 Grad-CAM:

python">import torch
import torch.nn as nn
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from torchvision import transforms
from torch.autograd import Variable
from PIL import Image
import matplotlib.pyplot as plt
import cv2
import numpy as np

# 加载 Faster R-CNN 模型
model = fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()

# 选择中间层,这里以 resnet50_fpn 的 layer3 的第一个卷积层为例
target_layer = model.backbone.body.layer3[0].conv1

# 图像预处理
transform = transforms.Compose([
    transforms.Resize((800, 800)),  # 适应 Faster R-CNN 的输入大小
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

# 读取并预处理图像
img_path = 'path/to/your/image.jpg'
img = Image.open(img_path).convert('RGB')
img_tensor = transform(img)
img_tensor = Variable(img_tensor.unsqueeze(0))

# 前向传播获取预测
with torch.no_grad():
    output = model(img_tensor)

# 获取目标层的梯度
grads = target_layer.weight.grad

# 对梯度进行全局平均池化
pooled_grads = torch.mean(grads, dim=[2, 3])

# 获取目标层的输出特征图
target = target_layer(img_tensor)

# 将梯度与目标层的输出特征图相乘
for i in range(pooled_grads.shape[1]):
    target[0, i, :, :] *= pooled_grads[0, i]

# 计算热力图
heatmap = torch.mean(target, dim=1).squeeze()

# 使用ReLU将负值置零
heatmap = np.maximum(heatmap.numpy(), 0)

# 归一化热力图
heatmap /= torch.max(heatmap)

# 使用OpenCV将热力图叠加到原始图像上
img_array = cv2.imread(img_path)
heatmap = cv2.resize(heatmap, (img_array.shape[1], img_array.shape[0]))
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
superimposed_img = cv2.addWeighted(img_array, 0.6, heatmap, 0.4, 0)

# 显示结果
plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()


http://www.niftyadmin.cn/n/5235345.html

相关文章

[传智杯 #3 决赛] 面试

题目背景 disangan233 和 disangan333 去面试了,面试官给了一个问题,热心的你能帮帮他们吗? 题目描述 现在有 n 个服务器,服务器 i 最多能处理 ai​ 大小的数据。 接下来会有 k 条指令 bk​,指令 i 表示发送 bi​ …

Python虚拟环境创建和使用

前言 Python 虚拟环境是一个独立的 Python 环境,你可以在其中安装和使用 Python 库,而不会影响系统的全局 Python 环境。这在你需要为不同的项目使用不同版本的库时非常有用 Python 3.3 以后的版本都内置了 venv 模块,用来创建和管理虚拟环境…

04-配置远程仓库的SSH免密登陆

配置SSH免密登录 配置步骤 创建好的远程仓库也可以使用SSH的方式进行访问,但如果没有配置公钥会有警告 第一步: 删除用户家目录下的.ssh目录,如果没有该目录或者该目录下已经有密钥了就不用执行该操作 #进入当前用户的家目录,删除.ssh 目录 LayneLAPTOP-Layne MINGW64 ~ $ r…

c语言常见面试题(持续更新)

八股文的意义在于,如果你真正理解这些八股,那么你的编程语言才达到了入门级别,如果你不懂,你绝对还没有入门编程语言,也就是说在接下来的工作中,受限于基础的薄弱,你的工作进展会非常的慢&#…

树与二叉树堆:经典OJ题集(2)

目录 二叉树的性质及其问题: 二叉树的性质 问题: 一、对称的二叉树: 题目: 解题思路: 二、另一棵树: 题目: 解题思路: 三、翻转二叉树: 题目:…

Problem P25. [算法课动态规划] 整数拆分

Problem P25. [算法课动态规划] 整数拆分 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 提示: 2 < n < 58 题目数据保证运算过程不超过 int 所能…

如何使用Windows自带的IIS服务搭建本地站点并远程访问

文章目录 1.前言2.Windows网页设置2.1 Windows IIS功能设置2.2 IIS网页访问测试 3. Cpolar内网穿透3.1 下载安装Cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5.结语 1.前言 在网上各种教程和介绍中&#xff0c;搭建网页都会借助各种软件的帮助&#xf…

HttpRunner自动化测试之响应中文乱码处理

响应中文乱码&#xff1a; 当调用接口&#xff0c;响应正文返回的中文是乱码时&#xff0c;一般是响应正文的编码格式不为 utf-8 导致&#xff0c;此时需要根据实际的编码格式处理 示例&#xff1a; 图1中 extract 提取title标题&#xff0c;output 输出 title 变量值&#x…