DeepLab系列总结

DeepLab系列

DeepLab网络是由Liang-Chieh Chen(下文以大神指代)与google团队提出来的,是一个专门用来处理语义分割的模型。目前推出了4个(或者说3.5个)版本。最近把四个版本从头撸了一遍,做一个简单的总结。
CV解决的几类问题

DeepLab V1

DeepLab V1是基于VGG16网络改写的,一共做了三件事。

在这里插入图片描述
首先,去掉了最后的全连接层。做语义分割使用全卷积网络是大势所趋,DeepLab当然也不能例外。

然后,去掉了最后两个池化层。池化层是神经网络中的一个经典结构,没记错的话,BP解决了神经网络训练的软件问题(权重更新),pooling解决了训练的硬件问题(对计算资源的需求)。这就是池化层的第一个作用,缩小特征层的尺寸。池化层还有另一个重要作用,快速扩大感受野。为什么要扩大感受野呢?为了利用更多的上下文信息进行分析。

在这里插入图片描述
既然pooling这么好用,为什么要去掉俩呢?这个问题需要从头捋。先说传统(早期)DCNN,主要用来解决图片的分类问题,举个栗子,对于下边这张语义分割的图,传统模型只需要指出图片中有没有小轿车,至于小轿车在哪儿,不care。这就需要网络网络具有平移不变性。我们都知道,卷积本身就具有平移不变性,而pooling可以进一步增强网络的这一特性,因为pooling本身就是一个模糊位置的过程。所以pooling对于传统DCNN可以说非常nice了。
再来说语义分割。语义分割是一个end-to-end的问题,需要对每个像素进行精确的分类,对像素的位置很敏感,是个精细活儿。这就很尴尬了,pooling是一个不断丢失位置信息的过程,而语义分割又需要这些信息,矛盾就产生了。没办法,只好去掉pooling喽。全去掉行不行,理论上是可行的,实际使用嘛,一来显卡没那么大的内存,二来费时间。所以只去掉了两层。
(PS:在DeepLab V1原文中,作者还指出一个问题,使用太多的pooling,特征层尺寸太小,包含的特征太稀疏了,不利于语义分割。)

在这里插入图片描述

矛盾解决了,喜大普奔。
em……等等,好像忘了点儿啥。
哦,去了两个pooling,感受野又不够了怎么办?没关系,大神想了个办法,把atrous convolution借来用一下,这也是对VGG16的最后一个修改。atrous convolution人称空洞卷积(好像多称为dilation convolution,不过这是DeepLab的总结,那就得按DeepLab的来啊),相比于传统卷积,可以在不增加计算量的情况下扩大感受野,厉害了(?)。先上张图

在这里插入图片描述
空洞卷积与传统卷积的区别在于,传统卷积是三连抽,感受野是3,空洞卷积是跳着抽,也就是使用图中的rate,感受野一下扩大到了5(rate=2),相当于两个传统卷积,而通过调整rate可以自由选择感受野。这样感受野的问题就解决了。
另外,原文指出,空洞卷积的优势在于增加了特征的密度。盯着上边这张图我想了很久这个问题,虽然你画的密,但是卷积都是一对一的输入多大输出多大,怎么空洞卷积的特征就密了呢。~~一道闪电划过后,~~我终于想明白了,这张图你不能单独看,上边的传统卷积是经过pooling以后的第一个卷积层,而下边卷积输入的浅粉色三角正是被pooling掉的像素。所以,下边的输出是上边的两倍,特征多出了一倍当然密啦(?‍♂️)。

DeepLab V1的另一个贡献是使用条件随机场CRF提高分类精度。效果如下图,可以看到提升是非常明显的。具体CRF是什么原理呢?没有去研究,因为到了V3就舍弃了CRF。

在这里插入图片描述
最后来张DeepLab V1的全流程图,其中上采样直接使用了双线性采样。
在这里插入图片描述

DeepLab V2

在DeepLab V2中,可能是觉得VGG16表达能力有限,于是大神换用了更复杂,表达能力更强的ResNet-101。ResNet是由另一位大神Kaiming He 何恺明提出的。

在这里插入图片描述
在V2中,大神同样对ResNet动了刀,刀法和V1相同。V2的贡献在于更加灵活的使用了atrous convolution,提出了空洞空间金字塔池化ASPP。还是先给图

在这里插入图片描述
虽然名字挺复杂,但是看图就能轻易理解ASPP作用,说白了就是利用空洞卷积的优势,从不同的尺度上提取特征。这么做的原因也很简单,因为相同的事物在同一张图或不同图像中存在尺度上的差异。还是以这张图为例,图中的树存在多种尺寸,使用ASPP就能更好的对这些树进行分类。

在这里插入图片描述
至于ASPP如何融合到ResNet中,看图说话。将VGG16的conv6,换成不同rate的空洞卷积,再跟上conv7,8,最后做个大融合(对应相加或1*1卷积)就OK了。

