https://github.com/haofanwang/Score-CAM
Score-CAM:Score-Weighted Visual Explanations for Convolutional Neural Networks
https://www.cnblogs.com/wanghui-garcia/p/14116215.html
Abstract
近年来,卷积神经网络的内部机制以及网络做出特定决策的原因越来越受到人们的关注。在本文中,我们开发了一种新的基于类激活映射的post-hoc视觉解释方法,Score-CAM。与以往基于类激活映射的方法不同,Score-CAM通过每个激活映射在目标类上的前向传递分数来获得每个激活映射的权重,从而摆脱了对梯度的依赖,最终结果由权重和激活映射的线性组合得到。研究结果表明,Score-CAM在解释决策过程方面具有更好的视觉效果和公平性。我们的方法在识别和定位任务上都优于以前的方法,它也通过了完整性检查。
- Introduction
深层神经网络(DNNs)的解释的目的是增加模型对人类的透明度,以便推理背后的逻辑可以以人类理解的
方式进行解释。在提供解释的过程中,可视化一些感兴趣的东西,例如输入特性或学习权重的重要性,成为获得用户信任的最直接的方法。在DNNs中各种成分中,空间卷积一直是图像和语言处理特征提取的首选。为了更好地解释卷积运算和卷积神经网络(CNNs),目前被广泛采用的方法有梯度可视化[15]、Perturbation[10]、类激活映射(CAM)[21]。
我们的工作总结如下:
(1)我们引入了一种新的无梯度可视化解释方法——Score-CAM,它弥补了基于Perturbation和基于CAM的方法之间的差距,并以直观易懂的方式表示激活maps的权重。
(2)定量评价了Score-CAM生成的显著maps在识别任务上的公平性,具体为Average Drop / Average Increase and Deletion curve / Insertion curve 指标,表明Score-CAM能够更好地找到目标类的证据。
(3)定性地评估了可视化和定位性能,在这两个任务上都取得了较好的效果。最后,我们介绍了它作为一个调试工具在分析模型错误行为中的有效性。
梯度方法的问题
- 梯度饱和
由于Sigmoid函数的饱和问题或ReLU函数的零梯度区域,深度神经网络的梯度可能会有噪声,并且容易消失。结果之一是输出关于输入的梯度或内部层激活可能在视觉上是有噪音的,
这也是显著图(Saliency Map )方法[14]的问题之一,它将输入特征的重要性归功于输出。梯度在视觉上带有噪声的例子如图
- 错误置信度
给定两个激活图,对应权重大的认为对应的输入区域也更重要。而实际上,具有更高权重的激活map对网络输出的贡献可能更低。我们随机选择激活map并将它们向上采样到输入大小中,然后记录如果我们只在激活map中保持高亮显示的区域,目标分数将是多少。
与“head”部分对应的激活map获得最高的权重,但在目标分数上增加的最低。这种现象可能是由于梯度顶部的全局池化操作和网络中的梯度消失问题造成的。
3 Score-CAM
其实过程就是:
1)将输入代入模型,得到对应的分数S,以及得到对应选择的卷积层的输出激活map
2)将channel数为N的N个激活map作为mask,乘以输入,作为新的输入,代入模型,得到N个新的输出分数S’
3)然后用N个新的输出分数S’分别与原始的分数S相减,这就得到N个S_minus结果
4)N个S_minus使用softmax函数计算得到的结果就作为了选择的卷积层的输出激活map的权重
5)N个权重分别和对应的N个输出激活map相乘,然后求和,在输入ReLU(),就能够得到对应的saliency map了
对获取的特征图进行channel-wise遍历,对每层特征图进行上采样+归一化,与原始图片进行pixel-wise相乘融合,然后送进网络获取目标类别score(softmax后),减去baseline的目标类别score,获取CIC。再进行softmax操作来保证所有CIC之和为1。最后将CIC作为特征融合权重融合需要可视化的特征层。
值得注意的是,计算CIC时默认使用的baseline为全黑的图片,既全0的矩阵,因此CIC score不需要减去baseline的score。
with torch.no_grad():# gradient-free, 所以不需要计算梯度
for i in range(K): # 对K层特征图进行遍历操作
# 获取第i层特征图,并进行上采样操作
saliency_map = torch.unsqueeze(activations[:, i, :, :], 1)
saliency_map = F.interpolate(saliency_map, size=(h, w), mode='bilinear')
# 归一化
norm_saliency_map = (saliency_map - saliency_map.min()) /
(saliency_map.max() - saliency_map.min())
# 利用第i层特征图作为mask覆盖原图,重新送入网络获取对应类别得分
output = self.model_arch(input * norm_saliency_map)
output = F.softmax(output)
score = output[0][predicted_class]
# 利用该得分作为权重对该层的特征图进行加权线性融合, baseline默认为全0的图,所以这里直接
# 用该得分作为特征权重
score_saliency_map += score * saliency_map
# relu去除负值
score_saliency_map = F.relu(score_saliency_map)
# 归一化
score_saliency_map = (score_saliency_map - score_saliency_map.min())/
(score_saliency_map_max - score_saliency_map.max())
# score_saliency_map 为所求
return score_saliency_map
试验
Score-CAM不仅能够准确地定位单个对象,而且在定位多个同类对象时也比以往的工作表现出更好的性能。结果如图7所示,Grad-CAM[12]倾向于只捕捉图像中的一个目标,Grad-CAM++[4]和Score-CAM都显示了定位多个目标的能力,但是Score-CAM的显著map比Grad-CAM++更加聚焦。