【Python】mmSegmentation语义分割框架教程(1.x版本)

news2024/12/24 2:15:43

文章目录

  • 0.引言
  • 1. 数据集设置
    • 1.1. dataset implementation py
    • 1.2. dataset config py
  • 2.模型设置
  • 3.训练

0.引言

\qquad 本文是mmSegmentation语义分割框架教程(0.x版本)的1.x版本。不熟悉mmsegmentation是什么的读者可参考原文的引言部分,熟悉之后即可阅读本文。本文重点介绍使用mmsegmentation已有的模型快速搭建训练和测试自定义数据集的功能,全部功能请参考mmsegmentation的GitHub。

\qquad 与0.x版本类似,1.x版本的重点仍然是在使用配置文件上,分为四个部分

  1. dataset config
  2. model config
  3. runtime config
  4. schedule config
    如果只是实现基本功能,那只需要重点关注前两类config即可。

1. 数据集设置

config filesimplementation files
在这里插入图片描述dataset mmseg

与0.x的版本类似,如上图,mmsegmentation的dataset的功能实现(implement)部分放在mmseg/datasets的文件夹中,而config部分放在configs/base/datasets的文件夹中。因此需要先定义一个简单的数据集implementation的py文件,再设置数据集config的py文件。

1.1. dataset implementation py

第一步,把新定义的数据集文件放在mmseg/datasets/文件夹中,下图是一个demo (broad.py):

# Copyright (c) OpenMMLab. All rights reserved.
from mmseg.registry import DATASETS
from .basesegdataset import BaseSegDataset


@DATASETS.register_module()
class BinaryRoadDataset(BaseSegDataset):
    """Cityscapes dataset.

    The ``img_suffix`` is fixed to '.jpg' and ``seg_map_suffix`` is
    fixed to '.jpg' for BinaryRoad dataset.
    """
    METAINFO = dict(
        classes=('background', 'road'),
        palette=[[0,0,0], [244, 35, 232]])

    def __init__(self,
                 img_suffix='.jpg',
                 seg_map_suffix='.jpg',
                 **kwargs) -> None:
        super().__init__(
            img_suffix=img_suffix, seg_map_suffix=seg_map_suffix, **kwargs)

需要注意的点不多:

  1. suffix: 需要与原图片suffix和分割图片的suffix一致,目前只尝试过jpg和png格式的seg_map_suffix,seg_map是灰度图像,默认从0开始算标签,整形,尺寸大小与原图一致。
  2. classes & palette:classes是标签的类别名,会以字符串形式显示在log中,palette是标签visualize时的半透明颜色,训练和测试的时候不重要但是必须要有。

第二步,修改同目录下__init__文件,修改的也不多:

# Copyright (c) OpenMMLab. All rights reserved.
# yapf: disable
from .ade import ADE20KDataset
from .basesegdataset import BaseSegDataset
from .chase_db1 import ChaseDB1Dataset
from .cityscapes import CityscapesDataset
from .coco_stuff import COCOStuffDataset
from .dark_zurich import DarkZurichDataset
from .dataset_wrappers import MultiImageMixDataset
from .decathlon import DecathlonDataset
from .drive import DRIVEDataset
from .hrf import HRFDataset
from .isaid import iSAIDDataset
from .isprs import ISPRSDataset
from .lip import LIPDataset
from .loveda import LoveDADataset
from .mapillary import MapillaryDataset_v1, MapillaryDataset_v2
from .night_driving import NightDrivingDataset
from .pascal_context import PascalContextDataset, PascalContextDataset59
from .potsdam import PotsdamDataset
from .refuge import REFUGEDataset
from .stare import STAREDataset
from .synapse import SynapseDataset
# yapf: disable
from .transforms import (CLAHE, AdjustGamma, BioMedical3DPad,
                         BioMedical3DRandomCrop, BioMedical3DRandomFlip,
                         BioMedicalGaussianBlur, BioMedicalGaussianNoise,
                         BioMedicalRandomGamma, GenerateEdge, LoadAnnotations,
                         LoadBiomedicalAnnotation, LoadBiomedicalData,
                         LoadBiomedicalImageFromFile, LoadImageFromNDArray,
                         PackSegInputs, PhotoMetricDistortion, RandomCrop,
                         RandomCutOut, RandomMosaic, RandomRotate,
                         RandomRotFlip, Rerange, ResizeShortestEdge,
                         ResizeToMultiple, RGB2Gray, SegRescale)
