系列文章目录(共五章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类(完结)
文章目录
前期准备和说明
- modeling.py是对前面几节代码的整合,所以务必搞清楚前面的_deeplab.py之后再学习。
- 部分会用到本文件夹下的utils.py的内容,在本章最后一节讲述。
- modeling.py包含17个函数,5个私有函数(本节,4个骨干网,1个模型载入),12个可供调用的函数(下一节)。
导入部分
from .utils import IntermediateLayerGetter #utils.py导入
from ._deeplab import DeepLabHead, DeepLabHeadV3Plus, DeepLabV3 #_deeplab.py导入
from .backbone import (
resnet,
mobilenetv2,
hrnetv2,
xception
) #4类骨干网
_segm_hrnet类
提示:hrnet骨干网络。
def _segm_hrnet(name, backbone_name, num_classes, pretrained_backbone):
backbone = hrnetv2.__dict__[backbone_name](pretrained_backbone)#从hrnetv2.__dict__选择骨干网的具体名称
# HRNetV2 config:
# the final output channels is dependent on highest resolution channel config (c).
# output of backbone will be the inplanes to assp:
hrnet_channels = int(backbone_name.split('_')[-1]) #从backbone_name参数最后1项选择骨干网的通道数
inplanes = sum([hrnet_channels * 2 ** i for i in range(4)]) #根据hrnetv2网络结构需求,计算输入总通道数。详见backbone文件夹hrnetv2.py
low_level_planes = 256 # all hrnet version channel output from bottleneck is the same #hrnet的各版本bottleneck输出都是256.
aspp_dilate = [12, 24, 36] # If follow paper trend, can put [24, 48, 72].#此处与论文不同,修改了参数。
if name=='deeplabv3plus': #如果是v3+版本,则有个out+low_level的汇总。
return_layers = {'stage4': 'out', 'layer1': 'low_level'}
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)#详见_deeplab.py的DeepLabHeadV3Plus。
elif name=='deeplabv3':#如果是v3版本,则只有out,没有low_level的部分。
return_layers = {'stage4': 'out'}
classifier = DeepLabHead(inplanes, num_classes, aspp_dilate)#详见_deeplab.py的 DeepLabHead。
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers, hrnet_flag=True)#详见本文件夹utils.py的IntermediateLayerGetter。
model = DeepLabV3(backbone, classifier)#详见_deeplab.py的DeepLabV3,即utils.py的_SimpleSegmentationModel。
return model
_segm_resnet类
提示:resnet骨干网络。
def _segm_resnet(name, backbone_name, num_classes, output_stride, pretrained_backbone):
if output_stride==8: #如果output_stride==8,则用dilation替代stride设置为[False, True, True],空洞卷积设置为[12, 24, 36]。
replace_stride_with_dilation=[False, True, True]
aspp_dilate = [12, 24, 36]
else: #如果output_stride!=8,则参数设置为如下值。
replace_stride_with_dilation=[False, False, True]
aspp_dilate = [6, 12, 18]
backbone = resnet.__dict__[backbone_name]( #从resnet.__dict__选择骨干网的具体名称
pretrained=pretrained_backbone,
replace_stride_with_dilation=replace_stride_with_dilation)
inplanes = 2048 #输入和 low_level_planes设定。
low_level_planes = 256
if name=='deeplabv3plus': #下面部分同_segm_hrnet函数的解释。
return_layers = {'layer4': 'out', 'layer1': 'low_level'}
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
elif name=='deeplabv3':
return_layers = {'layer4': 'out'}
classifier = DeepLabHead(inplanes , num_classes, aspp_dilate)
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers)
model = DeepLabV3(backbone, classifier)
return model
_segm_xception类
提示:xception骨干网络。
def _segm_xception(name, backbone_name, num_classes, output_stride, pretrained_backbone):
if output_stride==8: #上半部分同_segm_resnet函数的解释。
replace_stride_with_dilation=[False, False, True, True]
aspp_dilate = [12, 24, 36]
else:
replace_stride_with_dilation=[False, False, False, True]
aspp_dilate = [6, 12, 18]
backbone = xception.xception(pretrained= 'imagenet' if pretrained_backbone else False, replace_stride_with_dilation=replace_stride_with_dilation)
inplanes = 2048
low_level_planes = 128
if name=='deeplabv3plus': #下面部分同_segm_hrnet函数的解释。
return_layers = {'conv4': 'out', 'block1': 'low_level'}
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
elif name=='deeplabv3':
return_layers = {'conv4': 'out'}
classifier = DeepLabHead(inplanes , num_classes, aspp_dilate)
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers)
model = DeepLabV3(backbone, classifier)
return model
_segm_mobilenet类
提示:mobilenet骨干网络。
def _segm_mobilenet(name, backbone_name, num_classes, output_stride, pretrained_backbone):
if output_stride==8: #上半部分同_segm_resnet函数的解释。
aspp_dilate = [12, 24, 36]
else:
aspp_dilate = [6, 12, 18]
backbone = mobilenetv2.mobilenet_v2(pretrained=pretrained_backbone, output_stride=output_stride)
# rename layers
backbone.low_level_features = backbone.features[0:4] #详见mobilenetv2.py,self.features就是别的骨干网里的self.layers。此处即重新调整层的名字。前4层叫low_level_features,之后的叫high_level_features。
backbone.high_level_features = backbone.features[4:-1]
backbone.features = None #重命名之后,features置空。
backbone.classifier = None #分类层也置空。
inplanes = 320
low_level_planes = 24
if name=='deeplabv3plus': #下面部分同_segm_hrnet函数的解释。
return_layers = {'high_level_features': 'out', 'low_level_features': 'low_level'}
classifier = DeepLabHeadV3Plus(inplanes, low_level_planes, num_classes, aspp_dilate)
elif name=='deeplabv3':
return_layers = {'high_level_features': 'out'}
classifier = DeepLabHead(inplanes , num_classes, aspp_dilate)
backbone = IntermediateLayerGetter(backbone, return_layers=return_layers)
model = DeepLabV3(backbone, classifier)
return model
_load_model类
提示:调用上面的4个函数而已。
def _load_model(arch_type, backbone, num_classes, output_stride, pretrained_backbone):
#根据不同输入参数,选择调用对应的函数,载入对应的骨干网模型的feature-map数据(即最终分类输出之前的数据)。
if backbone=='mobilenetv2':
model = _segm_mobilenet(arch_type, backbone, num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
elif backbone.startswith('resnet'):
model = _segm_resnet(arch_type, backbone, num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
elif backbone.startswith('hrnetv2'):
model = _segm_hrnet(arch_type, backbone, num_classes, pretrained_backbone=pretrained_backbone)
elif backbone=='xception':
model = _segm_xception(arch_type, backbone, num_classes, output_stride=output_stride, pretrained_backbone=pretrained_backbone)
else:
raise NotImplementedError
return model
Tips
- 此部分代码就是整合骨干网的最终feature map数据(最终分类之前的数据)给deeplab v3(+),没有新的知识,下一节是modeling.py剩余的部分。