Berkeley团队于2014年提出Fully Convolutional Networks(FCN)方法用于图像语义分割,将图像级别的分类扩展到像素级别的分类。
FCN可以接受任意尺寸的输入图像,采用转置卷积层对最后一个卷积层的feature map进行上采样,使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生一个预测,同时保留了原始输入图像中的空间信息,最后在上采样的特征图上进行逐像素分类。

下图,原始图片经过FCN的模型,作特征提取,最后得到的特征图会进行上采样,得到的跟原始图像尺寸相同的作为逐像素分类的输出结果(如果是计算机图像分割python算法代码 图像分割的经典算法fcn_卷积的原始图片,则最后的特征图也有10000个像素点,每个像素点都会被分类到1个类别中) 。用的VOC数据集,得到21(包括背景)个特征图,也是21个类别的概率值。每一个特征图管1个类别,预测每一个像素点属于这1类别的概率。最后把每一个像素点分类到概率最大的类别中

计算机图像分割python算法代码 图像分割的经典算法fcn_卷积_02

全卷积网络的由来

FCN将传统CNN中的全连接层转化成一个个的卷积层,使用1x1的卷积来替代全连接层

计算机图像分割python算法代码 图像分割的经典算法fcn_转置_03

卷积后再进行转置卷积

可以发现,经过多次卷积和池化以后,得到的图像越来越小,分辨率越来越低。为了从这个分辨率低的粗略图像恢复到原图的分辨率,FCN使用了上采样。例如经过5次卷积和池化以后,图像的分辨率依次缩小了2,4,8,16,32倍。对于最后一层的输出图像,需要进行32倍的上采样,才能得到原图一样的大小。

这个上采样是通过转置卷积(deconvolution)实现的。对第5层的输出转置卷积(32倍放大)到原图大小,得到的结果还是不够精确,一些细节无法恢复。

跳级连接

为了解决此问题,作者引入了跳级连接的策略;FCN-16s的含义是:首先将最后一层上采样(长宽只变大两倍,也就是跟第4次池化得到的特征图一样的尺寸)。然后和池4层的预测结合起来,最后再上采样恢复为原图大小,使网络能够更好地预测细节,同时保留高级别的语义信息;FCN-8s的含义是:同样的,具体过程可见下图

经过5次池化的特征图已经很小了(保留的信息很少),经过32倍上采样才能恢复到原始输入图像的大小,因为保留的信息很少,上采样得到特征图很粗糙(分割效果很粗糙);所以用跳级结构:

先将最后的特征图2倍上采样,得到的特征图跟第4次池化得到的特征图尺寸是一样的;这样就可以把两者数值加起来得到新的特征图;
再把新的特征图2倍上采样,再跟pool3得到的特征图累加起来得到新的特征图;
最后用上面的特征图8倍上采样,得到跟原始输入图像尺寸一样的特征图(分辨率较高,包含的信息较多,分割效果更精细),用来作预测

计算机图像分割python算法代码 图像分割的经典算法fcn_卷积_04

计算机图像分割python算法代码 图像分割的经典算法fcn_转置_05

不同上采样对比

下图是32倍,16倍和8倍上采样得到的结果的对比,可以看到它们得到的结果越来越精确(分割效果由粗糙到精细)。

计算机图像分割python算法代码 图像分割的经典算法fcn_计算机图像分割python算法代码_06

损失函数和结果预测

逐个像素计算softmax分类的损失,通过逐个像素地求其在N(分类个数)个种类中每个种类的概率,将最大概率的种类作为该像素的分类。

训练时,对每一个像素都要计算loss,100x100的图像就有10000个像素,所以计算量是很大的。

测试时也是每个像素都要分类。总之图像分割的算法速度是比较慢的。

计算机图像分割python算法代码 图像分割的经典算法fcn_池化_07


计算机图像分割python算法代码 图像分割的经典算法fcn_计算机图像分割python算法代码_08

FCN结果分析对比不同上采样方式的结果

计算机图像分割python算法代码 图像分割的经典算法fcn_计算机图像分割python算法代码_09

对比不同上采样方式的结果
FCN-32s-fixed只微调Vgg16最后1层的权值,直接32倍上采样,其结果也是最差的;
FCN-32s微调Vgg16整个网络的权值,直接32倍上采样,结果比FCN-32s-fixed好了挺多;

FCN-8s在最后的特征图作2倍的上采样,再跟第4个池化的输出结合起来,进行2倍的上采样,最后跟第3个池化的输出结合起来,进行8倍的上采样。其结果是最好的。

其实作者也进行过FCN-4s,试验结果没有FCN-8s好。

用500×500 input 在 NVIDIA Tesla K40c 上测试了不同的网络结构

计算机图像分割python算法代码 图像分割的经典算法fcn_转置_10