我一直在尝试为Inception V3生成热图。我原以为倒数第二层应该是最后的卷积层,即conv2d_94
(索引299)。然而,这会生成非常粗糙的地图(大的区域)。我尝试使用另一个层mixed10
(索引310),如这个笔记本中所建议的,以解决这里描述的问题,虽然区域变小了,但看起来仍然不够好。其他人确实使用了conv2d_94
,如这里所示。
我理解这可能表明我的模型并未关注正确的要素,但从概念上讲,我对应该使用哪一层感到困惑。什么是合适的倒数第二层?
我使用的是Keras 2.2.0和keras-vis
中的visualize_cam
。
heatmap = visualize_cam(model, layer_idx, filter_indices=classnum, seed_input=preprocess_img, backprop_modifier=None)
其中layer_idx
是dense_2
的索引。
我尝试不定义penultimate_layer
,根据文档,这会将参数设置为最近的倒数第二Conv
或Pooling
层。这与penultimate_layer=299
的结果相同。
回答:
关于您自己的数据无法给出任何建议,但Inception V3用于Grad-CAM可视化的倒数第二层确实是mixed10
(索引310),如您链接的笔记本中所报告的:
310是全局平均池化前的拼接层
理由是:由于conv2d_94
(299)的输出与其他卷积层(或拼接层)如mixed9_1
、concatenate_2
等下游连接,根据定义,它不能是倒数第二的卷积层;另一方面,mixed10
不是这样——相反,它只是在最终平均池化层之前的一层。倒数第二层应该是一个卷积层,而不是池化层,这是从Chollet的展示中建议的,其中对于VGG他使用的是block5_conv3
,而不是紧随其后的block5_pool
(尽管事实是,即使使用block5_pool
似乎也给出了非常相似的视觉结果)。
让我进一步解释一下,并说明上面“建议”一词的强调…
与当前深度学习研究与实践中的许多其他事物一样,Grad-CAM是一种启发式方法,而不是一种“硬性”的科学方法;因此,有关于如何使用它以及可能的结果的建议和期望,但没有硬性规则(和“适当”的层)。请考虑原始论文中的以下摘录(第2节末尾,强调是我的):
我们期望最后的卷积层在高层次语义和详细的空间信息之间具有最佳的折衷,因此我们使用这些特征图来计算Grad-CAM和Guided Grad-CAM。
即,正如我已经说的,确实有建议和期望,但预期的是一定程度的实验和自由发挥的态度…
现在,假设您正在遵循Chollet的笔记本(即使用纯Keras,而不是Keras-vis包),这些是您需要在代码中进行的更改,以便使其与Inception V3兼容:
# cell 24from keras import backend as Kfrom keras.applications.inception_v3 import InceptionV3K.clear_session()K.set_learning_phase(0) # needs to be set BEFORE building the modelmodel = InceptionV3(weights='imagenet')# in cell 27from keras.applications.inception_v3 import preprocess_input, decode_predictionsimg = image.load_img(img_path, target_size=(299, 299)) # different size than VGG# in cell 31:last_conv_layer = model.get_layer('mixed10')for i in range(2048): # was 512 for VGG conv_layer_output_value[:, :, i] *= pooled_grads_value[i]
然后,叠加在原始creative_commons_elephant.jpg
图像上的热图应该看起来像这样:
可以说,这与Chollet的笔记本中由VGG生成的相应图像并没有那么不同(尽管诚然,热图确实更加分散,并且似乎不符合Chollet关于“关注耳朵”的叙述)…