from .voc import PascalVOCDataset
from .broad import BinaryRoadDataset  # add custom dataset

# yapf: enable
__all__ = [
    'BaseSegDataset', 'BioMedical3DRandomCrop', 'BioMedical3DRandomFlip',
    'CityscapesDataset', 'PascalVOCDataset', 'ADE20KDataset',
    'PascalContextDataset', 'PascalContextDataset59', 'ChaseDB1Dataset',
    'DRIVEDataset', 'HRFDataset', 'STAREDataset', 'DarkZurichDataset',
    'NightDrivingDataset', 'COCOStuffDataset', 'LoveDADataset',
    'MultiImageMixDataset', 'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset',
    'LoadAnnotations', 'RandomCrop', 'SegRescale', 'PhotoMetricDistortion',
    'RandomRotate', 'AdjustGamma', 'CLAHE', 'Rerange', 'RGB2Gray',
    'RandomCutOut', 'RandomMosaic', 'PackSegInputs', 'ResizeToMultiple',
    'LoadImageFromNDArray', 'LoadBiomedicalImageFromFile',
    'LoadBiomedicalAnnotation', 'LoadBiomedicalData', 'GenerateEdge',
    'DecathlonDataset', 'LIPDataset', 'ResizeShortestEdge',
    'BioMedicalGaussianNoise', 'BioMedicalGaussianBlur',
    'BioMedicalRandomGamma', 'BioMedical3DPad', 'RandomRotFlip',
    'SynapseDataset', 'REFUGEDataset', 'MapillaryDataset_v1',
    'MapillaryDataset_v2',"BinaryRoadDataset"
] # add custom dataset

  • from … import …处添加自定义数据集类
  • __all__变量添加类名(为了兼容yapf,这里就不展开了)

1.2. dataset config py

只需要一步操作即可,添加一个父级config,放在configs/_base_/datasets/下 (binaryroad.py)

# dataset settings
dataset_type = 'BinaryRoadDataset'  # must be the same name of custom dataset
data_root = '' # subconfig file must define this path
crop_size = (1080, 1440)  # raw image size (H, W), subconfig file can overwrite

train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations'),
    dict(
        type='Resize',
        scale=crop_size,
        keep_ratio=True),
    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    dict(type='RandomFlip', prob=0.5),
    dict(type='PhotoMetricDistortion'),
    dict(type='PackSegInputs')
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='Resize', scale=crop_size, keep_ratio=True),
    # add loading annotation after ``Resize`` because ground truth
    # does not need to do resize data transform
    dict(type='LoadAnnotations'),
    dict(type='PackSegInputs')
]
img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75]
tta_pipeline = [
    dict(type='LoadImageFromFile', backend_args=None),
    dict(
        type='TestTimeAug',
        transforms=[
            [
                dict(type='Resize', scale_factor=r, keep_ratio=True)
                for r in img_ratios
            ],
            [
                dict(type='RandomFlip', prob=0., direction='horizontal'),
                dict(type='RandomFlip', prob=1., direction='horizontal')
            ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')]
        ])
]
train_dataloader = dict(
    batch_size=4,
    num_workers=4,
    persistent_workers=True,
    sampler=dict(type='InfiniteSampler', shuffle=True),
    dataset=dict(
        type=dataset_type,
        data_root=data_root,
        data_prefix=dict(
            img_path='img/train', seg_map_path='ann/train'),
        pipeline=train_pipeline))
val_dataloader = dict(
    batch_size=1,
    num_workers=4,
    persistent_workers=True,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type=dataset_type,
        data_root=data_root,
        data_prefix=dict(
            img_path='img/val', seg_map_path='ann/val'),
        pipeline=test_pipeline))
