• win10下mmsegmentation的安装训练以及使用mmdeploy部署的全过程


    环境搭建

    由于上一篇中已经搭建了mmdetection的环境,本实验中沿用上一个环境
    源码https://github.com/open-mmlab/mmsegmentation下载zip,解压,然后使用pip install -v -e .进行安装

    跑示例demo进行验证
    第一步 我们需要下载配置文件和模型权重文件。

    mim download mmsegmentation --config pspnet_r50-d8_512x1024_40k_cityscapes --dest .
    
    • 1

    完成后,你会在当前文件夹中发现两个文件pspnet_r50-d8_512x1024_40k_cityscapes.py和pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth。
    第二步 验证推理示例

    python demo/image_demo.py demo/demo.png pspnet_r50-d8_512x1024_40k_cityscapes.py pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth --device cpu --out-file result.jpg
    
    • 1

    在当前文件夹中看到一个新的图像result.jpg,其中的分割掩膜覆盖在所有对象上。
    成功

    训练自己的模型

    数据集准备和定制化

    数据集准备,推荐在 mmsegmetaion 目录新建路径 data-my_data,然后将数据集转换成 MMSegmentation 可用的格式,我采用的是VOC2012格式
    │ ├── VOCdevkit
    │ │ ├── VOC2012
    │ │ │ ├── JPEGImages
    │ │ │ ├── SegmentationClass
    │ │ │ ├── ImageSets
    │ │ │ │ ├── Segmentation
    在这里插入图片描述

    修改配置文件

    • data config
      Dataset Config文件在 configs/base/ datasets目录下,需要自己新建一个xxx.py文件。我们以pascal_voc12.py,我的数据格式是VOC的格式;
      需要做以下修改:
    # dataset settings
    dataset_type = 'groupVOCDataset'
    data_root = 'data/my_dataset'
    img_norm_cfg = dict(
        mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
    crop_size = (512, 512)
    train_pipeline = [
        dict(type='LoadImageFromFile'),
        dict(type='LoadAnnotations'),
        dict(type='Resize', img_scale=(2048, 512), ratio_range=(0.5, 2.0)),
        dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
        dict(type='RandomFlip', prob=0.5),
        dict(type='PhotoMetricDistortion'),
        dict(type='Normalize', **img_norm_cfg),
        dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
        dict(type='DefaultFormatBundle'),
        dict(type='Collect', keys=['img', 'gt_semantic_seg']),
    ]
    test_pipeline = [
        dict(type='LoadImageFromFile'),
        dict(
            type='MultiScaleFlipAug',
            img_scale=(2048, 512),
            # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
            flip=False,
            transforms=[
                dict(type='Resize', keep_ratio=True),
                dict(type='RandomFlip'),
                dict(type='Normalize', **img_norm_cfg),
                dict(type='ImageToTensor', keys=['img']),
                dict(type='Collect', keys=['img']),
            ])
    ]
    data = dict(
        samples_per_gpu=4,
        workers_per_gpu=4,
        train=dict(
            type=dataset_type,
            data_root=data_root,
            img_dir='JPEGImages',
            ann_dir='SegmentationClass',
            split='ImageSets/Segmentation/train.txt',
            pipeline=train_pipeline),
        val=dict(
            type=dataset_type,
            data_root=data_root,
            img_dir='JPEGImages',
            ann_dir='SegmentationClass',
            split='ImageSets/Segmentation/val.txt',
            pipeline=test_pipeline),
        test=dict(
            type=dataset_type,
            data_root=data_root,
            img_dir='JPEGImages',
            ann_dir='SegmentationClass',
            split='ImageSets/Segmentation/val.txt',
            pipeline=test_pipeline))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    dataset_type:更改为自己数据集的类型,可以自己命名,也可以不动;

    data_root:更改为自己数据集的路径;

    img_dir:更改为自己数据集图片路径;

    ann_dir:更改为自己数据集标签的路径;

    split:更改为自己的train.txt路径。

    其他参数的含义:

    img_norm_cfg:数据集的方差与均差

    crop_size:数据增强时裁剪的大小

    image_scale:原始图像大小

    sample_per_gpu: batch size

    works_per_gpu: dataloader的线程数目,一般设置为2,4,8

    photoMetricDistortion:数据增强操作。分贝是亮度、对比度、饱和度和色调。

    • class配置
      Dataset Class文件存放在 mmseg/datasets/ 目录下,需要自己新建一个xxx.py文件。我们以groupvoc.py,我的数据格式是VOC的格式
      复制voc.py到新python文件中,需要修改部分:
    1. class GroupVOCDataset(类名,数据格式):这个类名可以更改为自己容易识别的,且与configs/base/ datasets/group_voc2012.py中dataset_type的名称一致;
    2. CLASS:类型标签,更改为自己的类别种类标签;
    3. PALETTE:色盘,更改为自己想要的的色盘颜色;色盘个数与标签个数一致;
    4. super (GroupVOCDateset.self):调用父类的时候更改为自己的数据格式,与类名一致。
    # Copyright (c) OpenMMLab. All rights reserved.
    import os.path as osp
    
    from .builder import DATASETS
    from .custom import CustomDataset
    
    
    @DATASETS.register_module()
    class groupVOCDataset(CustomDataset):#改成自己的
        """Pascal VOC dataset.
    
        Args:
            split (str): Split txt file for Pascal VOC.
        """
        #改
        CLASSES = ('background', 'white_edge', 'silver_defect', 'white_exposed', 'top_half', 'bottom_half',
                   'triangle', 'black_spot', 'sides', 'bag_sides', 'small_white_strip')
    	#个数保持一致
        PALETTE = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128],
                   [128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0],
                   [192, 0, 0], [64, 128, 0]]
    
        def __init__(self, split, **kwargs):
            super(groupVOCDataset, self).__init__(
                img_suffix='.jpg', seg_map_suffix='.png', split=split, **kwargs)
            assert osp.exists(self.img_dir) and self.split is not None
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    设置好之后,还需要设置一下该目录下的__init__文件:

    # Copyright (c) OpenMMLab. All rights reserved.
    from .ade import ADE20KDataset
    from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset
    from .chase_db1 import ChaseDB1Dataset
    from .cityscapes import CityscapesDataset
    from .coco_stuff import COCOStuffDataset
    from .custom import CustomDataset
    from .dark_zurich import DarkZurichDataset
    from .dataset_wrappers import (ConcatDataset, MultiImageMixDataset,
                                   RepeatDataset)
    from .drive import DRIVEDataset
    from .hrf import HRFDataset
    from .isaid import iSAIDDataset
    from .isprs import ISPRSDataset
    from .loveda import LoveDADataset
    from .night_driving import NightDrivingDataset
    from .pascal_context import PascalContextDataset, PascalContextDataset59
    from .potsdam import PotsdamDataset
    from .stare import STAREDataset
    from .voc import PascalVOCDataset
    from .mydata_voc import groupVOCDataset
    
    __all__ = [
        'CustomDataset', 'build_dataloader', 'ConcatDataset', 'RepeatDataset',
        'DATASETS', 'build_dataset', 'PIPELINES', 'CityscapesDataset',
        'PascalVOCDataset', 'ADE20KDataset', 'PascalContextDataset',
        'PascalContextDataset59', 'ChaseDB1Dataset', 'DRIVEDataset', 'HRFDataset',
        'STAREDataset', 'DarkZurichDataset', 'NightDrivingDataset',
        'COCOStuffDataset', 'LoveDADataset', 'MultiImageMixDataset',
        'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset','groupVOCDataset'
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    import的时候要把自己的Dataset加载进来
    __all__数组里面需要加入自己的Dataset类名称

    • total config
      文件在 configs/目录下,以bisenettvv2为例,打开.py的文件,修改base中的datasets。
    _base_ = [
        '../_base_/models/bisenetv2.py',
        '../_base_/datasets/mydata_voc2012.py',
        '../_base_/default_runtime.py', '../_base_/schedules/schedule_160k.py'
    ]
    lr_config = dict(warmup='linear', warmup_iters=1000)
    optimizer = dict(lr=0.05)
    data = dict(
        samples_per_gpu=4,
        workers_per_gpu=4,
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行

    python tools/train.py E:\PycharmProjects\mmsegmentation-master\configs\bisenetv2\bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py --work-dir workplace
    
    
    • 1
    • 2

    结果测试

    python tools/test.py configs/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py workplace/latest.pth --show-dir workplace/output_dir
    
    • 1

    137/137, 3.4 task/s, elapsed: 40s, ETA: 0s

    demo展示

    python demo/image_demo.py data/my_dataset/JPEGImages/20220328_white_6.jpg work_dirs/my_psp/my_psp.py work_dirs/my_psp/latest.pth --device cuda:0 --palette mydata
    
    
    • 1
    • 2

    部署

    python tools/deploy.py configs/mmdet/detection/detection_tensorrt_dynamic-320x320-1344x1344.py ../mmdetection-master/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py ../mmdetection-master/checkpoints/latest.pth ../mmdetection-master/demo/1.jpg --work-dir ../mmdeploy_out/mmdet/faster_rcnn_r50_trt/ --device cuda:0 --dump-info
    
    python tools/pytorch2onnx.py \
        configs/bisenetv2、bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py
        --checkpoint ${CHECKPOINT_FILE} \
        --output-file ${ONNX_FILE} \
        --input-img ${INPUT_IMG} \
        --shape ${INPUT_SHAPE} \
        --rescale-shape ${RESCALE_SHAPE} \
        --show \
        --verify \
        --dynamic-export \
        --cfg-options \
          model.test_cfg.mode="whole"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    config : 模型配置文件的路径

    • checkpoint : 模型检查点文件的路径

    • output-file: 输出的 ONNX 模型的路径。如果没有专门指定,它默认是 tmp.onnx

    • input-img : 用来转换和可视化的一张输入图像的路径

    • shape: 模型的输入张量的高和宽。如果没有专门指定,它将被设置成 test_pipeline 的 img_scale

    • rescale-shape: 改变输出的形状。设置这个值来避免 OOM,它仅在 slide 模式下可以用

    • show: 是否打印输出模型的结构。如果没有被专门指定,它将被设置成 False

    • verify: 是否验证一个输出模型的正确性 (correctness)。如果没有被专门指定,它将被设置成 False

    • dynamic-export: 是否导出形状变化的输入与输出的 ONNX 模型。如果没有被专门指定,它将被设置成 False

    • cfg-options: 更新配置选项

    python ./tools/deploy.py 
        configs/mmseg/segmentation_tensorrt_dynamic-512x1024-2048x2048.py 
        ../mmsegmentation-master/configs/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py
        ../mmsegmentation-master/checkpoints/latest.pth
        ../mmsegmentation-master/workplace/demo/1.jpg
        --work-dir ../mmdeploy_out/mmseg/bisenetv2
        --show 
        --device cuda:0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    python ./tools/deploy.py configs/mmseg/segmentation_tensorrt_dynamic-512x1024-2048x2048.py ../mmsegmentation-master/configs/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py ../mmsegmentation-master/checkpoints/latest.pth ../mmsegmentation-master/workplace/demo/1.jpg --work-dir ../mmdeploy_out/mmseg/bisenetv2 --show --device cuda:0
    
    python tools/deploy.py configs/mmseg/segmentation_tensorrt_static-512x512.py ../mmsegmentation-master/configs/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py ../mmsegmentation-master/checkpoints/bisenetv2/latest.pth ../mmsegmentation-master/workplace/demo/1.jpg --work-dir ../mmdeploy_out/mmseg/bisenetv2/test/ --device cuda:0 --dump-info
    
    • 1
    • 2
    • 3

    部署完成以后在c++中使用exe文件进行推理

    cd Release
    image_segmentation.exe cuda E:\\PycharmProjects\\mmdeploy_out\\mmseg\\bisenetv2 E:\\PycharmProjects\\mmsegmentation-master\\workplace\\demo\\1.jpg
    image_segmentation.exe cuda E:\\PycharmProjects\\mmdeploy_out\\mmseg\\bisenetv2\\test E:\\PycharmProjects\\mmsegmentation-master\\workplace\\demo\\1.jpg
    
    • 1
    • 2
    • 3
  • 相关阅读:
    腾讯推理框架TNN简介
    第十章 JavaScript操作BOM对象
    Shiro授权--ssm
    期望E与高斯分布的期望
    nacos注册中心集群
    Android_Monkey_测试执行策略及标准
    Linux下使用openssl为harbor制作证书
    微信快捷回复怎么设置?
    常用的SSH,你了解多少?(长文警告)
    DevOps和SRE还没搞清楚,平台工程又出现了,它会取代DevOps吗?
  • 原文地址:https://blog.csdn.net/yuanjiaqi_k/article/details/126153117