精华内容
下载资源
问答
  • 2021-11-19 20:15:34
    更多相关内容
  • pytorch-deeplab-xception 于2018/12/06更新。 提供在VOC和SBD数据集上训练的模型。 于2018/11/24更新。 发布最新版本的代码,该代码可以解决一些以前的问题,并增加对新主干和多GPU培训的支持。 有关以前的代码,...
  • deeplab-v3-plus网络结构,利用该网络结构可以实现语义分割,分割普通影像或者遥感影像。
  • 完整工程案例:深度学习Tensorflow 图像语义分割(Image Segmentation)DeepLab基于ResNet101模型(tensorflow1.1以上、python3.5及以上)
  • 我不会回答问题,但会合并PR DeepLab是用于语义图像分割的最先进的深度学习模型。 模型基于原始的TF冻结图。 可以将预训练的权重加载到此模型中。 权重直接从原始TF检查点导入。 原始TF模型的分割结果。 输出步幅...
  • 用卷积滤波器matlab代码DeepLab v2 介绍 DeepLab是基于的最先进的深度学习系统,用于语义图像分割。 它结合了(1)粗糙卷积以显式控制深度卷积神经网络中计算特征响应的分辨率;(2)粗糙空间金字塔池,以多个采样率...
  • https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/model_zoo.md 中有许多个模型。 先下一个试试效果如何:...
  • 针对这个问题,把Deeplab V3+模型的骨干网(ResNet101)的瓶颈单元设计为1D非瓶颈单元,且对空洞空间金字塔池化模块(Atrous Spatial Pyramid Pooling,ASPP)的卷积层进行分解.该算法能大幅度降低Deeplab V3+网络的...
  • 用卷积滤波器matlab代码训练DeepLab进行语义图像分割 马丁·科斯纳(Martin Kersner), 该存储库包含用于使用和进行培训的脚本。 和论文分别描述了使用强注释数据和弱注释数据的训练过程。 git clone --recursive ...
  • 从,我们可以了解Deeplab v3 +的详细信息()。 提供了四个pre_train模型。 使用Mibilenetv2作为特征exstractor根据(上运行 ),我在给予tensorflow分割演示 。 这些代码是pytorch上的mobiletv2_deeplab_v3的...
  • deeplab-demo 使用Deeplab进行图像分割 @article {deeplabv3plus2018,title = {具有Atrous可分离卷积的编码器-解码器进行语义图像分割},作者= {Liang-Chieh Chen和Yukun Zhu和George Papandreou和Florian Schroff...
  • 使用PyTorch的DeepLab非官方实现,可在COCO-Stuff 10k数据集上训练DeepLab v2(ResNet-101)。 DeepLab是用于语义图像分割的CNN架构之一。 COCO Stuff 10k是带有PyTorch的DeepLab的语义分割数据这是带有ResNet-101...
  • Axial-DeepLab(ECCV 2020,聚光灯) 这是正在进行的PyTorch重新实现。重新实现主要是由一位了不起的高中生。 @inproceedings { wang2020axial , title = { Axial-DeepLab: Stand-Alone Axial-Attention for ...
  • DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs
  • deeplab-resnet.pth.tar

    2020-07-31 07:14:26
    resnet26训练实例分割模型,用于overhaul distillation模型教师网络训练 resnet26训练实例分割模型,用于overhaul distillation模型教师网络训练
  • 目标分割DeepLab v1讲解

    2021-01-06 17:54:58
    目标分割DeepLab v1ABSTRACT1、 INTRODUCTION2、 RELATED WORK3、 CONVOLUTIONAL NEURAL NETWORKS FOR DENSE IMAGE LABELING3.1 利用空洞算法实现高效的密集滑动窗口特征提取3.2 利用卷积网控制感受野大小,加速密集...
  • 遥感影像分类是模式识别技术在遥感领域的具体应用,针对普通卷积神经网络处理遥感图像分类遇到的边缘分类不准确、分类精度低等问题,提出了一种基于编码解码器的空洞卷积模型(DeepLab-v3+)的遥感图像分类方法。...
  • 用卷积滤波器matlab代码DeepLab v2 介绍 DeepLab是基于的最先进的深度学习系统,用于语义图像分割。 它结合了(1)粗糙卷积以显式控制深度卷积神经网络中计算特征响应的分辨率;(2)粗糙空间金字塔池,以多个采样率...
  • 从官网下载的Deeplab-v2中vgg和resnet的模型文件,包括caffemodel以及prototxt
  • 用卷积滤波器matlab代码DeepLab v2 介绍 DeepLab是基于的最先进的深度学习系统,用于语义图像分割。 它结合了(1)粗糙卷积以显式控制深度卷积神经网络中计算特征响应的分辨率;(2)粗糙空间金字塔池,以多个采样率...
  • Deeplab 系列文章

    2020-10-24 13:18:58
    语义分割论文总结, 将最近几年发表的相关语义分割的论文进行整理,便于学习。 语义分割可以认为是像素级别的分类,能力要求更大,需要涉及知识面更多更广。
  • deeplab 官方PPT

    2018-07-22 19:50:12
    deeplab 官方PPT
  • 用卷积滤波器matlab代码DeepLab v2 介绍 DeepLab是基于的最先进的深度学习系统,用于语义图像分割。 它结合了(1)粗糙卷积以显式控制深度卷积神经网络中计算特征响应的分辨率;(2)粗糙空间金字塔池,以多个采样率...
  • keras-deeplab-v3-plus-master_deeplab_v3plus_遥感_分割_遥感语义分割_遥感分割.zi
  • win图像语义分割实用程序,由《model_zoo.md》中的模型《mobilenetv2_dm05_coco_voc_trainaug》改编而成。
  • Deeplab v2

    2017-11-13 17:00:29
    deeplab-v2 基于vgg训练自己的数据的prototxt 和cityscapes的prototxt
  • 文章目录预备知识空洞卷积:1、DeepLab V11.1 基于VGG模型1.2 总体架构1.2.1 Fully Connected CRF(条件随机场)1.3 DeepLab V1的思考 预备知识 空洞卷积: 参考我之前写的博客: CSDN链接 空洞卷积详解 1、DeepLab ...

    预备知识

    空洞卷积

    参考我之前写的博客:
    CSDN链接 空洞卷积详解

    1、DeepLab V1

    其他图像分割模型如FCN和U-Net都使用了反卷积和pooling保持分别率不变,而只使用空洞卷积就可以实现反卷积和pooling的效果,而且空洞卷积还具有可学习的优点。

    1.1 基于VGG模型

    在这里插入图片描述
    1、以VGG模型为基础,因为想利用VGG模型预训练的参数;
    2、去除掉最后2个max pooling,并使用空洞卷积保持感受野一致,空洞卷积使用在原VGG模型最后2个max pooling之间;
    3、最后3个FC层都换成3×3的卷积,所以输出feature size为28×28;
    4、第3步使用3×3 的卷积输出的通道数换成1024,不影响效果而且也增加速度;

    1.2 总体架构

    在这里插入图片描述
    1、基于VGG模型修改的结构在上图的第一行已完成;
    2、第四步是对基于VGG修改模型输出的结果进行双线性插值,增加8倍还原成原feature size的大小;
    3、使用了Fully Connected CRF(条件随机场)

    1.2.1 Fully Connected CRF(条件随机场)

    公式:
    在这里插入图片描述
    其中:
    在这里插入图片描述
    解释: 图像分割是对每一个像素点进行分类,而每一个像素之间的分类是有联系的,所以用到了条件随机场。优化 E ( x ) E(x) E(x),使其最小,所以可以使用梯度下降法来优化。

    E ( x ) E(x) E(x):优化 E ( x ) E(x) E(x)使其最小;
    θ i ( x i ) \theta_i(x_i) θi(xi):仔细看就会发现如果 P ( x i ) P(x_i) P(xi)越大则 θ i ( x i ) \theta_i(x_i) θi(xi)越小;
    ∑ i θ i ( x i ) \sum_{i}\theta_i(x_i) iθi(xi):是各个像素概率的联合概率分布;
    θ i , j ( x i , x j ) \theta_{i,j}(x_i,x_j) θi,j(xi,xj):是衡量像素与像素之间的概率分布;
    ∣ ∣ p i − p j ∣ ∣ 2 ||p_i-p_j||^2 pipj2:像素之间的距离;
    ∣ ∣ I i − I j ∣ ∣ 2 ||I_i-I_j||^2 IiIj2:像素之间的灰度值;
    σ \sigma σ:正态分布相关的参数;
    ω \omega ω:待优化的参数;

    1.3 DeepLab V1模型实验

    在这里插入图片描述
    总结:
    1、增加CRF、通过设置较大的dilation增加感受野、以及多尺度输入可增加模型的效果;
    2、所以根据上面所做的增加模型效果的实验,就诞生了DeepLab V2。


    在这里插入图片描述
    总结:
    根据第一行和最后一行可知:在3*3的kernel size下,增加stride可增加模型的效果,而且还减少了参数量。


    2、DeepLab V2

    与V1版本的区别就是引入了ASPP,结合V1所做的实验,增加多尺度训练和较大的感受野可增加mIOU;
    在这里插入图片描述
    步骤:
    1、对输入的feature map进行分组空洞卷积,rate为(6,12,18,24),此对应多尺度输入;
    2、通过padding,使各个组输出的feature size与输入相同;
    3、对各个组输出的feature map进行sum;
    ASPP code:

    import torch
    from torch._C import Size
    import torch.nn as nn
    import torch.nn.functional as F
    
    
    class ASPP(nn.Module):
        """
        空洞空间金字塔池化(Atrous Spatial Pyramid Pooling)在给定的输入上以不同采样率(dilation)的空洞卷积
        并行采样,相当于以多个比例捕捉图像的上下文。
        """
    
        def __init__(self, in_chans, out_chans, rate=1):
            super(ASPP, self).__init__()
            # 以不同的采样率预制空洞卷积(通过调整dilation实现)
            # 1x1卷积——无空洞
            self.branch1 = nn.Sequential(
                nn.Conv2d(in_chans, out_chans, 1, 1, padding=0, dilation=rate, bias=True),
                nn.BatchNorm2d(out_chans),
                nn.ReLU(inplace=True)
            )
            # 3x3卷积——空洞6
            self.branch2 = nn.Sequential(
                nn.Conv2d(in_chans, out_chans, 3, 1, padding=6 * rate, dilation=6 * rate, bias=True),
                nn.BatchNorm2d(out_chans),
                nn.ReLU(inplace=True)
            )
            # 3x3卷积——空洞12
            self.branch3 = nn.Sequential(
                nn.Conv2d(in_chans, out_chans, 3, 1, padding=12 * rate, dilation=12 * rate, bias=True),
                nn.BatchNorm2d(out_chans),
                nn.ReLU(inplace=True)
            )
            # 3x3卷积——空洞18
            self.branch4 = nn.Sequential(
                nn.Conv2d(in_chans, out_chans, 3, 1, padding=18 * rate, dilation=18 * rate, bias=True),
                nn.BatchNorm2d(out_chans),
                nn.ReLU(inplace=True)
            )
            # 全局平均池化——获取图像层级特征,image pooling,
            self.branch5_avg = nn.AdaptiveAvgPool2d(1)  # 1:输出为1*1
            # 1x1的conv、bn、relu——用于处理平均池化所得的特征图
            self.branch5_conv = nn.Conv2d(in_chans, out_chans, 1, 1, 0, bias=True)
            self.branch5_bn = nn.BatchNorm2d(out_chans)
            self.branch5_relu = nn.ReLU(inplace=True)
            # 1x1的conv、bn、relu——用于处理concat所得的特征图
            self.conv_cat = nn.Sequential(
                nn.Conv2d(out_chans * 5, out_chans, 1, 1, padding=0, bias=True),
                nn.BatchNorm2d(out_chans),
                nn.ReLU(inplace=True)
            )
    
        def forward(self, x):
            # 获取size——用于上采样的时候确定上采样到多大
            b, c, h, w = x.size()
            # 一个1x1的卷积
            conv1x1 = self.branch1(x)
            # 三个3x3的空洞卷积
            conv3x3_1 = self.branch2(x)
            conv3x3_2 = self.branch3(x)
            conv3x3_3 = self.branch4(x)
            # 一个平均池化
            global_feature = self.branch5_avg(x)
            # 对平均池化所得的特征图进行处理
            global_feature = self.branch5_relu(self.branch5_bn(self.branch5_conv(global_feature)))
            # 将平均池化+卷积处理后的特征图上采样到原始x的输入大小
            global_feature = F.interpolate(global_feature, (h, w), None, 'bilinear', True)
            # 把所有特征图cat在一起(包括1x1、三组3x3、平均池化+1x1),cat通道的维度
            feature_cat = torch.cat([conv1x1, conv3x3_1, conv3x3_2, conv3x3_3, global_feature], dim=1)
            # 最后再连一个1x1卷积,把cat翻了5倍之后的通道数缩减回来
            result = self.conv_cat(feature_cat)
            return result
    
    

    2.1 整体架构

    在这里插入图片描述

    2.2 训练策略

    在这里插入图片描述
    总结:
    通过调小batch size和增加训练的epoch可增加mIOU。

    2.2.1 学习率的调整

    随着训练epoch的增加,学习率应作适当减小,所以V2提出新的学习率的策略,公式为:
    l r = l r ⋅ ( 1 − i t e r m a x _ i t e r ) p o w e r lr = lr\cdot(1-\frac{iter}{max\_iter})^{power} lr=lr(1max_iteriter)power

    其中原论文 p o w e r power power设置的是:0.9;


    3、DeepLab V3

    DeepLab V3有cascade和parallel两种的形式,先介绍cascade;

    3.1 cascade形式的DeepLab V3

    在这里插入图片描述
    重要点:
    1、output stride:输出的feature map为原输入的多少分之一,如:为 1 / 4 , 1 / 8 , 1 / 16 1/4,1/8,1/16 1/41/81/16
    2、通过做实验,output stride越大效果越不好,所以cascade形式采用下面一种;
    3、 b l o c k 1 , 2 , 3 , 4... block_{1,2,3,4...} block1,2,3,4...为resnet50的block;
    如何避免输出图片栅格化:
    1、因为空洞卷积只涉及block4中的3×3的卷积,为了避免栅格化所以设置dilation rate为1,2,4,不能设置为同一个值;
    2、上图中的rate的意思是: r a t e ⋅ ( 1 , 2 , 4 ) rate \sdot(1,2,4) rate(1,2,4)


    resnet

    3.2 parallel形式的DeepLab V3

    在这里插入图片描述
    因为在cascade模型中,网络做的太深效果反而出现下降,所以就引用了ASPP。


    4、DeepLab V3+

    在这里插入图片描述
    改进点:
    1、借鉴了Encode和Decode的结合,进行了特征的concat;
    2、使用了Modified Xception;
    3、使用了深度可分离空洞卷积(Depthwise Separable Convolution);

    4.1 深度可分离空洞卷积

    在这里插入图片描述
    先说一下什么是Depthwise Convolution,它就是先对输入的feature map的每一个通道进行卷积,如果输入的feature map为 D F ⋅ D F ⋅ M D_F\sdot D_F\sdot M DFDFM,输出的feature map仍为 D F ⋅ D F ⋅ M D_F\sdot D_F\sdot M DFDFM,然后再进行 1 ∗ 1 ∗ M ∗ N 1 * 1 * M * N 11MN的卷积,Operations的计算如上图,所以通过Depthwise Convolution后减少了计算量。

    4.2 Modified Xception

    在这里插入图片描述
    总结
    1、类似于resnet,但与resnet有很大的不同;
    2、Modified Xception使用了Depthwise Separable Convolution;
    DeepLab V3+ 代码:

    """
    Attention:需要把上一个ASPP的代码和当前的代码放在同一目录下
    """
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.utils.model_zoo as model_zoo
    
    bn_mom = 0.0003
    
    # 预先训练模型地址
    model_urls = {
        'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
        'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
        'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
        'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth'
    }
    
    
    # same空洞卷积
    # 对于k=3的卷积,通过设定padding=1*atrous,保证添加空洞后的3x3卷积,输入输出feature map同样大小
    def conv3x3(in_planes, out_planes, stride=1, atrous=1):
        """3x3 convolution with padding"""
        return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
                         padding=1 * atrous, dilation=atrous, bias=False)
    
    
    # 通过 same 空洞卷积实现BasicBlock
    class BasicBlock(nn.Module):
        expansion = 1
    
        def __init__(self, in_chans, out_chans, stride=1, atrous=1, downsample=None):
            super(BasicBlock, self).__init__()
            # 使用自定义的same 空洞卷积
            self.conv1 = conv3x3(in_chans, out_chans, stride, atrous)
            self.bn1 = nn.BatchNorm2d(out_chans)
            self.relu = nn.ReLU(inplace=True)
    
            self.conv2 = conv3x3(out_chans, out_chans)
            self.bn2 = nn.BatchNorm2d(out_chans)
            self.downsample = downsample
            self.stride = stride
    
        def forward(self, x):
            residual = x
    
            out = self.conv1(x)
            out = self.bn1(out)
            out = self.relu(out)
    
            out = self.conv2(out)
            out = self.bn2(out)
    
            if self.downsample is not None:
                residual = self.downsample(x)
    
            out += residual
            out = self.relu(out)
    
            return out
    
    
    # 实现带有空洞卷积的Bottleneck
    # 这个bottleneck结构,
    # 在resnet 50的block1中串连使用了3个,block2中串连使用了4个,block3中串连使用了6个,block4中串连使用了3个。
    # 在resnet 101的block1中串连使用了3个,block2中串连使用了4个,block3中串连使用了24个,block4中串连使用了3个。
    # 在resnet 152的block1中串连使用了3个,block2中串连使用了8个,block3中串连使用了36个,block4中串连使用了3个。
    # 所以,当我们定block1,block2,block3,block4分别为[3,4,6,3]时,就对应resnet50
    # 所以,当我们定block1,block2,block3,block4分别为[3,4,24,3]时,就对应resnet101
    # 所以,当我们定block1,block2,block3,block4分别为[3,8,36,3]时,就对应resnet152
    
    class Bottleneck(nn.Module):
        # bottleneck block中,有三个卷积层,分别是:C1:1x1conv,C2:3x3conv,C3:1x1conv
        # C1的输入featue map 的channel=4C,输处feature map 的channel=C
        # C2的输入featue map 的channel=C,输处feature map 的channel=C
        # C3的输入featue map 的channel=C,输处feature map 的channel=4C
        # expansion:定义瓶颈处的feature map,C2的输入输出feature map 的 channel是非瓶颈处的channel的1/4
        expansion = 4
    
        def __init__(self, in_chans, out_chans, stride=1, atrous=1, downsample=None):
            super(Bottleneck, self).__init__()
            # 这里in_chans是out_chans的4倍,在make_layer函数里有实现,大概在本代码164行左右
            self.conv1 = nn.Conv2d(in_chans, out_chans, kernel_size=1, bias=False)
            self.bn1 = nn.BatchNorm2d(out_chans)
            # same空洞卷积
            self.conv2 = nn.Conv2d(out_chans, out_chans, kernel_size=3, stride=stride,
                                   padding=1 * atrous, dilation=atrous, bias=False)
            self.bn2 = nn.BatchNorm2d(out_chans)
            self.conv3 = nn.Conv2d(out_chans, out_chans * self.expansion, kernel_size=1, bias=False)
            self.bn3 = nn.BatchNorm2d(out_chans * self.expansion)
            self.relu = nn.ReLU(inplace=True)
            self.downsample = downsample
            self.stride = stride
    
        def forward(self, x):
            residual = x
    
            out = self.conv1(x)
            out = self.bn1(out)
            out = self.relu(out)
    
            out = self.conv2(out)
            out = self.bn2(out)
            out = self.relu(out)
    
            out = self.conv3(out)
            out = self.bn3(out)
    
            if self.downsample is not None:
                residual = self.downsample(x)
    
            out += residual
            out = self.relu(out)
    
            return out
    
    
    # 定义完整的空洞残差网络
    class ResNet_Atrous(nn.Module):
        # 当layers=[3,4,6,3]时,block为bottlenet时,就生成resnet50
        def __init__(self, block, layers, atrous=None, os=16):
            super(ResNet_Atrous, self).__init__()
            self.block = block
            stride_list = None
            if os == 8:
                # 控制block2,block3,block4的第一个bottleneck的3x3卷积的stride
                # 这里指将block2内的第一个bottleneck的3x3卷集的stride设置为2
                # 这里指将block3内的第一个bottleneck的3x3卷集的stride设置为1
                # 这里指将block4内的第一个bottleneck的3x3卷集的stride设置为1
                stride_list = [2, 1, 1]
            elif os == 16:
                stride_list = [2, 2, 1]
            else:
                raise ValueError('resnet_atrous.py: output stride=%d is not supported.' % os)
    
            self.inplanes = 64
            self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,
                                   bias=False)
    
            self.bn1 = nn.BatchNorm2d(64)
            self.relu = nn.ReLU(inplace=True)
            self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
            # resnet的 block1
            self.layer1 = self._make_layer(block, 64, 64, layers[0])
            # resnet的 block2
            self.layer2 = self._make_layer(block, 64 * block.expansion, 128, layers[1], stride=stride_list[0])
            # resnet的 block3
            self.layer3 = self._make_layer(block, 128 * block.expansion, 256, layers[2], stride=stride_list[1],
                                           atrous=16 // os)
            # resnet的 block4,block4的atrous为列表,里面使用了multi-grid技术
            self.layer4 = self._make_layer(block, 256 * block.expansion, 512, layers[3], stride=stride_list[2],
                                           atrous=[item * 16 // os for item in atrous])
            self.layer5 = self._make_layer(block, 512 * block.expansion, 512, layers[3], stride=1,
                                           atrous=[item * 16 // os for item in atrous])
            self.layer6 = self._make_layer(block, 512 * block.expansion, 512, layers[3], stride=1,
                                           atrous=[item * 16 // os for item in atrous])
            self.layers = []
    
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
    
        def _make_layer(self, block, in_chans, out_chans, blocks, stride=1, atrous=None):
            downsample = None
            if atrous == None:
                # 当没有设置atrous,blocks=3时,atrous=[1,1,1]
                # 此时表示resnet的block1,或者block2,或者block3,或者block4内的bottleneck中的3x3卷积的膨胀系数为1,
                # 膨胀系数为1,就表示没有膨胀,还是标准卷积。
                atrous = [1] * blocks
            elif isinstance(atrous, int):
                # 当设置atrous=2,blocks=3时,atrous=[2,2,2]
                # 此时表示resnet的block1,或者block2,或者block3,或者block4内的bottleneck中的3x3卷积的膨胀系数为2
                atrous_list = [atrous] * blocks
                atrous = atrous_list
            # 如果atrous不是None,也不是一个整数,那么atrous被直接设定为[1,2,3]
            # 此时表示resnet的block1,或者block2,或者block3,或者block4内的bottleneck中的3个3x3卷积的膨胀系数分别为[1,2,3]
    
            if stride != 1 or in_chans != out_chans * block.expansion:
                downsample = nn.Sequential(
                    nn.Conv2d(in_chans, out_chans * block.expansion,
                              kernel_size=1, stride=stride, bias=False),
                    nn.BatchNorm2d(out_chans * block.expansion),
                )
    
            layers = []
            layers.append(block(in_chans, out_chans, stride=stride, atrous=atrous[0], downsample=downsample))
            in_chans = out_chans * block.expansion
            for i in range(1, blocks):
                layers.append(block(in_chans, out_chans, stride=1, atrous=atrous[i]))
    
            return nn.Sequential(*layers)
    
        def forward(self, x):
            layers_list = []
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.relu(x)
            x = self.maxpool(x)
            x = self.layer1(x)
            # 此时x为4倍下采样
            layers_list.append(x)
            x = self.layer2(x)
            # 此时x为8倍下采样
            layers_list.append(x)
            x = self.layer3(x)
            # 此时x为8倍或者16倍下采样,由本代码的123,125行的 stride_list决定
            # stride_list[2,1,1]时,就是8倍下采样
            # stride_list[2,2,1]时,就是16倍下采样
    
            layers_list.append(x)
            x = self.layer4(x)
            x = self.layer5(x)
            x = self.layer6(x)
            # 此时x为8倍或者16倍下采样,由本代码的123,125行的 stride_list决定
            # stride_list[2,1,1]时,就是8倍下采样
            # stride_list[2,2,1]时,就是16倍下采样
            layers_list.append(x)
            # return 4个feature map,分别是block1,block2,block3,block6的feature map
            return layers_list
    
    
    def resnet34_atrous(pretrained=True, os=16, **kwargs):
        """Constructs a atrous ResNet-34 model."""
        model = ResNet_Atrous(BasicBlock, [3, 4, 6, 3], atrous=[1, 2, 1], os=os, **kwargs)
        if pretrained:
            old_dict = model_zoo.load_url(model_urls['resnet34'])
            model_dict = model.state_dict()
            old_dict = {k: v for k, v in old_dict.items() if (k in model_dict)}
            model_dict.update(old_dict)
            model.load_state_dict(model_dict)
        return model
    
    
    def resnet50_atrous(pretrained=True, os=16, **kwargs):
        """Constructs a atrous ResNet-50 model."""
        model = ResNet_Atrous(Bottleneck, [3, 4, 6, 3], atrous=[1, 2, 1], os=os, **kwargs)
        if pretrained:
            old_dict = model_zoo.load_url(model_urls['resnet50'])
            model_dict = model.state_dict()
            old_dict = {k: v for k, v in old_dict.items() if (k in model_dict)}
            model_dict.update(old_dict)
            model.load_state_dict(model_dict)
        return model
    
    
    def resnet101_atrous(pretrained=True, os=16, **kwargs):
        """Constructs a atrous ResNet-101 model."""
        model = ResNet_Atrous(Bottleneck, [3, 4, 23, 3], atrous=[1, 2, 1], os=os, **kwargs)
        if pretrained:
            old_dict = model_zoo.load_url(model_urls['resnet101'])
            model_dict = model.state_dict()
            old_dict = {k: v for k, v in old_dict.items() if (k in model_dict)}
            model_dict.update(old_dict)
            model.load_state_dict(model_dict)
        return model
    
    
    from aspp import ASPP
    
    
    class Config(object):
        # 决定本代码的123,125行的 stride_list的取值
        OUTPUT_STRIDE = 16
        # 设定ASPP模块输出的channel数
        ASPP_OUTDIM = 256
        # Decoder中,shortcut的1x1卷积的channel数目
        SHORTCUT_DIM = 48
        # Decoder中,shortcut的卷积的核大小
        SHORTCUT_KERNEL = 1
        # 每个像素要被分类的类别数
        NUM_CLASSES = 21
    
    
    class DeeplabV3Plus(nn.Module):
        def __init__(self, cfg, backbone=resnet50_atrous):
            super(DeeplabV3Plus, self).__init__()
            self.backbone = backbone(pretrained=False, os=cfg.OUTPUT_STRIDE)
            input_channel = 512 * self.backbone.block.expansion
            self.aspp = ASPP(in_chans=input_channel, out_chans=cfg.ASPP_OUTDIM, rate=16 // cfg.OUTPUT_STRIDE)
            self.dropout1 = nn.Dropout(0.5)
            self.upsample4 = nn.UpsamplingBilinear2d(scale_factor=4)
            self.upsample_sub = nn.UpsamplingBilinear2d(scale_factor=cfg.OUTPUT_STRIDE // 4)
    
            indim = 64 * self.backbone.block.expansion
            self.shortcut_conv = nn.Sequential(
                nn.Conv2d(indim, cfg.SHORTCUT_DIM, cfg.SHORTCUT_KERNEL, 1, padding=cfg.SHORTCUT_KERNEL // 2, bias=False),
                nn.BatchNorm2d(cfg.SHORTCUT_DIM),
                nn.ReLU(inplace=True),
            )
            self.cat_conv = nn.Sequential(
                nn.Conv2d(cfg.ASPP_OUTDIM + cfg.SHORTCUT_DIM, cfg.ASPP_OUTDIM, 3, 1, padding=1, bias=False),
                nn.BatchNorm2d(cfg.ASPP_OUTDIM),
                nn.ReLU(inplace=True),
                nn.Dropout(0.5),
                nn.Conv2d(cfg.ASPP_OUTDIM, cfg.ASPP_OUTDIM, 3, 1, padding=1, bias=False),
                nn.BatchNorm2d(cfg.ASPP_OUTDIM),
                nn.ReLU(inplace=True),
                nn.Dropout(0.1),
            )
            self.cls_conv = nn.Conv2d(cfg.ASPP_OUTDIM, cfg.NUM_CLASSES, 1, 1, padding=0)
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
    
        def forward(self, x):
            # 利用backbone生成block1,2,3,4,5,6,7的feature maps
            layers = self.backbone(x)
            # layers[-1]是block7输出的feature map相对于原图下采样了16倍
            # 把block7的输出送入aspp
            feature_aspp = self.aspp(layers[-1])
            feature_aspp = self.dropout1(feature_aspp)
            # 双线行插值上采样4倍
            feature_aspp = self.upsample_sub(feature_aspp)
    
            # layers[0],是block1输出的featuremap,相对于原图下采样的4倍,我们将它送入1x1x48的卷积中
            feature_shallow = self.shortcut_conv(layers[0])
            # aspp上采样4倍,变成相对于原图下采样4倍,与featue _shallow 拼接融合
            feature_cat = torch.cat([feature_aspp, feature_shallow], 1)
            result = self.cat_conv(feature_cat)
            result = self.cls_conv(result)
            result = self.upsample4(result)
            return result
    
    
    cfg = Config()
    model = DeeplabV3Plus(cfg, backbone=resnet50_atrous)
    x = torch.randn((2, 3, 128, 128), dtype=torch.float32)
    y = model(x)
    print(y.shape)
    
    
    展开全文
  • Deep lab家族ppt.pdf

    2019-07-08 15:27:28
    一个官方ppt,涵盖了Deep LabV1V2V3的概括总结,能够丰富语义分割论文内容
  • DeepLab_V3图像语义分割网络 语义分割DeepLab_V3 CNN的实现,如。 有关此实现的完整文档,请查看。 依存关系 Python 3.x 脾气暴躁的 Tensorflow 1.10.1 资料下载 评价 预训练模型。 将checkpoints文件夹放在./...
  • 1、Deeplab V1 《Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFS》 http://arxiv.org/pdf/1412.7062v3.pdf 由于卷积神经网络在提取特征时会将输入图像逐渐缩小,featuremap变...

    1、Deeplab V1

    《Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFS》
    http://arxiv.org/pdf/1412.7062v3.pdf
    由于卷积神经网络在提取特征时会将输入图像逐渐缩小,featuremap变小形成高级别的特征对分割任务并不适用,DeepLab采用了空洞卷积替换传统的卷积和fully connected CRF。为了利用已经训练好的VGG模型进行fine-tuning,又想改变网络结构得到更加dense的score map而引入的空洞卷积。

    1-空洞卷积的引入
    VGG16的原始模型,卷积层的卷积核大小统一为 3x3,步长为 1,最大池化层的池化窗口为 2x2,步长为2 。
    在这里插入图片描述
    改进是使用 1x1 的卷积层代替FC层,那么就变成了全卷积网络,输出得到的是得分图,也可以理解成概率图。将pool4和pool5的步长由2改为1, 这样在原本FC7的位置,VGG网络总的步长由原来的32变为8(总步长=输入size/特征图size)。一般来说,池化层的步长为2,池化后输出大小变为输入大小的一半。原VGG16模型有5次池化,缩小 2^5=32倍,修改后的VGG16有3次步长为2的池化,缩小 2^3=8倍,两次步长为1的池化,输出大小基本不变,所以说VGG网络总的步长由原来的32变为8。这样改的原因是为了获得更为稠密(dense)的score map。感受野是当前这一层的节点往前能看到多少前些层的节点,最直观的是与步长和pooling size有关。步长缩小之后感受野不变,但输出更加Dense密集,有利于分割结果的精细化
    在这里插入图片描述
    2-Fully connected CRF
    CRF就是Conditional Random Field (条件随机场),在图像处理领域的作用是平滑处理,在针对某个位置的像素值处理时会综合考虑周围像素的值,采用Fully connected CRF可以综合考虑全局信息,恢复详细的局部结构,如精确图形的轮廓。CRF几乎可以用于所有的分割任务中图像精度的提高
    在这里插入图片描述第一列是原图像和Ground Truth;第二列是DCNN的输出,上面是得分图(Score map),下面是置信图(Belief map)。最后一个DCNN层的输出用作CRF的输入。后面三列分别是CRF迭代1、2、10次后的得分图和置信图。

    2、DeepLab V2

    《DeepLab-v2: Semantic Image Segmentation 》
    https://arxiv.org/pdf/1606.00915.pdf
    Deeplabv2 在之前的基础上做了新的改进,引入ASPP(Atrous spatial pyramid pooling)使用多尺度multi-scale构造多感受野域,对最后输出的性能提升明显。
    使用空间金字塔池化的方法,代替原来对图像做预处理resize 的方法,使得输入图片可以具有任意尺度,而不影响神经网络中全连接层的输入大小,实现对图像大小和不同长宽比的处理,通过不同的空洞卷积对图像进行不同程度的缩放,得到不同大小的feature map,之后进行池化得到固定大小的图像,
    DeepLab V2有两个基础网络结构,一个是基于vgg16,另外一个是基于resnet101的。
    在这里插入图片描述在这里插入图片描述上图a为DeepLab-LargeFOV(仅单个atrous conv),b为DeepLab-ASPP。

    3、PSPNet

    《Pyramid Scene Parsing Network》
    https://arxiv.org/pdf/1612.01105.pdf

    通过多尺度 Pooling 的方式得到不同 Scale 的 Feature,Concat 得到判别的多尺度特征,对于输入图像,首先通过一个ResNet网络提取图像特征(feature map),如图(b);之后将得到的feature map输出到一个全局pool层,再通过一个Pyramid Pooling Module金字塔池化模块获得多个sub-region的特征表示,之后通过上采样(upsampling),并串联层(concat)所有特征,得到最后的特征表示向量,从而获得图像的局部和全局特征,如图©所示,图中从上到下四个卷积层,最后将得到的向量输入一个卷积层(卷积,用于减小维度),得到最后的预测结果。
    在这里插入图片描述
    并且引入额外的深度监督 Loss,除了使用softmax loss,还引入了res4b22 residule模块的loss2,并引入一个权重参数来控制loss2的权重,辅助分类器可以帮助优化学习过程。在这里插入图片描述

    4、Deeplab v3

    《Rethinking Atrous Convolution for Semantic Image Segmentation》
    https://arxiv.org/pdf/1706.05587.pdf

    空洞卷积是一种显式调整滤波器感受野和控制网络特征响应分辨率的有效工具。为了解决多尺度分割对象的问题,我们设计了采用级联或并行多个不同膨胀系数的空洞卷积模块,以更好的捕获上下文语义信息。此外,改进了在DeepLab V2中提出的ASPP模块,将BN层引入ASPP,采用全局平均池化进一步提升了它的性能,deeplabv3中,使用大采样率的3X3空洞卷积,图像边界响应无法捕捉远距离信息,会退化为1×1的卷积, 所以deeplabv3将图像级特征融合到ASPP模块中,去掉了 CRFs。
    文章讨论了四种利用上下文信息进行语义分割的全卷积网络(FCNs)如下,
    图像金字塔(Image pyramid):多个尺度的图片输入到一个相同的网络中,并将所有比例的特征图合并。
    编码器-解码器(Encoder-Decoder) 。应用有反卷积进行上采样、SegNet复用编码器中的池化索引,学习额外的卷积层来平滑特征响应、U-Net将编码器中的特征层通过跳跃连接添加到相应的解码器激活层中。
    上下文模块(Context module) 包含了额外的模块,采用级联的方式,用来编码远距离上下文信息。一种有效的方法是合并Dense CRF到DCNN中,共同训练DCNN和CRF。
    空间金字塔池化(Spatial pyramid pooling) 空间金字塔池化可以在多个范围内捕捉上下文信息。DeepLabv V2提出了空洞卷积空间金字塔池化(ASPP),使用不同采样率的并行空洞卷积层才捕获多尺度信息。PSPNet在不同网格尺度上执行空间池化,并在多个语义分割数据集上获得出色的性能。在这里插入图片描述在这里插入图片描述这篇论文还提出了三种改善ASPP的方法,涉及了像素级特征的连接、加入1×1的卷积层和三个不同比率下3×3的空洞卷积,还在每个并行卷积层之后加入了批量归一化操作。

    5、DeepLab V3+

    Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation
    https://arxiv.org/pdf/1802.02611.pdf
    在语义分割任务中,spatial pyramid pooling module(SPP)可以捕获更多尺度信息,encoder-decoder结构可以更好恢复物体的边缘信息。DeepLab V3+将DeepLab V3作为encoder,把Xception和深度可分离卷积Depthwise separable convolution(之前的文章介绍过)应用到ASPP和decoder中,encoder网络使用resnet101或 Xception,
    在这里插入图片描述文章还对Xception 改进作为backbone,介绍了两种backbone,一是Resnet101,二是改进后的xception。xception效果好于resnet。
    Xception 主要采用了deepwish seperable convolution来替换原来的卷积层。Entry flow 保持不变,但是添加了更多的 Middle flow。所有的 max pooling 被 depthwise separable convolutions 替代。在每个 3x3 depthwise convolution 之外,增加了 batch normalization 和 ReLU。
    在这里插入图片描述

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,264
精华内容 5,705
关键字:

deeplab