复现、并改进open-mmlab的mmpose详细细节

news2024/12/22 22:35:11

复现open-mmlab的mmpose详细细节

  • 1.配置环境
  • 2.数据处理
  • 3.训练
  • 4.改进mmpose
    • 4.1 快速调试技巧
    • 4.2 快速定位
    • 4.3 改进backbone
      • 4.3.1 使用说明
      • 4.3.2 改进案例
        • 4.3.2.1 复现mmpose原配置文件
        • 4.3.2.2 复现开源项目
        • 4.3.2.3 修改配置文件
        • 4.3.2.4 修改新模型
    • 4.4 添加auxiliary_head
      • 4.4.1 添加auxiliary_head配置
      • 4.4.2 注意事项

1.配置环境

stage1:创建python环境

conda create --name openmmlab python=3.8 -y
conda activate openmmlab

stage2:安装pytorch(这里我是以torch1.10.0为例)

pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio==0.11.0 --extra-index-url https://download.pytorch.org/whl/cu113

stage3:安装MMCV,全部都可以加上清华源,-i https://pypi.tuna.tsinghua.edu.cn/simple

pip install openmim
pip install mmengine
pip install "mmcv>=2.0.1"
pip install "mmdet>=3.1.0"

但是,这里在安装mmcv的时候,容易出错,比如:ImportError: DLL load failed while importing _ext: 找不到指定的程序。
很大就是mmcv版本装的有问题。
我们定位到mmcv的安装文档

https://mmcv.readthedocs.io/en/latest/get_started/installation.html#install-mmcv

会有根据操作系统、cuda版本,以及torch的版本后,确定自己选择的mmcv版本,进而生成最终的安装指令。
在这里插入图片描述
stage4:安装MMPose:
方式1:

git clone https://github.com/open-mmlab/mmpose.git
cd mmpose
pip install -r requirements.txt
pip install -v -e .

方式2:

pip install "mmpose>=1.1.0"

2.数据处理

这里我们以 CrowdPose 数据集为例,下载链接为:

https://github.com/MVIG-SJTU/AlphaPose/blob/pytorch/doc/CrowdPose.md

这里我们任意选取configs/body_2d_keypoint文件中的文件,以:topdown_heatmap/crowdpose/td-hm_res50_8xb64-210e_crowdpose-256x192.py为例。
新建文件夹CrowdPose,并将下载下来的数据集文件夹存放进去:
在这里插入图片描述
我们首先更改选好的配置文件td-hm_res50_8xb64-210e_crowdpose-256x192.py中的data_root,路径就是刚才我们新建好的文件夹。
在这里插入图片描述
接着,还是同一份配置文件,我们更改标注文件,这里文件的默认为:'annotations/mmpose_crowdpose_train.json',我们可以根据这个来修改我们下载下来的数据集文件夹名称,也可以将这里反过来改成我们自己的数据集文件夹名,都可以的。
在这里插入图片描述

3.训练

4.改进mmpose

MMPose中,所有与模型结构实现相关的代码都存放在 models目录下:
在这里插入图片描述

4.1 快速调试技巧

mmpose是基于pytorch开发的,所以在数据预处理以及前向传播的调用,都在底层环境的mmengine中:/mmengine/model/base_model/base_model.py
在这里插入图片描述
我们这里可以打断点过来,可以看到,image的维度是[batch_szie, 3, 256, 192];
在这里插入图片描述
随后,我们可以在我们选用的backbone,或者自己新加的backbone中,在前向传播forward函数中打上断点,会发现这里的x就是上述的image,与此同时,也能看到每一层网络结构后feature map的变化。
在这里插入图片描述
这里,给推荐另一个小技巧,因为每次从整个框架的train开始断点,耗时麻烦。
我们直接在backbone的py文件中,进行调试,这样就大大减少了我们改进或者调试模型的复杂度,我们只要添加如下代码,将config配置文件中模型的extra 字典复制过来,然后在当前py文件进行debug就省事省力了。

if __name__ == '__main__':
	extra = dict(
	    stage1=dict(
	        num_modules=1,
	        num_branches=1,
	        block='BOTTLENECK',
	        num_blocks=(4,),
	        num_channels=(64,)),
	    stage2=dict(
	        num_modules=1,
	        num_branches=2,
	        block='BASIC',
	        num_blocks=(4, 4),
	        num_channels=(32, 64)),
	    stage3=dict(
	        num_modules=4,
	        num_branches=3,
	        block='BASIC',
	        num_blocks=(4, 4, 4),
	        num_channels=(32, 64, 128)),
	    stage4=dict(
	        num_modules=3,
	        num_branches=4,
	        block='BASIC',
	        num_blocks=(4, 4, 4, 4),
	        num_channels=(32, 64, 128, 256)))
	model = HRNet(extra, in_channels=3)
	model.eval()

	x = torch.randn((2, 3, 256, 192))

 	outputs = model(x)

