AI 黑玉断续膏: 自底向上的二维人体姿态估计

简介: 大家好!此前我们介绍了二维人体姿态估计(2D Human Pose Estimation,以下简称2D HPE)的基本概念、常用数据集,以及自顶向下的2D HPE算法。本文将结合MMPose对自底向上的2D HPE算法做一些更详细的分析。

大家好!此前我们介绍了二维人体姿态估计(2D Human Pose Estimation,以下简称2D HPE)的基本概念、常用数据集,以及自顶向下的2D HPE算法。本文将结合MMPose对自底向上的2D HPE算法做一些更详细的分析。640.png


2D HPE旨在从图像或者视频中预测人体关节点(或称关键点,比如头,左手,右脚等)的二维空间位置坐标。应用场景包括:动作识别,动画生成,增强现实等。传统的2D HPE算法,设计手工特征提取图像信息,从而进行关键点的检测。


近年来随着深度学习的快速发展,基于深度学习的2D HPE算法取得了重大突破,算法精度得到了大幅提升。


当前主流的2D HPE方法主要可以分为自顶向下(top down)和自底向上(bottom up)两种方式。

640.png


自顶向下的方法主要有如下两方面的问题:


1)依赖人体框检测的效果。如果检测器没有检测到某个人体,或者一个框内框出了多个人体(在密集人群场景中,会经常遇到),自顶向下的方法会失效。


2)自顶向下方法的计算复杂度随着图片中总人数的增加而线性上升。在人数比较多的场景,耗时难以满足实时性要求。而自底向上的算法,能够有效解决这两方面的问题,因此也受到了研究者的广泛关注。


那么,让我们来学习下如何使用自底向上的二维人体姿态估计方法吧~


本文内容


主流算法

MMPose 中的 2D HPE 算法实现

     模型、数据、训练配置


1.  主流算法



基于 Part Affinity Fields 的方法


OpenPose


OpenPose [1] 算法基于 CPM(Convolutional Pose Machines)[5]模型结构设计了一个多阶段(multi-stage)的卷积神经网络,每个stage的输入是上一个stage输出和图像特征的融合,其网络结构如下图所示

640.png

OpenPose用神经网络同时预测多人关节点热度图(Heatmap 或 Confidence Map) 和关节点亲和场(Part Affinity Fields, PAFs)。其中,关节点热度图代表了关节点的位置;而 PAFs 表示不同关节点之间的骨架连接关系。PAFs是一组二维向量图,其每个像素表征该位置的骨架连接方向信息。

640.png

OpenPose首先使用NMS算法,从关键点热度图中得到一系列候选关节点,再利用关节点亲和场来匹配关节点。


然而,将候选关键点进行关节匹配并得到完整的人体的过程,是一个NP-Hard问题。OpenPose采用了greedy inference算法,将关节点作为图的顶点,把关节点之间的PAFs向量看作两点间的边的权重,将多人检测问题转换成了一个二分图匹配问题,并用匈牙利算法求得局部最优匹配。


基于 Associative Embedding 的方法


Associative Embedding


AE(Associative Embedding) [2]算法采用了基于堆叠沙漏网络(Stacked Hourglass [6])的网络结构,连续进行上采样和下采样,融合多尺度特征。

640.png

该算法提出了关联嵌入特征图(Associative Embedding),以实现关键点聚类。


如下图所示,网络会预测 N 张关键点热度图,用于多人关键点定位;同时预测 N 张关联嵌入特征图,用于关键点聚类。


在训练过程中,要求同一个人的各个关键点的关联嵌入特征尽可能相似(Pull loss),不同人的关联嵌入特征尽可能不同(Push loss)。在预测阶段,我们只需要对关联嵌入特征的取值进行聚类,即可将关键点匹配成人体姿态。

640.png

下图对网络预测的关联嵌入特征图进行了可视化。由图中可以看出,同一个人不同关键点的关联嵌入特征图的取值非常接近,且不同人的关联嵌入特征图的取值各不相同。

640.png

HigherHRNet


该算法整体沿用了 AE 的思想,设计了 HigherHRNet 网络结构,致力于解决自底向上的人体姿态估计方法的尺度变化问题,有利于同时预测图片中不同尺度大小的人体姿态。


HigherHRNet特征金字塔由 1)HRNet [7]的特征图输出和 2)通过转置卷积上采样的高分辨率输出组成。该模型采用多分辨率监督训练和多分辨率聚合推理,能够更精确地定位关键点。

640.png

基于中心点回归的方法

SPM


近几年,单阶段人体姿态检测器逐渐流行。而SPM(Single-Stage Multi-Person Pose Machines)[4]是其中的代表性方法,也是最早的单阶段多人姿态估计方法之一。


