https://www.jianshu.com/p/9d963a867860 vgg 代码没有问题
代码生成三张图cam.jpg对的
但resnet50 Guided Backpropagation gb.jpg 是纯黑色的不对
cam_gb.jpg 也不对
所以参考 这是resnet50
https://github.com/Caoliangjie/pytorch-gradcam-resnet50/blob/master/grad-cam.py,的代码,没有问题
例如 conv1 feature [1, 64, 112, 112]
对应的分类梯度维度也是一样的的(1, 64, 112, 112)
对这个梯度求 hw维度的平均值,得到64个权重值,我的理解是,这个权重类似于y=ax1 + bx2…,函数求a,b的过程,a,b 通过求导得到,就是权重
而现在得到训练好的神经网络,也是最后输出类别,对应某个层的复杂函数,得到每个输入数值的权重而已
对应代码 如下。
##关键求的谁的梯度
grads_val = self.extractor.get_gradients()[-1].cpu().data.numpy()
target = features[-1]
target = target.cpu().data.numpy()[0, :]
weights = np.mean(grads_val, axis = (2, 3))[0, :]
#梯度和输入维度是对应的conv1 (1, 64, 112, 112)
#target(特征的维度,上面是特征的每个值对应的梯度)[1, 64, 112, 112]
## 例如conv1 特征维度[1, 64, 112, 112],对应的梯度维度也是(1, 64, 112, 112)
## 区分下,这里的weights ,不是卷积的权重w, conv1 对应的权重w是[64,3,7,7],
##这里权重对应的是输入数据对应的梯度,然后求平均值,得到每片特征图的重要程度权重,和输入相乘再相加
##得到的就是 代表分类预测结果的各个特征综合
for module in self.model.named_modules():
print module
输出如下,是一个元组,每一层的名字,和层的类型)
&&&&&&&&&&&&&&&
('layer2.0.conv1', Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False))
&&&&&&&&&&&&&&&
('layer2.0.bn1', BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))
&&&&&&&&&&&&&&&
('layer2.0.conv2', Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False))
&&&&&&&&&&&&&&&
('layer2.0.bn2', BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))
&&&&&&&&&&&&&&&
('layer2.0.conv3', Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False))
&&&&&&&&&&&&&&&
('layer2.0.bn3', BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))
&&&&&&&&&&&&&&&
('layer2.0.relu', ReLU(inplace))
&&&&&&&&&&&&&&&
('layer2.0.downsample', Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
))
&&&&&&&&&&&&&&&
('layer2.0.downsample.0', Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False))
&&&&&&&&&&&&&&&
('layer2.0.downsample.1', BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))
&&&&&&&&&&&&&&&
('layer2.1', Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
))
这个计算是论文中,根据作者公式得来的计算过程。建议看论文
论文地址:https://arxiv.org/pdf/1610.02391v1.pdf
中文翻译 https://www.jianshu.com/p/b2f7efe10ad8
Pytorch代码实现:https://github.com/Stephenfang51/Grad_CAM_Pytorch-1.01
https://github.com/utkuozbulak/pytorch-cnn-visualizations
Guided Backpropagation 简写gb 引导反向传播
Pytorch自带Resnet50特征图heat map热力图可视化
这个是weight 特征图的 可视化
Pytorch可视化神经网络热力图(CAM)
热力图操作