4.2 快速定位

backboneneckhead各结构实例化的接口位于mmpose/models/pose_estimators/base.py中。
在这里插入图片描述

4.3 改进backbone

4.3.1 使用说明

如果希望实现一个新的backbone,你需要在目录 backbones新建一个文件进行定义。
在这里插入图片描述

新建的骨干网络需要继承BaseBackbone 类,其他方面与你继承 nn.Module 来创建没有任何不同。

在完成骨干网络的实现后,你需要使用 MODELS来对其进行注册:

from mmpose.registry import MODELS
from .base_backbone import BaseBackbone
@MODELS.register_module()
class YourNewBackbone(BaseBackbone): 

在这里插入图片描述
最后,请记得在backbones/__init__.py 中导入你的新骨干网络。
在这里插入图片描述

4.3.2 改进案例

以复现mmpose配置文件:configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py为例,该配置文件的backbone对应的配置文件为:‘HRNet’,我们比如想替换:

https://github.com/xzz777/SCTNet

中的开源项目中的分割backbone。

4.3.2.1 复现mmpose原配置文件

为了确保替换的backbone能跑通,最好是跑一遍原始配置文件,这样清楚知道模型的backbone、neck、head各结构输出的维度,这样方便在新模型中进行调整。
我们首先复现官方提供的原配置文件:configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py
配置文件中:input_size表示dataloder预处理后图片的size(也就是模型的输入图像大小),heatmap_size表示最后输出的key points热图的size,这里可以更改为指定的size,比如:640,相应的热图size相应缩放4倍。
在这里插入图片描述
backbone输入:[2, 3, 640, 640],backbone的输出为:[batch_size, 32, 160, 160]。
在这里插入图片描述
Head表示输出头,in_channels为32,表示backbone的输出通道数(如果没有设置neck结构的话),out_channels为17,表示Head的输出通道数,结合上述的heatmap_size最终的输出为:[batch_size, 17, 160, 160]。
在这里插入图片描述

4.3.2.2 复现开源项目

我们想用:

https://github.com/xzz777/SCTNet

中的开源项目中的分割backbone,那复现一下看一下底层的feature map的变化对于我们快速改完模型是帮助很大的。
输入:[2, 3, 640, 640],输出如下:
在这里插入图片描述

4.3.2.3 修改配置文件

我们参照4.3.1 使用说明新建好开源项目中的backbone后,我们对配置文件中的model字典文件进行更改:

# model settings
model = dict(
    type='TopdownPoseEstimator',
    data_preprocessor=dict(
        type='PoseDataPreprocessor',
        mean=[123.675, 116.28, 103.53],
        std=[58.395, 57.12, 57.375],
        bgr_to_rgb=True),
    # backbone=dict(
    #     type='HRNet',
    #     in_channels=3,
    #     extra=dict(
    #         stage1=dict(
    #             num_modules=1,
    #             num_branches=1,
    #             block='BOTTLENECK',
    #             num_blocks=(4, ),
    #             num_channels=(64, )),
    #         stage2=dict(
    #             num_modules=1,
    #             num_branches=2,
    #             block='BASIC',
    #             num_blocks=(4, 4),
    #             num_channels=(32, 64)),
    #         stage3=dict(
    #             num_modules=4,
    #             num_branches=3,
    #             block='BASIC',
    #             num_blocks=(4, 4, 4),
    #             num_channels=(32, 64, 128)),
    #         stage4=dict(
    #             num_modules=3,
    #             num_branches=4,
    #             block='BASIC',
    #             num_blocks=(4, 4, 4, 4),
    #             num_channels=(32, 64, 128, 256))),
    #     init_cfg=dict(
    #         type='Pretrained',
    #         checkpoint='https://download.openmmlab.com/mmpose/'
    #         'pretrain_models/hrnet_w32-36af842e.pth'),
    # ),
    backbone=dict(
        type='SCTNet',
        init_cfg=dict(
            type='Pretrained',
            checkpoint=checkpoint_backbone
        ),
        base_channels=64,
        spp_channels=128),
    head=dict(
        type='HeatmapHead',
        #in_channels=32,
        in_channels=256,
        out_channels=17,
        deconv_out_channels=None,
        loss=dict(type='KeypointMSELoss', use_target_weight=True),
        decoder=codec),
    test_cfg=dict(
        flip_test=True,
        flip_mode='heatmap',
        shift_heatmap=True,
    ))
