经典语义分割(一)全卷积神经网络FCN
1 FCN网络介绍
FCN(Fully Convolutional Networks,全卷积网络) 用于图像语义分割,它是首个端对端的针对像素级预测的全卷积网络
,自从该网络提出后,就成为语义分割的基本框架,后续算法基本都是在该网络框架中改进而来,属于语义分割的开山之作。
FCN论文:https://arxiv.org/abs/1411.4038
1.1 CNN和FCN
-
通常CNN网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。例如:下图中的猫, 输入AlexNet, 得到一个长为1000的输出向量, 表示输入图像属于每一类的概率, 其中在“tabby cat”这一类统计概率最高。
-
但是这个概率信息是1维的,即只能标识整个图片的类别,不能标识每个像素点的类别,所以这种全连接方法不适用于图像分割。
-
FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。简单的来说,FCN与CNN的区别在于把于FCN将CNN最后的全连接层换成卷积层,然后再进行上采样,得到与输入大小相同的图像,然后使用softmax获得每个像素点的分类信息,从而解决了分割问题。
-
与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全联接层+softmax输出)不同,
FCN可以接受任意尺寸的输入图像
,采用反卷积层对最后一个卷积层的feature map进行上采样, 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时保留了原始输入图像中的空间信息, 最后在上采样的特征图上进行逐像素分类。 -
在下图中,输入图像经过卷积和池化之后,得到的 feature map 宽高相对原图缩小了32倍,提取特征之后"特征长方体"的宽高为原图像的 1/32,为了得到与原图大小一致的输出结果,需要对其进行上采样(upsampling),(图中最终输出的channel是 21,因为类别数是 21,每一层可以看做是原图像中的每个像素属于某类别的概率)。
注:
- FCN中采将全连接层换成卷积层可以适应不同尺度的图片。现在看来,这种转化你可能觉得不足为奇,但是大家请注意,这篇文章是2015发表的,那时候有这种思想还是非常可贵的。
- 上采样可以参考:Pytorch常用的函数(四)深度学习中常见的上采样方法总结
1.2 为何含有全连接层的网络需要固定输入图片大小
-
为何说一般含有全连接层的网络,需要固定输入图片大小?
-
一般而言,全连接层的一个神经元对应一个输入。在含有全卷积的CNN网络中,至少需要做一次flatten,假设和卷积层连接的全连接层的权重矩阵规格是(n,m),此时n=channel × w × h,而最后一个卷积层的feature map的w和h是和图片尺寸有关的。所以这种神经网络的训练和推断时的图片尺寸一般需要保持一致。
-
不过,也不是说只要有全连接层,输入的图像大小就一定要固定。固定输入图像大小的原因是:
全连接层要求固定的输入维度
。如果在卷积模块和全连接层之间加一个中间层,整理一下卷积模块的输出,就能保证不管输入图像大小怎么变,传给全连接层的始终是固定的输入。例如,在何凯明等提出的SPP(Spatial Pyramid Pooling,空间金字塔池化)中,卷积模块的输出通过SPP层,转换为固定维度的向量,然后传给之后的全连接层。
-
-
全卷积网络FCN中,输入的图像大小是可以任意的。
- 如果只有卷积层,比如要分10个类别,那么最后一个卷积层的feature map只要确保有10个channel就好了,而channel这个参数是你自己设定的和图片尺寸无关,因此输入的图像大小是可以任意的。
-
当然,除了卷积层外,还可以用别的层替换全连接层。
- 比如用
全局平均池化(Global Average Pooling)层
替换全连接层。因为全局平均池化
可以将任意h × w × d的张量(特征映射)转换为1 × 1 × d的张量,因此碰巧可以自动适应不同尺寸的输入图像。
- 比如用
2 FCN的网络架构
- FCN是一个端到端,像素对像素的全卷积网络,用于进行图像的语义分割。整体的网络结构分为两个部分:全卷积部分和上采样部分。
- 在FCN的论文中,主要给出了三种FCN的结构,分别是FCN-32,FCN-16,FCN-8s。其中,这几种网络的backbone都是基于VGG16网络,32s、16s和8s表示的是最后上采样的倍数。
2.1 FCN-32S
-
FCN-32S的网络结构如下图所示:
- 首先一张任意大小的图片经过VGG16下采样了32倍,此时特征图尺寸为h/32×w/32×512。
- 接着是三个卷积层,其对应着VGG16网络中最后三个全连接层,这样做的原因上文已经说过了,是为了使网络可以适应不同尺寸的输入,这部分结束后特征图的尺寸变为h/32×w/32×num_cls ,其中num_cls为语义分割的总类别数,对于VOC数据集来说,num_cls=21。
- 最后我们会经过一个上采样,如使用转置卷积或双线性插值算法进行上采样,将刚刚得到的特征图还原为h×w×num_cls尺寸。
-
但是FCN-32S模型的缺点是在上采样的过程中,一次性将最后的特征图上采样32倍,此时由于最后一层的特征图太小,所以在上采样的过程中会损失很多细节。
-
语义分割模型大部分都是编码-解码框架的。通过编码器不断将输入不断进行下采样达到信息浓缩(下采样),而解码器则负责上采样来恢复输入尺寸(上采样)。VGG、ResNet、MobileNet、Inception和DenseNet等,均可作为编码器,用于分割时的信息编码。
2.2 FCN-16S
下图是FCN-16S的网络结构图,它在FCN-32S的基础上增加了一个分支,这个分支的输入部分是vgg16中的第四个池化层的输出特征图。最后将两个分支的输出相加,然后进行16倍上采样,还原到原图大小。
2.3 FCN-8S
下图是FCN-8S的网络结构图,它在FCN-16S的基础上增加了一个分支,这个分支的输入部分是vgg16中的第3个池化层的输出特征图。最后将三个分支的输出相加,然后进行8倍上采样,还原到原图大小。
2.4 FCN总结
-
如果只利用反卷积对最后一层的特征图进行上采样得到原图大小的分割,由于最后一层的特征图太小,会损失很多细节。因而,FCN提出增加Skips(跳层连接结构)将最后一层的预测(有更富的全局信息)和更浅层(有更多的局部细节)的预测结合起来。
-
如果忽略部分细节,FCN-32S, FCN-16S, FCN-8S的结构可以用下图来概括:
- 对于FCN-32s,直接对pool5 feature进行32倍上采样,再对上采样后的图像的每个点做softmax 获得最终的分割图。
- 对于FCN-16s,首先对pool5 feature进行2倍上采样获得,然后再将其与pool4 feature逐点相加,最后将相加的feature进行16倍上采样,再对上采样后的图像的每个点做softmax获得最终的分割图。
- 对于FCN-8s,首先进行pool5 feature进行2倍上采样,然后再将相加后的结果与pool4 feature逐点相加,得到的结果再与经过2倍上采样后的pool3 feature 逐点相加,最后将相加后featrue进行8倍上采样,再对上采样后的图像的每个点做softmax获得最终的分割图。
- 如下图,随着上采样做得越多,分割结果越来越精细。
3 FCN相关细节
3.1 FCN的损失计算
在VOC数据集中,语义分割的GT是一张张单通道的图片(如下图所示),其尺寸为h×w×1。为什么单通道的图片可以是彩色的?它其实是有一个调色板,单通道的图片有0-255个灰度值,每一个灰度值就是一个索引,会在调色板中找到对应的颜色。
{
"0": [0, 0, 0],
"1": [128, 0, 0],
"2": [0, 128, 0],
......,
"255": [224, 224, 192]
}
比如P模式某个像素灰度值为0,则它会在调色板中找0对应的颜色,即[0, 0, 0],为黑色,即P模式下所有灰度值为0像素颜色都是黑色。
由VGG网络得到的输出尺寸为h×w×num_cls,我们会根据GT和得到的输出计算出损失LOSS,大致过程如下:
3.2 FCN缺点
- 是得到的结果还是不够精细。进行8倍上采样虽然比32倍的效果好了很多,但是上采样的结果还是比较模糊和平滑,对图像中的细节不敏感。
- 是对各个像素进行分类,没有充分考虑像素与像素之间的关系。忽略了在通常的基于像素分类的分割方法中使用的空间规整(spatial regularization)步骤,缺乏空间一致性。
FCN的理论部分就为介绍到这里了,总体来讲网络结构还是挺简单的。后面会讲解FCN源码,来对FCN有更深的理解。