FCN:Fully Convolutional Networks for Semantic Segmentation

FCN:Fully Convolutional Networks for Semantic Segmentation_第1张图片
image

github:https://github.com/shelhamer/fcn.berkeleyvision.org

图像语义分割,就是给定一张图片,对图片上的每一个像素点分类。上图就是我们需要将实际的场景图分割成的分割图。不同颜色代表不同类别。 当下流行的各种模型表现可以通过PASCAL VOC Challenge performance evaluation server查看。大部分的语义分割模型都是前端使用FCN进行特征粗提取,后端使用CRF/MRF(条件随机场)优化前端的输出,最后得到分割图。

为什么需要FCN?

图像语义分割的输出需要是个分割图,所以,我们需要丢弃全连接层,换上全卷积层,而这就是全卷积网络了。具体定义请参看论文:Fully Convolutional Networks for Semantic Segmentation

前端结构

此处的FCN特指Fully Convolutional Networks for Semantic Segmentation论文中提出的结构,而非广义的全卷积网络。作者的FCN主要使用了三种技术:

  • 不含全连接层(fc)的全卷积(fully conv)网络。可适应任意尺寸输入。
  • 增大数据尺寸的反卷积(deconv)层。能够输出精细的结果。
  • 结合不同深度层结果的跳级(skip)结构。同时确保鲁棒性和精确性。
FCN:Fully Convolutional Networks for Semantic Segmentation_第2张图片
image

输入可为任意尺寸图像彩色图像;输出与输入尺寸相同,深度为:20类目标+背景=21。(在PASCAL数据集上进行的,PASCAL一共20类)。

  1. 虚线上半部分为全卷积网络。(蓝:卷积,绿:max pooling)。对于不同尺寸的输入图像,各层数据的尺寸(height,width)相应变化,深度(channel)不变。
  2. 虚线下半部分中,分别从卷积网络的不同阶段,以卷积层(蓝色×3)预测深度为21的分类结果。

1. 全卷积层

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

[图片上传失败...(image-b1e081-1553237577420)]

上图是一个全卷积层,CNN中输入的图像大小是统一固定成 227x227 大小的图像,第一层pooling后为55x55,第二层pooling后图像大小为27x27,第五层pooling后的图像大小为1313。而FCN输入的图像是HW大小,第一层pooling后变为原图大小的1/4,第二层变为原图大小的1/8,第五层变为原图大小的1/16,第八层变为原图大小的1/32(勘误:其实真正代码当中第一层是1/2,以此类推)。

[图片上传失败...(image-bcfd01-1553237577420)]

经过多次卷积和pooling以后,得到的图像越来越小,分辨率越来越低。其中图像到 H/32∗W/32 的时候图片是最小的一层时,所产生图叫做heatmap热图,热图就是我们最重要的高维特征图,得到高维特征的heatmap之后就是最重要的一步也是最后的一步对原图像进行upsampling,把图像进行放大、放大、放大,到原图像的大小。

2. 反卷积

此处的反卷积即是上采样(Deconvolution)。Caffe和Kera里叫Deconvolution,而tensorflow里叫conv_transpose。CS231n这门课中说,叫conv_transpose更为合适。普通的池化会缩小图片的尺寸,比如VGG16 五次池化后图片被缩小了32倍。为了得到和原图等大的分割图,我们需要上采样/反卷积。

反卷积和卷积类似,都是相乘相加的运算。只不过后者是多对一,前者是一对多。而反卷积的前向和后向传播,只用颠倒卷积的前后向传播即可。所以无论优化还是后向传播算法都是没有问题。图解如下:

FCN:Fully Convolutional Networks for Semantic Segmentation_第3张图片
image

目前使用得最多的deconvolution有2种,

  • full卷积, 完整的卷积可以使得原来的定义域变大
  • 记录pooling index,然后扩大空间,再用卷积填充
FCN:Fully Convolutional Networks for Semantic Segmentation_第4张图片
image

输入:2x2, 卷积核:4x4, 滑动步长:3, 输出:7x7

  1. 输入图片每个像素进行一次full卷积,根据full卷积大小计算可以知道每个像素的卷积后大小为 1+4-1=4, 即4x4大小的特征图,输入有4个像素所以4个4x4的特征图
  2. 将4个特征图进行步长为3的fusion(即相加); 例如红色的特征图仍然是在原来输入位置(左上角),绿色还是在原来的位置(右上角),步长为3是指每隔3个像素进行fusion,重叠部分进行相加,即输出的第1行第4列是由红色特阵图的第一行第四列与绿色特征图的第一行第一列相加得到,其他如此类推。

可以看出反卷积的大小是由卷积核大小与滑动步长决定, in是输入大小, k是卷积核大小, s是滑动步长, out是输出大小得到 out = (in - 1) * s + k,上图过程就是, (2 - 1) * 3 + 4 = 7

这里的步长也可以这样理解 当stride =1 时,如下的左图,当stride=2时,如下的右图

FCN:Fully Convolutional Networks for Semantic Segmentation_第5张图片

3.跳级结构

FCN:Fully Convolutional Networks for Semantic Segmentation_第6张图片

image是原图像,conv1,conv2..,conv5为卷积操作,pool1,pool2,..pool5为pool操作,注意con6-7是最后的卷积层,最右边一列是upsample后的end to end结果。必须说明的是图中nx是指对应的特征图上采样n倍(即变大n倍),如32x upsampled 中的32x是图像只变大32倍,不是有32个上采样图像,又如2x conv7是指conv7的特征图变大2倍。

