MMDetection研究-1.入门及框架

news2024/11/25 1:55:17

记录MMDetection研究过程

0.前言

参考:
1.MMDetection框架入门教程(完全版)
2.

1.框架概述

MMDetection是商汤和港中文大学针对目标检测任务推出的一个开源项目,它基于Pytorch实现了大量的目标检测算法,把数据集构建、模型搭建、训练策略等过程都封装成了一个个模块,通过模块调用的方式,我们能够以很少的代码量实现一个新算法,大大提高了代码复用率

整个MMLab家族除了MMDetection,还包含针对目标跟踪任务的MMTracking,针对3D目标检测任务的MMDetection3D等开源项目,他们都是以Pytorch和MMCV以基础。

Pytorch不需要过多介绍,
MMCV是一个面向计算机视觉的基础库,最主要作用是提供了基于Pytorch的通用训练框架,比如我们常提到的Registry、Runner、Hook等功能都是在MMCV中支持的。
另外,MMCV还提供了通用IO接口、多种CNN网络结构、高质量实现的常见CUDA算子。
在这里插入图片描述

2. 框架流程

2.1 Pytorch算法开发流程

我们使用Pytorch构建一个新算法时,通常包含如下几步:

构建数据集:新建一个类,并继承Dataset类,重写__getitem__()方法实现数据和标签的加载和遍历功能,并以pipeline的方式定义数据预处理流程
构建数据加载器:传入相应的参数实例化DataLoader
构建模型:新建一个类,并继承Module类,重写forward()函数定义模型的前向过程
定义损失函数和优化器:根据算法选择合适和损失函数和优化器
训练和验证:循环从DataLoader中获取数据和标签,送入网络模型,计算loss,根据反传的梯度使用优化器进行迭代优化
其他操作:在主调函数里可以任意穿插训练Tricks、日志打印、检查点保存等操作

2.2 MMDetection算法开发流程

使用Pytorch构建一个新算法时,通常包含如下几步:

  • 注册数据集:CustomDataset是MMDetection在原始的Dataset基础上的再次封装,其__getitem__()方法会根据训练和测试模式分别重定向到prepare_train_img()和prepare_test_img()函数。用户以继承CustomDataset类的方式构建自己的数据集时,需要重写load_annotations()和get_ann_info()函数,定义数据和标签的加载及遍历方式。完成数据集类的定义后,还需要使用DATASETS.register_module()进行模块注册。
  • 注册模型:模型构建的方式和Pytorch类似,都是新建一个Module的子类然后重写forward()函数。唯一的区别在于MMDetection中需要继承BaseModule而不是Module,BaseModule是Module的子类,MMLab中的任何模型都必须继承此类。另外,MMDetection将一个完整的模型拆分为backbone、neck和head三部分进行管理,所以用户需要按照这种方式,将算法模型拆解成3个类,分别使用BACKBONES.register_module()、NECKS.register_module()和HEADS.register_module()完成模块注册。
  • 构建配置文件:配置文件用于配置算法各个组件的运行参数,大体上可以包含四个部分:datasets、models、schedules和runtime。完成相应模块的定义和注册后,在配置文件中配置好相应的运行参数,然后MMDetection就会通过Registry类读取并解析配置文件,完成模块的实例化。另外,配置文件可以通过_base_字段实现继承功能,以提高代码复用率。
  • 训练和验证:在完成各模块的代码实现、模块的注册、配置文件的编写后,就可以使用./tools/train.py和./tools/test.py对模型进行训练和验证,不需要用户编写额外的代码。

2.3 流程对比

虽然从步骤上看MMDetection相比Pytorch的算法实现步骤存在挺大差异,但底层的逻辑实现和Pytorch本质上还是一样的,可以参考下图对照着进行理解,其中蓝色部分表示Pytorch流程,橙色部分表示MMDetection流程,绿色部分表示和算法框架无关的通用流程。
在这里插入图片描述
在开始接触MMDetection的算法实现流程之前,必须要先对注册机制和Hook机制有一个大致的了解,推荐先快速阅读,对注册机制和Hook机制先有一个大体上的了解,看完第五章后再回过头来看注册机制和Hook机制的细节部分会有更深的体会。

