deeplabv3+源码之慢慢解析21 第四章network文件夹(2)_deeplab.py--ASPP相关的4个类和1个函数

系列文章目录(共五章33节已完结)

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

第二章deeplabv3+源码之慢慢解析 datasets文件夹(1)voc.py–voc_cmap函数和download_extract函数
第二章deeplabv3+源码之慢慢解析 datasets文件夹(2)voc.py–VOCSegmentation类
第二章deeplabv3+源码之慢慢解析 datasets文件夹(3)cityscapes.py–Cityscapes类
第二章deeplabv3+源码之慢慢解析 datasets文件夹(4)utils.py–6个小函数

第三章deeplabv3+源码之慢慢解析 metrics文件夹stream_metrics.py–StreamSegMetrics类和AverageMeter类

第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a1)hrnetv2.py–4个函数和可执行代码
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a2)hrnetv2.py–Bottleneck类和BasicBlock类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a3)hrnetv2.py–StageModule类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a4)hrnetv2.py–HRNet类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(b1)mobilenetv2.py–2个类和2个函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(b2)mobilenetv2.py–MobileNetV2类和mobilenet_v2函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(c1)resnet.py–2个基础函数,BasicBlock类和Bottleneck类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(c2)resnet.py–ResNet类和10个不同结构的调用函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(d1)xception.py–SeparableConv2d类和Block类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(d2)xception.py–Xception类和xception函数
第四章deeplabv3+源码之慢慢解析 network文件夹(2)_deeplab.py–ASPP相关的4个类和1个函数
第四章deeplabv3+源码之慢慢解析 network文件夹(3)_deeplab.py–DeepLabV3类,DeepLabHeadV3Plus类和DeepLabHead类
第四章deeplabv3+源码之慢慢解析 network文件夹(4)modeling.py–5个私有函数(4个骨干网,1个模型载入)
第四章deeplabv3+源码之慢慢解析 network文件夹(5)modeling.py–12个调用函数
第四章deeplabv3+源码之慢慢解析 network文件夹(6)utils.py–_SimpleSegmentationModel类和IntermediateLayerGetter类

第五章deeplabv3+源码之慢慢解析 utils文件夹(1)ext_transforms.py.py–2个翻转类和ExtCompose类
第五章deeplabv3+源码之慢慢解析 utils文件夹(2)ext_transforms.py.py–2个裁剪类和2个缩放类
第五章deeplabv3+源码之慢慢解析 utils文件夹(3)ext_transforms.py.py–旋转类,填充类,张量转化类和标准化类
第五章deeplabv3+源码之慢慢解析 utils文件夹(4)ext_transforms.py.py–ExtResize类,ExtColorJitter类,Lambda类和Compose类
第五章deeplabv3+源码之慢慢解析 utils文件夹(5)loss.py–FocalLoss类
第五章deeplabv3+源码之慢慢解析 utils文件夹(6)scheduler.py–PolyLR类
第五章deeplabv3+源码之慢慢解析 utils文件夹(7)utils.py–去标准化,momentum设定,标准化层锁定和路径创建
第五章deeplabv3+源码之慢慢解析 utils文件夹(8)visualizer.py–Visualizer类(完结)


前期准备和说明

  1. 空洞卷积(atrous convolutions)又称扩张卷积(dilated convolutions),dilation参数设定忘记的同学务必先看看前面的章节。
  2. deeplab家族的事情,大家先要了解一下。(老规矩,看文后补充链接)。
  3. Xception是的deeplab v3+文章的骨干网络,但大家可以多试试玩玩其他的。
  4. ASPP:Atrous Spatial Pyramid Pooling,空洞空间卷积池化金字塔。就是多个不同dilation的空洞卷积,然后合起来。(老规矩,看文后补充链接)。
  5. 提示:ASPP,主要有5个部分:
    (1)1x1卷积
    (2)膨胀率(dilation)为6的3x3卷积 (ASPPConv类)
    (3)膨胀率为12的3x3卷积 (ASPPConv类)
    (4)膨胀率为18的3x3卷积 (ASPPConv类)
    (5)对输入进去的特征层进行池化 (ASPPPooling类)
  6. _deeplab.py包含7个类和1个函数,本节介绍其中ASPP相关内容,即AtrousSeparableConvolution类,ASPPConv类,ASPPPooling类,ASPP类和convert_to_separable_conv函数。

导入部分

#以下是torch的常用功能
import torch
from torch import nn
from torch.nn import functional as F
#以下是从本文件夹下utils.py导入的部分,就是骨干网选择。详见后面utils.py这一节。
from .utils import _SimpleSegmentationModel

非函数非类代码

__all__ = ["DeepLabV3"]  #DeepLabV3类,简单明了的一句。

空洞可分离卷积 AtrousSeparableConvolution类

提示:#可以对比backbone文件夹中xception.py中SeparableConv2d类的写法。

