MMsegmentation与MMdeploy简单使用

最近涉及到了图像分割的任务,于是拿来写下博客加深下使用。
MMsegmentation与MMdeploy的环境配置暂不做讲解,在官网和其他博客中有很多说明。
MMdeploy主要是把pt转为 onnx_int8的情况。
MMsegmentation环境配置可以参考 : 安装与配置MMSegmentation

目录

    • MMsegmentation简易使用
      • 数据集的准备
      • 数据集的config设置
        • 新建一个自己的dataset类
        • 修改__init__.py
        • 新建自己config文件
      • model文件设置
        • 训练
        • 测试
    • MMdeploy简易使用
      • deploy_cfg
      • deploy.py
      • 问题及改进
    • 参考博客
  • 欢迎指正

MMsegmentation简易使用

数据集的准备

采用MICCAI2023牙齿分割挑战的数据集----CHASE_DB1
以下的例子都是针对这个数据集,算是一个二分类的图像分割任务(背景,牙齿)
CHASE_DB1_牙齿分割数据集
我将其放到了如下位置:
work_dir/tt/mmsegmentation-main/datasets/CHASE_DB1/

数据集的config设置

新建一个自己的dataset类

路径如下 : work_dir/mmsegmentation-main/mmseg/datasets
新建一个tooth_test_dataset.py
可以复制同目录下的 cityscapes.py,然后在它上面进行如下3处修改
在这里插入图片描述

修改__init__.py

work_dir/mmsegmentation-main/mmseg/datasets/init.py
在如下两个位置加上刚才的类名,来供后续的代码调用。
在这里插入图片描述

新建自己config文件

work_dir/mmsegmentation-main/configs/base/datasets/
下新建自己的config文件 tooth_test_640x320.py (结尾可以是W x H的形式,方便后续更改)
可以复制同目录下的cityscapes.py进行更改

更改:dataset_type; data_root ; crop_size
train_dataloader中 Img_path 和 seg_map_path路径的设置
其中batch_size 和num_workers可以自行设置
在这里插入图片描述
在这里插入图片描述

model文件设置

上面这样就算是把数据集相关的文件设置好了,现在来配置Model文件的设置

work_dir/mmsegmentation-main/configs
下面有很多种模型,读者可以自行选择一个,笔者选择的是hrnet模型
新建如下py:work_dir/mmsegmentation-main/configs/hrnet/fcn_hr18_4xb2-40k_tooth_test-640x320.py
可以复制同目录下的fcn_hr18_4xb2-40k_cityscapes-512x1024.py 然后进行修改

同样的还有crop_size也需要修改,要和数据集中的大小设置为一致。
在这里插入图片描述

然后来看__base__第一个文件,fcn_hr18_cls2.py
新建/home/siyingzhen/tt/mmsegmentation-main/configs/base/models/fcn_hr18_cls2.py
读者可以通过复制同目录下fcn_hr18.py进行修改
在这里插入图片描述
修改对应类别即可

然后来看__base__第二个文件,这是第一步 数据集的config设置的文件,没什么好讲的
然后来看__base__第四个文件,这是训练时的一些超参数:
在这里插入图片描述

训练

使用.tools/train.py或者.tools/dist_train.sh进行训练
接下来就可以进行训练了
单gpu训练:

mmsegmentation-main]$ python tools/train.py work_dir/mmsegmentation-main/configs/hrnet/fcn_hr18_4xb2-20k_tooth_test-640x320.py --work-dir work_dir

B U G ,笔者不会解决 \textcolor{red}{BUG,笔者不会解决} BUG,笔者不会解决 :
如果使用–resume会使得刚开始加载数据的时候卡住
官方ISSUE

多GPU训练:
CUDA_VISIBLE_DEVICES=3,4,5,6 ./tools/dist_train.sh work_dir/mmsegmentation-main/configs/hrnet/fcn_hr18_4xb2-20k_tooth_test-640x320.py 4

测试

使用.tools/test.py进行测试

python tools/test.py work_dir/mmsegmentation-main/configs/hrnet/fcn_hr18_4xb2-40k_tooth_test-640x320.py  work_dir/mmsegmentation-main/work_dirs/fcn_hr18_4xb2-40k_tooth_test-640x320/iter_20000.pth --show-dir work_dir/mmsegmentation-main/work_dirs/eval_show

然后就可以看到测试结果可视化情况
在这里插入图片描述

MMdeploy简易使用