第一行对应FCN-32s,第二行对应FCN-16s,第三行对应FCN-8s。

  1. 先从FCN-32s开始说明upsample过程,只需要留意第一行,网络里面有5个pool,所以conv7的特征图是原始图像1/32,可以发现最左边image的是32 x 32,同时我们知道在FCN中的卷积是不会改变图像大小(或者只有少量像素的减少,特征图大小基本不会小很多),得到pool1是16 x 16,pool2是8 x 8,pool3是4 x 4,pool4是2 x 2,pool5是1 x 1,所以conv7对应特征图大小为1 x 1,然后再经过32x upsampled prediction 图片变回32x32。FCN作者在这里增加一个卷积层,卷积后的大小为输入图像的32(2^5)倍,我们简单假设这个卷积核大小也为32,这样就是需要通过反馈训练32x32个权重变量即可让图像实现end to end,完成了一个32s的upsample,FCN作者称做反卷积。事实上在源码中卷积核的大小为64,同时没有偏置bias。还有一点就是FCN论文中最后结果都是21x…,这里的21是指FCN使用的数据集分类,总共有21类。

  2. 现在我们把1,2行一起看,忽略32x upsampled prediction,先说明FCN-16s的upsample过程,FCN作者在conv7先进行一个2x conv7操作,其实这里也只是增加1个卷积层,这次卷积后特征图的大小为conv7的2倍,可以从pool5与2x conv7中看出来,此时2x conv7与pool4的大小是一样的,FCN作者提出对pool4与2x conv7进行一个fuse操作(事实上就是将pool4与2x conv7相加),fuse结果进行16x upsampled prediction,与FCN-32s一样,也是增加一个卷积层,卷积后的大小为输入图像的16(2^4)倍,我们知道pool4的大小是2x2,放大16倍,就是32x32,这样最后图像大小也变为原来的大小,至此完成了一个16s的upsample。现在我们可以知道,FCN中的upsample实际是通过增加卷积层,通过bp反馈的训练方法训练卷积层达到end to end,这时卷积层的作用可以看作是pool的逆过程。

  3. 这时我们看第2行与第3行,忽略32x upsampled prediction,conv7经过一次4x upsample,即使用一个卷积层,特征图输出大小为conv7的4倍,所以4x conv7的大小为4x4,然后pool4需要一次2x upsample,变成2x pool4,大小也为4x4,最后吧4x conv7,2x pool4与pool3进行fuse,得到求和后的特征图,最后增加一个卷积层,使得输出图片大小为pool3的8倍,也就是8x upsampled prediction的过程,最后也得到一个end to end的图像。同时FCN-8s均优于FCN-16s,FCN-32s。

我们可以发现,如果继续仿照FCN作者的步骤,我们可以对pool2,pool1实现同样的方法,可以有FCN-4s,FCN-2s,最后得到end to end的输出。这里作者给出了明确的结论,超过FCN-8s之后,结果并不能继续优化。结合上述的FCN的全卷积与upsample,在upsample最后加上softmax,就可以对不同类别的大小概率进行估计,实现end to end,最后输出的图是一个概率估计,对应像素点的值越大,其像素为该类的结果也越大。

网络训练

第一阶段

FCN:Fully Convolutional Networks for Semantic Segmentation_第7张图片

以经典的分类网络为初始化。最后两级是全连接(红色),参数弃去不用。

第二阶段

FCN:Fully Convolutional Networks for Semantic Segmentation_第8张图片

从特征小图(16 x 16 x 4096)预测分割小图(16 x 16 x 21),之后直接升采样为大图。
反卷积(橙色)的步长为32,这个网络称为FCN-32s。

第三阶段

FCN:Fully Convolutional Networks for Semantic Segmentation_第9张图片

反卷积分为两次完成(橙色×2)。
在第二次升采样前,把第4个pooling层(绿色)的预测结果(蓝色)融合进来。使用跳级结构提升精确性。
第二次反卷积步长为16,这个网络称为FCN-16s。

第四阶段

FCN:Fully Convolutional Networks for Semantic Segmentation_第10张图片

升采样分为三次完成(橙色×3)。
进一步融合了第3个pooling层的预测结果。 第三次反卷积步长为8,记为FCN-8s。

较浅层的预测结果包含了更多细节信息。比较2,3,4阶段可以看出,跳级结构利用浅层信息辅助逐步升采样,有更精细的结果。

FCN:Fully Convolutional Networks for Semantic Segmentation_第11张图片

缺点

  1. 是得到的结果还是不够精细。进行8倍上采样虽然比32倍的效果好了很多,但是上采样的结果还是比较模糊和平滑,对图像中的细节不敏感。
  2. 是对各个像素进行分类,没有充分考虑像素与像素之间的关系。忽略了在通常的基于像素分类的分割方法中使用的空间规整(spatial regularization)步骤,缺乏空间一致性。
  3. 使用了较浅层的特征,因为fuse操作会加上较上层的pool特征值,导致高维特征不能很好得以使用,同时也因为使用较上层的pool特征值,导致FCN对图像大小变化有所要求,如果测试集的图像远大于或小于训练集的图像,FCN的效果就会变差。

[参考链接]
https://zhuanlan.zhihu.com/p/22308032
http://www.cnblogs.com/gujianhan/p/6030639.html
https://blog.csdn.net/gyh_420/article/details/78570415
https://blog.csdn.net/qq_36269513/article/details/80420363
https://zhuanlan.zhihu.com/p/22976342

你可能感兴趣的:(FCN:Fully Convolutional Networks for Semantic Segmentation)