该算法同样采用堆叠沙漏(Stacked Hourglass [6])网络结构。SPM抛弃了以往的”先检测所有关键点,再进行聚合”的策略。它提出首先检测人体中心点,再回归从人体中心到各个关键点的偏移向量。

640.png

如上图所示,SPM算法在预测一张人体根节点的热度图(Root Conf. Map)的同时,预测了N*2张关键点偏移向量图(Joint Disp. Map)。在预测阶段,首先根据根节点热度图,定位各个人体的中心点坐标。中心点坐标再加上各个关键点的偏移向量,最终得到了每个人的姿态动作。


2. MMPose 中的 2D HPE 算法实现



MMPose现已支持 Associative Embedding,  HigherHRNet 等不同的算法模型。我们也提供了基于图像和视频的 demo ,感兴趣的话不妨先尝试一下~


demo 链接:

https://mmpose.readthedocs.io/en/latest/demo.html#d-human-pose-bottom-up-image-demo

640.png

接下来,我们以HigherHRNet为例介绍自底向上的2D HPE算法在MMPose中的实现。


模型


Backbone


模型的骨干网络(Backbone)为 HRNet 模型(具体实现见hrnet.py),输入为3通道的图片,输出为num_branches=4 个不同分辨率下的特征。特征分辨率越小的branch,其特征通道数越多 num_channels=(32, 64, 128, 256)。

backbone=dict(
    type='HRNet', # 骨干网络的类型
    in_channels=3, # 输入通道数
    extra=dict(
        stage1=dict(
            num_modules=1, # 串行module数
            num_branches=1, # 并行branch数
            block='BOTTLENECK', # 使用block的类型
            num_blocks=(4, ), # 使用block的数量
            num_channels=(64, )), # 特征通道数
        stage2=dict(
            num_modules=1, # 串行module数
            num_branches=2, # 并行branch数
            block='BASIC', # 使用block的类型
            num_blocks=(4, 4), # 使用block的数量
            num_channels=(32, 64)), # 特征通道数
        stage3=dict(
            num_modules=4, # 串行module数
            num_branches=3, # 并行branch数
            block='BASIC', # 使用block的类型
            num_blocks=(4, 4, 4), # 使用block的数量
            num_channels=(32, 64, 128)), # 特征通道数
        stage4=dict(
            num_modules=3, # 串行module数
            num_branches=4, # 并行branch数
            block='BASIC', # 使用block的类型
            num_blocks=(4, 4, 4, 4), # 使用block的数量
            num_channels=(32, 64, 128, 256))), # 特征通道数
)

Head


模型的Head部分,采用了AEHigherResolutionHead,具体实现见ae_higher_resolution_head.py。该网络头用于产生多分辨率的输出结果。模型训练的损失类型为MultiLossFactory,来分别监督多人关键点热度图和关联嵌入特征图。

keypoint_head=dict(
    type='AEHigherResolutionHead', # 网络头的类型
    in_channels=32, # 输入通道数
    num_joints=17, # 输出关节点数
    tag_per_joint=True, # 是否每个关节点使用单独的关联嵌入特征图
    extra=dict(final_conv_kernel=1, ), # final_conv 为1x1的卷积
    num_deconv_layers=1, # 反卷积层数量
    num_deconv_filters=[32], # 反卷积层的输出通道数
    num_deconv_kernels=[4], # 反卷积层的卷积核大小
    num_basic_blocks=4, # BasicBlock的数量
    cat_output=[True], # 是否级联输出
    with_ae_loss=[True, False], # 是否使用AE损失
    loss_keypoint=dict(
        type='MultiLossFactory', # 损失函数类别
        num_joints=17, # 关节点数量
        num_stages=2, # 网络头阶段数
        ae_loss_type='exp', # AE损失类型
        with_ae_loss=[True, False], # 是否使用AE损失
        push_loss_factor=[0.001, 0.001], # push损失的权重
        pull_loss_factor=[0.001, 0.001], # pull损失的权重
        with_heatmaps_loss=[True, True], # 是否使用热度图损失
        heatmaps_loss_factor=[1.0, 1.0])) # 热度图损失的权重


数据


Data config


以下是与训练数据相关的一些配置,具体实现见bottom_up_coco.py 。


