FCN

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012897374/article/details/79980911

论文原文: Fully Convolutional Networks for Semantic Segmentation

FCN是第一次真正地将CNN用到了semantic segmentation上,由UC Berkeley发明。FCN的主要贡献是提出了一种Transpose Conv的方式,将分辨率小的feature map映射到分辨率大的feature map上,并将高层次的、粗粒度特征和低层次的、细粒度的特征结合起来,最后取得了不错的效果。

1. Transpose Convolution(Deconv)

传统的Convolution是将大的feature map通过不断conv的方式变成了小的feature map。feature map变小,但是channel变大。每个feature map对应到了不同的高层次特征。Transpose Convolution则是一个相反的过程。但是实际上本文中的Transpose Convolution与Conv的操作其实没有什么相似之处。(因此不推荐Deconv这个名字)。

upsampling有两种类型,learnable和unlearnable两种方式。

1.1 unlearnable In-Network unsampling

  • Nearest Neighbor
    这里写图片描述
    这种方法是将所有的地方都填充成一样的值。
  • Bed of Nail
    这里写图片描述
    这种方法是将最大值填充到左上角,其余地方填0
  • Max Pooling
    这里写图片描述
    这种方法是在进行max pooling的时候,将最大位置的index记录下来,然后后面做对应的max unpooling的时候,将数字填充到对应的index上。

1.2 Learnable Upsampling: Transpose Convolution

这里写图片描述
这里写图片描述

Transpose Convolution其实已经和Conv没有什么关系了。具体做法是,将Input的每个像素点都当成filter的权重。比如图中的Input是2×2,那么就有4个权重。然后对于每个filter,现将filter乘上Input[0][0]即坐上角的权重后,作为一个输出。然后输入每移动一个像素点,输出就移动2个像素点。其中2就是stride。这样得到的输出就是一个5×5的feature map。然后图中的重叠区域的值是直接相加。注意还有一个1×1的padding(上图中的crop one pixel)。因此去掉该padding之后,得到的就是一个4×4得到feature map。

因此Deconv的卷积不是做内积,而是加权后的filter直接作为输出。相当与是conv的逆向过程。当然这里的padding也是conv里面paddng的逆向过程。

1.3 crop操作

下面以caffe为例说明。
Caffe中的数据是以 blobs形式存在的,blob是四维数据,即(Batchsize,numberofChennels,Height,Width)=(N,C,H,W)。对应的axis为(0,1,2,3)

Crop层的输入(bottom blobs)有两个,让我们假设为A和B,输出(top)为C。

  • A是要进行裁切的bottom,他的size是 (20,50,512,512)
  • B是裁切的参考输入,他的size是(20,10,256,256)
  • C是输出(top blob),由A裁切而来,那么他的size是(20,10256,256)
    在这个例子中,轴0的维度不变,我们只需要裁切blob的轴1,2,3,所以我们设置axis=1,代表我们将会裁切轴1和它之后的所有轴。

有两个裁切模式:

  • 模式1: 给出3个offsets,每个针对一个dimensionoffset=(25,128,128)。如果axis=1,offset=(25,128,128)
    crop operation:
    C=A[:,25:25+B.shape[1],128:128+B.shape[2],128:128+B.shape[3]]
  • 模式2: 给出1个offset,适用于三个dimension,offset=25
    那么就相当于模式1 的 offset=(25,25,25)。

但是FCN中的crop的axis=2。即第0、1维都保持不变,从第2维开始裁剪。因此对于上面的例子,输出应该为:(20,50,256,256)。虽然A的第1维比B的第1维大,但是仍然不裁剪。因为axis=2

2. FCN的具体过程

2.1 网络结构

这里写图片描述
相较于传统的卷积网络,将后面的全连接层全部换成了卷积层。这是绘制出来的feature map叫做heat map。

网络的整体结构为:
这里写图片描述
网络当中有两个需要注意的关键点。一个是作者在做卷积的过程当中,将pooling 3和pooling 4的feature map保留下来。主要是因为这些细粒度的特征有利于像素点的定位。而后面通过反卷积得到的粗粒度特征更适合分类而不是像素点的定位。

此外,由于卷积和反卷积得到的对应的feature map的通道数量不一样,因此作者在文中加入了3个crop操作:pooling 3的feture map与对应的反卷积后的feature map进行crop, pooling 4的feature map与对应的反卷积后的feature map进行crop, 原图与对应的feature map进行反卷积后的feature map进行crop。其中crop操作的参数如下:

  • 与pooling 4的crop:
    这里写图片描述
  • 与pooling 3的crop:
    这里写图片描述
  • 与input image的crop
    这里写图片描述

因此在crop的时候,对应的通道数目是不改变的,仅仅改变feature map的大小。前面两个crop完成后,会与前面对应的pooling的feature map相加(Eltwise)。最后一个crop完成之后没有相加操作,直接输出结果。

注意crop完了之后有相加操作,但是此时channel可能不一样。因此在crop之前有一个1×1的卷积层,用来将channel弄到相同。因此pooling3和pooling4后面有一个1×1的卷积操作。

crop的目的:主要是全卷积时原始图像加了100×100的padding,因此卷积后的feature map会比比原图大一些,最后要把那些多余的padding裁剪掉。

2.2 skip layers

这里写图片描述
粗粒度特征和细粒度特征结合,粗粒度有利于分类,细粒度有利于定位。简要的意思就是说图片在浅层的convnet里头的位置信息是很好的,然而语义不清晰;而在深层里头的位置信息不好(像素太低),语义很清晰。实际上这也很好理解,图片的语义是由于一块“邻域”所决定的,不能只看单像素。所以语义分割图必然非常“粗糙”。所以我们需要借助前面几层的信息。FCN-8s则多借助VGG的第三层和第四层的信息,来帮助确定更精确的“位置信息”。

2.3 最开始的padding 100操作的意义

要解决这个问题,我们先来推算顺着结构推算一下:(假设是一般的VGG16结构,第一个卷积层只pad 1)。

我们假设输入图片的高度是h,根据我们的卷积公式:

conv11:h1=(h+213)/1+1=hconv12:h2=(h+213)/1+1=h

我们发现,VGG中缩小输出map只在池化层,所以下面我们忽略卷积层:
pool1:h1=(h2)/2+1=h/2pool2:h2=(h12)/2+1=h/4pool3:h3=(h22)/2+1=h/8

很明显,feature map的尺寸缩小了32倍,接下来是卷积化的fc6层,如下图:

这里写图片描述

fc6:h6=(h57)/1+1=(h192)/25,

接下来还有两个卷积化的全连接层,fc7以及score_fr,但他们都是1×1的卷积核,对输出的尺寸并不会有影响,所以最终在输入反卷积之前的尺寸就是h6!

推导到这里padding 100的作用已经很明显了,如果不进行padding操作,对于长或宽不超过192像素的图片是没法处理的,而当我们padding 100像素之后,再进行以上推导,可以得到:

h6=(h+8)/32

这样就解决了以上问题,但是毋庸置疑,这会引入很多噪声。

2.4 优缺点

2.4.1 优点

  • 可以接受任意大小的输入图像(没有全连接层)
  • 更加高效,避免了使用邻域带来的重复计算和空间浪费的问题

2.4.2 缺点

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

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

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页