FCN (FullyConvolutional Networks for Semantic Segmentation )

基于深度学习主要的做法有两种:

·        基于图像分块:利用像素、超像素块周围小邻域进行独立的分类。(在分类网络中使用全连接层,固定图像块尺寸)

·        基于全卷积网络:对图像进行pixel-to-pixel的预测,可以得到任意大小的图像分割结果,而且不需要对每个图像块进行分类,速度快。重要的两点:卷积层上采样、skipconnection结构

FCN的主要思路:

把CNN改为FCN,输入一幅图像后直接在输出端得到dense prediction,也就是每个像素所属的class,从而得到一个end-to-end的方法来实现image semantic segmentation。

传统的基于CNN的分割方法;

为了对一个像素分类,使用该像素周围的一个图像块作为CNN的输入用于训练和预测。这种方法有几个缺点:一是存储开销很大。例如对每个像素使用的图像块的大小为15×15,然后不断滑动窗口,每次滑动的窗口给CNN进行判别分类,因此则所需的存储空间根据滑动窗口的次数和大小急剧上升。二是计算效率低下。相邻的像素块基本上是重复的,针对每个像素块逐个计算卷积,这种计算也有很大程度上的重复。三是像素块大小的限制了感知区域的大小。通常像素块的大小比整幅图像的大小小很多,只能提取一些局部的特征,从而导致分类的性能受到限制。

FCN对CNN的改进:

通常CNN网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。以AlexNet为代表的经典CNN结构适合于图像级的分类和回归任务,因为它们最后都期望得到整个输入图像的一个数值描述(概率),比如AlexNet的ImageNet模型输出一个1000维的向量表示输入图像属于每一类的概率(softmax归一化)。

FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。FCN把cnn全连接层换成了卷积层,可以接受任意尺寸的输入图像,采用反卷积对卷积层的特征图进行采样,使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测,同时保留了原始输入图像的空间信息,然后在上采样上的特征图进行逐像素分类,最后逐个像素计算softmax损失,相当于每个像素对应一个训练样本。

 

FCN全连接层转化为卷积层:

 

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

 

·        针对第一个连接区域是[7x7x512]的全连接层,令其滤波器尺寸为F=7,这样输出数据体就为[1x1x4096]了。

·        针对第二个全连接层,令其滤波器尺寸为F=1,这样输出数据体为[1x1x4096]。

·        对最后一个全连接层也做类似的,令其F=1,最终输出为[1x1x1000]

 

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

 

 

FCN框架:

对原图像进行卷积conv1、pool1后原图像缩小为1/2;之后对图像进行第二次conv2、pool2后图像缩小为1/4;接着继续对图像进行第三次卷积操作conv3、pool3缩小为原图像的1/8,此时保留pool3的featureMap;接着继续对图像进行第四次卷积操作conv4、pool4,缩小为原图像的1/16,保留pool4的featureMap;最后对图像进行第五次卷积操作conv5、pool5,缩小为原图像的1/32,然后把原来CNN操作中的全连接变成卷积操作conv6、conv7,图像的featureMap数量改变但是图像大小依然为原图的1/32,此时图像不再叫featureMap而是叫heatMap。

现在我们有1/32尺寸的heatMap,1/16尺寸的featureMap和1/8尺寸的featureMap,1/32尺寸的heatMap进行upsampling操作之后,因为这样的操作还原的图片仅仅是conv5中的卷积核中的特征,限于精度问题不能够很好地还原图像当中的特征,因此在这里向前迭代。把conv4中的卷积核对上一次upsampling之后的图进行反卷积补充细节(相当于一个差值过程),最后把conv3中的卷积核对刚才upsampling之后的图像进行再次反卷积补充细节,最后就完成了整个图像的还原。

 

FCN的反卷积:

 

反卷积层也是卷积层,不关心input大小,滑窗卷积后输出output。

配个动图简单理解一下:下图中蓝色是反卷积层的input,绿色是反卷积层的output。

kernel size = 3, stride= 1的反卷积,input是2×2,output是4×4

 

 

kernel size = 3, stride = 2的反卷积,input是3×3, output是5×5:

最后,问题来了,怎么使反卷积的output大小和输入图片大小一致,从而得到pixel level prediction。

FCN里面全部都是卷积层(pooling也看成卷积),卷积层不关心input的大小,inputsize和outputsize之间存在线性关系。假设图片输入为n×n大小,第一个卷积层输出map就为conv1_out.size=(n-kernelsize)/stride + 1, 记做conv1_out.size = f(n), 依次类推,conv5_out.size= f(conv5_in.size) = f(… f(n)), 反卷积是要使n = f‘(conv5_out.size)成立,要确定f’,就需要设置deconvolution层的kernelsize,stride,padding。

dense prediction 

 理解:标注出图像中每个像素点的对象类别,要求不但给出具体目标的位置,还要描绘物体的边界,如图像分割、语义分割、边缘检测等等。

这里通过upsampling得到dense prediction,作者研究过3种方案:

1,shift-and-stitch:设原图与FCN所得输出图之间的降采样因子是f,那么对于原图的每个f*f的区域(不重叠),“shift the input x pixels to theright and y pixels down for every (x,y) ,0 < x,y < f." 把这个f*f区域对应的output作为此时区域中心点像素对应的output,这样就对每个f*f的区域得到了f^2个output,也就是每个像素都能对应一个output,所以成为了dense prediction。

2,filter rarefaction:就是放大CNN网络中的subsampling层的filter的尺寸,得到新的filter:

其中s是subsampling的滑动步长,这个新filter的滑动步长要设为1,这样的话,subsampling就没有缩小图像尺寸,最后可以得到dense prediction。

以上两种方法作者都没有采用,主要是因为这两种方法都是trad-off的,原因是:
对于第二种方法:下采样的功能被减弱,使得更细节的信息能被filter看到,但是receptive fileds会相对变小,可能会损失全局信息,且会对卷积层引入更多运算。
对于第一种方法:虽然receptive fileds没有变小,但是由于原图被划分成f*f的区域输入网络,使得filters无法感受更精细的信息。

重点方法:
反卷积层->pixelwise->bp parameters->实现把conv的前传和反传过程对调一下即可
3,这里upsampling的操作可以看成是反卷积(deconvolutional),卷积运算的参数和CNN的参数一样是在训练FCN模型的过程中通过bp算法学习得到。

 

 

在这里我们要注意的是FCN的缺点:

1.           是得到的结果还是不够精细。进行8倍上采样虽然比32倍的效果好了很多,但是上采样的结果还是比较模糊和平滑,对图像中的细节不敏感。

2.           是对各个像素进行分类,没有充分考虑像素与像素之间的关系。忽略了在通常的基于像素分类的分割方法中使用的空间规整(spatial regularization)步骤,缺乏空间一致性。