4.3.2.4 修改新模型

上述我们分别在复现mmpose框架和我们想要采用的分割开源项目后,可以发现即使统一输入图像为640x640,两个项目的backbone的输出都是不一样的。这里因为基于mmpose框架来改,所以我们肯定是将分割开源项目backbone的输出尽量调整和我们上述复现mmpose中hrnet的输出一致,这样在框架后续中求loss等也就不会报错了。
这是分割开源项目的backbone的输出:
在这里插入图片描述
这是mmpose中hrnet的输出:
在这里插入图片描述
两个backbone输出的通道数不一致,这会导致Head报错,这里我们对配置文件的Head接受输入的通道数进行修改,将32更改为我们的新backbone的输出通道数256。
在这里插入图片描述

所以,现在两个backbone的输出还差宽高不一致,我们这个时候来进一步看一下,Head部分的代码,Head采用’HeatmapHead’,我们定位到mmpose/models/heads/heatmap_heads/heatmap_head.py,发现前向传播forward中代码不多,所以我们选择在Head部分调整backbone的输出。
在这里插入图片描述
因为我们的backbone中输出的是list,这里我们要对原始的forward进行修改,我们选用backbone最后层的输出,也就是list[0],同时我们采用双线性插值调整输出的宽高。

    def forward(self, feats: Tuple[Tensor]) -> Tensor:
        """Forward the network. The input is multi scale feature maps and the
        output is the heatmap.

        Args:
            feats (Tuple[Tensor]): Multi scale feature maps.

        Returns:
            Tensor: output heatmap.
        """
        # x = feats[-1]
        x = feats[0]

        x = self.deconv_layers(x)
        x = self.conv_layers(x)
        x = self.final_layer(x)

        x = F.interpolate(input=x, scale_factor=2, mode='bilinear')

        return x

4.4 添加auxiliary_head

4.4.1 添加auxiliary_head配置

上述git中使用了Transformer Block作为辅助head,这里我们也尝试在我们的mmpose框架中进行改进。

https://github.com/xzz777/SCTNet

我们参照这个git,添加auxiliary_head的配置文件。
在这里插入图片描述

# model settings
model = dict(
    type='TopdownPoseEstimator',
    data_preprocessor=dict(
        type='PoseDataPreprocessor',
        mean=[123.675, 116.28, 103.53],
        std=[58.395, 57.12, 57.375],
        bgr_to_rgb=True),
    backbone=dict(
        type='SCTNet',
        init_cfg=dict(
            type='Pretrained',
            checkpoint=checkpoint_backbone
        ),
        base_channels=64,
        spp_channels=128),
    head=dict(
        type='HeatmapHead_Revise',
        # in_channels=32,
        in_channels=256,
        out_channels=17,
        deconv_out_channels=None,
        loss=dict(type='KeypointMSELoss', use_target_weight=True),
        decoder=codec),
    auxiliary_head=[
            dict(
                type='VitGuidanceHead',
                init_cfg=dict(
                    type='Pretrained',
                    checkpoint= checkpoint_teacher),
                in_channels=256,
                channels=256,
                base_channels=64,
                in_index=2,
                num_classes=171,
                loss_decode=dict(type='AlignmentLoss', loss_weight=[3, 15, 15, 15]))
        ],
    test_cfg=dict(
        flip_test=True,
        flip_mode='heatmap',
        shift_heatmap=True,
    ))

但是,发生了报错:

TypeError: init() got an unexpected keyword argument ‘auxiliary_head’

我们在进入底层环境(这里就是我们对应配置的Anaconda环境)后,我的是:D:\Anaconda3\envs\SCTNet\Lib\site-packages\mmengine\registry\build_functions.py,定位到报错的位置,发现是在:mmpose/models/pose_estimators/topdown.py
在这里插入图片描述
在TopdownPoseEstimator类中,添加缺少了‘auxiliary_head’字典的键。
在这里插入图片描述
随后,我们得在mmpose框架中注册一个新的head,你需要在目录 mmpose/models/heads/heatmap_heads新建一个文件进行定义。
在这里插入图片描述

