【霹雳吧啦】手把手带你入门语义分割の番外6:LR-ASPP 源码讲解(PyTorch)
目录
前言
文章性质:学习笔记 📖
主要内容:根据 视频教程 中提供的 LR-ASPP?源代码(PyTorch),对 train.py、lraspp_model.py 文件进行具体讲解。
Preparation
? ├── src: 模型的backbone以及LRASPP的搭建
? ├── train_utils: 训练、验证以及多GPU训练相关模块
? ├── my_dataset.py: 自定义dataset用于读取VOC数据集
? ├── train.py: 单GPU训练脚本
? ├── train_multi_GPU.py: 针对使用多GPU的用户使用
? ├── predict.py: 简易的预测脚本,使用训练好的权重进行预测测试
? ├── validation.py: 利用训练好的权重验证/测试数据的mIoU等指标,并生成record_mAP.txt文件
? └── pascal_voc_classes.json: pascal_voc标签文件?
一、LR-ASPP 网络结构图
在对 PyTorch 官方实现的 LR-ASPP 源代码进行解析的过程中,最好能够结合对应的 LR-ASPP 网络结构图:
二、LR-ASPP 源代码(PyTorch)?
1、create_model 函数
LR-ASPP 的 train.py 和 predict.py 都和 PyTorch 官方实现的 FCN 源代码类似,只有 train.py 中的?create_model 函数不同。
(1)实例化模型
【说明】通过 lraspp_mobilenetv3_large 函数来实例化 LR-ASPP 模型,传入参数包括:
- ?num_classes ?包含背景的类别个数
- ?pretrain_backbone ?是否使用 PyTorch 官方使用 LR-ASPP 模型在 COCO 数据集上的预训练权重
在 lraspp_mobilenetv3_large 函数中,使用?mobilenet_v3_large 构建?backbone ,传入的?dilated=True 说明使用了膨胀卷积,如下图所示:
【拓展】如果小伙伴们想了解?mobilenet_v3_large 网络结构以及如何用 PyTorch 实现这个网络结构,可学习下面这些视频:
- 视频教程 1 :7.1.2 MobileNetv3 网络详解
- 视频教程 2 :7.2.2 使用 Pytorch 搭建 MobileNetV3 并基于迁移学习训练
(2)预训练权重
关于 create_model 函数的 pretrain 参数取值:
【情况1】需要提前下载对应权重 lraspp_mobilenet_v3_large_coco :
在 train.py 文件中将 create_model 函数传入的 pretrain 设置为 True ,其使用的 lraspp_mobilenetv3_large 函数默认将 pretrain_backbone 设置为 False,这时使用的是 PyTorch 官方使用 LR-ASPP 模型在 COCO 数据集上的预训练权重,载入 backbone 的预训练权重。
【情况2】需要提取下载对应权重 mobilenetv3_large_imagenet :
在 train.py 文件中将 create_model 函数传入的?pretrain 设置为 False ,其使用的 lraspp_mobilenetv3_large 函数需要将 pretrain_backbone 设置为 True,这时就只使用 mobilenetv3 的 backbone 权重,而不载入整个模型的权重。
【彩蛋】为了更加直观地说明 create_model 的?pretrain、lraspp_mobilenetv3_large 的 pretrain_backbone、
[ train.py ] create_model 函数 | [ lraspp_model.py ] lraspp_mobilenetv3_large 函数 | 载入权重 |
---|---|---|
pretrain = True | pretrain_backbone = False | 使用 PyTorch 官方使用 LR-ASPP 模型在 COCO 数据集上的预训练权重,需下载对应权重 lraspp_mobilenet_v3_large_coco |
pretrain = False | pretrain_backbone = True | 使用 mobilenetv3 的 backbone 权重,而不是载入整个模型的权重,需下载对应权重 mobilenetv3_large_imagenet |
【补充】权重文件的下载链接(下载后记得重命名):
- ?mobilenetv3_large_imagenet :https://download.pytorch.org/models/mobilenet_v3_large-8738ca79.pth
- ?lraspp_mobilenet_v3_large_coco :https://download.pytorch.org/models/lraspp_mobilenet_v3_large-d234d4ea.pth
2、lraspp_mobilenetv3_large 函数
(1)stage_indices?
在 lraspp_mobilenetv3_large 函数中,stage_indices 由三部分组成:stage_indices 第一个值为 0 ;然后遍历 backbone ,也就是 mobilemetv3 中对应的所有层结构 ,通过 getattr 方法去取得层结构的 is_strided 参数数值,若 is_strided 为 True,则将对应层的索引 i 添加到 stage_indices 列表中,若 is_strided 为False 或者没有 is_strided 这个参数,则不添加索引;stage_indices 最后一个值对应 backbone 最后一个模块的索引 。
Question:如何判定?is_strided 为 False 还是 True 呢?
在 mobilenet_backbone.py 中,回顾 mobilenet 中 bottleneck 的实现,在 InvertedResidual 类,当 cnf.stride > 1 时 is_strided 为 True 。
Question:为什么 stage_indices 得到的层索引就相当于层名称?
在 mobilenet_backbone.py 的 MobileNetV3 类中,features 是通过 Sequential 方法搭建的,其每一个子模块的名称与其在 Sequential 中的索引是对应的,因此 stage_indices 得到的层索引就相当于层名称 ,它的第一个索引 0 对应第一个 3x3 的 conv2d 卷积层,它中间遍历得到的索引对应 bottleneck 中 stride 步距为 2 的层,最后一个索引对应 1x1 的 conv2d 卷积层。
(2)low_pos & high_pos
关于 low_pos、high_pos、low_channels、high_channels 的理解:
- 通过 backbone [ low_pos ] 得到下采样 8 倍的层结构,再通过 .out_channels 得到对应特征层的输出 channels 。?
- 通过 backbone [ high_pos ] 得到下采样 16 倍的层结构,再通过 .out_channels 得到对应特征层的输出 channels 。?
(3)backbone & model
【代码解析】对?lraspp_mobilenetv3_large 函数的具体解析(结合上图):
- ?构建 return_layers 字典,通过 IntermediateLayerGetter 方法重构 backbone ,重构后 backbone 的输出包含 low 和 high 两个特征层。
- ?最后将 backbone,low_channels,high_channels 和 num_classes 参数传入到 LRASPP 类中去实例化模型。
【注意】LR-ASPP 网络模型使用的 backbone 是 MobileNetV3 !
3、LRASPP 类 &?LRASPPHead 类
?LRASPP 类在?__init__ 初始化函数中,构建 LRASPPHead,结合结构图:
【说明】在 LRASPP 类的 forward 函数中:x 是图像数据,x.shape[-2:] 是图像的宽高,out = self.classfier(features) 是 FCNHead 的输出。?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!