FCN论文笔记(看目录就知道有多详细:)

5 篇文章 0 订阅
3 篇文章 0 订阅


(标题有够中二)

FCN(Fully Convolutional Network)全卷积网络,是应用深度学习进行语义分割的开山大作!!!所以俺对于它的创新点进行了比较详细的笔记记录,可以说确实是看目录就知道了吧!

一、简介

FCN是深度学习应用在图像分割的代表作, 是一种端到端(end to end)的图像分割方法, 让网络做像素级别(pixel level)的预测直接得出label map。因为FCN网络中所有的层都是卷积层,故称为全卷积网络。
全卷积神经网络主要使用了三种技术:
1.卷积化(Convolutional)
2.上采样(Upsample)
3.跳跃结构(Skip Layer)

二、对CNN的fc层进行卷积化

FCN全称Fully Convolution Network即全卷积网络,相对CNN,即将CNN中除了Convolution层和pooling层其外的FC全连接层Fully Connected)改为卷积层

原文中将VGG16的全连接层改为1x1卷积层,该卷积层有21个通道,分别对应数据集中的21个类

引用以下一段话:

FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全联接层+softmax输出)不同,FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map进行上采样, 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时保留了原始输入图像中的空间信息, 最后在上采样的特征图上进行逐像素分类。

三、transpose convolution (deconv)(Up-sampling)

FCN没有沿用之前的插值(Interpolation)上采样方法,而是提出了新的上采样方法,即反卷积(Deconvolution)。

反卷积可以理解为卷积操作的逆运算,deconv的前向传播就是conv的反向传播。

反卷积并不能复原卷积操作造成的值的损失,它仅仅将卷积过程中的步骤反向变换一次,因此它还可以被称为转置卷积(transpose convolution)

为什么叫转置卷积(transpose convolution)呢?

因为计算时它是对卷积核作了转置!

反卷积参数: 利用卷积过程filter的转置(实际上就是水平和竖直方向上翻转filter)作为计算卷积前的特征图。

为什么是转置?

个人理解:举例!

W * X = Y

X的shape是(4,1),Y的shape是(9,1)

则W矩阵的shape是(9,4)

那么如果要从Y变到X

则需要一个(4,9)的矩阵,正好和W矩阵的转置W.T的shape是一样的

(个人认为:矩阵内值的问题暂时不用管,因为参数是可学习的)

通道在卷积层的计算公式:

output = (input - kernel_size +2 * padding)/stride + 1

则在反卷积的计算公式:

output = (input -1)xstride +kernel_size -2 * padding

四、跳跃连接skip layer(也叫特征融合,补偿前后的特征图)


注意:图中都是在VGG16基础上做的

输入图片经过了5个池化层,即5次下采样,尺寸变成原图的1/32

conv7的feature map进行了32倍的上采样到原图尺寸

2x con7代表对先对conv进行了2倍的上采样,从原图1/32到1/16

然后和pool4的feature map(原图1/16)进行特征融合(还是得到原图的1/16大小,再进行16倍的上采样到原图尺寸(比1/32的32倍上采样效果更好)

同理:conv7做4倍上采样,pool4做2倍上采样,再和pool3(1/8原图)进行特征融合(得到原图的1/8大小),然后进行8倍上采样到原图尺寸(在FCN论文里准确率是最高的,效果是比较好的)

整个网络架构图如下:

16 * 16 * 4096 ————————>16 * 16 * 21 就是通过1x1 conv改变channels数目

绿色层即pool层的feature map在跳跃连接时,先进行了1x1的卷积改变了通道数

之后还进行了crop 即裁剪

为什么要裁剪?

怕pooling的时候除不尽出现向上或向下取整,导致进行特征融合的两个feature map尺寸对不上

特征融合的时候两个feature map的尺寸必须一样!!!

跳跃连接、特征融合将原本模型的线性拓扑结构变成了环形的拓扑结构(DAG)

创新点:一定程度上解决了浅层特征信息和深层特征信息的矛盾,即浅层特征提取不够,深层特征提取虽然足够了,但损失的又太多了(feature map尺寸小就说明了损失多)

五、与传统CNN比较结果总结:

1.FCN中将全连接层替换为1 * 1卷积层,我们知道全连接层的参数是非常非常多的,这样做其实使参数的数量变少了

2.FCN进行了上采样使feature map恢复成和原图一样大小,原本的CNN只是一味的减小feature map,对于semantic segmentation任务来说不是很适用

3.原本的CNN是图像级别的网络,也就是从一张图像到结果。而FCN是end-to-end的,是pixel-wise的,标注出每个像素最可能属于哪个类别。

六、模型细节(训练技巧)(对原文做的一个总结)

1.加载预训练模型(试验了AlexNet,VGG16,VGG19,GoogleNet,后选择了VGG16)(VGG19性能和VGG16相似,但参数多了很多)

2.初始化反卷积层(采用线性插值的方式进行了初始化)

3.至少175个epoch后算法才会有不错的表现(经验之谈,经过了大量实验)

4.学习率在100个epoch之后进行调整(调参试验出来的,即一个思想:中后期学习率要调小)

5.pool3(1/8原图)之前的特征图不进行融合(实验结果表明性能不好,还反而增大了参数量和计算量)

6.训练的一些参数以及策略:

optimizer:SGD+momentum0.9

minibatch:20

学习率(VGG16):10的-4次方

还采用了Dropout防止overfitting

7.data augmentation:选择了randomly mirror随机镜像以及jittering的方式(jittering在我的另一篇博文ALexNet里有讲)

8.模型本身对比:全局fine-tuning比局部fine-tuning好70%

七、损失函数NLLLoss()

NLL loss与crossentropy是很类似的,损失函数本身表达式完全一样
但NLL loss没有自带softmax

为什么用交叉熵呢?

因为语义分割事实上还是一个分类的问题,只不过这个分类针对的并不是一张图片,而是每个像素,是对每个像素进行了分类

既然是分类问题,损失函数选择交叉熵自然没什么问题

八、数据集

数据集选用CamVid数据集(原文还采用了PASCAL VOC、NYUDv2和SIFT Flow等经典数据集)

举个例子:

data:

ground truth:

九、encode label 标签编码

读入标签之后,得到的是什么?

是像素点,每个像素点都上了色,而每个颜色对应一个类别

所以编码就是要将颜色和类别之间建立一个一对一的对应关系

例如:红色(255,0,0)对应类别0

黑色(0,0,0)对应类别1

比如读入一张100 * 100的ground truth,得到像素之后,我希望黑色的像素都是类别1,红色的像素都是类别0

即编码后的输出
[ [0 0 0 0 0 … 1 1 1 1 1 1]
[. … . ]
‘’’
[1 1 1 1 1 … 0 0 0 0 0 0]]

得到的是类别信息

我们可以将这个对应关系放在哈希表里,这样查找起来可以更加迅速

注意:在进行交叉熵计算的时候,类别信息还要进行one-hot编码

十、模型的缺点:

1.得到的结果还是不够精细。进行8倍上采样虽然比32倍的效果好了很多,但是上采样的结果还是比较模糊和平滑(尤其是边界),对图像中的细节不敏感

2.对各个像素进行分类,没有充分考虑像素与像素之间的关系(如不连续性和相似性)。忽略了在通常的基于像素分类的分割方法中使用的空间规整(spatial regularization)步骤,缺乏空间一致性

参考:

1.https://blog.csdn.net/bestrivern/article/details/89523329

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值