[Towards Interpretable Deep Learning] Post-hoc explanation series
本篇文章发表于ECCV 2014。
文章链接:[1311.2901] Visualizing and Understanding Convolutional Networks (arxiv.org)
代码链接:emmm就不贴了,感兴趣的小伙伴可以去github上搜一下;至于为什么不贴,是因为不同的implementations之间并不统一......这一切的原因都是原文对实现方式表述的并不是很明确,一会我会讲到。(虽然不影响我们汲取本篇论文的思想,但是还是想在这吐槽一下......)
近年来,卷积神经网络(ConvNets)在手写体数字识别、人脸检测等多个领域取得了卓越的成果。然而,我们对这些复杂模型的内部几乎是一无所知,不知道它们为什么能够实现如此好的性能;而如果我们不清楚这些模型的运作方式,那么就很难有方向地得到更好的模型,只能去反复尝试“碰运气”。
在这篇文章中,作者提出了一项可视化技术,可以reveal针对网络任一层的单个特征的输入“刺激”(stimuli);简单来说,就是探寻网络中间层的某一特征是受输入图像的哪一部分影响的。所使用的方法是multi-layered Deconvolutional Network (DeconvNet),将feature activations反向映射到输入的像素空间。
Visualization with a Deconvnet - A novol way to map the activatities back to the input pixel space.
如无特殊说明,本文提出的可视化方法都是针对于图像分类任务的标准ConvNets,这些模型通常包括卷积、activation (ReLU)、最大池化、归一化等操作,在网络的最后为FC全连接层,最终的激活函数为softmax。
为了实现DeconvNet,需要以下操作:
(i) Unpooling
在卷积神经网络中池化操作是不可逆的,但是我们可以在池化的时候将最大值所处的位置记录下来(以最大池化为例),然后在反池化的时候恢复这个位置的数值并将其它位置补零,这样就得到了原始feature map的一个近似。
(ii) Rectification
卷积神经网络使用的非线性激活函数为ReLU,以保证feature map的值总是正的;为了获取valid feature reconstructions at each layer (也应该是正的),作者在DeconvNet中也使用ReLU函数对恢复的feature map进行激活。
(iii) Filtering
为了实现卷积操作的反操作,DeconvNet使用transposed convolution以实现反卷积,即,反卷积=转置卷积。
太好了!我们已经有了DeconvNet所需要的操作了,现在只需要给它一张feature map,就可以得到它在pixel space对应的可视化结果了!
那么问题来了......这张feature map是什么?是怎么选的?
原文中有两句话是这样写的:
1. “To examine a given convnet activation, we set all other activations in the layer to zero and pass the feature maps as input to the attached deconvnet layer.”
2. “For a given feature map, we show the top 9 activations, each projected separately down to pixel space.”
实话说,当时看论文的时候这两句话给我整懵了......于是我决定,既然看不懂,那就去看看代码如何实现的吧!然而不看不知道,一看吓一跳,github上的implementations各不相同,原因就在于大家对这两句话的理解不同;看来大家也都比较懵,所以都只能各自按照自己的理解实现。这些implementations之间的区别我在这里就不展开了,欢迎感兴趣的小伙伴一起讨论。
在这里仅给出我自己的理解:假设我们共有 张图像,选定网络的某一层layer ,在layer 中共有 个卷积核,而这些卷积核各司其职,比如有的卷积核关注纹理、有的关注颜色......现在,每张图像经过layer 都会产生 个feature maps,然后对于每一张feature map,我们只保留其中最大的activation值 ,而将其余位置全部置零。
接下来,在layer 下我们定义一个矩阵 ,row对应于不同的图像,colomn对应于不同的卷积核; 代表第 张图像在layer 下由第 个卷积核产生的feature map中的最大activation值,即 。
现在,我们对矩阵的每一列进行从大到小排序,选取top-9,就得到了在当前卷积核下最“活跃”的9张图片(比如这个卷积核是用来识别“草坪”的,那么这9张图片中的“草坪”元素一定相对较多);选择好9张图像之后,也就得到了它们对应的9张只保留了最大激活值 的feature maps,然后将这9张feature maps分别输入到DeconvNet中得到9个可视化的结果;
每个卷积核都有与其对应的9张可视化结果,详见第(3)节实验一。
实验比较多,在这里展示几个比较有趣的结果。
实验一:
此实验对应于第(2)节结尾部分。可以发现虽然每组(9张)原始图像彼此之间差距很大,但是它们的feature map得到的可视化结果却很相似;比如Layer 5, row 1,column 2,如下:
虽然右边的原图差异很大,但是左边的可视化结果关注的貌似都是原图中的“草地”部分,由此可见,layer 5的某个特定卷积核所关注的可能是“草”的特征,从一定程度解释了该卷积核的“功能”。
实验二:
作者也展示了给定feature map(再次强调,这个feature map只有一个unique value,也是原feature map中的最大值)的可视化结果随模型训练过程的变化情况:
每一行有8张可视化结果,分别对应epoch=[1,2,5,10,20,30,40,64];可以发现浅层很快收敛,而较深的层收敛较慢,并且提取到的也是更加high-level的特征。
实验三:
(a) 对原图的不同位置用灰色方块进行遮挡;
(b) Layer 5的“strongest feature map”;
(c) Layer 5的“strongest feature map”的“projection”;
(d) 遮挡物位于不同位置时对正确类别的分类概率;
(e) 遮挡物位于不同位置时的分类结果。
所谓的strongest feature map指的其实就是图片中最显著的特征,也是当前layer下“最显著的卷积核”,其排序方式是将每个卷积核产生的feature map的所有activations值相加,找出最大的。以第一行的“小狗”为例,我们可以发现:
1. 我们先观察(c)左上角黑色方框的图片,strongest feature map所对应的feature大概是“狗头”;其余三张不带黑框的是其它图像的projection,与实验一的结果类似,虽然原始图像不同(这里没有给出另外三张原始图像),但提取到的特征是相似的;
2. 再看(b),每个像素点代表当遮挡物位于该位置时layer 5 strongest feature map的总activations;可以发现当“狗头”被遮挡住的时候,总activations降低(蓝色);再一次说明了该feature map对应的卷积核提取的特征是“狗头”;
3. 当遮住“狗头”的时候,分类器将图像分类为“dog”的概率降低(蓝色),遮住别的地方没什么影响;
4. 当遮住“狗头”的时候,分类器倾向于将图像分类为小狗嘴里叼着的“Tennis ball”。