FCN全卷积网络

来源:互联网 发布:mac苹果diy显示器 编辑:程序博客网 时间:2024/05/03 10:32

最近在做图像分割的任务,看到了伯克利的Jonathan Long、Evan Shelhamer等在CVPR2015上发表的《Fully Convolutional Networks for Fully Convolutional Networks》,这是CVPR的Best Paper。顿时感觉CNN+图像搜索的方法有些笨拙了。特此总结一下,并归纳其与CNN的关系。

背景

自2012年AlexNet提出并刷新了当年ImageNet物体分类竞赛的世界纪录以来,CNN在物体分类、人脸识别、图像检索等方面已经取得了令人瞩目的成就。通常CNN网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。

以AlexNet、VGGNet等为代表的经典CNN结构适合于图像级 的任务处理,因为它们的目标是:得到整个输入图像的一个数值描述(概率)。 比如AlexNet的ImageNet模型输出一个1000维的向量表示输入图像属于每一类的概率。
举个例子,将下图中的猫作为样本输入到AlexNet中, 得到一个长为1000的输出向量, 向量中的每个item表示输入图像属于1000类中的每一类的概率,其中在“tabby cat”这一类上值最高,即认为样图是属于“tabby cat”类。

这里写图片描述

与物体分类要建立图像级理解任务不同的是,有些应用场景下要得到图像像素级别的分类结果,例如:1)语义级别图像分割(semantic image segmentation), 最终要得到对应位置每个像素的分类结果。2) 边缘检测(edge detection), 相当于对每个像素做一次二分类(是边缘或不是边缘)。3) 光流分析(optical flow)。
以语义图像分割为例,其目的是将图像分割为若干个区域, 使得语义相同的像素被分割在同意区域内。
下图是一个语义图像分割的例子:视网膜层的边界确定,我们的目标是要确定视网膜层的9个boundary(图中的一条条线)。
这里写图片描述

纯粹CNN的模型对于像素级语义分割的问题在于:

  • ①存储开销很大。例如对每个像素使用的图像块的大小为15x15,然后不断滑动窗口(patch by patch),每次滑动的窗口给CNN进行判别分类,因此则所需的存储空间根据滑动窗口的次数和大小急剧上升。
  • ②计算效率低下。相邻的像素块基本上是重复的,针对每个像素块逐个计算卷积,这种计算也有很大程度上的重复。
  • ③像素块大小的限制了感知区域的大小。通常像素块的大小比整幅图像的小得多,只能提取一些局部的特征,从而导致分类的性能受到限制。

全卷积网络(FCN)则是从抽象的特征中恢复出每个像素所属的类别。即从图像级别的分类进一步延伸到像素级别的分类。

FCN和CNN的区别

FCN全卷积网络和CNN的本质区别在于:FCN是没有全连接层的CNN。Jonathan Long、Evan Shelhamer和Trevor Darrell在CVPR2015上的会议论文《Fully Convolutional Networks for Fully Convolutional Networks》为图像语义分割挖了一个坑,于是大家都开始尝试将其应用于对应的行业,用于像素级语义分割。

此外,与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行图像分类不同,FCN可以接受任意尺寸的输入图像,采用反卷积层(keras中:Conv2DTranspose)对最后一个卷积层的feature map进行上采样(Upsampling), 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时也保留了原始输入图像中的空间信息。最后,对上采样后的特征图上进行逐像素分类。论文中逐像素计算softmax分类的损失, 可以理解为分类任务中的每一个像素对应一个训练样本。

1、CNN转换为FCN的例子(转载自代码初学者的博客)

全连接层和卷积层之间唯一的不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,并且在卷积列中的神经元共享参数。在两类层中,神经元都是计算点积,所以它们的函数形式是一样的。因此,将此两者相互转化是可能的。

全连接层转化为卷积层:在两种变换中,将全连接层转化为卷积层在实际运用中更加有用。假设一个卷积神经网络的输入是 224x224x3 的图像,一系列的卷积层和下采样层将图像数据变为尺寸为 7x7x512 的激活数据体。AlexNet使用了两个尺寸为4096的全连接层,最后一个有1000个神经元的全连接层用于计算分类评分。我们可以将这3个全连接层中的任意一个转化为卷积层:

  • 针对第一个连接区域是[7x7x512]的全连接层,令其滤波器尺寸为F=7**(卷积核为7x7)**,这样输出数据体就为[1x1x4096]了。
  • 针对第二个全连接层,令其滤波器尺寸为F=1**(卷积核为1x1)**,这样输出数据体为[1x1x4096]。
  • 对最后一个全连接层也做类似的,令其F=1**(卷积核为1x1)**,最终输出为[1x1x1000]

