# 机器学习可解释性(二)——类激活映射(CAM)
1、序言
本次分享接在 机器学习可解释性(一) —— 累积局部效应图(ALE) 的后面显得跨度有些大。由于最近正在学习相关的算法,因此希望在此将学习的结果在此展示出来。后续还会看时间分享Lime, DeepLift以及shap的一系列算法。
类激活映射(Class Activation Mapping,CAM 方法在现在看来可能存在着各种问题,但是其作为该类显著性图算法的“开山之作”,其思想影响了后续诸多方法的产生。本文将在CAM的基础上,介绍的GradCAM, GradCAM++, LayerCAM。
笔者只是简单实验了这几种算法,并根据自己的理解整理出来,在博客中存在的谬误还请指正。
2、方法介绍
在正式介绍算法实现之前,首先感性认识一下这类算法。CAM以及在此基础上衍生出来的GradCAM, GradCAM++等等都是属于显著性图可解释性算法,因此这类算法只能应用在图像的问题上,或者说是专门为**卷积神经网络(CNN)**设计的一类可解释性算法。
该类算法利用神经网络的特征图(feature map)得到原图各个部分的重要性,具体来说就是为特征图赋予不同的权重来获得显著性图。
L c = ∑ k w c k ⋅ A k (1) L^{c}= \sum_k{w_{c}^{k}\cdot A^k} \tag{1} Lc=k∑wck⋅Ak(1)
大体的思路如上述公式所示,其中, L i , j c L_{i,j}^c Li,jc是第 c c c类 i , j i,j i,j坐标处的显著性图, w k c w_k^c wkc是 c c c类第 k k k张特征图的权重, A i , j k A_{i,j}^k Ai,jk是第 k k k张特征图 i , j i,j i,j处的值。各类算法的主要区别体现在算法权重的获取上,其余部分的差异在后文中讲解。
这类算法在实现的过程中需要用到梯度的计算,因此如果使用pytorch实现,需要借助pytorch hook机制。
2.1 CAM
该算法发表在*“Learning Deep Features for Discriminative Localization”*中。
下图是论文中展示的图像。
在CAM中,作者认为全局平均池化层具有局部定位能力,将卷积网络后的原本的池化层和全连接层改为全局平均池化和全连接层(这里全连接层神经元数和模型类别数相同),重新训练训练模型获得权重,将深层特征图加权求和获得显著性图,为卷积神经网络的可解释性提供了全新的思路。
以CAM为基础,为了不需要修改模型结构,根据是否使用梯度计算权重发展出两个类别,使用梯度的方法如GradCAM、GradCAM++、LayerCAM等,而不使用梯度的算法有诸如AblationCAM和ScoreCAM。本文主要介绍使用梯度的算法。
2.2 GradCAM
该算法发表在 “Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization” 中。
为了不需要修改模型结构,GradCAM算法巧妙地利用梯度计算权重,得到的显著性图表达式为:
L
c
=
R
e
l
u
(
∑
k
w
c
k
⋅
A
k
)
(2)
L^{c}=\mathrm{Re}lu\left( \sum_k{w_{c}^{k}\cdot A^k} \right) \tag{2}
Lc=Relu(k∑wck⋅Ak)(2)
L
c
L^c
Lc为第
c
c
c类的显著性图;
w
c
k
w^k_c
wck为第
c
c
c类第
k
k
k张特征图的权重,计算方法见公式(3);
A
k
A^k
Ak为第k张特征图。Relu函数将对预测有正向影响的结果展示出来。
w
c
k
=
1
z
∑
i
,
j
∂
y
c
∂
A
i
,
j
k
(3)
w_{c}^{k}=\frac{1}{z}\sum_{i,j}{\frac{\partial y^c}{\partial A_{i,j}^{k}}} \tag{3}
wck=z1i,j∑∂Ai,jk∂yc(3)
其中,
y
c
y^c
yc是
c
c
c类得分,通过平均一阶导数得到权重;
z
z
z是特征图的大小。
2.3 GradAM++
该算法发表在 “Grad-CAM++: Improved Visual Explanations for Deep Convolutional Networks” 中。
GradCAM算法尽管为类激活映射算法提供了全新的思路,但是观察计算公式可以发现,如果某张特征图用来定位图片中的“小目标”,那么该特征图的权重将会很小。为了提高算法的多目标定位能力,GradCAM++利用高维梯度计算权重。
显著性图表达式仍然如公式(2)所示,权重表达式为:
w
c
k
=
∑
i
,
j
α
i
,
j
k
,
c
⋅
R
e
l
u
(
∂
y
c
∂
A
i
,
j
k
)
(4)
w_{c}^{k}=\sum_{i,j}{\alpha _{i,j}^{k,c}\cdot \mathrm{Re}lu\left( \frac{\partial y^c}{\partial A_{i,j}^{k}} \right)} \tag{4}
wck=i,j∑αi,jk,c⋅Relu(∂Ai,jk∂yc)(4)
也就是说特征图的权重经过再次加权求和得到,
α
i
,
j
k
,
c
\alpha _{i,j}^{k,c}
αi,jk,c计算公式如公式(5)所示。
α
i
,
j
k
,
c
=
∂
2
y
c
(
∂
A
i
,
j
k
,
c
)
2
2
∂
2
y
c
(
∂
A
i
,
j
k
,
c
)
2
+
∑
a
,
b
A
a
,
b
k
{
∂
3
y
c
(
∂
A
i
,
j
k
,
c
)
3
}
(5)
\alpha _{i,j}^{k,c}=\frac{\frac{\partial ^2y^c}{\left( \partial A_{i,j}^{k,c} \right) ^2}}{2\frac{\partial ^2y^c}{\left( \partial A_{i,j}^{k,c} \right) ^2}+\sum_{a,b}{A_{a,b}^{k}\left\{ \frac{\partial ^3y^c}{\left( \partial A_{i,j}^{k,c} \right) ^3} \right\}}} \tag{5}
αi,jk,c=2(∂Ai,jk,c)2∂2yc+∑a,bAa,bk{(∂Ai,jk,c)3∂3yc}(∂Ai,jk,c)2∂2yc(5)
看到这里可能有小伙伴会好奇一阶偏导数可以通过hook机制实现,但是应该如何实现二阶或者三阶导数呢?
扒了两种完整的Github仓库,发现实现过程运用了一种近似的方法,使用一阶导数的平方近似二阶导数,使用一阶导数的三次方近似三阶导数。
2.4 LayerCAM
该算法发表在 “LayerCAM: Exploring Hierarchical Class Activation Maps for Localization” 中。
CAM类算法理论上是可以部署在卷积神经网络任何一个卷积层上的,然而上述的GradCAM和GradCAM++均在最深层的特征图上取得最好的效果。但是因为深层特征图较小,不够细粒度,为了充分利用浅层的特征图,该算法提供了像素级的权重,而不是像之前算法的那种特征图级的权重。
显著性图的计算公式如公式(6)
L
i
,
j
c
=
R
e
l
u
(
∑
k
w
i
,
j
k
,
c
⋅
A
i
,
j
k
)
(6)
L_{i,j}^{c}=\mathrm{Re}lu\left( \sum_k{w_{i,j}^{k,c}\cdot A_{i,j}^{k}} \right) \tag{6}
Li,jc=Relu(k∑wi,jk,c⋅Ai,jk)(6)
相对而言,权重的计算方法较为简单,如公式(7)所示。
w
i
,
j
k
,
c
=
R
e
l
u
(
∂
y
c
∂
A
i
,
j
k
)
(7)
w_{i,j}^{k,c}=\mathrm{Re}lu\left( \frac{\partial y^c}{\partial A_{i,j}^{k}} \right) \tag{7}
wi,jk,c=Relu(∂Ai,jk∂yc)(7)
具体实现过程还经过一些归一化处理,使LayerCAM得到的显著性图控制在[0,1]范围内。
3、算法实现
代码根据frgfm/torch-cam: Class activation maps for your PyTorch models实现;
更一般的实现方法还可以参考jacobgil/pytorch-grad-cam
包括异常检测和目标检测两方面的实现;
这里仅展示结果,算法的详细实现展示在我的Github项目项目。
3.1 异常检测
这里对CutPaste异常检测算法(发表在*“CutPaste: Self-Supervised Learning for Anomaly Detection and Localization”*)部署可解释性算法。
数据集:MvTec-AD
待解释算法:CutPaste,本质是其中的ResNet网络
使用最深层部署各算法,结果如下:
3.2 目标检测
数据集:ILSVRC2012
待解释算法:Vgg网络
使用最深层部署各算法,结果如下:
结语
-
上文中提到了四种可解释性算法,但是事实上CAM类的算法远不止这些,还有很多变种(如上面提到的不需要梯度的方法)和优化方法(包括去噪方法或提供细粒度解释的Guilded算法);
-
上述介绍的实验本质上都是部署在一个分类网络的框架上,事实上只要能合理地设计分数,也就是上文的 y c y^{c} yc,就可以将算法部署在更多任务中;
-
通过巧妙利用求导机制,重新设计算法,一些CAM算法还可以应用在非CNN神经网络上,包括近两年比较火的vit;