3.注册机制

3.1 Registry类

MMDetection作为MMCV的下游项目,继承了MMCV的模块管理方式——注册机制。简单来说,注册机制就是维护几张查询表,key是模块的名称,value是模块的句柄,每张查询表都管理一批功能相似的不同模块。我们每新建一个模块,都要根据模块实现的功能将对应的key-value查询对保存到对应的查询表中,这个保存的过程就称为“注册”。当我们想要调用某个模块时,只需要根据模块名称从查询表中找到对应的模块句柄,然后就能完成模块初始化或方法调用等操作。MMCV通过Registry类来实现字符串(key)到类(value)的映射。

Registry的构造函数如下所示,变量self._module_dict就是上面提到的“查询表”,注册的模块都会存到这个字典类型的变量里,新建一个Registry实例就是新建一张查询表。另外,Registry还支持继承机制。

from mmcv.utils import Registry

class Registry:
	# 构造函数
    def __init__(self, name, build_func=None, parent=None, scope=None):
        # 注册器的名称
        self._name = name
        # 使用module_dict管理字符串到类的映射
        self._module_dict = dict()
        # 使用children管理注册器的子类
        self._children = dict()

        # build_func按照如下优先级初始化:
        # 1. build_func: 优先使用指定的函数
        # 2. parent.build_func: 其次使用父类的build_func
        # 3. build_from_cfg: 默认从config dict中实例化对象
        if build_func is None:
            if parent is not None:
                self.build_func = parent.build_func
            else:
                self.build_func = build_from_cfg
        else:
            self.build_func = build_func
            
        # 设置父类-子类的从属关系
        if parent is not None:
            assert isinstance(parent, Registry)
            parent._add_children(self)
            self.parent = parent
        else:
            self.parent = None

模块的注册通过Registry的成员函数register_module()来实现,register_module()内部又会调用另一个私有函数_register_module(),模块注册的核心功能其实是在_register_module()中实现的。核心代码也很简单,就是将传入的module_name和module_class保存到字典self._module_dict中。

def _register_module(self, module_class, module_name=None, force=False):
	# 如果未指定模块名称则使用默认名称
    if module_name is None:
        module_name = module_class.__name__
        
    # 为了支持在nn.Sequentail中构建pytorch模块, module_name为list形式
    if isinstance(module_name, str):
        module_name = [module_name]
        
    for name in module_name:
    	# 如果force=False, 则不允许注册相同名称的模块
    	# 如果force=True, 则用后一次的注册覆盖前一次
        if not force and name in self._module_dict:
            raise KeyError(f'{
     name} is already registered in {
     self.name}')
        # 将当前注册的模块加入到查询表中
        self._module_dict[name] = module_class

在我们通过字符串获取到一个模块的句柄后,可以通过self.build_func函数句柄来实例化这个模块。build_func可以人为指定,也可以从父类继承,一般来说都是默认使用build_from_cfg()函数,即使用配置参数cfg来初始化该模块。配置参数cfg是一个字典,里面的type字段是模块名称的字符串,其他字段则对应模块构造函数的输入参数。

def build_from_cfg(cfg, registry, default_args=None):
    args = cfg.copy()
	# 将cfg以外的外部传入参数也合并到args中
    if default_args is not None:
        for name, value in default_args.items():
            args.setdefault(name, value)
            
	# 获取模块名称
    obj_type = args.pop('type')
    if isinstance(obj_type, str):
    	# get函数返回registry._module_dict中obj_type对应的模块句柄
        obj_cls = registry.get(obj_type)		
        if obj_cls is None:
            raise KeyError(f'{
     obj_type} is not in the {
     registry.name} registry')
    elif inspect.isclass(obj_type):
    	# type值是模块本身
        obj_cls = obj_type
    else:
        raise TypeError(f'type must be a str or valid type, but got {
     type(obj_type)}')
    
    # 模块初始化, 返回模块实例
    try:
        return obj_cls(**args)
    except Exception as e:
        raise type(e)(f'{
     obj_cls.__name__}: {
     e}')