class AtrousSeparableConvolution(nn.Module): #convert_to_separable_conv函数使用,就是论文中输入数据的第一个处理环节。但本代码中没有实际用到。
    """ Atrous Separable Convolution #空洞可分离卷积,相对与之前的深度可分离卷积(DW+PW)的区别,就是把DW的dilation换成1以外的值,即使用空洞卷积。
    """
    def __init__(self, in_channels, out_channels, kernel_size,
                            stride=1, padding=0, dilation=1, bias=True):
        super(AtrousSeparableConvolution, self).__init__()
        self.body = nn.Sequential(
            # Separable Conv #和DW没有什么变化,主要是输入的dilation不同罢了。
            nn.Conv2d( in_channels, in_channels, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, bias=bias, groups=in_channels ),
            # PointWise Conv #PW部分还是kernel_size=1,stride=1没什么变化。
            nn.Conv2d( in_channels, out_channels, kernel_size=1, stride=1, padding=0, bias=bias),
        )
        
        self._init_weight() #初始化权重

    def forward(self, x): #返回Separable Conv+PW,没有复杂内容。
        return self.body(x)

    def _init_weight(self): #初始化权重
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

ASPPConv类

class ASPPConv(nn.Sequential): #ASPP第(2)-(4)部分。
    def __init__(self, in_channels, out_channels, dilation):    #此处的主要参数为:空洞dilation。
        modules = [
            nn.Conv2d(in_channels, out_channels, 3, padding=dilation, dilation=dilation, bias=False),  #论文中kernel=3。padding=dilation保证不同卷积核,获得的结果尺寸相同,以便整合。
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        ]
        super(ASPPConv, self).__init__(*modules)

ASPPPooling类

class ASPPPooling(nn.Sequential): #ASPP第(5)部分。池化。
    def __init__(self, in_channels, out_channels):
        super(ASPPPooling, self).__init__(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(in_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True))

    def forward(self, x):
        size = x.shape[-2:] #输入x的shape取最后2项,长宽尺寸即h和w。
        x = super(ASPPPooling, self).forward(x)
        return F.interpolate(x, size=size, mode='bilinear', align_corners=False)#为接下来的数据整合,池化后进行插值数据采样,改变数据的尺寸。 F.interpolate后补链接。

ASPP类

提示:ASPP类就是整个之前的内容,在DeepLabHeadV3Plus类和DeepLabHead类倍调用。

class ASPP(nn.Module):               #空洞卷积。论文中的Encoder部分主要就是ASPP。
    def __init__(self, in_channels, atrous_rates):       
        super(ASPP, self).__init__()
        out_channels = 256
        modules = []                      #论文中ASPP的5个部分
        modules.append(nn.Sequential(      #此处是ASPP第1个部分:卷积核为1。
            nn.Conv2d(in_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)))

        rate1, rate2, rate3 = tuple(atrous_rates)   #此处调取不同的rate,对应论文中的不同卷积核,DeepLabHead类中aspp_dilate。
        modules.append(ASPPConv(in_channels, out_channels, rate1))  #此处是ASPP第2个部分:卷积核为3(固定),dilation=rate1(参数传入)
        modules.append(ASPPConv(in_channels, out_channels, rate2)) #此处是ASPP第3个部分:卷积核为3(固定),dilation=rate2(参数传入)
        modules.append(ASPPConv(in_channels, out_channels, rate3))   #此处是ASPP第4个部分:卷积核为3(固定),dilation=rate3(参数传入)
        modules.append(ASPPPooling(in_channels, out_channels))     #此处是ASPP第5个部分:,Image_pooling

        self.convs = nn.ModuleList(modules)      #ASPP各部分统一为self.convs。

        self.project = nn.Sequential(           #需要将ASPP的5个部分整合输出,因此整个部分输入为5倍,输出为原来的输出数量。之后按卷积核1输出。
            nn.Conv2d(5 * out_channels, out_channels, 1, bias=False), #卷积核1。
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True),
            nn.Dropout(0.1),)

    def forward(self, x):
        res = []
        for conv in self.convs:     
            res.append(conv(x))   #每一层数据走一遍输入数据,注意5个部分在最后汇总前,都是独立并行的,因此都是单独输入x,而不是前者输出为后后者输入。
        res = torch.cat(res, dim=1) #torch.cat() 的dim=1拼接,是指将两个2*3,变成一个4*3。对应前面将5个部分的结果进行拼接(5 * out_channels)。
        return self.project(res)

convert_to_separable_conv函数

提示:就是个转化函数,这段代码中没用到。

def convert_to_separable_conv(module):
    new_module = module
    if isinstance(module, nn.Conv2d) and module.kernel_size[0]>1: #对于参数传入模型中的nn.Conv2d层(卷积层),只要kernel>1,则转为空洞可分卷积层。
        new_module = AtrousSeparableConvolution(module.in_channels,
                                      module.out_channels, 
                                      module.kernel_size,
                                      module.stride,
                                      module.padding,
                                      module.dilation,
                                      module.bias)
    for name, child in module.named_children():
        new_module.add_module(name, convert_to_separable_conv(child)) #递归转换。
    return new_module

Tips

  1. 补充:Deeplab家族
  2. 补充:Deeplabv3+理论
  3. 补充:ASPP
  4. 补充:F.interpolate插值数据采样
  5. 下一节是_deeplab.py剩余的部分,即DeepLabV3类,DeepLabHeadV3Plus类和DeepLabHead类。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值