学习使用paddle来构造hrnet网络模型
1、首先阅读了hrnet的网络结构分析,了解到了网络构造如下:
参考博文姿态估计之2D人体姿态估计 - (HRNet)Deep High-Resolution Representation Learning for Human Pose Estimation(多家综合)-CSDN博客
最重要的就是这个图了:
在这里主要是注释自己对这个图的认识和理解:
在RGB图片(256*192*3)输入主干网络之前先经过了两次conv卷积网络(包含3*3的卷积层和归一层,激活函数relu),然后就来到了layer1(主要是改变了通道数,通过重复堆叠Bottleneck来实现
),然后进行两个层次的特征处理,一个是向下进行二倍采样,一个是直接过来,这就形成了所谓的不同维度的特征信息,然后进行融合,因为它们的通道数并不相同,所以就需要进行下采样(down),和上采样(up),具体这两个网络结构也已经放出来了。然后就是将前面得到的不同维度的特征信息融合·,输入到下一层里面。按照这个流程做下去,到最后,也就是stage4的时候,进行最后一次的多维度的特征信息融合,然后输入到最后一个卷积里面,这个卷积主要是输出17个关键点的预测信息,所以可以看到那里是C17(17个通道)也相当于17个卷积核(1*1的)。
然后图片里面的
k3, s2, p1, 和 c64 通常是卷积层的超参数,它们分别代表:
k3:这通常指的是卷积核(kernel)的大小。k3 表示卷积核的大小为 3x3,即宽度和高度都是3。
s2:这是步长(stride)的参数。s2 表示卷积操作的步长为2。步长决定了卷积核在输入特征图上滑动时,每次移动的像素数量。
p1:这是填充(padding)的参数。p1 表示在输入特征图的边界周围填充1个像素。填充通常用于控制输出特征图的大小,以及确保在特征图的边缘信息不会被丢失。
c64:这指的是输出通道数(number of output channels)。c64 表示该卷积层有64个输出通道,即卷积操作会产生64个不同的特征图。
其中输出通道数C64是和卷积核相对应的,有多少个卷积核就有多少个输出通道。
我去学习,看了一哈paddledetection里面的,发现有使用paddle实现HRNet网络,于是我就打算进行复现,训练出自己想要的模型效果,
值得一提的是这个hrnetpostprocess的代码的实现,运用了中心点+尺度因子+热力图的关系,来改变固定预测关键点是整数值。
class HRNetPostProcess(object):def __init__(self, use_dark=True):self.use_dark = use_darkdef get_max_preds(self, heatmaps):'''get predictions from score maps
该类主要用于从热图(heatmaps)中获取预测的关键点坐标和对应的最大置信度Args:heatmaps: numpy.ndarray([batch_size, num_joints, height, width])heatmaps是一个四维数组 batch_size是批处理大小,num_joints是关键点的数量,height和width是热图的高度和宽度Returns:preds: numpy.ndarray([batch_size, num_joints, 2]), keypoints coordsmaxvals: numpy.ndarray([batch_size, num_joints, 2]), the maximum confidence of the keypoints输出:两个numpy数组,preds和maxvals。preds的形状为[batch_size, num_joints, 2],表示每个关键点的坐标;maxvals的形状也为[batch_size, num_joints, 1],表示每个关键点的最大置信度。'''assert isinstance(heatmaps,np.ndarray), 'heatmaps should be numpy.ndarray'assert heatmaps.ndim == 4, 'batch_images should be 4-ndim'#检查heatmaps是否是4维的batch_size = heatmaps.shape[0]num_joints = heatmaps.shape[1]width = heatmaps.shape[3]heatmaps_reshaped = heatmaps.reshape((batch_size, num_joints, -1))#代码重新整形heatmaps,使其从[batch_size, num_joints, height, width]变为[batch_size, num_joints, height*width]idx = np.argmax(heatmaps_reshaped, 2)#使用np.argmax获取每个位置的最大值的索引,这对应于每个关键点在热图中的位置。maxvals = np.amax(heatmaps_reshaped, 2)#使用np.amax获取每个位置的最大值,这对应于每个关键点的置信度。# 将maxvals和idx重新整形为[batch_size, num_joints, 1]maxvals = maxvals.reshape((batch_size, num_joints, 1))idx = idx.reshape((batch_size, num_joints, 1))preds = np.tile(idx, (1, 1, 2)).astype(np.float32)#使用np.tile复制idx的每一行和每一列,生成一个新的三维数组preds[:, :, 0] = (preds[:, :, 0]) % width #对这个新数组的第三列(即每个关键点的x坐标)进行模运算,以确保其值在[0, width)范围内preds[:, :, 1] = np.floor((preds[:, :, 1]) / width)#对新数组的第二列(即每个关键点的y坐标)进行整除运算,然后取整,以获取每个关键点的y坐标。pred_mask = np.tile(np.greater(maxvals, 0.0), (1, 1, 2))#创建一个掩码pred_mask,其中最大置信度大于0的位置为1,否则为0。pred_mask = pred_mask.astype(np.float32)#使用pred_mask将preds中置信度不为0的位置设置为0。preds *= pred_mask#preds *= pred_mask这一行,实际上是将那些置信度不大于0的关键点坐标设置为0。这可能是为了确保只返回那些有足够置信度的预测结果。return preds, maxvalsdef gaussian_blur(self, heatmap, kernel):#对热力图进行高斯模糊border = (kernel - 1) // 2#根据核大小计算边界大小,用于扩展热图以处理边界效应batch_size = heatmap.shape[0]num_joints = heatmap.shape[1]height = heatmap.shape[2]width = heatmap.shape[3]for i in range(batch_size):#遍历批处理中的每个热图:对于每个热图,遍历每个关键点。for j in range(num_joints):origin_max = np.max(heatmap[i, j])dr = np.zeros((height + 2 * border, width + 2 * border))dr[border:-border, border:-border] = heatmap[i, j].copy()#将原始热图扩展,以便在应用高斯模糊时不会丢失边界信息dr = cv2.GaussianBlur(dr, (kernel, kernel), 0)#使用OpenCV的GaussianBlur函数对扩展的热图进行高斯模糊heatmap[i, j] = dr[border:-border, border:-border].copy()#还原热图:将模糊后的热图裁剪回原始大小。heatmap[i, j] *= origin_max / np.max(heatmap[i, j])#确保模糊后的热图的最大值与原始热图的最大值相同。return heatmapdef dark_parse(self, hm, coord):#两个参数:hm(一个二维numpy数组,表示一个关键点的热图)和coord(一个包含x和y坐标的列表或元组)heatmap_height = hm.shape[0]heatmap_width = hm.shape[1]px = int(coord[0])py = int(coord[1])if 1 < px < heatmap_width - 2 and 1 < py < heatmap_height - 2:#确保提供的坐标位于热图的有效范围内dx = 0.5 * (hm[py][px + 1] - hm[py][px - 1])#计算梯度和Hessian矩阵:基于热图在给定坐标周围的像素值,计算梯度(dx, dy)和Hessian矩阵(dxx, dxy, dyy)。dy = 0.5 * (hm[py + 1][px] - hm[py - 1][px])dxx = 0.25 * (hm[py][px + 2] - 2 * hm[py][px] + hm[py][px - 2])dxy = 0.25 * (hm[py + 1][px + 1] - hm[py - 1][px + 1] - hm[py + 1][px - 1] \+ hm[py - 1][px - 1])dyy = 0.25 * (hm[py + 2 * 1][px] - 2 * hm[py][px] + hm[py - 2 * 1][px])derivative = np.matrix([[dx], [dy]])hessian = np.matrix([[dxx, dxy], [dxy, dyy]])if dxx * dyy - dxy ** 2 != 0:#如果Hessian矩阵的行列式不为零(确保Hessian矩阵非奇异),则使用计算出的偏移量更新原始坐标。hessianinv = hessian.Ioffset = -hessianinv * derivativeoffset = np.squeeze(np.array(offset.T), axis=0)coord += offsetreturn coorddef dark_postprocess(self, hm, coords, kernelsize):#hm(热图),coords(关键点的初步坐标),和kernelsize(高斯模糊核的大小)'''DARK postpocessing, Zhang et al. Distribution-Aware CoordinateRepresentation for Human Pose Estimation (CVPR 2020).'''hm = self.gaussian_blur(hm, kernelsize)#进行高斯模糊hm = np.maximum(hm, 1e-10)#为了确保数值稳定性,热图中的值被限制为最小为 1e-10hm = np.log(hm)#对热图应用对数变换for n in range(coords.shape[0]):for p in range(coords.shape[1]):coords[n, p] = self.dark_parse(hm[n][p], coords[n][p])#对于每一个初步坐标,使用 dark_parse 函数来修正坐标return coordsdef get_final_preds(self, heatmaps, center, scale, kernelsize=3):"""the highest heatvalue location with a quarter offset in thedirection from the highest response to the second highest response.Args:heatmaps (numpy.ndarray): The predicted heatmapscenter (numpy.ndarray): The boxes centerscale (numpy.ndarray): The scale factorReturns:preds: numpy.ndarray([batch_size, num_joints, 2]), keypoints coordsmaxvals: numpy.ndarray([batch_size, num_joints, 1]), the maximum confidence of the keypoints"""coords, maxvals = self.get_max_preds(heatmaps)#使用 get_max_preds 函数从热图中获取初步的关键点坐标和最大置信度heatmap_height = heatmaps.shape[2]#获取热图的高度和宽度heatmap_width = heatmaps.shape[3]#if self.use_dark:#如果启用了 use_dark,则使用 dark_postprocess 函数对坐标进行后处理。否则,对于每个初步坐标,如果它不在热图的边界内,则根据热图在该点的梯度进行简单的偏移coords = self.dark_postprocess(heatmaps, coords, kernelsize)else:for n in range(coords.shape[0]):#将修正后的坐标复制到 preds 变量中。for p in range(coords.shape[1]):hm = heatmaps[n][p]px = int(math.floor(coords[n][p][0] + 0.5))py = int(math.floor(coords[n][p][1] + 0.5))if 1 < px < heatmap_width - 1 and 1 < py < heatmap_height - 1:diff = np.array([hm[py][px + 1] - hm[py][px - 1],hm[py + 1][px] - hm[py - 1][px]])coords[n][p] += np.sign(diff) * .25preds = coords.copy()# Transform back 将关键点坐标从热图的空间转换回原始图像的空间for i in range(coords.shape[0]):preds[i] = transform_preds(coords[i], center[i], scale[i],[heatmap_width, heatmap_height])#根据每个图像的中心点(center)、尺度因子(scale)以及热图的尺寸(heatmap_width 和 heatmap_height)来调整坐标return preds, maxvalsdef __call__(self, output, center, scale):preds, maxvals = self.get_final_preds(output.numpy(), center, scale)#获得最终的预测结果"""将 preds 和 maxvals 沿着最后一个维度(axis=-1)进行连接。这意味着如果 preds 的形状是 (batch_size, num_joints, 2)(每个关键点的二维坐标),而 maxvals 的形状是 (batch_size, num_joints, 1)(每个关键点的最大置信度),那么连接后的结果将具有形状 (batch_size, num_joints, 3),其中最后一列是每个关键点的最大置信度。np.mean(maxvals, axis=1) 计算 maxvals 沿着第二个维度(axis=1)的均值。这通常用于获取每个图像(或批次中的每个样本)上所有关键点置信度的平均值。"""outputs = [[np.concatenate((preds, maxvals), axis=-1), np.mean(maxvals, axis=1)]]return outputs#连接后的 preds 和 maxvals 可以直接用于可视化,而 maxvals 的均值则可以用于评估模型的整体性能
相关文章:

