论文笔记-深度估计(2) Fully Convolutional Networks for Semantic Segmentation

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

1.介绍

该文讲述的是语义分割,但思路和框架和深度恢复是十分相似的,毕竟当前语义和深度问题本质上是一个像素级的分类问题。从该文3000+引用用量也可见该文章的巨大启发效果。

所谓全卷积网络,是指由仅由卷积层、池化层和非线性激活函数层交错组织起来的网络。

作者的贡献在于将非常热门且有效地做分类的卷积网络应用于语义分割中。整个框架是接受整张图像作为输入,用卷积做一个coarse的分类输出,然后将这些输出与每个像素联系在一起,得到最后的像素级别的语义分类结果输出。主要改进如下:
这里写图片描述

可以看出,作者将全连接层改为卷积层。
全连接层可以看成核大小为图像边长的卷积层,感知到整张图像。所以相对于全连接层,普通的核很小的的卷积层只能感知上一层中的区域信息,所谓卷积层能很好地保持空间信息(不剧烈变化),有“spatial output”,而全连接层只有“non-spatial output”。而且卷积层可以随意调整输出大小(一般是降采样,即图像变小),得到coarse 的输出。

作者分别使用了pretrained VGG,AlexNet和自己实现的GoogleNet。将上述模型后半的全连接层改为卷积层。这样这些模型就成了FCN了。再加上一个1x1x21(有21种类别)的卷积层作为预测输出,得到缩小的语义map。最后再对输出进行反卷积得到最终和原图同等大小的输出。

2.patch training 与fully convolutional training

语义分割是对每个像素x分类,假如将整个图像作为输入,那么与x所在的object距离较远的图像部分对x的分类将毫无作用。因此以前的做法是将图像分为很多块,每次epoch是随机选择整个训练集上的n个图像块作为mini batch来做一次训练。这就是所谓的“ patch training ”。而FCN的作者认为没有这种必要,直接将整张图像作为输入即可。如果patchwise 的一个batch刚好包含了价值函数所对整张图receptive filed时,即相当于输入整张图像。但patchwise的方法却不可避免每取一次batch,总会有一些图像块是有重叠的。输入整张图却可以避免patchbatch之间的重叠,这样更加高效。作者给的第二个理由是虽然在整个训练集中的patches采样虽然能减少类别之间的不平衡,缓和patch之间的空间重叠,但通过对最后输出map的价值函数进行权重和采样,也能达到这个效果。作者发现对于FCN来说,并没有必要进行分类的平衡(因为整张图片大部分都是背景)。

3.model

文章没有细说模型的价值函数,但说明是用传统的CNN进行多分类的模型,最后的价值函数是预测值与真实值的像素重叠面积对于每个像素的平均值。并且是考虑所有语义类包括背景的平均值。这其中忽略掉没有真值或真值有问题(ambiguous)的图像部分。

4.unsample

随着卷积层的预测深入,预测输出的size越来越小,为了最终得到原图每个像素对应的预测值,需要对卷积层末端的预测值进行升采样。
shift-and-stitch
假如输出o是输入i大小(本文大小一般指图像长或宽)的1/f,那么对输入图像进行缩放平移到一个大小为f的区间,然后将shifted之后的输入ii和o结合在一起作为新的输入。尽管作者认为这种方法具有输出更稠密且保持每个输出的感知区域大小的优点(也有缺点,在此不赘述),但作者仅仅是尝试了这种想法,实际上用的还是以下的升采样的方法。
backwards convolution
将图像由小变大的阶段使用转置卷积(deconvolution,backwards convolution 或transpose convolution)的方法提升输出的分辨率。转置卷积的核参数初值为线性插值,但在整个训练过程中会不断学习调整最终确定。这种转置卷积+非线性激活函数构成的升采样层,能模拟一个很好地非线性升采样映射。

Refine(Combine what and where)

一般来说,随着卷积层数的增多,每层的输出会越来越模糊,这导致了单纯通过上述的卷积网络后图像变得十分钝,分类效果不精细。为了更精细的分类,势必引入更浅(前面)层的信息。所以作者加了skip层,来融合底层的信息:
这里写图片描述
第一行中用stride为32来进行融合,第二行用stride=15来融合,第三行用stride=8来融合,也就是越偏底层,stride越小,得到的结果越精细。对第一行中通过1x1卷积得到的最右端输出结果FCN-32s(意思是需要进行32的unsample才能得到最终大小的图像),和一个卷积层conv进行stride为32的卷积,得到结果o1,同时此时pool4经过1x1核卷积处理得到o2;将o1和o2进行融合(直接加上去),最后再升采样到原始图像得到FCN-16s。以下处理类似。
这种方式极大地提升了最后的精度,UI从3提升到62。效果如下:

这里写图片描述

这样一来,如果池化的stride越小,那么浅层的输出就越精细,并非越小越好。因为这样一来,前面降采样速度下降,同等层数下后方的卷积层的核就要增大。这样对计算消耗影响太大了。

正所谓:
Global information resolve what, and local information resolve where
这句话一定要写出来:)

patch sampling

其实就是dropout。由于dropout丢弃了部分神经元,为了保持最后输出数目不变,作者同等增加了每个batch的图像数目。作者尝试了不同的dropout值,有效果上的提升但不明显,于是作者最后结论是不用它。

最后,作者的代码奉上。

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

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