FCN(Fully Convolutional Network)全卷积网络笔记
本文只是个人学习笔记
参考自:
全卷积网络FCN详细讲解(超级详细哦)
转置卷积(Transposed Convolution)
一、FCN讲解
1.1 FCN与CNN的区别
CNN:CNN就是卷积神经网络,在最后的卷积层之后会连接上若干个全连接层,将卷积层产生的特征图(feature map)映射成为一个固定长度的特征向量。
FCN: FCN是对图像进行像素级的分类(也就是每个像素点都进行分类),从而解决了语义级别的图像分割问题。与上面介绍的经典CNN在卷积层使用全连接层得到固定长度的特征向量进行分类不同,FCN可以接受任意尺寸的输入图像,**采用反卷积层对最后一个卷积层的特征图(feature map)进行上采样,使它恢复到输入图像相同的尺寸,**从而可以对每一个像素都产生一个预测,同时保留了原始输入图像中的空间信息,最后在上采样的特征图进行像素的分类。
两者区别:FCN和CNN的区别就是,FCN将CNN最后的全连接层也换成了卷积层,其输出是一张已经标记好的图,而不是一个概率值。
1.2 FCN如何进行上采样
为什么要进行上采样: FCN网络一般是用来对图像进行语义分割的,于是就需要对图像上的各个像素进行分类,这就需要一个上采样将最后得到的输出上采样到原图的大小。上采样对于低分辨率的特征图,常常采用上采样的方式将它还原高分辨率,以下是上采样的三种方法。
1.2.1 双线性插值上采样
单线性插值(一个方向上)就是知道两个点的值,并将两点连成一条直线,来确定中间的点的值。是一个二维的坐标系。
相当于是求正方形主对角线上的点的值。
所以双线性插值(两个方向上)是一个三维的坐标系,因此需要找到4个点来确定中心点坐标,相当于是求正方体的主对角线上的点的值。我暂时没明白,详看这篇博客。
1.2.2 转置卷积上采样(也称为反卷积)
普通的卷积:会降低分辨率,提取特征,如下图33的卷积核卷积一个44的特征图得到2*2的输出。
而转置卷积上采样会使得分辨率提高,当然转置卷积也是卷积操作,不是卷积的逆运算。
转置卷积的运算步骤可以归为以下几步:
1、在输入特征图元素间填充s-1行、列(其中s表示转置卷积的步距)
2、在输入特征图四周填充k-p-1行、列(其中k表示转置卷积的kernel_size大小,p为转置卷积的padding,注意这里的padding和卷积操作中有些不同)
3、将卷积核参数上下、左右翻转
4、做正常卷积运算(填充0,步距1)
下面假设输入的特征图大小为2x2(假设输入输出都为单通道),通过转置卷积后得到4x4大小的特征图。这里使用的转置卷积核大小为k=3,stride=1,padding=0的情况(忽略偏执bias)。
1、首先在元素间填充s-1=0行、列(等于0不用填充)
2、然后在特征图四周填充k-p-1=2行、列
3、接着对卷积核参数进行上下、左右翻转
4、最后做正常卷积(填充0,步距1)
下图展示了转置卷积中不同s和p的情况:
![]() | ![]() | ![]() |
---|---|---|
s=1, p=0, k=3 | s=2, p=0, k=3 | s=2, p=1, k=3 |
转置卷积操作后特征图的大小可以通过如下公式计算:
其中stride[0]表示高度方向的stride,padding[0]表示高度方向的padding,kernel_size[0]表示高度方向的kernel_size,索引[1]都表示宽度方向上的。通过上面公式可以看出padding越大,输出的特征矩阵高、宽越小,你可以理解为正向卷积过程中进行了padding然后得到了特征图,现在使用转置卷积还原到原来高、宽后要把之前的padding减掉。
更多关于转置卷积的操作见转置卷积(Transposed Convolution)
1.2.3反池化上采样
反池化可以用下图来理解,再池化时需要记录下池化的位置,反池化时把池化的位置直接还原,其他位置填0。
上面三种方法各有优缺,双线性插值方法实现简单,无需训练;反卷积上采样需要训练,但能更好的还原特征图。
1.3 FCN具体实现过程
FCN与CNN的核心区别就是FCN将CNN末尾的全连接层转化成了卷积层:以Alexnet为例,输入是2272273的图像,前5层是卷积层,第5层的输出是256个特征图,大小是66,即25666,第6、7、8层分别是长度是4096、4096、1000的一维向量。如下图所示:
在FCN中第6、7、8层都是通过卷积得到的,卷积核的大小全部是1 * 1,第6层的输出是4096 * 7 * 7,第7层的输出是4096 * 7 * 7,第8层的输出是1000 * 7 * 7(7是输入图像大小的1/32),即1000个大小是77的特征图(称为heatmap),如下图所示:
经过多次卷积后,图像的分辨率越来越低,为了从低分辨率的热图heatmap恢复到原图大小,以便对原图上每一个像素点进行分类预测,需要对热图heatmap进行反卷积,也就是上采样。论文中首先进行了一个上池化操作,再进行反卷积(上述所提到的上池化操作和反卷积操作,其实可以理解为上卷积操作),使得图像分辨率提高到原图大小。如下图所示:
跳级(strip)结构:对第5层的输出执行32倍的反卷积得到原图,得到的结果不是很精确,论文中同时执行了第4层和第3层输出的反卷积操作(分别需要16倍和8倍的上采样),再把这3个反卷积的结果图像融合,提升了结果的精确度:
1.4 FCN模型实现过程
1.4.1 模型训练
-
用AlexNet,VGG16或者GoogleNet训练好的模型做初始化,在这个基础上做fine-tuning,只需在末尾加上upsampling,参数的学习还是利用CNN本身的反向传播原理。
-
采用全图做训练,不进行局部抽样。实验证明直接用全图已经很高效。
FCN例子: 输入可为任意尺寸图像彩色图像;输出与输入尺寸相同,深度为:20类目标+背景=21,模型基于AlexNet。 -
蓝色:卷积层
-
绿色:Max Pooling层。
-
黄色: 求和运算, 使用逐数据相加,把三个不同深度的预测结果进行融合:较浅的结果更为精细,较深的结果更为鲁棒。
-
灰色: 裁剪, 在融合之前,使用裁剪层统一两者大小, 最后裁剪成和输入相同尺寸输出。
-
对于不同尺寸的输入图像,各层数据的尺寸(height,width)相应变化,深度(channel)不变。
-
全卷积层部分进行特征提取, 提取卷积层(3个蓝色层)的输出来作为预测21个类别的特征。
-
图中虚线内是反卷积层的运算, 反卷积层(3个橙色层)可以把输入数据尺寸放大。和卷积层一样,升采样的具体参数经过训练确定。
1、以经典的AlexNet分类网络为初始化。最后两级是全连接(红色),参数弃去不用。
2、 第一次反卷积(橙色)的步长为32,这个网络称为FCN-32s
从16164096用11卷积成1616*21的特征图,之后直接上采样成大图。
3、 第二次反卷积步长为16,这个网络称为FCN-16s
上采样分为两次完成(橙色×2), 在第二次升采样前,把第4个pooling层(绿色)的预测结果(蓝色)融合进来。使用跳级结构提升精确性。
4、 第三次反卷积步长为8,记为FCN-8s。
升采样分为三次完成(橙色×3), 进一步融合了第3个pooling层的预测结果。
总体来说,本文的逻辑如下: -
想要精确预测每个像素的分割结果
-
必须经历从大到小,再从小到大的两个过程
-
在升采样过程中,分阶段增大比一步到位效果更好
-
在升采样的每个阶段,使用降采样对应层的特征进行辅助
1.4.2 实例
现在我们有1/32尺寸的heatMap,1/16尺寸的featureMap和1/8尺寸的featureMap。
1/32尺寸的heatMap进行upsampling操作之后,因为这样的操作还原的图片仅仅是conv5中的卷积核中的特征,限于精度问题不能够很好地还原图像当中的特征,因此在这里向前迭代。
把conv4中的卷积核对上一次upsampling之后的图进行反卷积补充细节。
最后把conv3中的卷积核对刚才upsampling之后的图像进行再次反卷积补充细节,最后就完成了整个图像的还原。