本文分为两个部分,第一部分详解FCN原理,第二部分给出简单的代码实现。
第一部分:算法理解
(理解FCN需要有CNN基础)
0.前言:基于CNN的分割方法与FCN的比较
传统的基于CNN的分割方法:为了对一个像素分类,使用该像素周围的一个图像块作为CNN的输入用于训练和预测。这种方法有几个缺点:
一是存储开销很大。例如对每个像素使用的图像块的大小为15x15,然后不断滑动窗口,每次滑动的窗口给CNN进行判别分类,因此则所需的存储空间根据滑动窗口的次数和大小急剧上升。
二是计算效率低下。相邻的像素块基本上是重复的,针对每个像素块逐个计算卷积,这种计算也有很大程度上的重复。
三是像素块大小的限制了感知区域的大小。通常像素块的大小比整幅图像的大小小很多,只能提取一些局部的特征,从而导致分类的性能受到限制。
而全卷积网络(FCN)则是从抽象的特征中恢复出每个像素所属的类别。即从图像级别的分类进一步延伸到像素级别的分类。
概括
FCN将传统卷积网络后面的全连接层换成了卷积层,这样网络输出不再是类别而是 heatmap;同时为了解决因为卷积和池化对图像尺寸的影响,提出使用上采样的方式恢复。
Keypoint
- 1.不含全连接层(fc)的全卷积(fully conv)网络。可适应任意尺寸输入。
- 2.增大数据尺寸的反卷积(deconv)层。能够输出精细的结果。
- 3.结合不同深度层结果的跳级(skip)结构。同时确保鲁棒性和精确性。
网络结构详解图:
输入可为任意尺寸图像彩色图像;输出与输入尺寸相同,深度为:20类目标+背景=21。
下面详细理解这三个核心思想
1.全连接层→全卷积
通常CNN网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。与经典的CNN不同,FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map进行上采样, 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时保留了原始输入图像中的空间信息, 最后在上采样的特征图上进行逐像素分类。最后逐个像素计算softmax分类的损失, 相当于每一个像素对应一个训练样本。
FCN将CNN中的全连接层用卷积层替换,全连接层和卷积层之间唯一的不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,并且不同卷积列中的神经元共享参数。然而在两类层中,神经元都是计算点积,所以它们的函数形式是一样的。因此,将此两者相互转化是可能的:
对于任一个卷积层,都存在一个能实现和它一样的前向传播函数的全连接层:权重矩阵是一个巨大的矩阵,除了某些特定块,其余部分都是零;且在其中大部分块中,元素都是相等的。
同样,任何全连接层都可以被转化为卷积层。比如,一个 K=4096 的全连接层,输入数据体的尺寸是 7∗7∗512,这个全连接层可以被等效地看做一个 F=7,P=0,S=1,K=4096 的卷积层。换句话说,就是将滤波器的尺寸设置为和输入数据体的尺寸一致了。因为只有一个单独的深度列覆盖并滑过输入数据体,所以输出将变成 1∗1∗4096,这个结果就和使用初始的那个全连接层一样了。
2.上采样-反卷积(deconvolution)
经过多次卷积和pooling以后,得到的图像越来越小,分辨率越来越低。其中图像小的一层时(下图的H/32 x W/32),所产生图叫做heatmap(热图),热图就是我们最重要的高维特征图,得到高维特征的heatmap之后就是最重要的一步也是最后的一步对原图像进行upsampling,把图像进行放大、放大、放大,到原图像的大小。最后的输出是n(类别数)个通道heatmap经过upsampling变为原图大小的图片,为了对每个像素进行分类预测label成最后已经进行语义分割的图像,通过逐个像素地求其在n个通道上该像素位置的最大数值描述(概率)作为该像素的分类,由此产生了一张已经分类好的图片。
上采样(upsampling),简单来说就是pooling的逆过程,pooling采样后数据数量减少,upsample采样后数据数量增多。FCN作者在论文中讨论了3种upsample方法(双线性插值、反卷积、反池化),最后选用的是反卷积的方法(FCN作者称其为后卷积)使图像实现end to end,可以理解upsample就是使大小比原图像小得多的特征图变大,使其大小为原图像大小。
2.1 反卷积(deconvolution)详解
众所诸知,普通的池化会缩小图片的尺寸,比如VGG16 五次池化后图片被长和宽被缩小了32倍。为了得到和原图等大的分割图,我们需要采用反卷积。
反卷积运算的参数和CNN的卷积运算的参数一样,都是在训练FCN模型的过程中通过BP算法学习得到。且都是相乘相加的运算。只不过卷积是多对一,反卷积是一对多(github上有一个项目用于演示各种卷积的动态过程)。而反卷积的前向和后向传播,只用颠倒卷积的前后向传播即可。所以无论优化还是后向传播算法都是没有问题。
2.1.1通过数学推导来理解反卷积过程:
先看卷积过程:
假设输入图像 input 尺寸为 4 x 4 ,元素矩阵为:
卷积核kernel的尺寸为3 x 3,元素矩阵为:
步长 strides = 1,填充 padding = 0 ,即 i = 4, k=3, s=1, p=0
则按照卷积计算公式 o = (i+2p-k) \ s + 1,输出图像 的尺寸为 2 x 2。
用矩阵乘法来描述卷过程:
把input和ouput展开为一个列向量:
input = X = [x1, x2, …, x16]T
output = Y = [y1, y2, y3, y4]T
对于输入的元素矩阵X和 输出的元素矩阵 Y,用矩阵运算描述这个过程:
Y = CX
通过推导,我们可以得到C为一个稀疏矩阵,其元素值为重复的kernel的元素值:
反卷积的操作就是要对这个矩阵运算过程进行逆运算,即通过 C 和 Y 得到 X ,根据各个矩阵的尺寸大小,我们能很轻易的得到计算的过程,即为反卷积的操作:
则通学习kernel(即C的参数)的参数,就可以得到我们想要的X。
** 2.1.2 反卷积的输入输出尺寸关系**
通过卷积运算的尺寸关系公式反推(把i换成o, o换成i)即可得到,反卷积的尺寸关系:
再考虑
时