新建的head网络需要继承BaseHead类,其他方面与你继承 nn.Module 来创建没有任何不同。

在完成骨干网络的实现后,你需要使用 MODELS来对其进行注册:

from mmpose.registry import MODELS
from ..base_head import BaseHead
@MODELS.register_module()
class YourNewHead(BaseHead): 

在这里插入图片描述

最后,请记得在heatmap_heads/__init__.py 中导入你的新nead网络。
在这里插入图片描述

4.4.2 注意事项

可能会报错:

No module named ‘mmcv.cnn.utils.weight_init’

改成:

from mmengine.model import BaseModule, constant_init, kaiming_init, trunc_normal_init, trunc_normal_init, normal_init

由于,继承了BaseHead,
在这里插入图片描述
BaseHead里有3个abstractmethod,抽象方法在基类中没有实现,子类必须实现这些方法,否则子类也会被视为抽象类,无法实例化。

在这里插入图片描述
如果我们暂时没有使用到这3个方法,可以重写出来,用pass带过:
在这里插入图片描述

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

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

相关文章

Python OpenCV 影像处理:读取、显示、储存影片

► 前言 本篇将介绍使用OpenCV Python撷取网路摄影机(webcam)的即时画面影像处理与显示,以及透过读取、显示和储存硬盘中的影片档案来实现影片操作。这将帮助大家了解如何使用OpenCV在影片上进行各种操作。 ► OpenCV Python撷取网路摄影机 OpenCV首先建立了一个…

【计算机网络】TCP实战

其实有了UDP的基础,TCP不管怎么说学习起来都还是比较舒服的,至少是比直接就学习TCP的感觉好。 这篇文章最多就是介绍一下起手式,如果想带业务的话和UDP那篇是完全一样的,就不进行演示了。 总的来说还是很简单的。 目录 Echo服务端…

魔方远程时时获取短信内容APP 前端Vue 后端Ruoyi框架(含搭建教程)

前端Vue 后端Ruoyi框架 APP原生JAVA 全兼容至Android14(鸿蒙 澎湃等等) 前后端功能: ①后端可查看用户在线状态(归属地IP) ②发送短信(自定义输入收信号码以及短信内容,带发送记录) ③短信内容分类清晰(接收时间、上传时间等等) ④前后端分离以及A…

Doris与StarRocks

目录 Doris Doris 架构 存储引擎 查询引擎 索引结构 存储模型 物化视图 使用场景 StarRocks 架构设计 架构选择 存算一体 节点 FE BE 存算分离 节点 存储 缓存 适用场景 OLAP 多维分析 实时数据仓库 高并发查询 统一分析 Doris和StarRocks对比 大规模…

Vue3中组件的多种写法

SFC单文件组件,一个vue写一个组件 使用 defineComponent h函数 去进行组件编写 使用 defineComponent JSX/TSX 去进行组件编写 需要安装插件pnpm i vitejs/plugin-vue-jsx -D 引入 配置 使用组件

Android的OkHttp使用和原理

前言 OkHttp的出现代替了HttpUrlConnection,被谷歌官方收纳为底层的网络框架。特点如下: 支持HTTP/2框架下的socket复用通过连接池减少连接的延时使用GZIP进行数据压缩使用缓存技术避免重复请求 当网络出现问题时,OkHttp会静默重新恢复连接…

uniapp组件使用

uni-popup 默认z-index是99 https://uniapp.dcloud.net.cn/component/uniui/uni-popup.html#uni-popup-%E5%BC%B9%E5%87%BA%E5%B1%82 uni-icons uniapp自带图标&#xff1a;https://hellouniapp.dcloud.net.cn/pages/extUI/icons/icons <uni-icons type"left"…

基于JAVA的在线教育系统设计与实现,源码、部署+讲解

摘 要 随着信息化的日益发展&#xff0c;互联网信息技术的发展日新月异。互联网在线教育模式也在不断的被革新。从传统的线下辅导授课&#xff0c;转变成现在的线上教育遍地开花。线上教育已经犹如雨后春笋一般冒芽而出&#xff0c;这为我们的生活带来了许多变动。 基于网络…

江协科技STM32学习笔记(第12章 PWR电源控制)

第12章 PWR电源控制 12.1 PWR电源控制 12.1.1 PWR简介 芯片在3种低功耗模式下&#xff0c;是没法直接再下载程序的。这是因为芯片在睡眠&#xff0c;不会关注调试端口了。解决办法就是&#xff1a;1.按住复位键不动&#xff1b;2.点下载按钮&#xff1b;3.及时从开复位键。这…