test_dataloader = dict(
    batch_size=1,
    num_workers=4,
    persistent_workers=True,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type=dataset_type,
        data_root=data_root,
        data_prefix=dict(
            img_path='img/test', seg_map_path='ann/test'),
        pipeline=test_pipeline))

val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU'], ignore_index=2)
test_evaluator = val_evaluator

下面是一些重要参数的解释:

  1. dataset_type:必须和自定义数据集类名称完全一致
  2. data_root: 数据集根目录,后续所有的pipeline使用的目录都会在此目录下的子目录读取
  3. pipeline: type='Reisze’是直接将图片Resize到指定大小(HxW),也可以使用1.x提供的RandomResize,有兴趣的读者可以去原项目提供的例程学习。
  4. dataloader: shuffle=True是打乱图片,一般训练集要求打乱图片训练增加随机性,val和test则不需要。num_workers和pytorch的定义差不多,使用多进程加载数据,一般num_workers>=4速度提升就不再明显。persistent_workers=True官方的解释也是一种加速图片加载的操作,在这里不展开其原理介绍。
  5. data_prefix:图片前缀,也可以包含路径。以data_root为子目录。按照上述的设置,训练集图片放在data_root/img/train下,训练集标签放在data_root/ann/train下。使用Linux的读者可以直接使用软连接的方式链接原路径下的文件,在不影响训练的同时还节省了磁盘空间。
  6. evaluator:分割指标评估器,ignore_index是忽略seg_map中像素值为xxx的点的metric性能指标。在1.x的更新文档中,相较0.x版本改善了IoU Metric的计算速度。
  7. 如若不需要测试集,可将其直接设为验证集。

2.模型设置

第一步,在configs/下找一个基准模型,这里我找的是HRNet,其他的网络设置类似:
在这里插入图片描述
根据基准模型的其他配置文件自己写一个配置文件,注意,这个配置文件就是最TopLevel的配置文件。
demo(fcn_hr18_4xb2-20k_binaryroad_480_640.py)如下:

_base_ = [
    '../_base_/models/fcn_hr18.py', '../_base_/datasets/binaryroad.py',
    '../_base_/default_runtime.py', '../_base_/schedules/schedule_20k.py'
]
crop_size = (480, 640)
data_preprocessor = dict(size=crop_size)
model = dict(data_preprocessor=data_preprocessor)
norm_cfg = dict(type='BN', requires_grad=True)
train_dataloader = dict(
    batch_size=2)

需要注意的是:

  1. 由于包含_base_变量,该文件的放置路径不要随意更改,应该和configs/_base_目录是同级关系
  2. TopLevel的配置文件设置的dict自动覆盖子配置文件的config,与python字典的.update()函数类似

常用参数解释:

  1. norm_cfg:如果是单GPU,应该设’BN’,否则设’SynBN’(默认)
  2. crop_size: 图片crop大小,在我的配置中,也是Resize后的图片大小,设的比原图片小可以减小训练时的内存占用,但Inference时也应执行相同的操作
  3. data_preprocessor: 1.x新增加的类型,我复制的其他config的配置
  4. batch_size:验证集和测试集都应该设为1,训练集的batch_size大小依据GPU内存而定,如果出现OOM内存溢出错误,就设置的小一些。但需要注意batch_size不要设1,部分pytorch版本的BatchNormalization操作不支持batch_size=1
  5. schedule config: 这里的schedule_20k.py设置的iteration=20k,iteration是训练的次数,按batch计算的,和数据集大小无关。例如batch_size=2iteration=20k,相当于送入网络训练了40k张图片。
  6. runtime config:可查看对应文件进行阅读,只是一些log和visualization的设置,一般不需要修改

3.训练

至于一行命令即可,在mmsegmentation的根目录执行:

python tools/train.py configs/hrnet/fcn_hr18_4xb2-40k_binaryroad_480_640.py --work-dir work_dir

