当前位置: 首页 > news >正文

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

复现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 theoutput 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带过:
在这里插入图片描述

相关文章:

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

复现open-mmlab的mmpose详细细节 1.配置环境2.数据处理3.训练4.改进mmpose4.1 快速调试技巧4.2 快速定位4.3 改进backbone4.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_head4.4.1 …...

编写兼容Python2.x与3.x代码

编写兼容Python2.x与3.x代码 当我们正处于Python2.x到Python3.x的过渡期时,你可能想过是否可以在不修改任何代码的前提下能同时运行在Python2和3中。这看起来还真是一个合理的诉求,但如何开始呢?哪些Python2代码在3.x解释器执行时容易出状况…...

比特币8.12学习问题

疑问:什么是过滤,什么是offset 没有投钱的情况下,怎么用api 公式:单币分配金额 总资金 / 2/ offset/选币数量,其中2 表示多空 买入滑点(Slippage)是指在执行交易订单时,实际成交…...

解析 Vue 中的app.version、 app.provide 与 app.runWithContext :原理、应用与实例剖析

目录 app.provide app.runWithContext ​​​​​​​app.version 非 VIP 用户能够通过积分下载博文资源 app.provide 在 Vue 3.0 中,app.provide充当着在应用层级提供全局共享数据或者服务的关键角色。 app.provide(key, value) 这一方法接收两个关键参数,其中 …...

Ubuntu server 命令行跑selenium

背景 自动化测试都是在本机win上使用selenium 跑自动化脚本,但是服务器都是命令行的没有web界面 依赖包部署 apt-get install zlib1g-dev zlib1g## 安装谷歌浏览器 ## 跳到底部,选择其他平台 https://www.google.com/chrome/## ubuntu # dpkg -i google-chrome-stable_…...

刚刚,模糊测试平台SFuzz受到行业认可

近日,中国网络安全产业联盟(CCIA)正式发布了“2024年网络安全优秀创新成果大赛-安全严选专题赛”评选结果,开源网安模糊测试平台SFuzz凭借重大创新能力,得到组委会认可,获本次大赛创新产品优胜奖。 2024年网…...

数据结构与算法——DFS(深度优先搜索)

算法介绍: 深度优先搜索(Depth-First Search,简称DFS)是一种用于遍历或搜索树或图的算法。这种算法会尽可能深地搜索图的分支,直到找到目标节点或达到叶节点(没有子节点的节点),然后…...

基于lambda简化设计模式

写在文章开头 本文将演示基于函数式编程的理念,优化设计模式中繁琐的模板化编码开发,以保证用尽可能少的代码做尽可能多的事,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder &#xff…...

揭秘! 经纬恒润“车路云一体化”方案研发服务背后的科技驱动力

随着高级别智能驾驶技术的飞速发展,自动驾驶与路侧基础设施协同合作已成为行业内的又一热点。我国率先提出以“车路云一体化”为核心的战略布局,国家政策密集出台,地方试点积极推进,行业标准日趋完善,智能网联汽车“车…...

Redis操作--RedisTemplate(二)StringRedisTemplate

一、介绍 1、简介 由于存储在 Redis 中的 key 和 value 通常是很常见的 String 类型,Redis模块提供了 RedisConnection 和 RedisTemplate 的扩展,分是 StringRedisConnection 和 StringRedisTemplate,作为字符串操作的解决方案。 通过源码…...

【自动驾驶】ROS中自定义格式的服务通信,含命令行动态传参(c++)

目录 通信流程创建服务器端及客户端新建服务通讯文件修改service的xml及cmakelistCMakeLists.txt编辑 msg 相关配置编译消息相关头文件在cmakelist中包含头文件的路径在service包下编写service.cpp在client包下编写client.cpp测试运行查询服务的相关指令列出目前的所有服务&…...

优思学院|PDCA和DMAIC之间如何选择?

在现代组织中,提升方法、质量和效率是企业追求卓越、保持竞争力的核心目标。在这条道路上,DMAIC(定义、测量、分析、改进、控制)和PDCA(计划、执行、检查、行动)被广泛应用于持续改进和问题解决。这两者虽然…...

5 款最佳 Micro SD 卡恢复软件,助您恢复文件

您是否对数据恢复存在某些疑问,并想知道如何恢复 Micro SD 卡上的文件?如果是,那么在本文中您将找到答案。网上有许多专门用于从 Micro SD 卡或格式化的 Micro 卡恢复已删除文件而设计的软件。因此,在本文中,我们将向您…...

【使用教程】CiA402中的“原点回归模式”和“轮廓位置模式”搭配使用操作实例

使用“原点回归模式”配合“轮廓位置模式”是步进或伺服电机使用过程中最常用的方法,其对于提高自动化生产线的准确性和效率具有重要意义,本文将对正常使用控制电机中发送的命令及顺序进行简要说明。 说明:“原点回归”以“堵转回原点”的方式…...

服务器网络不通排查方案

服务器网络不通排查方案 最近遇到了服务器上服务已经启动,但是在浏览器上无法访问的问题,记录一下排查流程 文章目录 服务器网络不通排查方案netstart排查网络连接信息netstat 命令netstat -aptn 命令 iptables总结 netstart排查网络连接信息 netstat …...

Spring Boot + Vue 跨域配置(CORS)问题解决历程

在使用 Spring Boot 和 Vue 开发前后端分离的项目时,跨域资源共享(CORS)问题是一个常见的挑战。接下来,我将分享我是如何一步步解决这个问题的,包括中间的一些试错过程,希望能够帮助到正在经历类似问题的你…...

Think | 大模型迈向AGI的探索和对齐

注:节选自我于24年初所写的「融合RL与LLM思想探寻世界模型以迈向AGI」散文式风格文章,感兴趣的小伙伴儿可以访问我的主页置顶或专栏收录,并制作了电子书供大家参考,有需要的小伙伴可以关注私信我,因为属于技术散文风格…...

为什么选择在Facebook投放广告?

2024年了你还没对 Facebook 广告产生兴趣?那你可就亏大了! 今天这篇文章,我们会分享它对你扩大业务的好处。要知道,Facebook 广告凭借它庞大的用户群和先进的定位选项,已经是企业主们有效接触目标受众的必备神器。接下…...

10 ARM 体系

10 ARM 体系 ARM体系1、基本概念1.1 常见的处理器1.2 ARM7三级指令流水线1.3 初识PC寄存器 2、 ARM核的七种工作模式3、ARM核七种异常 ARM体系 1、基本概念 1.1 常见的处理器 PowerPC处理器:飞思卡尔MPC系列 DSP:TI达芬奇系列 FPGA:Xilinx赛灵思的ZYN…...

ubuntu中设置开机自动运行的(sudo)指令

ubuntu版本:22.04.4 在Ubuntu中设置开机自动运行某一条(需要sudo权限的)指令,我们可以通过编辑系统的启动脚本来实现: 创建一个新的启动脚本:创建一个新的脚本文件,并将其放置在 /etc/init.d/ 目…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...