最近两周都在看semantic segmentation的论文,今天做一个总结,内容跟机器之心的从全卷积网络到大型卷积核:深度学习的语义分割全指南有很大的重复,我尽量多写一些细节,帮助自己更好地理解。

FCN

这是2014年加州大学伯克利的一篇工作,采用的是全卷积结构(Full Convolutional Network,FCN),此后语义分割领域很大一部分工作都采用了这一结构。模型可以采用在ImageNet上预训练过的VGG等模型,去掉全连接后再逐步进行反卷积恢复到原图像的尺寸,得到的便是最后的语义分割结果。例如,如PASCAL VOC2012中包含20种物体,模型的最后输出的便是一个21通道(20种物体加上背景)的特征图,每个特征矩阵和输入图像尺寸大小相同,其中每个值都表示原对应像素是某一类物体的概率值。

由于池化过程造成的信息丢失,上采样生成的分割图较为粗糙,论文中从高分辨率的特征图中引入跳跃连接,改善了上采样的粗糙程度,下图是模型的一个示意图。

FCN

Multi-Scale Context Aggregation by Dilated Convolutions

这是ICLR 2016上的一篇论文,该工作提出了空洞卷积的概念,可以在不增加参数的前提下让感受野呈现指数级增长,而空间维度不变,比之前的FCN的效果更好。原因在于,之前的FCN使用了池化层来增大感受野,之后又不得不通过反卷积来增大feature map的大小,这样的下采样和上采样的过程都会丢失原始图像中的部分信息。关于空洞卷积的具体介绍,这里贴出知乎上的一个答案,跟论文中的叙述差不多,还增加了其和反卷积的区别。

U-Net

U-Net的结构是基于FCN的,同时也是一种编解码结构,用于医学图像的增强,适用了小数据集。模型结构如下图所示,包含contracting path和expansive path两部分。缩小部分是典型的CNN结构。院传统CNN不同的是在放大过程中,这里会把缩小过程中对应的feature map给concatenate进来(当然,由于卷积时会丢失边界像素,因此这里需要进行crop)。最后是一个1x1的卷积层,将feature map的个数减小到应用场景需要的个数。

U-Net

DeconvNet

DeonvNet是ICCV 2015上的一篇文章,它的模型结构见下图,其和前面模型的区别在于,它的这个里边包含有两个全连接层。另外,它没有使用反卷积,而是使用了Unpooling,其示意图见下面第二章图。

DeconvNet

Unpooling

SegNet

SegNet也是一种基于编码器-解码器的结构,其和之前模型的差别在于:之前的模型在feature map缩小阶段使用了Pooling,在feature map阶段使用了反卷积进行放大;而SegNet在feature map缩小阶段使用Pooling时会将max Pooling的索引值记下来,在feature map放大阶段不再使用反卷积,而是使用前面记下来的索引值去进行放大,具体的示意见下图。这种操作跟DeconvNet中的unpooling是一样的,相当于省去了反卷积层,大大减少了模型参数,加快了计算。不过该模型的效果一般,现在已经不被使用了。

SegNet

DeepLab

DeepLab的主要贡献是使用了空洞卷积,提出了金字塔形的空洞池化(Atrous Spatial Pyramid Pooling, ASPP),且在最后的结构化预测中使用了条件随机场(Conditional Random Field, CRF)。CRF的训练和微调需要单独进行。现在越来越多的模型引入了CRF和MRF,不过我还没有搞明白二者,也不是很喜欢这样的操作。(主要是感觉需要单独处理,不是很漂亮,但是挡不住人家效果好啊)

RefineNet

该模型的编码器使用了ResNet101,解码器使用RefineNet,每个RefineNet模块都会融合相应编码器模块的高分辨率feature map和低一层RefineNet模块的低分辨率feature map。这个结构感觉很有趣,下面我会单独开一篇博客来介绍,这里只简略地贴出模型结构图。

RefineNet-1

RefineNet-2

PSPNet

该模型首先使用带空洞卷积的ResNet101将输入图像转换成1/8大小的feature map,然后喂给金字塔池化模块。金字塔池化模块包含4个不同大小的池化层,池化后分别上采样到原图像1/8大小,之后concat到一起,再经过池化、双线性插值得到与原始图像同等大小的Final prediction。另外模型在训练的时候还加入了中间监督,这在训练中很常见。模型结构见下图。不过看知乎上对PSPNet的讨论,这篇工作好像用了很多的trick,貌似比较难复现出论文中的效果。

PSPNet

Large Kernel Matters

该模型引入了全局卷积来实现大型卷积核,另外还有边界改善模块(Boundary Refinement),下面是模型结构。这是我第一次见全局卷积结构,感觉还是很有趣的,大大节省了卷积参数数量。

Semantic Segmentation using Adversarial Networks

这是FAIR在NIPS 2016上发表的一篇工作,应该是第一次使用GAN去做语义分割。