在这里插入图片描述

DeepLab V3

说是三个贡献也不准确,姑且这么说吧。先来说最后一个,舍弃了CRF,因为分类结果精度已经提高到不需要CRF了(也可能是CRF不起作用了,谁知道呢)。

另外两个贡献,一个是改进了ASPP,另一个是使用空洞卷积加深网络,这两者算是一个二选一吧,是拓展网络的宽度,还是增加网络的深度。一般说起DeepLab V3模型指的是前者,因为从大神给出的结果和后续发展来看,明显前者效果更好一些。

对于ASPP,大神在V3中做了两点改进。一是在空洞卷积之后使用batch normalization,大神说BN对训练很有帮助。理由嘛,没有。第二点是增加了1*1卷积分支和image pooling分支。增加这两个分支是为了解决使用空洞卷积带来的问题,随着rate的增大,一次空洞卷积覆盖到的有效像素(特征层本身的像素,相应的补零像素为非有效像素)会逐渐减小到1(这里没有图全靠脑补)。这就与我们的初衷(获取更大范围的特征)相背离了。所以为了解决这个问题,一是使用1*1的卷积,也就是当rate增大以后3*3卷积的退化形式,替代3*3卷积,减少参数个数;另一点就是增加image pooling,可以叫做全局池化,来补充全局特征。具体做法是对每一个通道的像素取平均,之后再上采样到原来的分辨率。

在这里插入图片描述

ASPP的变化就这么多,再来简单说说另一种思路Going deeper with atrous convolution。为什么要加深网络呢,我理解的是为了获取更大的感受野。提到感受野自然离不开空洞卷积。还是看图说话,很显然pooling用多了特征层都快小的看不见了,所以大神给出了使用空洞卷积不断加深网络的一种思路。就这么回事儿,没啥可说的了。

在这里插入图片描述

DeepLab V3+

DeepLab V3+再次修改了主网络,将ResNet-101升级到了Xception。在原始的Xception的基础上,大神进行了三点修改:1)使用更深的网络;2)将所有的卷积层和池化层用深度分离卷积Depthwise separable convolution进行替代,也就是下图中的Sep Conv;3)在每一次3*3 depthwise convolution之后使用BN和ReLU。

因为V3+使用深度分离卷积替代了pooling,那么为了缩小特征层尺寸,有几个block的最后一层的stride就必须为2,也就是下图中标红的层。具体有几个取决于输出output stride(下采样的大小)的设置。

在这里插入图片描述
Xception的核心是使用了Depthwise separable convolution。Depthwise separable convolution的思想来自inception结构,是inception结构的一种极限情况。Inception 首先给出了一种假设:卷积层通道间的相关性和空间相关性是可以退耦合的,将它们分开映射,能达到更好的效果。在inception结构中,先对输入进行1*1的卷积,之后将通道分组,分别使用不同的3*3卷积提取特征,最后将各组结果串联在一起作为输出。
在这里插入图片描述
Depthwise separable convolution是将这种分组演化到了极致,即把每一个通道作为一组。先对输入的每一个通道做3*3的卷积,将各个通道的结果串联后,再通过1*1的卷积调整到目标通道数。

在这里插入图片描述
说了这么多,好像还没说到使用depthwise separable convolution的好处。好处也很简单,大幅缩减参数个数。幅度有多大呢?举个简单的栗子,假设输入输出都是64通道,卷积核采用3*3,那么传统卷积的参数个数为
3 ∗ 3 ∗ 64 ∗ 64 = 36864 3*3*64*64=36864 336464=36864
而Depthwise separable convolution为
3 ∗ 3 ∗ 64 + 1 ∗ 1 ∗ 64 ∗ 64 = 4672 3*3*64+1*1*64*64=4672 3364+116464=4672
只有前者的八分之一多点儿,而且通道数越多,节省的参数越多。em……很逆天。

说完了backbone,再来说说V3+的整体结构。前三个版本都是backbone(ASPP)输出的结果直接双线性上采样到原始分辨率,非常简单粗暴的方法,下图中的(a)。用了三个版本,大神也觉得这样做太粗糙了,于是吸取Encoder-Deconder的结构,下图中的(b),增加了一个浅层到输出的skip层,下图中的©。
在这里插入图片描述
下面说说具体的skip方法。首先,选取block2中的第二个卷积输出(看代码这个是固定的),使用1*1卷积调整通道数到48(减小通道数是为了降低其在最终结果中的比重),然后resize到指定的尺寸,也就是output stride。然后,将ASPP的输出resize到output stride。最后将两部分串联起来做两次3*3的卷积。最后的最后再做一次1*1的卷积,得到分类结果。最后的最后的最后将分类结果resize到原来的分辨率,嗯,还是熟悉的双线性采样。

写不动了,最后来张完整的流程图吧。
在这里插入图片描述

以上纯属个人浅见,仅供参考。

  • 96
    点赞
  • 225
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值