考虑到registry参数需要指向当前注册器本身,我们一般是调用Registry类的build()方法而不是self.build_func。

def build(self, *args, **kwargs):
    return self.build_func(*args, **kwargs, registry=self)

下面是一个小例子,模拟了网络模型的注册和调用过程。注意一下,我们打印Registry对象时,实际上打印的是self._module_dict中的values。

# 实例化一个注册器用来管理模型
MODELS = Registry('myModels')

# 方式1: 在类的创建过程中, 使用函数装饰器进行注册(推荐)
@MODELS.register_module()
class ResNet(object):
    def __init__(self, depth):
        self.depth = depth
        print('Initialize ResNet{}'.format(depth))

# 方式2: 完成类的创建后, 再显式调用register_module进行注册(不推荐)   
class FPN(object):
    def __init__(self, in_channel):
        self.in_channel= in_channel
        print('Initialize FPN{}'.format(in_channel))
MODELS.register_module(name='FPN', module=FPN)

print

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

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

相关文章

数据排列组合实现

示例 将以下几组数据 (“01”, “02”),(“A1”, “A2”, “A3”),(“B1”, “B2”),(“D1”, “D3”)排列组合成,如:01:…

Isaac Sim软体仿真(以果实采摘场景为例)

如题,在做果蔬采摘的相关项目,背景是通过Isaac Sim做基于强化学习的果蔬采摘,因此简单搭建了一下场景。 效果如下图: 场景 物理环境(重力等):Create --> Physics --> Physics Scene   地面:Create --> Physics --> Ground Plane   灯光:新建文件自带…

基于SpringBoot+Vue的疫情居家办公系统(带1w+文档)

基于SpringBootVue的疫情居家办公系统(带1w文档) 基于SpringBootVue的疫情居家办公系统(带1w文档) 与传统疫情居家办公管理方案对比,应用疫情居家办公管理系统具备很多特点:最先,可以有效地提高疫情居家办公管理信息查找,仅需键入…

NL2SQL之DB-GPT-Hub详解篇:text2sql任务的微调框架和基准对比