--work-dir是保存记录文件及checkpoint的路径。如果中途训练终端了,还可以–resume进行继续训练,也可以使用load-from参数load一个已经训练的模型(但是iteration会置0)
work_dir中的文件截图如下:
work_dir
我把前几代iteration的checkpoint删掉了,deploy文件夹和mmdeploy_onnxrun是我新加的,后续会介绍。
与 MMSeg 0.x 相比,MMSeg 1.x 在 tools/train.py 中提供的命令行参数更少。
关于如何加载模型和断点继续训练,我把官方的Markdown拷贝如下:

功能原版(0.x)新版(1.x)
加载预训练模型--load_from=$CHECKPOINT--cfg-options load_from=$CHECKPOINT
从特定检查点恢复训练--resume-from=$CHECKPOINT--resume=$CHECKPOINT
从最新的检查点恢复训练--auto-resume--resume='auto'
训练期间是否不评估检查点--no-validate--cfg-options val_cfg=None val_dataloader=None val_evaluator=None
指定训练设备--gpu-id=$DEVICE_ID-
是否为不同进程设置不同的种子--diff-seed--cfg-options randomness.diff_rank_seed=True
是否为 CUDNN 后端设置确定性选项--deterministic--cfg-options randomness.deterministic=True

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sqlmap命令大全(附详细扫描流程)

一、sqlmap命令大全。 -u 指定目标URL (可以是http协议也可以是https协议)-d 连接数据库--dbs 列出所有的数据库--current-db 列出当前数据库--tables 列出当前的表--columns 列出当前的列-D 选择使用哪个数据库-T 选择使用哪个表-C 选择使用哪个列--dump 获取字段中的数据--…

程序猿想考一个PMP,可以吗,怎么考呢?

我从新考纲考完下来,3A通过了考试,最开始也被折磨过一段时间,但是后面还是找到了方法,也算有点经验,给大家分享一下吧。 程序猿应该是考PMP里面人最多的,毕竟有一个30大坎,大部分人还是考虑转型…

rk3588 大小核启动

setenv ipaddr 10.12.1.205;setenv serverip 10.12.1.200;tftp 0x800000 bsprk3588_owl_ai_box_plus_v10_x64.bin;go 0x800000 rk3588 启动 4 核无问题,启动 8 核出现乱码以及死机问题。 分析代码,对 psci 接口进行更新,启动 4 核&#xf…

【服务器数据恢复】EXT3文件系统下raid数据恢复案例

服务器数据恢复环境: 华为OceanStor某型号存储,10块硬盘组成raid6磁盘阵列。 上层操作系统采用EXT3文件系统,划分2个lun。 服务器故障&分析: 在巡检中发现存储中的raid不可用,管理员进行了重新分配并初始化raid的操…

VS2019 error LNK2001: 无法解析的外部符号 解决方法

今天编译一个项目的时候,用debug模式编译时可以通过并生成exe的。 换成release模式,直接报链接错误,如下: 1>libeay32.lib(pem_lib.obj) : error LNK2019: 无法解析的外部符号 ___iob_func,函数 _PEM_def_callback…

微信小程序| AIGC之动手实现ChatGPT法律顾问小程序

一、需求背景 在资本退去后,现如今的互联网行情很差劲,很多创新业务都不得不砍除。再加上国内互联网时代进入到了一个增量犹显疲态,增量杀红了眼!阶段,各大互联网公司均有一种断臂求生的态势!各位互联网同…

hadoop3.2.4集成flink 1.17.0

前言 flink安装部署有三种方式 local:单机模式,尽量不使用 standalone: flink自带集群,资源管理由flink集群管理,开发环境测试使用,不需要hadoop集群 flink on yarn: 把资源管理交给yarn实现,计算机资源统一由Haoop…

PCIe 载板设计资料原理图:382-基于FMC+的XCVU3P高性能 PCIe 载板

基于FMC的XCVU3P高性能 PCIe 载板 一、板卡概述 板卡主控芯片采用Xilinx UltraScale16 nm VU3P芯片(XCVU3P-2FFVC1517I)。板载 2 组 64bit 的DDR4 SDRAM,支持 IOX16或者 JTAG 口,支持PCIe X 16 ReV3.0以及 FMC 扩展接口。…

Hadoop基础学习---6、MapReduce框架原理

