Deeplabv3+概述(语义分割,小白必看)

这篇具有很好参考价值的文章主要介绍了Deeplabv3+概述(语义分割,小白必看)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

哈喽大家好 ! 我是唐宋宋宋,很荣幸与您相见!!

代码奉上:https://github.com/bubbliiiing/deeplabv3-plus-pytorch

图像分割可以分为两类:语义分割(Semantic Segmentation)和实例分割(Instance Segmentation),其区别如图所示。

Deeplabv3+概述(语义分割,小白必看)

可以看到语义分割只是简单地对图像中各个像素点分类,但是实例分割更进一步,需要区分开不同物体,这更加困难,从一定意义上来说,实例分割更像是语义分割加检测。这里我们主要关注语义分割。

语义分割使用的网络模型有很多比如pspnet,unet/unet++,deeplabv1,v2,v3,v3+,我们这里使用的是Deeplabv3+进行语义分割。

Deeplabv3+整体架构:

Deeplabv3+概述(语义分割,小白必看)

由这幅图我们可以发现,其实deeplabV3+模型仍然是两个部分,一个部分是Encoder,一个部分是Decoder

DeepLabv3+模型的整体架构如图所示,它的Encoder的主体是带有空洞卷积的DCNN,可以采用常用的分类网络如ResNet,然后是带有空洞卷积的空间金字塔池化模块(Atrous Spatial Pyramid Pooling, ASPP)),主要是为了引入多尺度信息;相比DeepLabv3,v3+引入了Decoder模块,其将底层特征与高层特征进一步融合,提升分割边界准确度。

Deeplabv3+对于Deeplabv系列的改进如下:

Deeplabv3+概述(语义分割,小白必看)
  1. 引入了对于膨胀卷积的膨胀系数。

  1. 改进了空洞空间金字塔池化

  1. 移除了条件随机场CFRs后处理,目的(精细化分割)

其实deeplabV3+与pspnet、segnet、unet相比,其最大的特点就是引入了空洞卷积,在不损失信息的情况下,加大了感受野,让每个卷积输出都包含较大范围的信息。这有利于提取多尺度信息,如下就是空洞卷积的一个示意图,所谓空洞就是特征点提取的时候会跨像素。

Deeplabv3+概述(语义分割,小白必看)

空洞卷积的目的其实也就是提取更有效的特征,所以它位于Encoder网络中用于特征提取。

接着我们先来看一下encoder。

Deeplabv3+概述(语义分割,小白必看)

可以看出来这部分由dcnn主干网络加一个aspp组成,dcnn可以使用任意一网络模型,官方使用的是resnet模型,这里我为了更轻量化使用的是基于mobilenet的deeplabv3+,由图可有看到dcnn使用的也是串行结构,然后输出的是两部分,一部分直接输出进入到decoder部分,一部分经过了aspp结构输出进行拼接,然后经过一个1*1的卷积压缩特征。

这里我们重点说一下这个ASPP模型

Deeplabv3+概述(语义分割,小白必看)

从上图我们可以看出对于Deeplabv2和Deeplabv3+ aspp的一个改进,在v2中仅仅使用了四个3*3的卷积,然后相加进行一个特征融合,而在v3中我们可以清晰的看到首先是使用了一个1*1的卷积+一个bn+一个relu 紧接着使用了3个3*3的卷积(所使用的膨胀系数也是不一样的 这里是12,24,36), 最后加一个全局平均池化(主要在于这里采用池化层来获取多尺度特征)+1*1大小的卷积+bn+relu+双线性插值来对特征进行上采样来保证特征图大小一样,(注意这里的分支特征大小都是一样规格的才可以拼接)最后对于这五个分支进行一个拼接,然后通过一个1*1的卷积 和一个随机失活进行输出。

然后我们来看一下decoder模块

Deeplabv3+概述(语义分割,小白必看)

这里的第一个下箭头是我们encoder,dcnn的输出,一个是我们通过aspp的输出,最后进行一个拼接,一个3*3的卷积和一个上采样,这里的上采样是使用双线性插值的方法,最后输出,就是这么简单。

