第一代的CAM
**CAM(class activation map)**是指输入中的什么区域能够指示CNN进行正确的识别
需要修改网络结构 添加一个gap层,进行fine_ture
网络结构分为两部分,一部分是特征提取(CNN),一部分是分类层(softmax),在特征提取的最后一层我们使用全局平均池化,这样GAP的将会输出每个feature map的平均值,接下来进行一个加权求和得到最后的输出。那么对应的,我们可以对最后一层feature map利用分类层的权值进行加权。
Grad_CAM
与CAM不同的是,CAM的特征加权系数是分类器的权值,Grad-CAM的加权系数是通过反向传播得到的。整个流程如下图:
- 如何求得各个feature map的加权权值,本文采用梯度回传的方法:
也很简单,分两步:
- 第1步求logits对卷积特征的梯度,
- 第2步,这些梯度进行一个global average pooling
target = output[0][index]
target.backward()
gradient = self.gradient[0].cpu().data.numpy() # [C,H,W]
# 对梯度进行gap 模拟 每个特征图的权重
weight = np.mean(gradient, axis=(1, 2)) # [C]
# 每一层的权重 * 卷积的特征输出 == 最后的热力图
feature = self.feature[0].cpu().data.numpy() # [C,H,W]
cam = feature * weight[:, np.newaxis, np.newaxis] # [C,H,W]
使用每一个特征图的权重 和 conv_feature 进行组合,然后使用 relu 滤掉负的特征
得到的这个heatmap是个粗略的图,它的大小与特征图大小一致,如VGG 最后一层特征图大小是14x14,然后使用双线性插值得到与原图同样的大小。