FCN(Fully Convolutional Networks)是深度学习应用在图像分割的代表作,是一种端到端(end to end)的图像分割方法,让网络做像素级别的预测直接得出label map。
图像分割的分类:
semantic segmentation:只标记语义,只要分割出某一类即可。instance segmentation:标记实例和语义,不仅分割出某一类,还要分割出是该类中的哪一个,也就是具体实例。 CNN与FCN通常CNN网络在卷积层之后会接上若干个全连接层,将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。以AlexNet为代表的经典CNN结构适合于图像级的分类和回归任务,因为它们最后都得到整个输入图像的一个概率向量,比如AlexNet的ImageNet模型输出一个1000维的向量表示输入图像属于每一类的概率(softmax归一化)。
FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全连接层+softmax输出)不同,FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map进行上采样,使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测,同时保留了原始输入图像中的空间信息,最后在上采样的特征图上进行像素分类。最后逐个像素计算softmax分类的损失,相当于每一个像素对应一个训练样本。
简单来说,FCN与CNN的区别在于把CNN最后的全连接层换成卷积层,输出的是一张已经label好的图片。
在CNN中,猫的图片输入到AlexNet,得到一个长为1000的输出向量,表示输入图像属于每一类的概率,其中在“tabby cat”这一类统计概率最高,用来做分类任务。FCN与CNN的区别在于把于CNN最后的全连接层转换成卷积层,输出的是一张已经label好的图片,而这张图片可以做语义分割。 卷积层CNN的强大之处在于它的多层结构能自动学习特征,并且可以学习到多个层次的特征:
较浅的卷积层感知域较小,学习到一些局部区域的特征。较深的卷积层具有较大的感知域,能够学习到更加抽象一些的特征。这些抽象特征对物体的大小、位置和方向等敏感性更低,从而有助于识别性能的提高,所以我们可以将卷积层看作是特征提取器。 这些抽象的特征对分类很有帮助,可以很好的判断出一幅图像中包含什么类别的物体,但是因为丢失了一些物体的细节,不能很好的给出物体的具体轮廓、指出每个像素具体属于哪个物体,因此做到精确的分割就很有难度。 传统的基于CNN的分割方法为了对一个像素分类,使用该像素周围的一个图像块作为CNN的输入用于训练和预测。这种方法有几个缺点:
存储开销很大。例如对每个像素使用的图像块的大小为15x15,然后不断滑动窗口,每次滑动的窗口给CNN进行判别分类,因此所需的存储空间根据滑动窗口的次数和大小急剧上升。计算效率低下。相邻的像素块基本上是重复的,针对每个像素块逐个计算卷积,这种计算也有很大程度上的重复。像素块大小的限制了感知区域的大小。通常像素块的大小比整幅图像的大小小很多,只能提取一些局部特征,从而导致分类的性能受到限制。而全卷积网络(FCN)则是从抽象的特征中恢复出每个像素所属的类别,即从图像级别的分类进一步延伸到像素级别的分类。
全连接->卷积层 全连接层卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。因为用到了所有的局部特征,所以叫全连接。 全连接层(Fully Connected Layers, FC)在卷积神经网络中相当于分类器的作用。如果说卷积层、池化层和激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的“分布式特征表示”映射到样本标记空间的作用。例如把一个3x3x5的最后一层卷积的输出feature map(特征图),转换成FC中1x4096的形式。 其实相当于又做了一层卷积,但是这次的卷积核尺寸是3x3x5(filter,或者称为滤波器),即全连接层特意设计了和feature map中大小尺寸相同的卷积核。此处卷积不想CNN之前卷积核下采样过程会产生深度矩阵feature map。这一次每一次卷积都会产生一个值(因为卷积核和feature map大小尺寸相同)。在把3x3x5的卷积输出转换成全连接层中4096神经元中之一的过程中,通过filter的激活函数,对5张3x3特征图中的每一张进行卷积,然后再把这5张feature map卷积结果求和,和就是4096个神经元之一。
全连接层存在的意义:全连接层之前的卷积层作用本质是提取特征,而全连接层的作用是分类。
全连接成在实际的运用中往往是2~3层,因为只有一层全连接层,有些情况下解决不了非线性问题。
注意到全连接层参数非常多(整个网络参数80%左右),一些性能优异的网络模型如GoogLeNet等,换用全局平均池化(Global Average Pooling, GAP)替换全连接层融合学到的深度特征。
以图像分类任务为例,在对最后一个卷积层进行池化后一般会再接2~3个全连接层(Full Connected Layer),这是一个高维向低维特征映射的过程,多个全连接层的作用是增加函数非线性,可以理解为提升分类的准确度。但是全连接层的加入会使模型产生过量参数,这种结构在VGG系列中仍有使用,之后的网络都在想办法减少和避免全连接层的使用(全卷积)。
全连接层和全卷积层的相互转化全连接层和卷积层之间不同在于:卷积核中的权值每次滑动计算时只是局部连接,且在卷积列中的神经元共享参数——计算局部信息,而全连接层神经元的权值与所有输入相连——计算全局信息。但二者都是采用的矩阵的点积运算,具有相似的函数计算形式,因此能够实现相互转换。
卷积——>全连接:权重矩阵参数增大,权重补0,由于参数共享性质,在其中大部分块中,存在大量相等参数。全连接——>全卷积:将卷积核的尺寸设置为和输入数据体的尺寸一致(NxWxHxC)。除第一层全连接外,其他通道数都为1,N表示本层神经元的个数,为一个提前设定的超参数,结果与初始的那个全连接层一致。现以图像分类问题为例,最后需要得到的是所属类别的得分,输出应该是一个向量的表示形式。假设经过多个卷积与池化层后准备输入到全连接的是一个4x4x3的一般特征图(或理解为一张彩色图片),如果进行全连接操作,需要先将特征reshape到1x1x48,下图给出了一次全连接的图像,然后再接softmax,最后一层全连接网络一般不使用激活函数和批归一化BN,而其他的所有层目前的做法是首先尝试BN+ReLU进行激活,两者的先后顺序不一定,一般是激活在前。
将这一步全连接转化为全卷积操作时,以相同的输出作为比较,卷积神经网络的输入是4x4x3的图像,使用10个与原特征图一致的卷积核操作变为1x1x10的输出。实际上,可以将这全连接层中的任意一个转化为卷积层。 显然最后得出的结果都是一个1x1x10的向量,分析上面计算的参数量,对于reshape的全连接参数量为48x10,全卷积操作的计算量为4x4x3x10,因此参数量相等。但是全连接训练出来的权重矩阵是48x10,如果要使用模型训练的参数进行测试,最后一层卷积池化后的特征图大小只能是4x4x3,即起始输入的图像大小必须固定(因为训练后的模型固定了)。如果仍想使用训练好的模型进行前向传播获得分类结构,需要对图片进行区域计算,即对原始图片进行裁剪,使其成为满足要求的图片后才可以进行输入。例如,训练时输入模型的图片大小为32x32x1,待测试图像为64x64x1,需要进行滑窗采样。由于全连接的参数不共享,所以最后分类的结果和准确度需要先后进行多次计算然后取平均值。
减少和避免全连接层额使用能够有效降低模型的参数,将全连接层转化为卷积层的作用:
解决了输入尺寸的限制。全连接层会破坏图像的空间结构,卷积会降低这种破坏,如channel=全连接的神经元个数时,使用1x1卷积代替全连接,效果很好。在两种变换中,将去连接层转化为卷积层在实际运用中更加有用。假设一个卷积神经网络的输入是227x227x3的图像,一系列的卷积层和下采样层将图像数据变为尺寸为7x7x512的激活数据体,AlexNet的处理方式为使用了两个尺寸为4096的全连接层,最后一个有1000个神经元的全连接层用于计算分类评分。可以将这3个全连接层中的任意一个转化为卷积层:
第一个连接区域是[7x7x512]的全连接层,令其滤波器尺寸为[7x7x4096],这样输出数据体就为[1x1x4096]。第二个全连接层,令其滤波器的尺寸为[1x1x4096],这样输出数据体为[1x1x4096]。最后一个全连接层也做类似的,令其滤波器尺寸为[1x1x1000],最终输出为[1x1x1000]。 FCN网络结构 输入图像为任意大小传统CNN输入图像为固定大小,对于CNN,一幅输入图片经过卷积和池化层时,这些层是不关心图片大小的。进入全连接层时,feature map要拉成一条向量,而向量中每个元素作为一个结点都要与下一个层的所有结点全连接,神经网络结构一旦确定,它的权值个数都是固定的,所以层层向回看,输出图片大小要固定。
把全连接层的权重重塑成卷积层的滤波器,这样的转化可以在单个向前传播的过程中,使得卷积网络在一张更大的输入图片上滑动,从而得到多个输出(可以理解为一个label map)。例如,让224x224尺寸的浮窗,以步长为32在384x384的图像上滑动,把每个经停的位置都带入卷积网络,最后得到6x6个位置的类别得分(6=(384-224)/32 + 1),那么通过将全连接层转化为卷积层之后的运算过程为:如果224x224的输入图像经过卷积层和下采样层之后得到了[7x7x512]的数组,那么384x384的图像直接经过同样的卷积层和下采样层后会得到[12x12x512]的数组,然后再经过上面由3个全连接层转化得到的3个卷积层,最终得到[6x6x1000]的输出((12-7)/1 + 1=6),这个结果正是浮窗在原图经停的6x6个位置的得分。
面对384x384的图像,让(含全连接层)的初始卷积神经网络以32像素的步长独立对图像中的224x224块进行多次评价,其效果和使用FCN把全连接层变换为卷积层后的卷积神经网络进行一次前向传播时一样的。
如下图所示,FCN将传统CNN中的全连接层转化成卷积层,对应CNN网络FCN把最后三层全连接层转换成为三层卷积层。在传统的CNN结构中,前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后的图像大小为13x13。而FCN输入的图像是HxW大小,第一层pooling后变为原图大小的1/4,第二层变为原图大小的1/8,第五层变为原图大小的1/16,第八层变为原图大小的1/32。(其实真正代码当中第一层是1/2,一次类推。) 经过多层卷积和pooling以后,得到的图像越来越小,分辨率越来越低。其中图像到H/32xW/32的时候图像是最小的一层时,所产生图叫heatmap热图,热图就是我们最重要的高维特征图,得到高维特征的heatmap之后就是最重要的一步,也是最后的一步对原图进行upsampling,把图像进行放大,放大到原图像的大小。
最后的输出是1000张heatmap,经过upsampling变为原图大小的图像,为了对每个像素进行分类预测,label成最后已经进行语义分割的图像,这里有一个小trick,就是最后通过逐个像素的求其在1000张图像该像素位置的最大数值描述(概率)作为该像素的分类。因此产生了一张已经分类好的图像,如下图所示右侧有狗狗和猫猫的图。 相较于使用被转化前的原始卷积神经网络对所有36个位置进行迭代计算,使用转化后的卷积神经网络进行一次前向传播计算要高效很多,因为36次计算都在共享计算资源。这一技巧在实践中经常使用,一次来获得更好的结果。比如,通常将一张图像尺寸变得更大,然后使用变换后的卷积神经网络来对空间上很多不同位置进行评价得到分类评分,然后再求这些分值的平均值。
上采样(upsampling)上采样操作可以看成是反卷积(Deconvolution),卷积运算的参数和CNN的参数一样是在训练FCN模型的过程中通过BP算法学习得到的。反卷积层也是卷积层,不关心输入图像尺寸大小。Deconv并不是真正的Deconvolution(卷积的逆变换),应该叫transposed convolution,deconv的前向传播就是conv的反向传播。
跳级(skip)结构对CNN的结果做处理,得到了dense prediction,而作者在试验中发现,得到的分割结果比较粗糙,所以考虑加入