环境配置相关还是不说了
参考:mmdeploy环境配置
(笔者是参考的官方github)

目标,mmsegmentation的pt模型转为onnx_int8

主要代码:
work_dir/deploy-main/tools/deploy.py
在这里插入图片描述
需要的是4个参数

deploy_cfg

/home/siyingzhen/tt/mmdeploy-main/configs/mmseg/segmentation_onnxruntime-int8_dynamic.py

在这里插入图片描述

需要修改__base__的第二个文件路径
需要修改input_shape中,一般是训练时的图片大小(640x320)
.
./segmentation_static.py如下:
在这里插入图片描述
再往下看…/base/onx_config.py

在这里插入图片描述
会发现这里和
torch.onnx.export的API参数设置基本一致,实际上deploy.py中如果选择转ONNX,最终执行的就是这个接口

现在回过头来看…/base/backends/onnxruntime_int8.py
work_dir/mmdeploy-main/configs/base/backends/onnxruntime-int8.py
笔者是复制了同目录下的onnxruntime-fp16.py然后进行修改的
在这里插入图片描述

deploy.py

于此,就得到了deploy_cfg。
model_cfg在mmsegmentation中我们已经设置了,在work_dir/mmsegmentation-main/configs/hrnet/fcn_hr18_4xb2-40k_tooth_test-640x320.py
checkpoint就是训练的模型权重结果
img 可以是训练中的任意一张图片
使用代码:

python tools/deploy.py 
work_dir/mmdeploy-main/configs/mmseg/segmentation_onnxruntime_static-640x320.py 
work_dir/mmsegmentation-main/configs/hrnet/fcn_hr18_4xb2-40k_tooth_test-640x320.py 
work_dir/mmsegmentation-main/work_dirs/fcn_hr18_4xb2-40k_tooth_test-640x320/iter_20000.pth 
work_dir/mmsegmentation-main/datasets/CHASE_DB1/images/training/A-1.png 
--work-dir work_dir/mmdeploy-main/work_dir/HRnet_640x320 

最终可能会报错(主要是可视化方面的报错),但是也会生成量化后的onnx

Error: 
RuntimeError: Exporting the operator einsum to ONNX opset version 11 is not supported. Support for this operator was added in version 12, try exporting with this version.

问题及改进

最后发现,这个onnx里面的数据还是fp32的。

如果进行如下修改:
在这里插入图片描述

会发现onnx中的数据是fp16的,这个是成功的。

后来问了下别人,如果要从pt量化为onnx int8的话最好使用 onnxruntime.quantization 下 quantize_static或quantize_dynamic的函数

以下是另一个大佬写的mmdeploy环境下,将pt转为onnx_int8的代码,读者可以参考
(涉及了Onnxsim简化 以及 核心的quantize_static)

# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import logging
import os
import os.path as osp
import numpy as np
import random
import subprocess
import sys
from mmdeploy.apis import (extract_model, get_predefined_partition_cfg,visualize_model,torch2onnx)
from mmdeploy.utils import get_input_shape
from mmdeploy.utils import (get_ir_config, get_backend_config,get_common_config,Backend,get_root_logger, load_config)from mmengine.runner import Runner
from mmengine.registry import DATASETS
from onnxruntime.quantization import CalibrationDataReader, QuantFormat, quantize_static, QuantType, CalibrationMethod
from mmdeploy.apis.utils import build_task_processordef batch_reader(datas,task_processor,data_preprocessor,input_shape,batch_size):_datas = []length = len(datas)# print("len: ",length)# exit()max_num = 20 #建议设置到300-500之间,此处设置为20是为了加速。print("max_num: ",max_num)for i, data in enumerate(datas):if i>max_num:return Noneimg_path = data['data_samples'].img_pathdata, model_inputs = task_processor.create_input(img_path,input_shape,data_preprocessor=data_preprocessor)if isinstance(model_inputs, list) and len(model_inputs) == 1:model_inputs = model_inputs[0]if batch_size==1:yield {'input': model_inputs.numpy()}elif (i+1) % batch_size==0:_datas.append(data)yield {'input': np.concatenate(_datas, 0)}_datas = []elif i<length-1:_datas.append(model_inputs.numpy())else:_datas.append(model_inputs.numpy())yield {'input': np.concatenate(_datas, 0)}class DataReader(CalibrationDataReader):def __init__(self, dataset,task_processor,data_preprocessor,input_shape,batch_size=1):self.datas = batch_reader(dataset,task_processor,data_preprocessor,input_shape, batch_size)def get_next(self):return next(self.datas, None)def parse_args():parser = argparse.ArgumentParser(description='Export model to ONNX.')# parser.add_argument('--deploy_cfg',default='/root/mmdeploy/configs/mmseg/segmentation_onnxruntime_int8_static-512x512.py', help='deploy config path')# parser.add_argument('--model_cfg',default='model_weights/fcn/fcn_r50-d8_4xb4-20k_voc12aug-512x512.py',help='model config path')# parser.add_argument('--checkpoint',default='model_weights/fcn/fcn_r50-d8_512x512_20k_voc12aug_20200617_010715-52dc5306.pth',help='model checkpoint path')# parser.add_argument('--test_img',default='/root/mmdeploy/data/VOCdevkit/VOC2012/JPEGImages/2007_000027.jpg',help='image used to convert model model')parser.add_argument('--deploy_cfg',default='', help='deploy config path')parser.add_argument('--model_cfg',default='',help='model config path')parser.add_argument('--checkpoint',default='',help='model checkpoint path')parser.add_argument('--test_img',default='',help='image used to convert model model')parser.add_argument('--work-dir',default='',help='Directory to save output files.')parser.add_argument('--device', help='device used for conversion', default='cpu')parser.add_argument('--log-level',help='set log level',default='INFO',choices=list(logging._nameToLevel.keys()))args = parser.parse_args()return argsdef main():args = parse_args()logger = get_root_logger(log_level=args.log_level)logger.info(f'torch2onnx: \n\tmodel_cfg: {args.model_cfg} 'f'\n\tdeploy_cfg: {args.deploy_cfg}')os.makedirs(args.work_dir, exist_ok=True)# load deploy_cfgdeploy_cfg, model_cfg = load_config(args.deploy_cfg, args.model_cfg)save_file = get_ir_config(deploy_cfg)['save_file']torch2onnx(args.test_img,args.work_dir,save_file,deploy_cfg=args.deploy_cfg,model_cfg=args.model_cfg,model_checkpoint=args.checkpoint,device=args.device)backend_cfg = get_backend_config(deploy_cfg)precision = backend_cfg.get('precision', 'fp32')if precision == 'fp16':import onnxfrom onnxconverter_common import float16common_cfg = get_common_config(deploy_cfg)model = onnx.load(os.path.join(args.work_dir,save_file))model_fp16 = float16.convert_float_to_float16(model, **common_cfg)onnx.save(model_fp16, os.path.join(args.work_dir,save_file.replace('.onnx','_fp16.onnx')))if precision == 'int8':dataset = DATASETS.build(model_cfg['train_dataloader']['dataset'])task_processor = build_task_processor(model_cfg, deploy_cfg, 'cpu')torch_model = task_processor.build_pytorch_model(args.checkpoint)data_preprocessor=getattr(torch_model, 'data_preprocessor', None)input_shape = get_input_shape(deploy_cfg)print("input_shape: ",input_shape)data_reader = DataReader(dataset,task_processor,data_preprocessor,input_shape,1)sim_onnx_path =  os.path.join(args.work_dir,save_file.replace('.onnx','_sim.onnx'))if os.path.exists(os.path.join(args.work_dir,save_file)):command = r"/root/miniconda3/envs/mmdeploy/bin/python -m onnxsim {} {}".format(os.path.join(args.work_dir,save_file),sim_onnx_path)process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)for line in process.stdout:print(line.rstrip())for line in process.stderr:print(line.rstrip(), file=sys.stderr)process.wait()quant_onnx_path = sim_onnx_path.replace("_sim.onnx","_sim_int8.onnx")if os.path.join(sim_onnx_path):quantize_static(model_input=sim_onnx_path, # 输入模型model_output=quant_onnx_path, # 输出模型calibration_data_reader=data_reader, # 校准数据读取器quant_format= QuantFormat.QDQ, # 量化格式 QDQ / QOperatoractivation_type=QuantType.QInt8, # 激活类型 Int8 / UInt8weight_type=QuantType.QInt8, # 参数类型 Int8 / UInt8calibrate_method=CalibrationMethod.MinMax, # 数据校准方法 MinMax / Entropy / Percentileper_channel=True, # 量化通道)# 可视化ONNX模型输出onnx_out_put_file = os.path.join(args.work_dir, 'output_onnxruntime_int8.png')visualize_model(model_cfg,deploy_cfg,[quant_onnx_path],args.test_img,device='cpu',backend=Backend.ONNXRUNTIME,output_file=onnx_out_put_file)#可视化torch模型输出torch_out_put_file = os.path.join(args.work_dir, 'output_torch.png')visualize_model(model_cfg,deploy_cfg,[args.checkpoint],args.test_img,device='cpu',backend=Backend.PYTORCH,output_file=torch_out_put_file)logger.info(f'torch2onnx finished. Results saved to {args.work_dir}')if __name__ == '__main__':main()