模型包含语义分割网络s(x)和辅助对抗网络a(x, y)两部分:给定一张尺寸为$H \times W \times 3$的图像,语义分割网络输出一个尺寸为$H \times W \times C$的概率map,即得到的语义分割map,其中的C是数据集中的物体种类。辅助对抗网络负责区分语义分割map是由语义分割网络得来的还是数据集真实标注的,这里我们定义$a(x, y) \in [0, 1]$来表示y是图像x的真实标注map的概率。如此以来,给定包含N张训练图像的一组数据,损失函数如下: $$l(\theta_s, \theta_a) = \sum_{n=1}^{N}l_{mce}(s(x_n), y_n) - \lambda [l_{bce}(a(x_n, y_n), 1) + l_{bce}(a(x_n, s(x_n)), 0)], \qquad \qquad \qquad \nonumber{(1)}$$ 其中$\theta_s$和$\theta_a$分别表示两个网络的参数,$l_{mce}()$和$l_{bce}()$分别表示multi-class cross-entropy loss和binary cross-entropy loss。

在训练辅助对抗网络时,我们使用下面的公式(2)作为损失函数。

$$\sum_{n=1}^{N}l_{bce}(a(x_n, y_n), 1)+l_{bce}(a(x_n, s(x_n)), 0), \qquad \qquad \qquad \nonumber{(2)}$$

在训练语义分割网络时,我们使用下面的公式(3)作为损失函数。不过,我们用$+\lambda l_{bce}(a(x_n, s(x_n)), 1)$来代替$-\lambda l_{bce}(a(x_n, s(x_n)), 0)$,这样更方便模型的训练。

$$\sum_{n=1}^{N}l_{mce}(s(x_n), y_n)-\lambda l_{bce}(a(x_n, s(x_n)), 0), \qquad \qquad \qquad \nonumber{(3)}$$

论文中使用了两个数据集,在两个数据集上使用了不同的结构。在Stanford Background dataset上论文使用了Yann Lecun的一个模型作为语义分割网络(这篇论文是2013年的,没有仔细看,感觉比较复杂,效果也不是很好),使用下图中的网络结构作为辅助对抗网络。辅助对抗网络的输入是一个label map和对应的RGB图像,这个label map要么是数据集中标注的要么是语义分割网络生成的。在Pascal VOC 2012 Dataset上使用前面介绍的dilated convolution那篇中的模型作为语义分割网络,辅助对抗网络的输入采用称为Basic、Product、Scaling的三个变种。在Basic情况下跟上面的一样;在Product情况下,用原始RGB图像去乘上label map得到3C个feature map,具体示意见下面第二张图;在Scaling情况下,所有的label按照给定公式进行计算,我没看懂,有兴趣的话自行阅读论文。模型最后的结果要优于FCN。

Semi Supervised Semantic Segmentation Using Generative Adversarial Network

这篇文章发表在ICCV 2017上,我觉得其新颖之处在于使用语义分割网络作为判别器,生成器用来生成新的训练数据,采用半监督的方式进行训练,从而提升训练效果。但是这个效果是很差的,甚至比FCN-8s还要差,感觉这篇能中应该是因为方法新颖而已。

下面我们来具体介绍一下GAN的半监督形式,其内容来源于Improved Techniques for Training GANs。考虑一个标准的K类分类器,模型对每一个输入都会输出一个K维的向量$\{l_1,...,l_K\}$,然后通过softmax转化为概率值$p_{model}(y=j|x)=\frac{exp(l_j)}{\sum_{k=1}^{K}exp(l_k)}$。在有监督学习中,模型的训练过程就是在不断最小化标注label和预测到的概率分布$p_{model}(y|x)$之间的交叉熵。现在,我们将生成器生成的样本作为一个单独的类别添加到分类器的训练中来,即现在变成K+1分类,生成数据的类别为y=K+1,$p_{model}(y=K+1|x)$表示生成数据为假的概率。现在损失函数变成了如下形式:

$$L = - E_{x,y \sim p_{data}(x,y)}[logp_{model}(y|x)]-E_{x \sim G}[logp_{model}(y=K+1|x)] = L_{supervised}+L_{unsupervised}$$

其中,

$$L_{supervised} = - E_{x,y \sim p_{data}(x,y)}logp_{model}(y|x,y \leq K)$$ $$L_{unsupervised} = -\{E_{x \sim p_{data}(x)}log[1-p_{model}(y=K+1|x)] + E_{x \sim G}log[p_{model}(y=K+1|x)]\}$$

附录

[1] Fully Convolutional Networks for Semantic Segmentation

[2] U-Net: Convolutional Networks for Biomedical Image Segmentation

[3] SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation

[4] DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs

[5] RefineNet: Multi-Path Refinement Networks for High-Resolution Semantic Segmentation

[6] Pyramid Scene Parsing Network

[7] Large Kernel Matters – Improve Semantic Segmentation by Global Convolutional Network

[8] Semantic Segmentation using Adversarial Networks

[9] Semi Supervised Semantic Segmentation Using Generative Adversarial Network