DeepLab v3+ 是DeepLab语义分割系列网络的最新作,其前作有 DeepLab v1,v2, v3, 在最新作中,Liang-Chieh Chen等人通过encoder-decoder进行多尺度信息的融合,同时保留了原来的空洞卷积和ASSP层, 其骨干网络使用了Xception模型,提高了语义分割的健壮性和运行速率。其在Pascal VOC上达到了 89.0% 的mIoU,在Cityscape上也取得了 82.1%的好成绩,下图展示了DeepLab v3+的基本结构:
其实在DCNN中主要是做一个特征提取,至于采用哪个网络做backbone具体问题具体对待,在这里我才用的是mobilenetv2(只是将deepwise_conv中添加了dilation, 添加空洞卷积是为了增大感受野)
网络结构分为Encode部分和decoder部分
先看encoder部分:
接在DCNN后面的实际上就是一个ASPP结构(采用不同的采样率来对特征图做空洞卷积),然后再将对应的结果进行拼接,需要注意的是传入ASPP结构的是DCNN得到的高层特征图image Pooling部分其实会改变特征图的尺寸,所以可以通过使用双线插值(为什么采用双线插值,因为简单)或者其他方式保证经过ASPP结构的各个特征图尺寸相同,最后再进行拼接
再看decoder部分
decoder部分首先会对传入的低层特征图进行通道调整,然后与encoder传入的特征图进行拼接,注意encoder传入的特征图需要经过上采样处理(维持与低层特征图相同的尺寸),最后输出部分只需要将尺寸还原到输入图片的尺寸就行了
import torch
import torch.nn as nn
import torch.functional as F
class ASPP(nn.Module):
def __init__(self, feature, atrous):
super(ASPP, self).__init__()
self.feature = feature
self.Conv1 = _Deepwise_Conv(in_channels=feature.size()[1], out_channels=256, use_bias=False)
self.Conv_rate1 = _Deepwise_Conv(in_channels=feature.size()[1], out_channels=256, rate=atrous[0],
padding=atrous[0], use_bias=False)
self.Conv_rate2 = _Deepwise_Conv(in_channels=feature.size()[1], out_channels=256, rate=atrous[1],
padding=atrous[1], use_bias=False)
self.Conv_rate3 = _Deepwise_Conv(in_channels=feature.size()[1], out_channels=256, rate=atrous[2],
padding=atrous[2], use_bias=False)
self.globalAvgPoolAndConv = nn.Sequential(
nn.AdaptiveAvgPool2d((1, 1)),
Conv(in_channels=320, out_channels=256, kernel_size=1, stride=1, use_bias=False),
)
self.Conv4 = Conv(in_channels=256 * 5, out_channels=256, kernel_size=1, stride=1, use_bias=False)
self.dropout = nn.Dropout(p=0.1)
def forward(self):
f1 = self.Conv1(self.feature.clone())
f2 = self.Conv_rate1(self.feature.clone())
f3 = self.Conv_rate2(self.feature.clone())
f4 = self.Conv_rate3(self.feature.clone())
f5 = self.globalAvgPoolAndConv(self.feature.clone()