笔者任务下部分结果展示
fp32.pt模型预测结果:
在这里插入图片描述

onnx_int8模型的预测结果:
在这里插入图片描述

参考博客

MMSegmentation的用法(手把手入门教程)搭配Colab,对自己的数据进行训练
【Python】mmSegmentation语义分割框架教程(1.x版本)

欢迎指正

因为本文主要是本人用来做的笔记,顺便进行知识巩固。如果本文对你有所帮助,那么本博客的目的就已经超额完成了。

欢迎交流
邮箱:refreshmentccoffee@gmail.com

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

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

相关文章

DriveLM的baseline复现

DriveLM是一篇很有意思的工作&#xff0c;把自动驾驶跟MLLM结合到一起了&#xff0c;实现端到端的决策。 Repo&#xff1a;https://github.com/OpenDriveLab/DriveLM 该工作是基于nuScenes数据集做的&#xff0c;官方paper里给出了数据的具体构建方式&#xff0c;感兴趣的可以…

[HZNUCTF 2023 preliminary]easyAPK-快坚持不下去的第三天

第一做安卓题&#xff0c;前提jadx,java环境&#xff0c;模拟器&#xff0c;我配了好久&#xff0c; 这段代码实现了一个简单的登录界面&#xff0c;用户需要输入用户名和密码。用户名和密码会与预设的硬编码值进行比较&#xff0c;登录成功后会启动另一个 Activity。如果密码错…

★ 算法OJ题 ★ 力扣11 - 盛水最多的容器

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;我将和大家一起做一道双指针算法题--盛水最多的容器~ 目录 一 题目 二 算法解析 三 编写算法 一 题目 11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 二 算法解析 解法1&#xff1a;暴力枚举 …

Mysql基础练习题 620.有趣的电影 (力扣)

620.编写解决方案&#xff0c;找出所有影片描述为 非 boring (不无聊) 的并且 id 为奇数 的影片,返回结果按 rating 降序排列 题目链接&#xff1a; https://leetcode.cn/problems/not-boring-movies/ 建表插入数据&#xff1a; Create table If Not Exists cinema (id int…

【云原生系列之SkyWalking的部署】

1、分布式链路追踪 1.1概念 在较大的web集群和微服务环境中&#xff0c;客户端的一次请求需要经过不同的模块&#xff0c;多个不同中间件&#xff0c;多个不同机器一起相互协作才能处理完成客户端的请求&#xff0c;而在这一系列的请求过程之中,处理流程可能是串行执行,也可能…

论斜率优化dp

论斜率优化dp 1问题2暴力算法-线性dp3斜率优化线性dp4后记 1问题 如下图 看到这题&#xff0c;题面很复杂 其实可以转化为如下问题 有 n n n个任务&#xff0c;排成一个有序序列&#xff0c;我们要解决这些任务 总费用是每一个任务的完成时间乘以费用系数求和 每个任务之前…

sessionstorage和localstorage的使用与区别

sessionstorage和localstorage的使用与区别 localStorage和sessionStorage一样都是用来存储客户端临时信息的对象。他们均只能存储字符串类型的对象&#xff08;虽然规范中可以存储其他原生类型的对象&#xff0c;但是目前为止没有浏览器对其进行实现&#xff09;。 localStor…

Hadoop 下载

下载法一&#xff1a;官方下载 hadoop官网 1.选择要下载的版本&#xff0c;这里我以3.4.0为例进行说明&#xff1b; 2.跳转后&#xff0c;选择对应系统架构的&#xff0c;进行下载&#xff1b; 下载法二&#xff1a;国内镜像源下载 1.阿里云 这里我以mac m1为案例&#x…

Linux日志-wtmp日志

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux 系统中的日志是记录系统活动和事件的重要工具&#xff0c;它们可以帮助管理员监视系统状态、调查问题以及了解系统运行…

【保姆级教程】如何在Win11上搭建一个GPU环境

