语义分割的定义:对像素进行精细化的分类。
用深度学习来解决语义分割,所面临的主要问题是:
早期的深度模型用于分类,输出一维向量,无法分割
深度模型不够精细
让网络输出二维特征就可以了
如何令早期神经网络输出二维图像?
去掉全连接层。
不精细的原因是?
经过多层卷积池化,feature map的分辨率较低。
比如224*224的图像输出为7*7的feature map,很显然无法很精细
一种可行的方法就是,再把7*7给变大
具体方法就是反卷积。
由于1/32分辨率太低,直接分割很粗糙,因此先扩大再与1/16的拼在一起...(yolov3后面的思路灵感来源于此)
FCN的pytorch实现
前面就是一个常规的CNN网络,将一张图像变成feature map。而后,进行反卷积,得到原图尺寸。
层 | 输出尺寸 |
---|---|
输入图像 | 224×224 |
卷积1 | 224×224 |
池化1 | 112×112 |
卷积2 | 112×112 |
池化2 | 56×56 |
卷积3 | 56×56 |
池化3 | 28×28 |
卷积4 | 28×28 |
池化4 | 14×14 |
卷积5 | 14×14 |
反卷积6 | 224×224 |
输出 | 224×224 |
反池化和反卷积:只是把尺寸恢复了,卷积(或池化)过程中丢失的信息并没有恢复
下采样(encoding)下采样(decoding)
池化层的存在导致细节信息丢失
空间不变性(在左边、右边不对分类结果有影响)对分割任务不友好
本质上,语义分割是一种包含了低维语义特征的任务。
对于边缘、纹理、颜色等信息较为敏感。
而池化层的存在导致了这些细节信息丢失,即便进行上采样也无法恢复。
之前讨论过,池化的意义在于对信息进行浓缩,从而扩大感受野,提高信息的维度。
那么如何才能在不损失细节信息的情况下,尽量扩大感受野?
空洞卷积可以在不进行池化的前提下,尽可能地扩大感受野,从而快速提高信息的浓缩程度。
练习:计算上述模型的最终感受野
空洞卷积的优势: 扩大感受野,保存细节信息
空洞卷积的劣势: 小物体不够健壮
CNN的一个重大优势在于空间不变性。
同一个物体,在图像的不同位置,不同形态,不同角度,都应当输出相同的值。
例如,一张猫的图像,总会输出猫类别的one hot向量。
但是对于分割来说,这种空间不变形会带来不便性。
引入了fully connected CRF,从原图作为输入,结合特征图进行了优化。
CRF
CRF是一种判别模型,利用条件概率图模型建模条件概率�(�|�)完成判别任务。
也就是说,CRF是对一个条件概率进行估计。
图像分割任务的核心目的在于对每个像素都分配一个标签。
然而,由于池化卷积的处理方式,导致目标区域的边缘存在较为模糊的地方。
那么就需要CRF为边缘提供新的信息,从而得到更好的边缘。
给定一张图像:
* 定义 $X=\{X_1, X_2, ..., X_N\}$, 其中$X_i$为第i个像素的预测标签;
* 定义 $L=\{L_1, L_2, ..., L_N\}$, 其中$L_i$为第i个像素的真实标签;
* 定义 $I=\{I_1, I_2, ..., I_N\}$, 其中$I_i$为第i个像素数据。
每个像素点(RGB为向量)可以作为观测值,我们需要根据观测值为每个像素点推测出一个标签。
因此,现在主流的语义分割模型,基本都是以下框架
CRF循环多少次?多少个类别,循环多少次
然而,这种方法存在一个比较大的问题,即速度慢
速度慢的原因,主要来自于CRF。
CRF的求解复杂度较高,因此需要更长的时间来优化结果。
用训练的方式近似地求解CRF
也就是说,将CRF过程分解成一系列的卷积过程,用RNN的方式进行求解。
step2
其次,message passing步骤中,是用m个高斯滤波器在Q上滤波实现的。
相当于对feature map进行模糊处理,等价于卷积操作。
得到如下结果
step3
第三步:compatibility transform
step4
之后,进行unary potentials,即(相减)
也就是将上次结果和这次结果的增量做对比。
最后,进行归一化,采用softmax实现。
将上述视为一个RNN过程,对每一类的feature map都进行CRF处理,即可得到较优的结果。
示例代码
分割 要得到一个二维的东西,因此,将fc--->conv2d:
code
DeepLabV2是对DeeplabV1的改进,主要改进包含以下内容:
新的bottelNet
ASPP
改进的CRF
ASPP的灵感来自于SPPNet
旨在于将不同尺度的特征融合到一起
比V2的改进:
1*1卷积:减少参数,改变通道数量。
特征融合更好的方式不是直接加起来:将其concat起来然后通过1*1的卷积学习新的通道的映射参数
总体结构:r 逐步递增
60*60-->480*480:通过线性插值实现,线性插值取代了V2中的CRF