2019-09-03 Grad-CAM++ 原理及实现

GradCAM++ vs GradCAM 优点

  1. 定位更准确
  2. 更适合同类多目标的情况

原理

和gradcam一样,都基于假设:

  • 某类的得分是权重和feature map点积而来。
    Y c = ∑ k w k c ⋅ ∑ i ∑ j A i , j k Y^{c}=\sum_{k}w^{c}_{k}\cdot\sum_{i}\sum_{j}A_{i,j}^{k} Yc=kwkcijAi,jk
  • 热力图是由feature map加权平均而来的。
    L i , j c = ∑ k w k c ⋅ A i , j k L_{i,j}^{c}=\sum_{k}w^{c}_{k}\cdot A_{i,j}^{k} Li,jc=kwkcAi,jk

不过gradcam++的权重计算更复杂,涉及三阶导数
假设每个feature map的权重,是由feature每个元素的gradient加权求和而来
w k c = ∑ i ∑ j α i j k c ⋅ r e l u ( ∂ Y c ∂ A i j k ) w_{k}^{c}=\sum_{i}\sum_{j}\alpha_{ij}^{kc}\cdot relu(\frac{\partial{Y^{c}}}{\partial{A_{ij}^{k}}}) wkc=ijαijkcrelu(AijkYc)
带入第一个公式得到
Y c = ∑ k { ∑ a ∑ b α a b k c ⋅ r e l u ( ∂ Y c ∂ A a b k ) } [ ∑ i ∑ j A i , j k ] Y^{c}=\sum_{k}\{\sum_{a}\sum_{b}\alpha_{ab}^{kc}\cdot relu(\frac{\partial{Y^{c}}}{\partial{A_{ab}^{k}}})\}[\sum_{i}\sum_{j}A_{i,j}^{k}] Yc=k{abαabkcrelu(AabkYc)}[ijAi,jk]
然后对这个公式左右同时对 A i , j k A_{i,j}^{k} Ai,jk求两次导
然后确定Y的形式
指数函数和Softmax

实现用了Softmax
pytorch反传一次即可得到
和gradcam只不同在weight的计算公式

grad=self.grad
features=self.features
alpha_num = grad.pow(2)
alpha_denom = 2 * alpha_num + features.mul(grad.pow(3)).view(b, k, u * v).sum(-1, keepdim=True).view(b, k, 1, 1)
alpha_denom = torch.where(alpha_denom != 0.0, alpha_denom, torch.ones_like(alpha_denom))
alpha = alpha_num.div(alpha_denom)
positive_gradients = F.relu(grad)
weights = (alpha * positive_gradients).view(b, k, u * v).sum(-1).view(b, k, 1, 1)

saliency_map = (weights * features).sum(1, keepdim=True)
saliency_map = F.relu(saliency_map)

结果:
2019-09-03 Grad-CAM++ 原理及实现_第1张图片
Grad CAM:定位比较偏
2019-09-03 Grad-CAM++ 原理及实现_第2张图片

你可能感兴趣的:(2019-09-03 Grad-CAM++ 原理及实现)