怎样使用sudo的时候不需要输入密码?

在Ubuntu等Linux系统下&#xff0c;经常要在个人账户使用sudo命令来执行一些需要root权限的命令&#xff0c;但是需要输入该账户的密码&#xff0c;有时候显得很繁琐&#xff0c; 那么怎样使用sudo的时候不需要输入密码呢&#xff1f; 有如下两种方法&#xff1a; 常规方法1…

颠覆传统 北大新型MoM架构挑战Transformer模型,显著提升计算效率

挑战传统的Transformer模型设计 在深度学习和自然语言处理领域&#xff0c;Transformer模型已经成为一种标准的架构&#xff0c;广泛应用于各种任务中。传统的Transformer模型依赖于一个固定的、按深度排序的层次结构&#xff0c;每一层的输出都作为下一层的输入。这种设计虽然…

Spring Boot集成selenium实现自动化测试

1.什么是selenium&#xff1f; Selenium 是支持web 浏览器自动化的一系列工具和 库的综合项目。 它提供了扩展来模拟用户与浏览器的交互&#xff0c;用于扩展浏览器分配的分发 服务器&#xff0c; 以及用于实现W3C WebDriver 规范 的基础结构&#xff0c; 该规范允许您为所有主…

全国各地认可再+4,美创入选ZJCERT等多省市网络数据安全支撑单位

近一个月以来&#xff0c;美创科技连获多省市认可&#xff0c;相继入选&#xff1a; ZJCERT网络安全应急服务支撑单位 杭州市委网信办网络安全技术服务单位 南通市网络和数据安全技术支撑单位 济南市卫生健康系统网络和数据安全应急技术支撑单位 ZJCERT第三届网络安全应急服…

力扣3148. 矩阵中的最大得分

题目 给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格&#xff08;不必相邻&#xff09;。从值为 c1 的单元格移动到值为 c2 的单元格的得分为 c2 - c1 。 你可以从 任一 单元格开始&#xff0c;并…

Ubuntu+QT编译QTXlsx库

1.在GitHub上下载QT Xlsx 的源码&#xff0c;网站链接如下&#xff08;需要科学上网&#xff09; https://github.com/dbzhang800/QtXlsxWriter 下载好的内容如下 然后在目录下右击启动终端 输入如下命令 先输入qmake qtxlsx.pro再输入make最后sudo make install 注意&…

医药企业如何选择数字化营销模式

有产品&#xff0c;有市场&#xff0c;便有了窜货这一现象&#xff0c;经销商之间窜货不仅伤害了生产企业的渠道和价格体系&#xff0c;还影响企业的形象&#xff0c;降低了企业品牌的价值。而这一问题的根源就是企业对产品的营销管理信息不对称&#xff0c;而数字化营销被视为…

【常见算法题】斐波那契数列(矩阵快速幂)

一、题目描述 大家都知道斐波那契数列&#xff0c;现在要求输入一个正整数 n &#xff0c;请你输出斐波那契数列的第 n 项。 斐波那契数列满足如下 二、解题思路 2.1 普通处理方式 使用递归直接计算 int fib(int n) {if (n 1 || n 2) return 1;return fib(n - 1) fib(n…

实现信创Linux麦克风摄像头录制(源码,银河麒麟、统信UOS)

随着信创国产化浪潮的来临&#xff0c;在国产操作系统上的应用开发的需求越来越多&#xff0c;其中一个就是需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音&#xff0c;将它们录制成一个mp4文件。那么这个要如何实现了&#xff1f; 一. 技术方案 要完成这些功能&a…

北大研究生公选课资料现已公开,数据库学习秘籍速来get!

为促进基础软件在中国高校的传播&#xff0c;进一步提高在校研究生对基础软件的学习和开发实践能力&#xff0c;拓数派与开源联盟 PG 分会携手合作&#xff0c;走进北京大学&#xff0c;进行了北大软件与微电子学院 2024 年《北京大学 PostgreSQL 内核开发&#xff1a;从入门到…

构建高效沃尔玛自养号测评系统:技术策略与实战指南

搭建沃尔玛自养号测评技术系统是一个涉及多方面技术和资源投入的过程&#xff0c;旨在通过自行构建和掌控测评环境&#xff0c;利用真实国外买家的信息和资料来创建买家账号&#xff0c;模拟真实的购买和评价过程&#xff0c;从而提升商品权重和销量。以下是搭建该系统的主要步…