学习使用paddle来构造hrnet网络模型
1、首先阅读了hrnet的网络结构分析,了解到了网络构造如下: 参考博文姿态估计之2D人体姿态估计 - (HRNet)Deep High-Resolution Representation Learning for Human Pose Estimation(多家综合)-CSDN博客 最…...
Redis 多线程操作同一个Key如何保证一致性?
单线程模型:Redis 是单线程模型的,它通过一个事件循环来处理所有客户端请求,这意味着 Redis 在任何时刻只会处理一个请求,从而避免了并发访问同一个 Key 的问题。这种设计保证了数据的一致性。 乐观锁(Watchÿ…...
单链表合并
【问题描述】 建立两个升序排列的单链表,表中元素的数据类型是整数,将建立的两个链表合并为 一个新的升序的单链表,并输出显示已合并好的有序的单链表 。 【输入形式】分别输入两组数据,两组数据以回车分隔;每组数据…...

【如何像网吧一样弄个游戏菜单在家里】
GGmenu 个人家庭版游戏、应用管理 桌面图标管理器...
CSS~~
CSS是一门语言,用于控制网页表现 CSS(Cascading Style Sheet):层叠样式表 W3C标准:网页主要由三部分组成 结构:HTML 表现: CSS 行为:JavaScript 1,CSS的导入方式 (1)内联样式 在标签内部使用style属性,属性值是cs…...

Docker技术概论(1):Docker与虚拟化技术比较
Docker技术概论(1) Docker与虚拟化技术比较 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https:…...

alibabacloud学习笔记07(小滴课堂)
讲解Sentinel自定义异常降级-新旧版本差异 讲解新版Sentinel自定义异常数据开发实战 如果我们都使用原生的报错,我们就无法得到具体的报错信息。 所以我们要自定义异常返回的数据提示: 实现BlockExceptionHandler并且重写handle方法: 使用F…...

Ansible-Playbook
目录 1、概念介绍 roles 角色 playbook 核心元素 ansible-playbook 命令 playbook 简单案例 2、Ansible 变量 自定义变量 facts 变量 Palybook 部署 LAMP ansible 端安装 LAMP playbook 系统环境脚本 构建 httpd 任务 构建 mariadb 任务 构建 php 任务 编写整个任务…...
UE5常见问题处理笔记
一、C工程中的文件出现很多头文件找不到,比如:#include CoreMinimal.h文件提示找不到。 解决方法:在UE编辑器中选择菜单Tools -> Refresh Visual Studio Project。 二、莫名其妙的编译错误。 解决方法,找到工程根目录下的Bi…...

docker中hyperf项目配置虚拟域名
在学习hyperf框架时遇到一些问题,这里是直接用了docker环境 下载镜像运行容器 docker run --name hyperf -v /data/project:/data/project -p 9501:9501 -itd -w /data/project --privileged -u root --entrypoint /bin/sh 镜像ID配置docker-compose.yml version…...

PID闭环控制算法的学习与简单使用
平台:matlab2021b,Vivado2018 应用场景和理解 一个早餐店,假如一天都有生意,生意有的时间很火爆,有时候又一般,老板又是个实在人,只知道在后厨蒸包子。由于包子蒸熟需要一定的时间,老…...

【无刷电机学习】光耦HCNR200基本原理及应用(资料摘抄)
【仅作自学记录,不出于任何商业目的。如有侵权,请联系删除,谢谢!】 本文摘抄翻译自: https://docs.broadcom.com/wcs-public/products/application-notes/application-note/331/6/av02-1333en-an_5394-16jul10.pdfhtt…...
【LeetCode】1768_交替合并字符串_C
题目描述 给你两个字符串 word1 和 word2 。请你从 word1 开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 https://leetcode.cn/problems/merge-strings-al…...
C#解析JSON
https://blog.csdn.net/weixin_43046974/article/details/131449900 C#解析JSON 1. JSON定义2. JSON一般构成及解析方法3. 解析举例子 1. JSON对象解析,只包含一层对象{}2. 嵌套JSON对象解析,包含多层对象{}3. JSON数组解析1(数组循环遍历&…...
AI图像识别算法助力安全生产*提升风险监测效率---豌豆云
2024年开年来安全生产事故频发,工厂爆炸、工程坍陷等重大安全生产事故的发生再次为我们敲响了警钟。 安全生产是企业发展的生命线,而传统的安全监测手段存在盲区和延迟,难以及时发现和应对潜在风险。 AI图像识别算法通过利用先进的计算机视…...

CSS技巧:实现两个div在同一行显示的方法
css如何让两个div在同一行显示 - web开发 - 亿速云 在Web开发中,经常遇到需要将多个元素水平排列在同一行的情况。其中一个常见的需求是将两个div元素放置在同一行上,使它们并排显示。在本文中,我们将介绍几种实现这一效果的CSS方法。 1. 使…...

【Unity】Node.js安装与配置环境
引言 我们在使用unity开发的时候,有时候会使用一些辅助工具。 Node.js就是开发中,经常会遇到的一款软件。 1.下载Node.js 下载地址:https://nodejs.org/en 2.安装Node.js ①点击直接点击Next下一步 ②把协议勾上,继续点击…...

Vue3:使用 Composition API 不需要 Pinia
在 Vue.js 开发的动态环境中,在单个组件中处理复杂的业务逻辑可能会导致笨重的文件和维护噩梦。虽然 Pinia 提供集中式状态管理,但仅依赖它来处理复杂的业务逻辑可能会导致代码混乱。本文探讨了使用 Composition API 的替代方法,说明开发人员…...
ExoPlayer 播放视频黑屏的解决方法
最近项目中在使用 ExoPlayer 来进行视频的播放,开发过程中遇到了部分视频打开后黑屏的问题,报错日志如下。 E Audio codec error android.media.MediaCodec$CodecException: Error 0xe E Playback error androidx.media3.exoplayer.ExoPlaybackExcept…...

C语言初阶—数组
数组是一组相同类型元素的集合。 在C99标准之前,数组的大小必须是常量或常量表达式。 在C99标准之后,数组的大小可以是变量,可以支持变长数组,但变长数组不能初始化。 不完全初始化,剩余的元素默认初始化为0 。 数组访…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...