深度可视化技术是深度学习中一个仍处于探索阶段的学术研究热点,它可以帮助我们更直观地理解模型做的事情。
以计算机视觉为例,CNN中有着数以千计的卷积滤波器。深度神经网络中不同的滤波器会从输入图像中提取不同特征表示。
己有的研究表明低层的卷积核提取了图像的低级语义特性(如边缘、角点),高层的卷积滤波器提取了图像的高层语义特性(如图像类别)。
但是,由于深度神经网络会以逐层复合的方式从输入数据中提取特征,我们仍然无法像Sobel算子提取的图像边缘结果图一样直观地观察到深度神经网络中的卷积滤波器从输入图像中提取到的特征表示。
我们在之前的课程里看到CNN的各种应用,在计算机视觉各项任务中发挥很大的作用,但我们一直把它当做黑盒应用,本节内容我们先来看看特征可视化,主要针对一些核心问题:
可视化卷积核的背后原理是,卷积就是卷积核与图像区域做内积的结果,当图像上的区域和卷积核很相似时,卷积结果就会最大化。我们对卷积核可视化来观察卷积层在图像上匹配寻找什么。
常见的CNN架构第一层卷积核如下:
从图中可以看到,不同网络的第一层似乎都在匹配有向边和颜色,这和动物视觉系统开始部分组织的功能很接近。
第二个卷积层就相对复杂一些,不是很好观察了。
然而第二层卷积不和图片直接相连,卷积核可视化后并不能直接观察到有清晰物理含义的信息。
与可视化卷积核相比,将激活图可视化更有观察意义。
可视化输入图片中什么类型的小块可以最大程度的激活不同的神经元。
如下图所示,每一行都是某个神经元被最大激活对应的图片块,可以看到:
如果不使用Conv5的激活图,而是更后面的卷积层,由于卷积核视野的扩大,寻找的特征也会更加复杂,比如人脸、相机等,对应图中的下面部分。
使用一些图片来收集这些特征向量,然后在特征向量空间上使用最邻近的方法找出和测试图片最相似的图片。作为对比,是找出在原像素上最接近的图片。
可以看到,在特征向量空间中,即使原像素差距很大,但却能匹配到实际很相似的图片。
比如大象站在左侧和站在右侧在特征空间是很相似的。
如果大家做这个实验,可以观察到相似内容的图片聚集在了一起,比如左下角都是一些花草,右上角聚集了蓝色的天空。
有一些方法可以判定原始图片的哪些位置(像素)对最后的结果起作用了,比如遮挡实验(OcclusionExperiments)是一种方法。
它在图片输入网络前,遮挡图片的部分区域,然后观察对预测概率的影响,可以想象得到,如果遮盖住核心部分内容,将会导致预测概率明显降低。
如下图所示,是遮挡大象的不同位置,对「大象」类别预测结果的影响。
除了前面介绍到的遮挡法,我们还有显著图(SaliencyMap)方法,它从另一个角度来解决这个问题。
显著图(SaliencyMap)方法是计算分类得分相对于图像像素的梯度,这将告诉我们在一阶近似意义上对于输入图片的每个像素如果我们进行小小的扰动,那么相应分类的分值会有多大的变化。
可以在下图看到,基本上找出了小狗的轮廓。
进行语义分割的时候也可以运用显著图的方法,可以在没有任何标签的情况下可以运用显著图进行语义分割。
不像显著图那样使用分类得分对图片上的像素求导,而是使用卷积网络某一层的一个特定神经元的值对像素求导,这样就可以观察图像上的像素对特定神经元的影响。
我们把引导式反向传播计算的梯度可视化和最大激活块进行对比,发现这两者的表现很相似。
下图左边是最大激活块,每一行代表一个神经元,右侧是该神经元计算得到的对原始像素的引导式反向传播梯度。
下图的第一行可以看到,最大激活该神经元的图像块都是一些圆形的区域,这表明该神经元可能在寻找蓝色圆形状物体,下图右侧可以看到圆形区域的像素会影响的神经元的值。
引导式反向传播会寻找与神经元联系在一起的图像区域,另一种方法是梯度上升,合成一张使神经元最大激活或分类值最大的图片。
我们在训练神经网络时用梯度下降来使损失最小,现在我们要修正训练的卷积神经网络的权值,并且在图像的像素上执行梯度上升来合成图像,即最大化某些中间神将元和类的分值来改变像素值。
梯度上升的具体过程为:输入一张所有像素为0或者高斯分布的初始图片,训练过程中,神经网络的权重保持不变,计算神经元的值或这个类的分值相对于像素的梯度,使用梯度上升改变一些图像的像素使这个分值最大化。
同时,我们还会用正则项来阻止我们生成的图像过拟合。
总之,生成图像具备两个属性:
正则项强制生成的图像看起来是自然的图像,比如使用L2正则来约束像素,针对分类得分生成的图片如下所示:
也可以使用一些其他方法来优化正则,比如:
上述方法会使生成的图像更清晰。
也可以针对某个神经元进行梯度上升,层数越高,生成的结构越复杂。
添加多模态(multi-faceted)可视化可以提供更好的结果(加上更仔细的正则化,中心偏差)。通过优化FC6的特征而不是原始像素,会得到更加自然的图像。
一个有趣的实验是「愚弄网络」:
输入一张任意图像,比如大象,给它选择任意的分类,比如考拉,现在就通过梯度上升改变原始图像使考拉的得分变得最大,这样网络认为这是考拉以后观察修改后的图像,我们肉眼去看和原来的大象没什么区别,并没有被改变成考拉,但网络已经识别为考拉(图片在人眼看起来还是大象,然而网络分类已经把它分成考拉了)。
DeepDream是一个有趣的AI应用实验,仍然利用梯度上升的原理,不再是通过最大化神经元激活来合成图片,而是直接放大某些层的神经元激活特征。
步骤如下:
对于以上步骤的解释:试图放大神经网络在这张图像中检测到的特征,无论那一层上存在什么样的特征,现在我们设置梯度等于特征值,以使神经网络放大它在图像中所检测到的特征。
下图:输入一张天空的图片,可以把网络中学到的特征在原图像上生成:
我们有一个查看不同层的特征向量能保留多少原始的图片信息的方法,叫做「特征反演」。
具体想法是:任选1张图片,前向传播到已经训练好的CNN,选取其在CNN某一层产生的特征向量,保留这个向量。我们希望生成1张图片,尽量让它在该层产生一样的特征向量。
我们依旧使用梯度上升方法来完成,这个任务的目标函数定义为「最小化生成图片的特征向量与给定特征向量的L2距离」,当然我们会加一些正则化项保证生成图片的平滑,总体如下图所示:
通过这个方法,我们可以看到不同层的特征向量所包含的信息完整度,如下图所示:
解释讲解:
下面我们聊到的是「纹理生成」,针对这个问题,传统的方法有「近邻法」:根据已经生成的像素查看当前像素周围的邻域,并在输入图像的图像块中计算近邻,然后从输入图像中复制像素。但是这类方法在面对复杂纹理时处理得并不好。
格莱姆矩阵计算方法:
纹理生成的神经网络做法会涉及到格莱姆矩阵(GramMatrix),我们来介绍一下它,我们先看看格莱姆矩阵怎么得到:
格莱姆矩阵含义:
格莱姆矩阵捕获了一些二阶统计量,即“映射特征图中的哪些特征倾向于在空间的不同位置一起激活”。
我们可以认为格莱姆矩阵度量了图片中的纹理特性,并且不包含图像的结构信息,因为我们对图像中的每一点所对应的特征向量取平均值,它只是捕获特征间的二阶同现统计量,这最终是一个很好的纹理描述符。
事实上,使用协方差矩阵代替格莱姆矩阵也能取得很好的效果,但是格莱姆矩阵有更高效的计算方法:
当我们有了格莱姆矩阵这一度量图像纹理特性的工具后,就可以使用类似于梯度上升算法来产生特定纹理的图像。
算法流程如下图所示:
纹理生成步骤:
生成的纹理效果如下图所示:
上图说明,如果以更高层格莱姆矩阵的L2距离作为损失函数,那么生成图像就会更好地重建图像的纹理结构(这是因为更高层的神经元具有更大的感受野)。
具体的做法是:准备两张图像,一张图像称为内容图像,需要引导我们生成图像的主题;另一张图像称为风格图像,生成图像需要重建它的纹理结构。然后共同做特征识别,最小化内容图像的特征重构损失,以及风格图像的格莱姆矩阵损失。
使用下面的框架完成这个任务:
上图所示的框架中,使用随机噪声初始化生成图像,同时优化特征反演和纹理生成的损失函数(生成图像与内容图像激活特征向量的L2距离以及与风格图像gram矩阵的L2距离的加权和),计算图像上的像素梯度,重复这些步骤,应用梯度上升对生成图像调整。
迭代完成后我们会得到风格迁移后的图像:它既有内容图像的空间结构,又有风格图像的纹理结构。
因为网络总损失是「特征反演」和「纹理生成」的两部分损失的加权和,我们调整损失中两者的权重可以得到不同倾向的输出,如下图所示:
也可以改变风格图像的尺寸:
我们甚至可以使用不同风格的格莱姆矩阵的加权和,来生成多风格图:
上面的风格迁移框架,每生成一张新的图像都需要迭代数次,计算量非常大。因此有研究提出了下面的FaststyleTransfer的框架:
快速图像风格迁移方法,会在一开始训练好想要迁移的风格,得到一个可以输入内容图像的网络,直接前向运算,最终输出风格迁移后的结果。
训练前馈神经网络的方法是在训练期间计算相同内容图像和风格图像的损失,然后使用相同梯度来更新前馈神经网络的权重,一旦训练完成,只需在训练好的网络上进行一次前向传播。