NL2SQL之DB-GPT-Hub<详解篇>:text2sql任务的微调框架和基准对比 随着生成式人工智能(Artificial Intelligence Generated Content&#xff0c;简写为 AIGC)时代的到来&#xff0c;使用大规模预训练语言模型(LLM)来进行 text2sql 任务的 sql 生成也越来越常见。基于 LLM 的…

小程序智能视频制作SDK解决方案,云端智能视频制作

无论是个人分享生活的点滴&#xff0c;还是企业展示品牌故事&#xff0c;一段精心制作的视频总能迅速抓住观众的眼球&#xff0c;传递无限价值。专业视频制作往往门槛较高&#xff0c;不仅需要专业的技能和设备&#xff0c;还耗费大量时间和精力。面对这一挑战&#xff0c;美摄…

软件项目开发流程与团队分工整体认知——基于《信息系统项目管理师教程》(需求分析、系统设计、开发、测试、部署与运维、开发工具与管理软件)

文章目录 1、信息系统项目管理师教程——精简说明2、软件工程开发流程与团队分工详解2.1 需求分析2.2 系统设计2.3 开发2.4 测试2.5 部署与运维 3、开发工具与管理软件4、总结 1、信息系统项目管理师教程——精简说明 在《信息系统项目管理师教程》中&#xff0c;有一些章节对…

【JAVA开源】基于Vue和SpringBoot的卫生健康系统

本文项目编号 T 076 &#xff0c;文末自助获取源码 \color{red}{T076&#xff0c;文末自助获取源码} T076&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

食堂订餐系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商品管理&#xff0c;论坛管理&#xff0c;攻略信息管理&#xff0c;公告信息管理&#xff0c;基础数据管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品&#xf…

vscode快速删除一行的快捷键不管用

vscode快速删除一行的快捷键 在vscode中&#xff0c;快速删除一行的快捷键是CtrlShiftk。 因为搜狗软键盘的快捷键和这个快捷键的按键是冲突了&#xff0c;所以快捷键被搜狗输入法给拦截了。把搜狗软键盘的快捷键关闭了或者修改成别的键就好了&#xff0c; 因为我不怎么用软键…

Meta推出的AI视频音频生成模型:Movie Gen

Meta Movie Gen&#xff0c;由 Meta 精心打造的 AI 视频和音频生成工具&#xff0c;能够让用户通过简洁的文本提示轻松创造出高清晰度的视频和音效&#xff0c;并实现精确的视频编辑。用户只需提供文本描述&#xff0c;即可生成高清视频&#xff1b;或者上传图片&#xff0c;便…

python22_replace替换

replace替换 a helloworlddef replace(s, old, new):return new.join(s.split(old))def replace_other(s, number):return s.replace(a[number], m)if __name__ "__main__":print(f"输出结果为{replace(a, hello, world)}")print(f"输出结果为{rep…

Window系统编程 - 文件操作

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天主要介绍使用windows系统编程操作读写文件 文件 CreateFile()函数讲解 介绍:该函数用于打开文件或者I/O流设备&#xff0c;文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和…

泰始明昌文旅:如何打造真正的文旅爆品体系

泰始明昌文旅&#xff1a;如何打造真正的文旅爆品体系 泰始明昌文旅&#xff1a;如何打造真正的爆品体系 关键词&#xff1a;泰始明昌文旅,文旅爆品,核心卖点,用户痛点,项目特点,对手弱点,爆品体系,爆品品类,结构化,品质,价值链接,生态体系,营销推广,持续创新 摘要&#xff…

Adobe Acrobat提示“3D数据解析错误”

原因&#xff1a;在使用Adobe Acrobat打开3D PDF时&#xff0c;因当前Adobe Acrobat的配置存在错误&#xff0c;所以无法打开 解决方法&#xff1a;重新生成配置 首先到达下面的路径C:\Users\你的用户名\AppData\Local\Adobe\Acrobat 下面为我的路径内容 若该路径下存在文件…

第 2 章 基础支持层(上)

2.1 解析器模块 常见的 XML 处理方式 DOM&#xff0c;基于树形结构的 XML 解析方式&#xff0c;它会将整个 XML 文档读入内存并构建一个 DOM 树&#xff0c;基于这棵树形结构对各个节点&#xff08;Node&#xff09;进行操作。 SAX&#xff0c;基于事件模型的 XML 解析方式&a…

如何制作低代码开发的视频教程?

如何制作低代码开发的视频教程&#xff1f; 随着数字化转型的加速&#xff0c;越来越多的企业和组织开始采用低代码开发平台来加速应用程序的构建。对于许多开发者和业务人员来说&#xff0c;学习如何使用这些平台可以显著提高工作效率。因此&#xff0c;创建一份清晰、实用且…

数字化AI新赋能,智享AI直播:开启一个全新的直播时代!

数字化AI新赋能&#xff0c;智享AI直播&#xff1a;开启一个全新的直播时代! 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;AI直播技术的崛起&#xff0c;无疑是数字化时代的一大亮…

springMVC添加webapp

项目结构-->模块-->找到想添加的模块下的web 点击号 添加路径 会在.../src/main/目录下自动生成目录

Javaava版本ERP管理系统源码-打造企业核心竞争力:ERP管理系统创新实践

在数字化转型的浪潮中&#xff0c;企业对于高效、稳定且易于扩展的管理系统的需求日益增长。为了满足这一需求&#xff0c;我们开发了一款基于Java技术的ERP&#xff08;Enterprise Resource Planning&#xff09;管理系统&#xff0c;该系统通过Spring Cloud Alibaba、Spring …

Axios 网络请求

文章目录 Axios 网络请求1.Axios 使用1.Axios 简介2.Axios 安装安装命令 3.Axios 引入方式全局引入局部引入 2.整合 vue1.在组件中使用 axios 发送请求发送结果这里就出现了跨域问题 3.跨域后端解决办法全局配置类 加入注解 CrossOrigin请求结果 全局配置 baseUrl Axios 网络请…