深度卷积神经网络在各类计算机视觉应用中取得了显著的成功,语义分割也不例外。这篇文章介绍了语义分割的 TensorFlow 实现,并讨论了一篇和通用目标的语义分割最相关的论文——DeepLab-v3。DeepLab-v3 是由谷歌开发的语义分割网络,近日,谷歌还开源了该系列的最新版本——DeepLab-v3+。
GitHub 地址:https://github.com/sthalles/deeplab_v3
语义分割
常规的图像分类深度卷积神经网络拥有相似的结构。这些模型以图像作为输入,并输出一个代表图像类别的数值。通常,分类深度卷积神经网络有 4 种主要运算。卷积、激活函数、池化以及全连接层。传递一张图片,通过一系列这些运算会输出一个包含每个类别标签的概率的特征向量。请注意,在这种设定下,我们是对图片的整体进行分类。也就是说,为一张图像分配一个标签。
用于图像识别的标准深度学习模型。如下图:
=====================================================
与图像分类不同的是,在语义分割中我们将对图像中的每一个像素作出分类。所以,对每个像素而言,模型需要将它归类为预定义的类别之一。换言之,语义分割是在像素级别理解图像。如下图:
请记住,语义分割不会区分目标实例。因此,如果我们有同一个类的两个目标,它们最终将具有相同的类别标签。实例分割是区分同一类实例的问题。直观理解如上图:语义分割与实例分割的区别。(中) 虽然它们是相同的目标,但它们被分类为不同的目标(实例分割)。(右) 相同的目标,相同的类别(语义分割)。
常规的深度卷积神经网络 (如 AlexNet 和 VGG ) 并不适用于密集预测的任务(而分割是逐像素级别的分类预测)。首先,这些模型包含许多用于减小输入特征的空间维度的层(致命缺点)。结果,这些层最终产生缺乏清晰细节的高度抽象的特征向量(而分割是逐像素级别的分类预测正好需要这些特征)。第二,全连接层在计算过程中具有固定的输入规模和松散的空间信息。
所以我们的分割网络一般如下:
如上图,通过一系列的卷积来传递图像,而不是使用池化和全连接层。我们将每次卷积都设置成步长为 1,padding 为「SAME」。通过这种处理,每一次卷积都保留了输入的空间维度。我们可以堆叠很多这种卷积,并最终得到一个分割模型。用于密集预测的全卷积神经网络。请注意,不存在池化层和全连接层。
这个模型可以输出形状为 [W,H,C] 的概率张量(在其形状范围内,对应c种物体的类别概率),其中 W 和 H 代表的是宽度和高度(意味着可以任意尺寸的预测其类别概率?),C 代表的是类别标签的个数。
在第三个维度上应用最大化函数会得到形状为 [W,H,1] 的张量(在c种物体类别概率里面选择最大的概率的类别,作为该形状范围内物体的类别)。然后,我们计算真实图像和我们的预测的每个像素之间的交叉熵。最终,我们对计算结果取平均值,并且使用反向传播算法训练网络。
然而,这个方法存在一个问题。正如前面所提到的,使用步长为 1,padding 为「SAME」,保留了输入的维度。但是,那样做的后果就是模型会极其耗费内存,而且计算复杂度也是很大的。
====================================
为了缓解这个问题,分割网络通常会有三个主要的组成部分:卷积层、降采样层和上采样层。如下图:图像语义分割模型的编码器-解码器结构。
卷积层那就不提了。在卷积神经网络中实现降采样的常用方式有两个:通过改变卷积步长或者常规的池化操作。一般而言,降采样的目标就是减少给定特征图的空间维度。因此,降采样可以让我们在执行更深的卷积运算时不用过多地考虑内存。然而,这样一来在计算的时候会损失一些特征。
值得注意的是,这个架构的第一部分看上去类似于普通的分类深度卷积神经网络。不同的是,其中没有设置全连接层。
在第一部分之后,我们就得到了形状为 [W, H, D] 的特征向量,其中 W,H,D 分别是特征张量的宽度、高度和深度。注意,这个压缩向量的空间维度比原始输入更加少,但是更紧致。如下图:
顶部:VGG-16 网络的原始形式。要注意的是,堆叠的卷积层的顶部有三个全连接层。底部:VGG-16 网络中用 1x1 的卷积代替全连接层。这种改变可以让网络输出粗略的热图。
此时,常规的分类深度卷积神经网络会输出一个包含每个类别概率的密集(非空间)向量。取而代之,我们将这个压缩向量输入到一系列上采样层中。这些上采样层的作用就是重建与输入维度相同的输出向量。
通常,上采样都是基于步长置换卷积(strided transpose convolution)完成的。这些函数从深而窄的层变成浅而宽的层。这里,我们使用置换卷积将特征向量的维度增加到期望的结果。
小结;
在大多数论文中,分割网络的这两个部分被称作编码器和解码器。简而言之,第一部分将信息「编码」为压缩向量来代表输入。第二部分(解码器)的作用是将这个信号重建为期望的输出。
有很多基于编码器—解码器结构的神经网络实现。FCNs、SegNet,以及 UNet 是最流行的几个。
==============================
模型架构
与大多数编码器—解码器架构设计不同的是,Deeplab 提供了一种与众不同的语义分割方法。Deeplab 提出了一种用于控制信号抽取和学习多尺度语境特征的架构。
reference:
http://tech.ifeng.com/a/20180326/44919779_0.shtml