我正在使用带有tensorflow后端的Keras,并且已经基于VGG权重微调了网络的最后一个Conv层和FC层。现在,我正在使用CAM技术来可视化图像的哪些部分触发了预测,并且在特定特征图通道上的梯度平均强度得到了全零。
我有4个班级,对于我的测试样本,这些是预测:
preds_sample = model.predict(x)
output>> array([[1., 0., 0., 0.]], dtype=float32)
# This is the "sample image" entry in the prediction vector
image_0 = model.output[:, 0]
last_conv_layer = model.get_layer('conv2d_13')
grads = K.gradients(toilet_w, last_conv_layer.output)[0]
grads.shape
output>> TensorShape([Dimension(None), Dimension(512), Dimension(14), Dimension(14)])
由于我使用theano图像排序-当我计算渐变的平均值时,我的轴是(0,2,3)
from keras import backend as K
K.set_image_dim_ordering('th')
pooled_grads = K.mean(grads, axis=(0,2,3))
pooled_grads.shape
output>> TensorShape([Dimension(512)])
iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x])
pooled_grads_value.shape, conv_layer_output_value.shape
output>> ((512,), (512, 14, 14))
pooled_grads_value都为零
我用更多的图像测试了该算法,发现它适用于某些图像。然后我注意到在最后一个转换层之后有一个退出层。我做了更多的研究https://github.com/jacobgil/keras-grad-cam/issues/2,并将代码修改为:
last_conv_layer = model.get_layer('conv2d_13')
grads = K.gradients(sample_output, last_conv_layer.output)[0]
# normalization trick: we normalize the gradient
#grads = normalize_grad(grads)
pooled_grads = K.mean(grads, axis=(0, 2, 3))
iterate = K.function([model.input, K.learning_phase()], [pooled_grads, last_conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x, 0])
但是对于某些图像,pooled_grads仍为零。