CUDA和CUDNN安装 CUDA安装 下载对应cuda环境 下载链接&#xff1a;https://developer.nvidia.com/cuda-downloads&#xff0c;图片下载的是 cuda_12.6.1_560.94_windows.exe 然后一路安装即可&#xff1a; 安装路径如下&#xff1a; CUDNN安装 打开cuDNN下载页面 解压后…

嵌入式基础知识-RS232通信协议电路与代码最全分析

1.RS232基本概念 RS232是异步通信&#xff0c;全双工传输&#xff08;异步通信就是无时钟CLK信号&#xff0c;全双工就是能同时收发数据&#xff09;。采用负逻辑传送&#xff0c;规定逻辑“1”的电平为-5V~-15 V&#xff0c;逻辑“0”的电平为5 V&#xff5e;15 V。选用该电气…

阻塞队列-单锁实现

使用阻塞队列 当我们多个线程下 对 一个队列进行操作&#xff0c;队列满了的情况下&#xff0c;其他线程再次 offer&#xff0c;会一直阻塞等待 对一个队列进行出队操作的时候&#xff0c;队列空的情况下&#xff0c;会一直阻塞等待删除&#xff0c;直到队列有元素的时候&a…

C++刷怪笼(2)类和对象的探索-上

1.前言 了解完C的一些入门干货之后&#xff0c;我们来对C的第一个重点就行学习——那就是类和对象&#xff0c;该重点我们分为三篇文章进行学习&#xff0c;请大家跟紧我的脚步&#xff0c;认真学知识哦~ 2.正文——类和对象 2.1类的定义 2.2.1类的定义格式 • class为定义…

echarts遍历区域折线图,单线和多线

// 单线折线图drawonelineCharts(){var echarts require("echarts");var lineCharts document.getElementsByClassName(lineChart); // 对应地使用ByClassNamethis.linecolor[#01FFD4,#1C70DD,#01FFD4,#1C70DD,#01FFD4,#1C70DD]for(var i 0;i < lineCharts.len…

内核头文件, makfile 传参

1 内核头文件&#xff0c;主要指的是&#xff0c; 在板卡上的系统上直接 &#xff0c;编译驱动模块&#xff0c;而不是在虚拟机的内核源码中 去编译内核模块。 2 makefile 传参 &#xff0c;指的是&#xff0c; 内核模块使用 makfile 定义的宏定义。 首先是 关于 在普通的makef…

ubuntu24安装cuda和cudnn

一、安装cuda 确保显卡驱动正确安装 终端输入&#xff1a; nvidia-smi显示下面结果&#xff0c;说明显卡驱动安装正常&#xff0c;可以进行下一步 1.去官网下载CUDA&#xff0c;需要注册账号下载 https://developer.nvidia.com/cuda-toolkit-archive由于我们显卡支持12.2&…

网络通信特刊合集(二)——CMC特刊推荐

特刊征稿 01 特刊名称&#xff1a; Security and Privacy for Blockchain-empowered Internet of Things 截止时间&#xff1a; 提交截止日期 2024 年 10 月 30 日 目标及范围&#xff1a; 本期特刊旨在探讨最近的进展&#xff0c;以解决在区块链授权的物联网中与安全和…

一文带你深度了解FreeRTOS——计数型信号量

本文记录FreeRTOS的计数型信号量知识&#xff0c;希望我的分享对你有所帮助&#xff01; 目录 一、计数型信号量简介 二、创建计数型信号量 1、动态创建计数型信号量 2、静态创建计数型信号量 三、结语 一、计数型信号量简介 计数型信号量在FreeRTOS中用于管理对共享资…

拥有这些AI绘画网站,让你轻松告别手绘时代!

在这个充满无限可能的数字世界里&#xff0c;AI 绘画动漫网站已经成为了许多艺术家和设计师的新宠。从手绘时代的岁月如歌&#xff0c;到今天科技的飞速发展&#xff0c;我们已经可以用AI技术创作出令人惊叹的艺术作品&#xff0c;打开了全新的创作空间。接下来&#xff0c;就让…

如何打造一个智能化的远程在线考试系统?

远程教育与在线考试已成为提升知识传播效率和学习灵活性的重要手段。 土著刷题在线考试系统&#xff0c;凭借其完善的多功能考试模块&#xff0c;为教育机构、学校乃至企业提供了一个智能化的远程在线考试解决方案。 接下来将介绍土著刷题在线考试系统如何助力用户构建一个高效…