data_cfg = dict(
    image_size=512, # 输入图片尺寸
    base_size=256, # 基准尺寸
    base_sigma=2, # 热度图高斯分布的标准差
    heatmap_size=[128, 256], # 输出多分辨率热度图的尺寸
    num_joints=channel_cfg['dataset_joints'], # 关键点个数
    dataset_channel=channel_cfg['dataset_channel'], # 数据集所对应的通道列表
    inference_channel=channel_cfg['inference_channel'], # 模型输出的通道列表
    num_scales=2, # 输出分辨率的个数
    scale_aware_sigma=False, # 高斯分布的标准差是否随尺度变化
)
data_root = 'data/coco' # 数据集路径
data = dict(
    samples_per_gpu=24, # 训练阶段,每张GPU的批处理大小
    workers_per_gpu=2, # 每个GPU的数据读取线程数量
    train=dict(
        type='BottomUpCocoDataset', # 训练数据集名称
        ann_file=f'{data_root}/annotations/person_keypoints_train2017.json', # 训练数据集标签路径
        img_prefix=f'{data_root}/train2017/', # 训练数据集图片路径前缀
        data_cfg=data_cfg,
        pipeline=train_pipeline),
    val=dict(
        type='BottomUpCocoDataset', # 验证数据集名称
        ann_file=f'{data_root}/annotations/person_keypoints_val2017.json', # 验证数据集标签路径
        img_prefix=f'{data_root}/val2017/', # 验证数据集图片路径前缀
        data_cfg=data_cfg,
        pipeline=val_pipeline),
    test=dict(
        type='BottomUpCocoDataset', # 测试数据集名称
        ann_file=f'{data_root}/annotations/person_keypoints_val2017.json', # 测试数据集标签路径
        img_prefix=f'{data_root}/val2017/', # 测试数据集图片路径前缀
        data_cfg=data_cfg,
        pipeline=val_pipeline),
)


Pipeline


数据预处理的 pipeline 主要由以下几个步骤组成:


2. LoadImageFromFile:读取图片。

3. BottomUpRandomAffine:随机仿射变换。

4. BottomUpRandomFlip:随机水平翻转 。

5. ToTensor:图片转换为Tensor。

6. NormalizeTensor:输入Tensor归一化,减均值,除方差。

7. BottomUpGenerateTarget:根据标签,生成所需GT。

8. Collect:整合训练中需要用到的数据。

train_pipeline = [
    dict(type='LoadImageFromFile'), # 读取图片
    dict(
        type='BottomUpRandomAffine', # 数据增强:随机仿射变换
        rot_factor=30, # 最大旋转幅度
        scale_factor=[0.75, 1.5], # 随机缩放范围
        scale_type='short', # 以图像的长边或短边进行缩放
        trans_factor=40), # 最大中心点偏移
    dict(
        type='BottomUpRandomFlip', # 数据增强:随机翻转 
        flip_prob=0.5), # 翻转概率
    dict(type='ToTensor'), # 数据格式转换为 Tensor
    dict(
        type='NormalizeTensor', # 输入Tensor归一化
        mean=[0.485, 0.456, 0.406], # 归一化均值
        std=[0.229, 0.224, 0.225]), # 归一化方差
    dict(
        type='BottomUpGenerateTarget', # 根据标签,生成GT
        sigma=2, # 热度图高斯分布的标准差
        max_num_people=30, # 最大人数
    ),
    dict(
        type='Collect', # 整合训练中所需要的数据
        keys=['img', 'joints', 'targets', 'masks'], # 保留的key
        meta_keys=[]), # 保留的meta-key
]


 训练配置



Optimizer


采用Adam作为优化器,并设置初始学习率为0.0015。

optimizer = dict(
    type='Adam', # 优化器的类型
    lr=0.0015, # 基础学习率
)
optimizer_config = dict(grad_clip=None) # 不进行梯度裁剪

Learning rate policy


学习率采用阶梯状衰减,分别在第200和第260个epoch,降低学习率(默认每次降低到 0.1倍),总计训练300个epoch。


我们采用了预热启动(warmup)策略,初始设置非常小的学习率(0.001倍的初始学习率lr),并在前500个迭代轮次中,线性增加为 lr=0.0015。

lr_config = dict(
    policy='step', # 学习率调整策略
    warmup='linear', # 预热启动策略
    warmup_iters=500, # 预热启动的训练迭代数
    warmup_ratio=0.001, # 预热启动阶段初始学习率为 warmup_ratio * lr
    step=[200, 260]) # 学习率下降的轮次,分别在第200和第260个epoch,降低学习率
total_epochs = 300 # 总迭代轮数

本文介绍了2D HPE一些自底向上的算法,并以HigherHRNet为例,介绍了MMPose中的具体算法实现。


希望大家通过本文的阅读能够对自底向上的2D HPE有一个初步的认识,也欢迎大家使用MMPose来支持相关的研究与应用~

文章来源:公众号【OpenMMLab】