1、MapReduce框架原理 1.1 InputFormat数据输入 1.1.1 切片与MapTask并行度决定机制 1、问题引出 MapTask的并行度决定Map阶段的任务处理并发度,进而影响到整个job的处理速度。 2、MapTask并行度决定机制 数据块:Block是HDFS物理上吧数据分成一块一块。…

3D CAD模型的体素化

你有没有搜索过如何将 Cad 模型转换为 python 就绪的 numpy 数组,但没有得到任何明确的答案? 我也是。 经过长时间的研究并尝试了很多软件和 python 库,我终于能够将 3D STEP 文件转换为 3 维 numpy 数组。 如果你想做同样的事情或只是想知道…

线性表的总结

逻辑结构 逻辑结构 具有相同特性的数据元素的有限序列 特性 有穷性:一个线性表的元素个数是有限的 一致性:一个线性表的所有元素的性质相同,也就是具有相同的数据类型 序列性:所有元素之间的相对…

OJ练习第114题——T 秒后青蛙的位置

T 秒后青蛙的位置 力扣链接:1377. T 秒后青蛙的位置 题目描述 给你一棵由 n 个顶点组成的无向树,顶点编号从 1 到 n。青蛙从 顶点 1 开始起跳。规则如下: 在一秒内,青蛙从它所在的当前顶点跳到另一个 未访问 过的顶点&#xf…

十、数据仓库详细介绍(数据质量)流程与工具

上篇我们主要介绍了以下三部分内容。 第一部分,介绍了五种常见的数据管理知识体系,数据质量在所有的知识体系中都有非常重要的地位,数据应用体现数据价值,数据质量为应用提供支撑。 第二部分,我们介绍了数据质量评判的…

程序优化 - ABAP并行处理

SAP的并行方式有很多种: SPTA框架,参考debug可以看出这个核心也是异步bgRFC 异步RFC,使用CALL FUNCTION “XXXXXX” STARTING NEW TASK XXXX CALLING XXXX ON END OF TASK BANK_PP_JOBCTRL框架 拆分成多个后台JOB执行 这里只说SPTA框架…

【高危】Linux Kernel OverlayFS 权限提升漏洞(POC公开)

漏洞描述 Linux Kernel OverlayFS 是 Linux 内核提供的一种文件系统,允许将多个文件系统合并为一个单一的虚拟文件系统。 在 Linux Kernel OverlayFS 受影响版本中,当用户将具备特权的文件从 nosuid 的挂载点复制到另一个挂载点时,未授权的…

【严重】ejs 存在服务端模板注入漏洞(存在POC)

漏洞描述 EJS 是开源的 JavaScript 模板引擎,允许在HTML代码中使用JavaScript代码块,closeDelimiter 参数是 EJS 模板中的结束标记,用于指定结束分隔符。 由于对 CVE-2022-29078 漏洞修复不完全,当应用程序使用 EJS 模板引擎&am…

如何恢复已删除或丢失的音乐文件

您是否遇到过您或其他人不小心删除了您的音乐文件的情况?作为我自己的音乐爱好者,我知道这种感觉有多么毁灭性。听音乐让我们平静和放松,它可以帮助一些人在工作时提高工作效率或缓解他们感受到的压力。 这就是为什么如果您不小心丢失了您心…

springcloud-alibaba (04)Gateway与Nacos结合使用

Gateway与Nacos结合使用 🎉欢迎来到这里,今天我将为大家介绍如何将Spring Cloud Gateway和Nacos结合使用,实现一个高效稳定的服务网关!在微服务架构中,API网关是必不可少的一部分,它提供了路由请求、负载均…

java版企业工程项目管理系统源代码-功能清单 图文解析

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示…

新手如何写新闻稿?一文带你了解记者稿的写作步骤与技巧

作为一名新手记者,写稿件是必须掌握的基本技能。记者稿的写作方式有很多种,但基本的步骤和技巧是相同的。在这篇文章中,我将向大家介绍记者稿的写作步骤和技巧,希望能对想要成为一名优秀记者的你有所帮助。 一、确定新闻价值 在写…