特征可视化--带你了解CNN到底在看什么

1. 引言

GoogLeNet layer4C

看到这些照片是不是觉得很神秘?

这些图片其实是GoogLeNet的Layer4C中channel做特征可视化后的成果。

如果你不明白我在说什么,没关系!

这次我要带大家来看看Google Brain团队在2017年分享的特征可视化的成果.

2. 特征可视化是什么?

特征可视化是什么呢?它是针对CNN的一种技巧,可以让我们以图像的方式去理解CNN内部到底在关注什么.

一个简单的CNN架构图,有一层又一层的卷积层

上图为一张简单的CNN的架构图,CNN最核心的架构就是一层又一层的卷积层,而卷积层的重点就是用一个kernel去对输入的图像做卷积运算来得到一张输出特征图.

这是一个标准的卷积层 许多张特征图代表有很多Kernel

一个Kernel对输入图像的一个区域(区域大小取决于Kernel大小)做完卷积运算后会输出一个数字,这个数字就是输出图像的pixel的值. 如下所示:

这是一个卷积运算,左边是输入,中间是Kernel,右边是输出

这个输出的值越大(可以为正数也可以为负数)代表Kernel对这个区域反应越大,也就是说Kernel对这个区域很关注,并且把这个关注的程度用数字的方式输出.所以如果我们可以知道Kernel对于那种类型的图像会产生很大反应的话,就可以知道这一个Kernel在关注什么.而CNN又是由一大堆Kernel组成的,所以基于了解Kernel在关注什么,我们就可以知道CNN在关注什么.

特征可视化指的就是将那些可以引起CNN Kernel最大反应的图像制作出来.
我们知道Kernel有很多,许多Kernel可以组成一个Layer,许多Layer构成一个神经网络.
所以我们可以针对不同层的不同Kernel,或者是针对某层的所有Kernel去做特征可视化.

3. 特征可视化怎么做?

我们知道特征可视化就是将引起CNN Kernel最大反应的图像制作出来,那么问题就转化为如何制作让Kernel产生最大反应的图片呢?

其实方法很简单,就和我们训练神经网络的方法类似.

  • 在训练神经网络的时候,我们主要依据我们的loss去改变网络权重,尝试让loss值越小越好.
  • 在制作特征可视化时,我们需要固定网络的权重,根据我们想看得的Kernel的输出去改变输入图片的像素,尝试使输出越大越好.


训练输入图片使得神经元Kernel输出最大化的过程.


当然,我们可以不只针对kernel做,我们也可以对整个Layer或是同一Layer中某几个kernel做特征可视化。

最左侧为单个Kernel对某个区域的输出,接着为单个kernel对整个区域的输出(单个通道的可视化),以及整个Layer的可视化输出

做完上述特征可视化后,这些图片代表什么意思呢? 我们前面提到过,这些图片是使神经元产生最大反应的图片,所以这代表我们的神经元是在关注这些图片所拥有的特性.

GoogLeNet Layer3A 一个比较浅的Layer中的二号神经元做特征可视化的结果,可以看到这个神经元关注的是一种特殊的纹理.

通过上述可视化,可以帮助我们理解CNN在看图片时,到底是根据那些东西来判断的,并且如果你挑选前面的layer和后面的layer做特征可视化,出现的图片复杂程度显然不太一样. 如下所示:

GoogLeNet Layer5A 一个比较深的Layer中的六号神经元做特征可视化的结果,可以看到这个神经元关注的是一个高度复杂的图案.

这也代表越浅层的神经元做的事情更多是将不同的纹理提取出来,而深层的神经元会结合这些简单的纹理特征合成更高复杂度的特征,像是上图中狗的脸,兔子的毛发等等.

看到这里我想大家大概都已经初步了解特征可视化的概念了.特征可视化只是让我们知道CNN中某个神经元(或者某个通道或者某个Layer)对什么样子的图片会更加在意. 而通过这些技巧,我们就能知道CNN到底在看什么,看的东西合理不合理.

4. 进阶内容

