概述
在FCN网络在2104年提出后,越来越多的关于图像分割的深度学习网络被提出,相比传统方法,这些网络效果更好,运算速度更快,已经能成熟的运用在自然图像上。语义分割显然已经是计算机视觉领域的一个热门研究领域,也是通往实现完全场景理解的道路之一,被广泛应用于无人驾驶、人机交互、医疗图像、计算摄影、图像搜索引擎、增强现实等应用领域。语义分割是像素级分类问题,将同一类物体像素点归为一类,如图所示。
主要挑战
- 池化或者卷积步长造成的特征图分辨率减小,不利于pixel-level的预测任务
- 图像中存在多尺度的目标;
- 需要利用上下文的关系(高层特征)提高预测精度
不清楚的问题:
- 错误匹配关系;
- 类别混淆;
- 类别不明显。
解决方法
-
dilated convolution;
不降低特征分辨率的同时增大感受野
图像金字塔;
-
编码解码结构;
多尺度特征
级联结构;
-
空间金字塔池化
不同大小的感受野的卷积核 捕捉多尺度的对象
FCN
https://blog.csdn.net/qq_37274615/article/details/73251503
传统的基于 CNN 的分割方法缺点
传统基于CNN的图像分割方法:为了对每一个像素点分类,将该像素点周围的一个图像块裁剪,输入到CNN进行分类
缺点:
- 存储开销大 因为有大量重复的存储
- 效率低,含有大量重复计算
- 裁剪像素块的大小限制了感受野大小,利用不到全局信息
FCN 的新思路:从抽象的全d局特征中恢复出每一个像素所属的类别。
解决了之前的效率低下和没有使用全局信息的缺点
https://blog.csdn.net/u011974639/article/details/79148719
DeepLab V1
- 网络最后两个池化层替换成d=2的卷积
- encoder高层使用空洞卷积 不可以少下采样一次 输出更加清晰
- backbone: vgg16
- 使用CRF 调整
- 使用MLP 结合多尺度特征解决 多尺度物体的问题
DeepLab v2
- 提出ASPP 解决多尺度物体的问题
- backbone: resnet
- 使用CRF调整
DeepLab v3
提出通用框架 可以使用任意backbone
-
复制resnet的block4 整出block5,6,7
- 每一个block里面三个卷积
- block5,6 stride=2
BN加入到 ASPP
-
串行并行结构的区别?
-
并行结构 承接v2的ASPP
空洞卷积的d越大,padding的zero也就越多
-
- 砍掉CRF
DeepLab v3 +
- encoder = deeplab v2
- decoder部分使用了encoder中stride=4的低层特征
代码学习
ASPP模块
某一个aspp支路
self.aspp4 = _ASPPModule(inplanes, 256, 3, padding=dilations[3], dilation=dilations[3], BatchNorm=BatchNorm)
细节: 为啥padding = dilation?
首先应该明确aspp模块的输入输出size不变,现在的卷积核大小是3,stride=1,对于大dilation的卷积核如果不padding是不可能滑行输入size那么多次的,需要padding的大小是k-1/2 这里的k指的是空洞卷积填充0之后的大小,不难看出恰好等于dilation
多支路并行
def forward(self, x):
x1 = self.aspp1(x)
x2 = self.aspp2(x)
x3 = self.aspp3(x)
x4 = self.aspp4(x)
x5 = self.global_avg_pool(x) # 强行获得全局信息
x5 = F.upsample(x5, size=x4.size()[2:], mode='bilinear')
x = torch.cat((x1, x2, x3, x4, x5), dim=1)
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
DeepLab整体框架
def forward(self, input):
x, low_level_feat = self.backbone(input)
x = self.aspp(x)
x = self.decoder(x, low_level_feat)
x = F.upsample(x, size=input.size()[2:], mode='bilinear', align_corners=True)
return x
可以看出 真个流程是 backbone
+ASPP
+decoder