2021-09-14 18:13

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
9天前
|
人工智能 小程序
【一步步开发AI运动小程序】五、帧图像人体识别
随着AI技术的发展,阿里体育等公司推出的AI运动APP,如“乐动力”和“天天跳绳”,使云上运动会、线上健身等概念广受欢迎。本文将引导您从零开始开发一个AI运动小程序,使用“云智AI运动识别小程序插件”。文章分为四部分:初始化人体识别功能、调用人体识别功能、人体识别结果处理以及识别结果旋转矫正。下篇将继续介绍人体骨骼图绘制。
|
24天前
|
机器学习/深度学习 人工智能 算法框架/工具
基于人体姿势估计的舞蹈检测(AI Dance based on Human Pose Estimation)
基于人体姿势估计的舞蹈检测(AI Dance based on Human Pose Estimation)
41 0
|
6月前
|
人工智能 计算机视觉
CVPR 2024:跳舞时飞扬的裙摆,AI也能高度还原了,南洋理工提出动态人体渲染新范式
【5月更文挑战第6天】南洋理工大学研究团队在CVPR 2024会议上提出SurMo,一种动态人体渲染新方法,能高度还原视频中的人物动作和细节,如飞扬的裙摆。SurMo通过4D运动建模,结合表面运动编码、物理运动解码和4D外观解码,实现动态图像的精确合成。尽管面临复杂动作捕捉和计算资源需求的挑战,SurMo在动态人体渲染任务上表现出色,展现了表面基运动三角平面的强大表达能力。[论文链接](https://arxiv.org/pdf/2404.01225.pdf)
157 1
|
6月前
|
人工智能
姿态识别+康复训练矫正+代码+部署(AI 健身教练来分析深蹲等姿态)-2
姿态识别+康复训练矫正+代码+部署(AI 健身教练来分析深蹲等姿态)-2
|
6月前
|
机器学习/深度学习 人工智能 算法
姿态识别+康复训练矫正+代码+部署(AI 健身教练来分析深蹲等姿态)-1
姿态识别+康复训练矫正+代码+部署(AI 健身教练来分析深蹲等姿态)-1
|
6月前
|
机器学习/深度学习 人工智能 安全
Human Generator:创建人体模型的 AI 工具
Human Generator:创建人体模型的 AI 工具
184 0
|
人工智能 算法 计算机视觉
AI开发者大会之计算机视觉技术实践与应用:2020年7月3日《如何利用计算机视觉增加便利店连锁每日销售额》、《基于图像 / 视频的人脸和人体分析基础技术及其应用介绍》
AI开发者大会之计算机视觉技术实践与应用:2020年7月3日《如何利用计算机视觉增加便利店连锁每日销售额》、《基于图像 / 视频的人脸和人体分析基础技术及其应用介绍》
AI开发者大会之计算机视觉技术实践与应用:2020年7月3日《如何利用计算机视觉增加便利店连锁每日销售额》、《基于图像 / 视频的人脸和人体分析基础技术及其应用介绍》
|
机器学习/深度学习 人工智能 分布式计算
Analytics Zoo 入门 | Spark“数字人体”AI挑战赛赛题解析一
首届Spark“数字人体”AI挑战赛已开启,奖金高达46万,欢迎大家踊跃报名!本次直播将由英特尔高级软件工程师邱鑫为大家介绍如何使用Spark, Big DL及Analytics Zoo平台,分别从Analytics Zoo & BigDL简介、Analytics Zoo入门以及Analytics Zoo提供的End-to-End Pipelines和ML Workflow等方面详细展开讲解。
1302 0
Analytics Zoo 入门 | Spark“数字人体”AI挑战赛赛题解析一
|
机器学习/深度学习 人工智能 分布式计算
阿里云发起首届 Spark “数字人体” AI 挑战赛 — 聚焦上班族脊柱健康
2020年6月4日,首届 Apache Spark AI 智能诊断大赛在天池官网上线。Spark “数字人体” AI 挑战赛——脊柱疾病智能诊断大赛,聚焦医疗领域应用,召集全球开发者利用人工智能技术探索高效准确的脊柱退化性疾病自动诊断。现已面向全社会开放,为所有大数据技术爱好者以及相关的科研企业提供挑战平台,个人参赛或高等院校、科研单位、互联网企业等人员均可报名参赛。本次挑战的目标是通过核磁共振成像来检测和分类脊柱的退行性改变,形成一批创新性强、复用率高的算法案例,并积极推动相关技术的临床应用,用科技造福医疗事业,鼓励人工智能与疾病预防深度融合的应用落地,由点到面驱动国内人工智能医疗产业发展。
阿里云发起首届 Spark “数字人体” AI 挑战赛 — 聚焦上班族脊柱健康
|
机器学习/深度学习 人工智能 分布式计算
EMR-DataScience介绍 | Spark“数字人体”AI挑战赛赛题解析二
首届Spark“数字人体”AI挑战赛已开启,奖金高达46万,欢迎大家踊跃报名!本次直播将由阿里云人工智能产品专家李博为大家介绍,Data Science节点概述,Data Science节点深度学习框架,PAI-Alink流批一体化机器学习算法平台,AutoML,FaissServer以及PAI-EMS等Data Science原子化组件。
766 0
EMR-DataScience介绍 | Spark“数字人体”AI挑战赛赛题解析二

热门文章

最新文章

下一篇
无影云桌面