1. 理解类激活图:从CAM到GradCAM++
在深度学习领域,类激活图(Class Activation Map)已经成为解释神经网络决策过程的重要工具。我第一次接触这个概念是在调试一个图像分类模型时,发现模型总是对某些特定区域"情有独钟"。CAM系列方法就像给模型装上了X光机,让我们能直观看到神经网络到底在关注图像的哪些部分。
传统CAM方法最大的限制是要求网络结构必须包含全局平均池化层(GAP)。这在实际应用中很不方便,因为很多预训练模型并不满足这个条件。GradCAM的出现解决了这个痛点,它通过梯度信息来计算激活图,适用范围更广。而GradCAM++则进一步优化了热图质量,特别是对于多目标场景的定位更加精准。
这三种方法的核心思想都是生成一个与输入图像尺寸匹配的热力图,数值越高表示该区域对当前分类结果的贡献越大。实际应用中,我们通常会将热图叠加在原图上,用颜色深浅直观展示关键区域。下面我会用PyTorch带大家一步步实现这些方法,并用真实图片演示效果差异。
2. 基础CAM实现与代码解析
2.1 准备工作与环境搭建
在开始编码前,我们需要准备好开发环境。我推荐使用Python 3.8+和PyTorch 1.10+版本,这些组合在我多个项目中表现稳定。安装依赖很简单:
pip install torch torchvision matplotlib numpy pillow
对于示例图片,我选择了一只边境牧羊犬的照片,因为这类图片通常包含多个可识别特征。模型方面,我们使用ResNet18预训练模型,它的结构简单但效果不错,非常适合教学演示。
2.2 CAM核心代码实现
CAM的实现关键在于获取最后一个卷积层的特征图和全连接层的权重。这里我们需要用到PyTorch的hook机制,这是很多初学者容易卡壳的地方。hook就像给神经网络安装监听器,可以在不修改网络结构的情况下获取中间结果。
import torch
import torch.nn.functional as F
from torchvision import models, transforms
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
# 初始化模型
model = models.resnet18(pretrained=True).eval().cuda()
# 定义hook获取特征图
feature_maps = None
def forward_hook(module, inp, out):
global feature_maps
feature_maps = out.detach()
# 注册hook到最后一个卷积层
layer = model.la

2174

被折叠的 条评论
为什么被折叠?



