类别激活热力图grad-cam(pytorch)实战跑图

写在前面

类激活热力图:用于检查图像哪一部分对模型的最终输出有更大的贡献。具体某个类别对应到图片的那个区域响应最大,也就是对该类别的识别贡献最大

pytorch-grad-cam库代码GitHub代码
如果只想跑个图的话不用下!

作用:一是清晰直观的看看到底影响检测结果的特征;而是cv论文里出图真的很好看
本篇只是跑了代码给的猫狗图,下一篇要写如何可视化其他类别实战

先上跑完结果

类别激活热力图grad-cam(pytorch)实战跑图
使用的是resnet50,可以看出其关注度不仅仅只有狗,还有后面的背景,这会对以后的检测结果造成影响

; 实战

1.安装 pytorch-grad-cam

在pycharm终端中输入

pip install grad-cam

我之前安装过了,页面如下

类别激活热力图grad-cam(pytorch)实战跑图

2.复制全部代码

'''
1)导入相关的包并加载模型
'''

from pytorch_grad_cam import GradCAM, ScoreCAM, GradCAMPlusPlus, AblationCAM, XGradCAM, EigenCAM
from pytorch_grad_cam.utils.image import show_cam_on_image, \
                                         deprocess_image, \
                                         preprocess_image
from torchvision.models import resnet50
import cv2
import numpy as np
import os

os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

model = resnet50(pretrained=True)

target_layer = [model.layer4]
'''
Resnet18 and 50: model.layer4[-1]
VGG and densenet161: model.features[-1]
mnasnet1_0: model.layers[-1]
ViT: model.blocks[-1].norm1
'''

'''
2)构建输入图像的Tensor形式,使其能传送到model里面去计算
'''

image_path = '../../examples/both.png'
rgb_img = cv2.imread(image_path, 1)[:, :, ::-1]

rgb_img = cv2.imread(image_path, 1)
rgb_img = np.float32(rgb_img) / 255

input_tensor = preprocess_image(rgb_img, mean=[0.485, 0.456, 0.406],
                                             std=[0.229, 0.224, 0.225])

'''
3)初始化CAM对象,包括模型,目标层以及是否使用cuda等
'''

cam = GradCAM(model=model, target_layers=target_layer, use_cuda=False)
'''
4)选定目标类别,如果不设置,则默认为分数最高的那一类
'''

target_category = None

'''
5)计算cam
'''

grayscale_cam = cam(input_tensor=input_tensor, target_category=target_category)

'''
6)展示热力图并保存
'''

grayscale_cam = grayscale_cam[0]
visualization = show_cam_on_image(rgb_img, grayscale_cam)
cv2.imwrite(f'first_try.jpg', visualization)

> 步骤:先把博客中代码复制,然后按照本博客写的修改即可,也可以直接拉到下面复制我的代码,然后按照说明修改路径

3.自己使用代码需要修改的部分

1、图片路径

第34行,将单引号地址改为你要用的图片地址

image_path = '../../examples/both.png'

不会的请详细参看错误1内容,写的很清楚
注意:路径中不要有中文

2、结果图名称

第79行

cv2.imwrite(f'first_try.jpg', visualization)

将”改为你希望的名字即可

4.查看结果图

其实就在代码当前路径的文件夹下
当然也可以复制图片名称first_try.jpg,在保存代码的文件夹里直接查找

类别激活热力图grad-cam(pytorch)实战跑图

点击结果图

类别激活热力图grad-cam(pytorch)实战跑图

; 运行代码所遇到的问题

错误1:TypeError: ‘NoneType’ object is not subscriptable

1、报错内容:

Traceback (most recent call last):
File “E:/CAM/pytorch-grad-cam/pytorch_grad_cam/utils/using_grad_cam.py”, line 32, in
rgb_img = cv2.imread(image_path, 1)[:, :, ::-1] # 1是读取rgb
TypeError: ‘NoneType’ object is not subscriptable

类别激活热力图grad-cam(pytorch)实战跑图

; 2、错误代码:

第2)构建输入图像的Tensor形式,使其能传送到model里面去计算,这一步

image_path = './examples/both.png'
rgb_img = cv2.imread(image_path, 1)[:, :, ::-1]
rgb_img = np.float32(rgb_img) / 255

使用OpenCV读取图片时发生错误,一直显示图片类型是”nonetype”

3、修正:

发现是路径错误

image_path = './examples/both.png'

修改后

image_path = '../../examples/both.png'

附上运行代码与读取的图片位置

类别激活热力图grad-cam(pytorch)实战跑图
关于路径如何正确表示可以看这篇文件路径./和…/

错误2:AttributeError: ‘GradCAM’ object has no attribute ‘activations_and_grads’

报错内容:

Traceback (most recent call last):
File “D:\anaconda\envs\pytorch\lib\site-packages\pytorch_grad_cam\base_cam.py”, line 192, in del
self.activations_and_grads.release()
AttributeError: ‘GradCAM’ object has no attribute ‘activations_and_grads’

类别激活热力图grad-cam(pytorch)实战跑图

; 错误3:TypeError: init () got an unexpected keyword argument ‘target_layer’

报错内容:

Traceback (most recent call last):
File “E:/CAM/pytorch-grad-cam/pytorch_grad_cam/utils/using_grad_cam.py”, line 60, in
cam = GradCAM(model=model, target_layer=target_layer, use_cuda=False)
TypeError: init() got an unexpected keyword argument ‘target_layer’

类别激活热力图grad-cam(pytorch)实战跑图

; 针对错误2与错误3的修改:

第一处:

target_layer = model.layer4[-1]

修改为 target_layer = [model.layer4]
第二处:

cam = GradCAM(model=model, target_layer=target_layer, use_cuda=False)

修改为

cam = GradCAM(model=model, target_layers=target_layer, use_cuda=False)

只想跑图出结果的不需要看,想大概熟悉代码与原理的可以看一看

使用pytorch实现grad-cam需了解hook机制,详细看 pytorch的autograd
pytorch的hook应用
个人理解:hook就是储存pytorch所释放的中间变量的”钩子”,哪里需要就钩在哪里 举例更好理解。
hook机制一定要理解,grad-cam中hook是重要代码

基础差的看不懂基础代码,可以哪里不懂点哪里
1、 *args**kargs 知识点讲解链接
2、Python自带模块argparse详细使用说明书 Python argparse命令行参数解析包的详细使用说明书
例:采用LeNet-5演示backward_hook在grad-cam中应用,下面是代码过程(具体代码上面链接中有) 1、创建网络net
2、注册forward_hook函数用于提取最后一层特征图;
3、注册backward_hook函数用于提取类向量(one-hot)关于特征图的梯度; 4、对特征图的梯度进行求均值,并对特征图进行加权;
5、可视化heatmap model._modules.items() 遍历输出每一层
register_hook的作用:即对x求导时,对x的导数进行操作,并且register_hook的参数只能以函数的形式传过去。(保护求导中中间值作用,不然pytorch将直接保存最后结果,中间结果不保存)详细解释

本篇主要参考CAM(类激活映射),卷积可视化,神经网络可视化,一个库搞定,真的简单的不能再简单

Original: https://blog.csdn.net/rensweet/article/details/123263812
Author: 半甜田田
Title: 类别激活热力图grad-cam(pytorch)实战跑图

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/705413/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球