来自旷世face++的一篇新颖论文,从语义分割的原理上设计了模型,读完对我理解语义分割有很大的帮助。
虽然很多人说深度学习的解释性弱,但我其实不这么看,通过ablation study和经验积累,以及grad cam等工具,研究人员已经能预先看到每个模块的作用。比如这篇DFN,就是很好的例子。
论文地址
背景
FCN-based 方法取得了很好的效果,但大部分基于此类的办法没能解决由类内不一致(intra-class inconsistency)和类间相似(inte-class indistinction)带来的问题。先看看什么是类内不一致和类间相似。
对于输入a,奶牛的身上有一块和牛身上别的位置很不协调(模型认为这块区域不该出现在牛身上),于是就把该区域判别为其他类了(第一行b),但事实上这块区域仍然属于奶牛。这就是类内不一致导致的。本来都属于一个语义label,但是因为差异性大导致模型的错误判断。
对于输入b,显示屏和主机箱形状、特征等有一定的相似之处,然后模型就把这两个不同的类别归类带一类去了,这当然也是有问题的,原因是类间的相似。类与类之间存在相似的特征,使得将语义信息不同的类别分到一类。
DFN提出两个子网络分别解决类间相似和类内不一致的问题,分别是borderNet和SmoothNet。
Border Net设计思路
Border Net为了解决相邻的不同标签的目标具有相似性导致分类到一类的问题。
我们往往使用全局信息来帮助decoder更好的分割,却忽视了类间的关系。BorderNet显示地(explictly)模型化这个类间关系,通过学习物体的边界(boundary),使得模型对于边界两边的类别能学习到更加有判别性的特征。作者认为,让模型在分割的同时,学习到物体的边界,有助于放大不同类(类间)的特征之间的区别性(distinction)
网络结构见后文。
Smooth Net设计思路
Smooth Net为了解决带有同一语义标签的目标因为局部区域的不一致导致分成多类的情况。
Smooth Net的输出即分割的logits,所以Smooth Net 是一个decoder,遵从up to bottom 设计原则。有以下特征
- 采用u-shape,融合multi-scale context。这是典型的decoder都该有的部分,但还不够
- 引入全局的信息(global context),将主干(trunk)的输出通过GAP作为image-level的特征,(和deeplabv3和v3+)一致。
- 设计了一个Channel Attention Block(CAB)融合上面两个优点。
主要贡献
- 从新的角度重新思考了语义分割的任务是什么,将语义分割视作为一类目标赋予相同的语义标签,而不是像素层次上的分类。
- 提出了DFN模型,同时解决类内不一致和类间相似的问题。
- 提出了Smooth Net来提升类内的一致性,使用CAB和global context
- 提出了bottom-up的Border Net来扩大语义边界的不相似性(区别性)
网络结构
可能有些人看到这里觉得我光用文字描述太枯燥了,到这里我就会结合图来讲解了。对照前面的文字理解,我相信同学们应该能很好理解DFN的思想和背后的原理性设计。
整体网络如下:
整体可以被分成三个部分:
- 主干使用resnet101
- 左边支路全部是RRB模块的堆叠或者并列。
- 右边支路是RRB和CAB的混合使用。
有必要解释线条颜色的不同意义:
- 绿色线代表分辨率不变
- 红色线代表上采样(UpSample)
接下来看看这两个模块
先看RRB,从主干得到的每个层次的特征都经过一个RRB,本质上就是残差结构的,至少能保证有它比没他效果好(因为是残差结构嘛,如果不能理解请参见我的另一篇文章resnet)
CAB就有些意思了,来自高级特征(路线是红色线,需要上采样)和低级特征concat之后,经过一系列的过程变成了1x1的特征图,用来做低级特征的通道选择(放大某些通道的值,抑制某些通道的值)。
注意红色是上采样,因为高级特征(high level)都经过一次上采样,所以Smooth net的输出和原图一致。
再看Border Net,是bottom-up结构,每一个stage先经过第一个RRB,之后上采样。上采样的扩张率是逐渐增大的。比如说:
三个箭头分别用1-3标号。第一个箭头的扩张倍数为2,第二个箭头的扩张倍数为4,第三个箭头的扩张倍数为8。这样,在最后的RRB的输出大小是原图的1/4倍。
方法
Border Net
Border Net用来显示地用边界label监督网络以期望能将边界两边的类的特征差异性被放大。所以它的输出是各个目标的边界logits。
这和semantic boundaries detection任务很相似。边界label的获取可以通过canny得到。
Border Net的监督使用focal loss作为损失函数
FL(pk)=?(1?pk)r×logpkFL(p_k) = - (1-p_k)^r \times logp^kFL(pk?)=?(1?pk?)r×logpk
关于focal loss可以参见我的另一篇文章focal_loss
Smooth Net
high-level的信息作为guidance送到上一个stage中,通过逐stage的方式不断refine分割的logits。
而第一个high-level信息来自于resnet最后的卷积层的输出。这个输出需要先经过1x1的conv降维,才能经过GAP,虽然论文没提,但从实现的角度上讲,这一步是必须的。
loss
ls=SoftmaxLoss(y;w)l_s = SoftmaxLoss(y;w)ls?=SoftmaxLoss(y;w)
lb=FocalLoss(y;w)l_b = FocalLoss(y;w)lb?=FocalLoss(y;w)
L=ls+λlbL = l_s+\lambda l_bL=ls?+λlb?
训练策略
对Border和Smooth的深度思考
其实语义分割和边界分割是矛盾的。为啥呢?看下图
对loss中的参数lambda增大值,就是说让网络重视对边界的学习,发现分割的效果变差了。哈哈,说明二者是conflict的关系。
那么我们下面简单分析下为啥是这样的。也和我开头强调语义分割的解释性像对应。
先看下前人的知识总结:
- 低级特征是一些线条,呈现出各种方向和不同颜色的线条。高级特征是有低级特征非线性组合得到的目标的外形或者成为轮廓
- 模型前几层(低层)对目标的细节很敏感,后几层(高层)会渐渐聚焦在目标的轮廓上。
第一条是将卷积核通过deconv或者deepdream对结果观察得到的结论。第二条则是将卷积的输出特征图可视化观察得到的结论。
高级特征富含语义信息,但也因为分辨率太小的问题,直到FCN出世,CNN才被应用到语义分割中。那么既然高级信息有很多语义信息,那么就可以使用高级特征作为guidance,结合低级的特征,提炼低级特征当中的语义信息,丢弃低级特征的很多无关的非语义信息。这不就是up-bottom结构嘛
而对于语义边界检测来说,首先边界是低级特征,但低级特征又富含很多无关的非语义特征,往往是那些人身上的褶皱,背景的图案产生的,它们不具有语义性,或者说它们属于另一个目标的子集。如果想去掉这些子集,我们需要使用富含语义信息的特征帮助我们,也就是说用high stage的特征帮助低级的边界特征,不断refine得到精确的带有语义的边界。这不是就是bottom up构嘛。
至此,说明模型结构不是想随意搭建就随意搭建的,需要按照原理原则来搭建。
觉得讲得好的同学请点赞或者留下问题。谢谢