实际操作中,每次这样的变换都需要把全连接层的权重W重塑成卷积层的卷积核(滤波器)。那么这样的转化有什么作用呢?它在下面的情况下可以更高效:让卷积网络在一张更大的输入图片上滑动,得到多个输出,这样的转化可以让我们在向前传播的过程中完成上述的操作。

如下图所示,FCN将传统CNN中的全连接层转化成卷积层,对应CNN网络FCN把最后三层全连接层转换成为三层卷积层。在AlexNet结构中,前5层是卷积层,第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个不同类别的概率。
FCN将这3层表示为卷积层,卷积核的大小 (通道数,宽,高) 分别为 (4096,1,1)、(4096,1,1)、(1000,1,1)。看上去数字上并没有什么差别,但是卷积跟全连接是不一样的概念和计算过程,使用的是之前CNN已经训练好的权值和偏置,但是不一样的在于权值和偏置是有自己的范围,属于自己的一个卷积核。因此FCN网络中所有的层都是卷积层,故称为全卷积网络。

这里写图片描述
下图是一个全卷积层,与上图不一样的是图像对应的大小下标,CNN中输入的图像大小是统一固定resize成 227x227 大小的图像,第一层pooling后为55x55,第二层pooling后图像大小为27x27,第五层pooling后的图像大小为13*13。
而FCN输入的图像是H*W大小,第一层pooling后变为原图大小的1/4,第二层变为原图大小的1/8,第五层变为原图大小的1/16,第八层变为原图大小的1/32(勘误:其实真正代码当中第一层是1/2,以此类推)。
这里写图片描述

显然,卷积操作本质上就是DownSampling(下采样)。经过多次卷积和pooling以后,得到的图像越来越小,分辨率越来越低。其中图像到 H/32∗W/32 的时候图片是最小的一层时,所产生图叫做heatmap热图,热图就是我们最重要的高维特征图,得到高维特征的heatmap之后就是最重要的一步也是最后的一步,就是对此heatmap进行UpSampling,把图像进行放大到原图像的大小。
这里写图片描述

最后的输出是1000张heatmap经过UpSampling变为原图大小的图片,为了对每个像素进行分类预测label成最后已经进行语义分割的图像。这里有一个小trick,就是最后通过逐个像素地求其在1000张图像该像素位置的最大数值描述(概率)作为该像素的分类。因此产生了一张已经分类好的图片,如下图右侧有狗狗和猫猫的图。
这里写图片描述

2、UpSampling(上采样)

关于上采样的解释转自知乎张萌-如何理解深度学习中的deconvolution networks?

逆卷积(Deconvolution)比较容易引起误会,转置卷积(Transposed Convolution)是一个更为合适的叫法.

举个栗子:

4x4的输入,卷积Kernel为3x3, 没有Padding / Stride, 则输出为2x2。

输入矩阵可展开为16维向量,记作x
输出矩阵可展开为4维向量,记作y
卷积运算可表示为y=Cx

不难想象C其实就是如下的稀疏阵:
这里写图片描述
平时神经网络中的正向传播就是转换成了如上矩阵运算。

那么当反向传播时又会如何呢?首先我们已经有从更深层的网络中得到的Lossy.

这里写图片描述
回想第一句话,你猜的没错,所谓逆卷积其实就是正向时左乘CT,而反向时左乘(CT)T,即C

总结:逆卷积相对于卷积在神经网络结构的正向和反向传播中做相反的运算。

3、跳跃结构(Skip Architecture)

其实直接使用前两种结构就已经可以得到结果了,但是直接将全卷积后的结果上采样后得到的结果通常是很粗糙的。所以这一结构主要是用来优化最终结果的,思路就是将不同池化层的结果进行上采样,然后结合这些结果来优化输出,具体结构如下:
这里写图片描述

而不同的结构产生的结果对比如下:

这里写图片描述

4、总结

图像语义分割在将来还是大有可期的,我在另一篇博客上详细介绍了对细胞进行分隔的Image Segmentation任务,有兴趣的可以移步医疗图像切割FCN的Keras实现。