其实要制造出像我们上面看到的那些图片,并没有我们刚刚讲的那么简单,只要固定好网络权重然后根据神经元的activation调整输入图片就好。如果你真的这么做了,你得到的多半是像下面这样的结果。

不管如何微调学习率,得到图片都有许多噪声

仔细观察,我们发现我们尝试生成的图片虽然有出现了一些图案,但是其中含有大量的高频噪声。而且这些高频噪声看上去很像是对抗样本会出现的情形。但是会出现对抗样本的pattern看上去也是非常合理,毕竟制造对抗样本的方式就是微调输入图片来让网络的输出改变。

目前这些高频噪声的出现的原因大家还不是太了解,不过似乎是来自CNN中stride和pooling,这两个操作会导致网络的梯度出现高频特征。

如果我们不对图片的生成做任何限制,我们最后只会得到对抗样本。所以我们必须对图片生成加上一些限制条件来阻止这些高频噪声的生成。基本上所有的限制方法可以分为以下三个类别,分别是:

  • Frequency penalization:通过限制高频信号的出现来阻止高频噪声,但是会导致真正的高频特征消失(比如锐利的边缘)。
  • Transformation robustness:通过对图片进行一些微小的抖动,旋转或是放大缩小来限制图片的生成。这些图片即使做了这些处理,神经网络依然对这张图片有很高的反应。
  • Learned priors:不是从随机噪声开始生成图片,而是从一张可能从Dataset里挑出的真实的图片来开始生成,这种方式可以产生最像实际存在的图片,不过一开始的图片要怎么挑是一个问题。

利用上述技巧可以做出比较没有高频噪声的特征可视化。但是这些方法都是针对图片生成去做限制,而且一个很大的缺点是它会改变minimum的位置。

因此作者提出了用另外一个方式来限制高频噪声的产生,叫做“Preconditioning”。这其实可以想像成是你在做梯度最速下降的时候,用另外一种定义的距离来做梯度下降。但是这并不会改变最终的minimum的位置。用这种新的距离定义来做梯度下降时,就可以大幅度抑制图片的高频噪声。

选用不同的距离定义对图片的影响

上图中作者给出了三种不同precondition对图片造成的影响,基本上可以看到在decorrelated space上进行优化可以最大的抑制高频噪声的产生。这边作者其实没有写得很清楚precondition具体来说要如何实现,大家想详细了解的话可以看一下原文。

在这篇文章中所有的图片除了有特殊说明的,基本上都是利用decorrelated space和一些transformation robustness的技巧来产生的。

多样性也是生成Feature Visualization时需要注意的一个问题。能够让神经元产生强烈反应的图片并不一定都是同一类,而我们平时用简单的优化方法产生的图片可能是多种不同类的特征的混合。

某个通道同时对猫的特征,狐狸的特征以及汽车的特征都有强烈的反应

多样性帮助我们了解到单单只是关注一个神经元,可能并不足够。或许多个神经元的组合才是我们想看到的某个类的特征. 换句话说,或许某些神经元的activation的线性组合加起来后,做出的特征可视化才是包含所有的某个类的特征。比如神经元A可能包含猫,狐狸,汽车;神经元B包含猫,狗,人等等;只有将这些所有包含猫的特征的神经元的线性组合的feature visualization才是代表猫的feature visualization。

这其实是很合理的,毕竟我们在训练神经网络时可没有规定神经元一号要学什么特征,神经元二号又要学什么特征。所以某个类别的特征被多个神经元学习是非常正常的事。

只不过这告诉我们,单单看某个神经元的feature visualization可能还是不足以帮助我们完全了解CNN。

5. 总结

本文主要带大家了解了Feature Visualization到底在说什么,希望大家看完也能大致上了解它的概念。

当然上面一些比较深入的部分我想大家看不懂也没有关系(除非你要重现Google Brain的成果),不过希望大家可以知道上述过程的重点: 特征可视化就是把CNN中的神经元(channel或是layer)做可视化,而可视化的方式就是固定网络权重然后去改变输入图片让神经元(channel或是layer)的输出最大化。

您学废了吗?

参考