👀👀 理论总结:

deeplabv3+的缺点:

  • 预测的feature map 直接双线性上采样16倍,到期望的尺寸,这样会 细节信息不够

deeplabv3+的特点:

  • 使用了 【encoder-decoder】(高层特征提供语义,decoder逐步恢复边界信息):提升了分割效果的同时,关注了边界的信息

  • 使用【ASPP】, 并将【深度可分离卷积(depthwise deparable conv)】应用在了ASPP 和 encoder 模块中,使网络更快

  • decoder结构:采用一个简单的模块,用于恢复目标边界细节

deeplabv3+的效果:

  • 在PASCAL VOC 2012 和 Cityscaps 数据集上获得 89.0% 和 82.1% 的分割效果,没有添加任何的后处理。

大家看一下我的代码。

dcnn模块使用的是MobileNetV2模型

class MobileNetV2(nn.Module):
    def __init__(self, downsample_factor=8, pretrained=True):
        super(MobileNetV2, self).__init__()
        from functools import partial

        model = mobilenetv2(pretrained)
        self.features = model.features[:-1]

        self.total_idx = len(self.features)
        self.down_idx = [2, 4, 7, 14]

        if downsample_factor == 8:
            for i in range(self.down_idx[-2], self.down_idx[-1]):
                self.features[i].apply(
                    partial(self._nostride_dilate, dilate=2)
                )
            for i in range(self.down_idx[-1], self.total_idx):
                self.features[i].apply(
                    partial(self._nostride_dilate, dilate=4)
                )
        elif downsample_factor == 16:
            for i in range(self.down_idx[-1], self.total_idx):
                self.features[i].apply(
                    partial(self._nostride_dilate, dilate=2)
                )

    def _nostride_dilate(self, m, dilate):
        classname = m.__class__.__name__
        if classname.find('Conv') != -1:
            if m.stride == (2, 2):
                m.stride = (1, 1)
                if m.kernel_size == (3, 3):
                    m.dilation = (dilate // 2, dilate // 2)
                    m.padding = (dilate // 2, dilate // 2)
            else:
                if m.kernel_size == (3, 3):
                    m.dilation = (dilate, dilate)
                    m.padding = (dilate, dilate)

    def forward(self, x):
        low_level_features = self.features[:4](x)
        x = self.features[4:](low_level_features)
        return low_level_features, x

ASPP特征提取模块 ,利用不同膨胀率的膨胀卷积进行特征提取,如下

class ASPP(nn.Module):
    def __init__(self, dim_in, dim_out, rate=1, bn_mom=0.1):
        super(ASPP, self).__init__()
        self.branch1 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 1, 1, padding=0, dilation=rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch2 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 3, 1, padding=6 * rate, dilation=6 * rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch3 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 3, 1, padding=12 * rate, dilation=12 * rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch4 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 3, 1, padding=18 * rate, dilation=18 * rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch5_conv = nn.Conv2d(dim_in, dim_out, 1, 1, 0, bias=True)
        self.branch5_bn = nn.BatchNorm2d(dim_out, momentum=bn_mom)
        self.branch5_relu = nn.ReLU(inplace=True)

        self.conv_cat = nn.Sequential(
            nn.Conv2d(dim_out * 5, dim_out, 1, 1, padding=0, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )

    def forward(self, x):
        [b, c, row, col] = x.size()

        #   一共五个分支

        conv1x1 = self.branch1(x)
        conv3x3_1 = self.branch2(x)
        conv3x3_2 = self.branch3(x)
        conv3x3_3 = self.branch4(x)
        # -----------------------------------------#
        #   第五个分支,全局平均池化+卷积
        # -----------------------------------------#
        global_feature = torch.mean(x, 2, True)
        global_feature = torch.mean(global_feature, 3, True)
        global_feature = self.branch5_conv(global_feature)
        global_feature = self.branch5_bn(global_feature)
        global_feature = self.branch5_relu(global_feature)
        global_feature = F.interpolate(global_feature, (row, col), None, 'bilinear', True)

        # -----------------------------------------#
        #   将五个分支的内容堆叠起来
        #   然后1x1卷积整合特征。
        # -----------------------------------------#
        feature_cat = torch.cat([conv1x1, conv3x3_1, conv3x3_2, conv3x3_3, global_feature], dim=1)
        result = self.conv_cat(feature_cat)
        return result

接着是对于这两个模型进行一个总结,我这里做了个选择 可以选择使用原始论文的xception,可以选择我使用的mobilenet

class DeepLab(nn.Module):
    def __init__(self, num_classes, backbone="mobilenet", pretrained=True, downsample_factor=16):
        super(DeepLab, self).__init__()
        if backbone == "xception":
            # ----------------------------------#
            #   获得两个特征层
            #   浅层特征    [128,128,256]
            #   主干部分    [30,30,2048]
            # ----------------------------------#
            self.backbone = xception(downsample_factor=downsample_factor, pretrained=pretrained)
            in_channels = 2048
            low_level_channels = 256
        elif backbone == "mobilenet":
            # ----------------------------------#
            #   获得两个特征层
            #   浅层特征    [128,128,24]
            #   主干部分    [30,30,320]
            # ----------------------------------#
            self.backbone = MobileNetV2(downsample_factor=downsample_factor, pretrained=pretrained)
            in_channels = 320
            low_level_channels = 24
        else:
            raise ValueError('Unsupported backbone - `{}`, Use mobilenet, xception.'.format(backbone))

        # -----------------------------------------#
        #   ASPP特征提取模块
        #   利用不同膨胀率的膨胀卷积进行特征提取
        # -----------------------------------------#
        self.aspp = ASPP(dim_in=in_channels, dim_out=256, rate=16 // downsample_factor)

        # ----------------------------------#
        #   浅层特征边
        # ----------------------------------#
        self.shortcut_conv = nn.Sequential(
            nn.Conv2d(low_level_channels, 48, 1),
            nn.BatchNorm2d(48),
            nn.ReLU(inplace=True)
        )

        self.cat_conv = nn.Sequential(
            nn.Conv2d(48 + 256, 256, 3, stride=1, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),

            nn.Conv2d(256, 256, 3, stride=1, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),

            nn.Dropout(0.1),
        )
        self.cls_conv = nn.Conv2d(256, num_classes, 1, stride=1)

    def forward(self, x):
        H, W = x.size(2), x.size(3)
        # -----------------------------------------#
        #   获得两个特征层
        #   low_level_features: 浅层特征-进行卷积处理
        #   x : 主干部分-利用ASPP结构进行加强特征提取
        # -----------------------------------------#
        low_level_features, x = self.backbone(x)
        x = self.aspp(x)
        low_level_features = self.shortcut_conv(low_level_features)

        # -----------------------------------------#
        #   将加强特征边上采样
        #   与浅层特征堆叠后利用卷积进行特征提取
        #   zykandqss
        # -----------------------------------------#
        x = F.interpolate(x, size=(low_level_features.size(2), low_level_features.size(3)), mode='bilinear',
                          align_corners=True)
        x = self.cat_conv(torch.cat((x, low_level_features), dim=1))
        x = self.cls_conv(x)
        x = F.interpolate(x, size=(H, W), mode='bilinear', align_corners=True)
        return x

最后我们可以看一下训练好的评价指标,运行代码部分的get_miou.py可以得到一些评价指标,这里可以看一下我的例子。

Deeplabv3+概述(语义分割,小白必看)

可以看到有miou,map,pre,recall各项指标。

Deeplabv3+概述(语义分割,小白必看)

感谢大家阅读!🙏🙏🙏文章来源地址https://www.toymoban.com/news/detail-434933.html

到了这里,关于Deeplabv3+概述(语义分割,小白必看)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图像分割实战-系列教程15:deeplabV3+ VOC分割实战3-------网络结构1

    有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 deeplab系列算法概述 deeplabV3+ VOC分割实战1 deeplabV3+ VOC分割实战2 deeplabV3+ VOC分割实战3 deeplabV3+ VOC分割实战4 deeplabV3+ VOC分割实战5 本项目的网络结构在network文件夹中,主要在

    2024年01月19日
    浏览(50)
  • 改进 DeepLabV3+

    CFF结构图    10.28更新(解码复习)

    2024年02月13日
    浏览(32)
  • DeepLabv3+

    本文在进行语义分割任务时将空间金字塔池化(SPP)模块或encoder-decoder结构引入到深度神经网络中。以前的网络通过对输入的feature map使用多种尺度的卷积核或者池化操作以及多种感受野能够编码出多尺度的环境信息。而之后的一些工作中提出的网络通过逐渐恢复空间信息能

    2024年02月06日
    浏览(64)
  • Docker 部署深度学习 运行deeplabV3

    本文主要介绍docker发展历史,常用的镜像,容器命令。以及部署深度学习环境,运行deeplabV3 项目。 2010年,美国一家公司dotcloud做一些pass的云计算服务,lxc有关的容器技术,他们讲自己的技术(容器化技术)命名为Docker。 刚诞生的时候,没有引起关注,然后2013年,他们讲D

    2024年01月21日
    浏览(33)
  • DeepLabV3+:ASPP加强特征提取网络的搭建

    目录 ASPP结构介绍 ASPP在代码中的构建 参考资料 ASPP:Atrous Spatial Pyramid Pooling,空洞空间卷积池化金字塔。 简单理解就是个至尊版池化层,其目的与普通的池化层一致,尽可能地去提取特征。 利用主干特征提取网络,会得到一个浅层特征和一个深层特征,这一篇主要以如何对

    2024年02月16日
    浏览(40)
  • DeepLabV3+:Mobilenetv2的改进以及浅层特征和深层特征的融合

    目录 Mobilenetv2的改进 浅层特征和深层特征的融合 完整代码 参考资料 在DeeplabV3当中,一般不会5次下采样,可选的有3次下采样和4次下采样。因为要进行五次下采样的话会损失较多的信息。 在这里mobilenetv2会从之前写好的模块中得到,但注意的是,我们在这里获得的特征是[-

    2024年01月19日
    浏览(47)
  • deeplabv3+源码之慢慢解析 第二章datasets文件夹(1)voc.py--voc_cmap函数和download_extract函数

    第一章deeplabv3+源码之慢慢解析 根目录(1)main.py–get_argparser函数 第一章deeplabv3+源码之慢慢解析 根目录(2)main.py–get_dataset函数 第一章deeplabv3+源码之慢慢解析 根目录(3)main.py–validate函数 第一章deeplabv3+源码之慢慢解析 根目录(4)main.py–main函数 第一章deeplabv3+源码之慢慢解析 根目

    2024年02月13日
    浏览(41)
  • 图神经网络:(语义分割)三维网格语义分割

    文章说明: 1)参考资料:PYG的文档。文档超链。斯坦福大学的机器学习课程。课程超链。(要挂梯子)。博客原文。原文超链。(要挂梯子)。原文理论参考文献。提取码8848。 2)我在百度网盘上传这篇文章的jupyter notebook以及预训练模型。提取码8848. 3)博主水平不高,如有错误,还

    2024年02月03日
    浏览(34)
  • 【计算机视觉 | 语义分割】干货:语义分割常见算法介绍合集(一)

    U-Net 是一种语义分割架构。 它由收缩路径和扩张路径组成。 收缩路径遵循卷积网络的典型架构。 它由两个 3x3 卷积(未填充卷积)的重复应用组成,每个卷积后跟一个修正线性单元 (ReLU) 和一个步长为 2 的 2x2 最大池化操作,用于下采样。 在每个下采样步骤中,我们将特征通

    2024年04月22日
    浏览(37)
  • 图像分割综述之语义分割

    博主的研究方向为图像分割,想顶会发一篇关于全景分割的论文,语义分割和实例分割是全景分割的必经之路。所以本人先把自己最近阅读的顶会中语义分割相关的优秀论文罗列出来,方便复习巩固,对语义分割方向有一个宏观的掌握。 目录 一、论文综述 1.1 经典分割算法

    2024年02月05日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包