转载于:https://www.zhihu.com/question/274926848/answer/473562723
卷积层输出的特征映射其实和原图是存在一定的空间对应关系的。把最后一层卷积输出的特征映射处理一下,然后绘制到原图上,就得到了热图(也就是网络模型更关注的区域)。
关键是通过什么方式处理得到的效果比较好?
GAP
让我们小小地绕行一下,先介绍下全局平均池化(global average pooling,GAP)这一概念。为了避免全连接层的过拟合问题,网中网(Network in Network)提出了GAP层。GAP层,顾名思义,就是对整个特征映射应用平均池化,换句话说,是一种极端激进的平均池化。
图片来源:Alexis Cook
图片
从上图可以看到,这维度降得真是彻底啊,本来是 现在生生降到 ,这样大幅简化参数,从而避免过拟合问题。
CAM
从另一方面来说,GAP层的输出,可以认为是“简要概括”了之前卷积层的特征映射。在网中网架构中,GAP后面接softmax激活,ResNet-50中,GAP层后面接一个带softmax激活的全连接层。softmax激活是为了保证输出分类的概率之和为1,对于热图来说,我们并不需要这一约束。所以可以把softmax拿掉。拿掉softmax的全连接层,其实就是线性回归。结果发现,这样一处理,效果挺不错的:
图片来源:Alexis Cook
这就是CAM算法背后的主要思路。
Grad-CAM
但是CAM要发挥作用,前提是网络架构里面有GAP层,但并不是所有模型都配GAP层的。另外,线性回归的训练是额外的工作。
为了克服CAM的这些缺陷,Selvaraju等提出了Grad-CAM。其基本思路是对应于某个分类的特征映射的权重可以表达为梯度,这样就不用额外训练线性回归(或者说线性层)。然后全局平均池化其实是一个简单的运算,并不一定需要专门使用一个网络层。
图片来源:arXiv:1610.02391
另外,因为热图关心的是对分类有正面影响的特征,所以在线性组合的技术上加上了ReLU,以移除负值。
图片来源:arXiv:1610.02391
我们之前提到了分类,其实并不一定要是分类问题,只要是可微的激活函数,其他问题也一样使用Grad-CAM。
顺带提一句,Grad-CAM的作者还将Grad-CAM和可视化所有有贡献的特征的技术Guided-Backprop结合,得到了Guided Grad-CAM,不过这个可视化的效果就不是热图了,所以这里我就不介绍了。
Grad-CAM++
为了得到更好的效果(特别是在某一分类的物体在图像中不止一个的情况下),Chattopadhyay等又进一步提出了Grad-CAM++,主要的变动是在对应于某个分类的特征映射的权重表示中加入了ReLU和权重梯度 :
图片来源:arXiv:1710.11063
只需一次反向传播即可计算梯度
下图是CAM、Grad-CAM、Grad-CAM++架构对比:
图片来源:arXiv:1710.11063
Grad-CAM和Grad-CAM++生成的热图效果是这样的,可以看到,Grad-CAM++的解释性更好:
图片来源:arXiv:1710.11063
代码
GitHub上有不少Grad-CAM(++)的实现,你可以根据情况自行选择。例如:
- 如果你用TensorFlow,可以看看Hive开源的hiveml/tensorflow-grad-cam
- 如果你用PyTorch,可以看看jacobgil/pytorch-grad-cam
当然,你也可以根据Grad-CAM++论文自行实现。
题主修改了问题,说是计算出attention map后如何可视化。我猜是想问如何把attention map可视化成matrix heatmap,类似这样:
既然已经有attention map了,那可视化只需用颜色或亮度表示权重就可以了(比如,颜色越浓权重越大,或者越亮权重越大)。可以参考datalogue/keras-attention中的代码。
In [1]: import seaborn as sns
In [2]: import numpy as np
In [3]: np.random.seed(0)
In [4]: unf = np.random.rand(10,12)
In [5]: sns.set()
In [6]: ax=sns.heatmap(unf)
In [7]: ax=sns.heatmap(unf,vmin=0,vmax=1)