3D人体姿态估计(3 Demensional Human Pose Estimation)的目标是在单张/多张RGB图片或2D人体姿态坐标的基础上,预测人体的三维坐标。目前流行的方法包括由单张图像直接预测3维姿态坐标、由多目图像构建3D空间位置信息、由2D姿态坐标预测3D姿态等。
其中第一种方法最为直接,通过深度学习模型建立单目RGB图像到3维坐标的端到端映射,但是对于单一模型来说需要学习的特征太过复杂,目前流行的网络模型难以达到理想的性能,大部分实验中表现较好的模型需要额外的信息如相机参数等作为计算3D坐标的辅助参数,或使用GAN等特殊网络结构来学习参数进行训练。
第二种方法使用多目图片获得3维空间位置信息,在已知镜头位置或拍照角度的情况下可以通过数学运算或机器学习方法构建空间坐标系,从而在预测出2D姿态的后直接加入深度信息,可以达到不错的性能;但是这种方法需要多目图像作为输入,在进行应用时对输入设备的数量和摆放位置等具有较高要求。
第三种方法相当于在单张图像的基础上先得到了2D姿态信息,减少了模型在2D姿态估计上的学习压力,能够通过简单的矩阵相乘或轻量级网络学习3D姿态,但是由于缺少原始图像输入,可能会丢失一些空间信息,造成预测时误差;另外,由于这种方法依赖于2D姿态输入,因此2D姿态估计的误差会在3D估计的过程中放大。
下面介绍2019CVPR中两种3D姿态生成的方法,根据目前个人业务的需要都是通过2D姿态估计的结果生成。
1. SemGCN:通过语义图卷积进行3D人体姿态估计
Semantic Graph Convolutional Networks for 3D Human Pose Regression (2019CVPR)
github
首先了解一下图卷积(GCN)的基本概念:
现有的卷积神经网络研究的对象大多数是图像、语音、文本这种能够用一维、二维的矩阵表示的数据,这种数据有天然的维度对齐特性,即使不同的数据也可以对齐到同样的特征尺度和矩阵维度。
但是,计算机数据结构中的图、树,大数据知识图谱等数据不满足这种特性。这些数据结构每个节点的连接数量、方向等都不相同,在深度学习中常见的处理方法是转换成列矩阵或按最大图结构转换成稀疏矩阵,这两种方法会导致空间信息的丢失或者特征维度的膨胀,采用图卷积是当前对这种数据最有效的分析处理方式之一。
图卷积的基本计算公式,是由卷积基本公式经过傅里叶变换得到的,在这里不展开讲,可以在这里看到推导:
计算公式其中c是归一化因子,N表示节点i的邻居,R表示节点i的类型,W表示权重,外层非线性变换。
其计算过程为:
第一步:发射(send)每一个节点将自身的特征信息经过变换后发送给邻居节点。这一步是在对节点的特征信息进行抽取变换。
第二步:接收(receive)每个节点将邻居节点的特征信息聚集起来。这一步是在对节点的局部结构信息进行融合。
第三步:变换(transform)把前面的信息聚集之后做非线性变换(ReLU等),增加模型的表达能力。
GCN四个特征:
- GCN 是对卷积神经网络在图数据上的自然推广。
- 它能同时对节点特征信息与结构信息进行端对端学习,是目前对图数据学习任务的最佳选择。
- 图卷积适用性极广,适用于任意拓扑结构的节点与图。
- 在节点分类与边预测等任务上,在公开数据集上效果要远远优于其他方法。
本文方法采用的语义图卷积模型,就是传统图卷积的一种延伸。可以看出2D姿态坐标在原图中的连接方式就是一种图连接,而我们的需求就是生成一个3D的姿态坐标,同样是一种图数据,非常适合使用图卷积进行端到端学习。
目前GCN的结构局限于卷积滤波器的小接收域和每个节点的共享变换矩阵。SemGCN的提出一定程度上解决了这些局限性,论文提出了全新的语义图卷积网络,用于处理具有图结构数据的回归任务。SemGCN学习捕获在图中没有显式表示的语义信息,例如局部和全局节点关系。这些语义关系可以通过端到端训练学习,而不需要额外的监督或手工特征。实验结果表明,SemGCN在使用的参数减少了90%的情况下,性能仍优于现有的技术水平。
论文由GCN的基本公式(下式)出发,加入了残差设计作为工作的Baseline,称之为ResGCN。
在本文中,GCN的基本公式有两点不足:
- 为了使图卷积在具有任意拓扑结构的节点上工作,核函数W对所有边都是权值共享的,这样会导致临边以及整个图的内部结构没有被很好地利用起来。
- 之前的工作仅使用了每个节点的第一级临边,这样就把感受野局限在1维大小,不利于学习全局特征。
在此基础上作者与传统的CNN结构相结合,提出了语义图卷积。主要思路是将CNN中单个卷积核提取多维特征的能力引用到GCN上,首先对每一个位置学习独立的权重向量a,然后使用一个共享的转换矩阵W把不同的a结合起来,因此上式可以转换为:
这里ρ是对节点i的所有输入矩阵进行的Softmax变换;⊙是一个矩阵元素级别的运算:如果在ρ操作后矩阵A中元素的值为1或是指数非常接近0的负数,那么运算将返回对应M中对应位置的值。矩阵A用来约束每个节点每次只计算其相邻节点的权重。
进一步地,可以把公式延伸成下式:
公式2
其中Md是在不同通道上的权重矩阵,结果通过||进行通道维度的拼接,这里wd是不同通道上的转换矩阵。
SemGCN与CNN
上图解释了SemGCN与CNN的对比关系,图a中CNN每个3x3卷积相当于对卷积核覆盖区域中的每个点学习一个权重向量,再通过转换矩阵W把它们结合起来。图b中的卷积GCN仅学习了所有节点共享的转换矩阵W0,图c和图d对应了上面的两个公式,采用分离每个节点权重向量和转换矩阵的形式实现感受野的扩大,同时学习全局与局部特征。网络结构如下:
网络结构
网络中的Non Local模块进行如下操作:
Non Local模块
其中W初始化为0,f是成对的函数操作,用于学习节点i和除此之外所有节点j之间的密切程度。
整个模型的结构如下:
模型的结构
在应用过程中,网络可以采用原始图像或2D关节点作为输入,如果输入图像则使用ResNet提取特征,采用RoIAlign提取卷积层输出,与2D坐标进行拼接后输入SemGCN。网络的损失函数为:
损失函数
由于图方法只关注于点以及点之间的连接,而不需要一整个图像矩阵作为输入,因此可以大大减少参数量和运算速度。从下表可知,本文方法较其他方法节省90%的参数,并达到同等效果。
比较
阅读代码,对于16个节点的输入,每个 ResGraphConv (X)的操作为:
Input = X: batch, 16, channels
W: 2, channels, 128
h0 = X*W[0]: 16, 128
h1 = X*W[1]: 16,128
adj: 16, 16 描述节点关系的稀疏矩阵(没有节点、没有连接的下标对应元素为0,其余按节点和连接分配权重)
M: 16, 16 对角矩阵
Out = (adj•M)*h0 + (adj•(1-M))*h1
以上为一个block,执行两次加X作为残差,输出。
每个Graph_non-local (X)的操作为:
g_x = X: batch,128,16 – conv1d(128,64):batch, 64, 16
– maxpool1d(2):batch, 64, 8 – trans:batch, 8, 64
theta_x = X: batch,128,16 - conv1d(128,64):batch, 64, 16 – view:batch,64,16,1
phi_x = X: batch,128,16 - conv1d(128,64):batch, 64, 16
– maxpool1d(2):batch, 64, 8 – view:batch,64,1,8
f = theta_x与phi_x对齐,拼接: batch, 128, 16, 8
– conv2d(128,1):1,1,16,16 – view: batch, 16, 16
f_div_C = f/16
y = f_div_C*g_x: 1, 16, 64 – conv1d(64,128): batch, 16, 128
2. 2. RepNet:通过GAN进行3D人体姿态估计
RepNet: Weakly Supervised Training of an Adversarial Reprojection Network for 3D Human Pose Estimation (2019CVPR)
github
首先了解GAN的基本概念:
GAN的基本原理其实非常简单,这里以生成图片为例进行说明。假设我们有两个网络,G(Generator)和D(Discriminator)。它们的功能分别是:
• G是一个生成图片的网络,它接收一个随机的噪声z,通过这个噪声生成图片,记做G(z)。
• D是一个判别网络,判别一张图片是不是“真实的”。它的输入参数是x,x代表一张图片,输出D(x)代表x为真实图片的概率,如果为1,就代表100%是真实的图片,而输出为0,就代表不可能是真实的图片。
在训练过程中,生成网络G的目标就是尽量生成真实的图片去欺骗判别网络D。而D的目标就是尽量把G生成的图片和真实的图片分别开来。在最理想的状态下,G可以生成足以“以假乱真”的图片G(z)。对于D来说,它难以判定G生成的图片究竟是不是真实的,因此D(G(z)) = 0.5。
训练的目的就是得到一个生成式模型G,用来生成图片。
以上只是大致说了一下GAN的核心原理,论文里的损失函数公式为:
- 整个式子由两项构成。x表示真实图片,z表示输入G网络的噪声,而G(z)表示G网络生成的图片。
- D(x)表示D网络判断真实图片是否真实的概率(因为x就是真实的,所以对于D来说,这个值越接近1越好)。而D(G(z))是D网络判断G生成的图片的是否真实的概率。
- G的目的:上面提到过,D(G(z))是D网络判断G生成的图片是否真实的概率,G应该希望自己生成的图片“越接近真实越好”。也就是说,G希望D(G(z))尽可能得大,这时V(D, G)会变小。因此我们看到式子的最前面的记号是min_G。
- D的目的:D的能力越强,D(x)应该越大,D(G(x))应该越小。这时V(D,G)会变大。因此式子对于D来说是求最大(max_D)
本文采用弱监督学习方法,使用GAN生成的鉴别器网络来学习3D人体姿态分布,从而摆脱了训练数据对3D姿态标签的依赖。另一个神经网络学习从检测到的2D关键点分布到3D关键点分布的映射,其映射的3D结果送入鉴别器网络进行判断。从生成对抗网络的角度来看,可以将其看做生成器网络。为了使生成器网络生成与2D观测结果相匹配的3D姿态,作者还添加了第三个神经网络,该网络能够根据输入数据预测出摄像机参数。推断出的摄相机参数用于将估计的3D姿态重新投影回2D,从而判断预测姿态与原始2D输入的偏差。
上图展示了该方法由包含噪声的2D关键点坐标预测出3D姿态坐标,这个弱监督方法不需要2D到3D对应的坐标点信息,而在3D投影回2D时由判别器强行约束计算一个可信的3D姿态。即使原始输入包括是强烈的变形和奇怪的相机角度,此模型也可以重建3D姿态。
下图是网络结构:
网络结构
该模型包含三个结构:
- 3D姿态和相机参数估计网络。包括两个分支,分别用于回归姿态和估计相机参数。前者包括两个连续的残差模块,每个模块包含两个1000神经元的全连接网络,使用lReLU作为激活函数,输出长度为3x16的一维向量;后者具有类似的网络结构,输出为6维的相机参数向量,使用时resize为2x3。
-
3D姿态判别网络。判别网络的最后一层采用瓦瑟斯坦损失函数,如下式所示。其中位置r对应为1,位置t对应-1。在这里向量b的方向和长度与对应的骨架长度相同。
瓦瑟斯坦损失函数
所有的骨架拼接成骨架集合B,其计算方式可以是B=XC,在这里C是对应的c向量。由此计算KCS矩阵ψ = BTB。
在训练过程中判别式接受的输入为:原始3D标签(正样本)和生成器模拟的3D姿态(负样本)。
整个判别网络借鉴了运动链空间(kinematic chain space,KCS),结构如下图所示。
判别网络 -
重投影网络。重投影网络的输入为预测的3D姿态(resize为3x16)X和相机参数K,得到重投影的2D坐标W’=KX,使用与网络2D姿态输入的Frobenius范式计算损失,如下式所示。2D姿态中遮挡的节点被设为0,从而减少对全局损失的影响,而缺失的节点会在生成式模型中被虚拟构建出来。
重投影网络
如果3D和2D姿态都根据他们的中心点对齐,那么K可以是一个弱透视投影矩阵。弱透视投影:如果摄像机的视场比较小,而且物体表面深度变化相对其到摄像机的距离很小的话,物体上个点的深度可以用一个固定的深度值z0近似,这个值一般取物体质心的深度。这种近似可以看作是两次投影的合成。首先,整个物体按平行于光轴的方向正投影到经过物体质心并与图像平面平行的平面上;然后,再按透视模型将上述物体平面的图像投影到摄像机的图像平面上,这一步实际是全局的放缩。因此,弱透视也叫放缩正投影(scaled orthographic projection)。
弱透视
也就是说,K就是在正交投影的基础上加上一个缩放,即K是由两个正交的行向量组成,满足:
其中s是投影缩放尺度,I是2*2的单位矩阵。S未知,可以求解K的最大奇异值或l2范数来得到。K的两个奇异值相等,而KKT的迹就是奇异值的平方和,因此有:
弱透视
普通GAN大多是由特定分布作为生成器输入,而RepNet直接采用2D姿态+噪声。
在作者的代码中,使用Keras定义了四个网络:
cam_net = Model(inputs=pose_in, outputs=cam_out)
rep_net = Model(inputs=pose_in, outputs=rec_pose)
generator = Model(inputs=pose_in, outputs=pose_out)
discriminator = Model(inputs=d_in, outputs=d_out)
上面四个网络中的前三个的输入都是长为2*关节点个数的坐标序列,将他们包装为生成式模型,计算3个loss:
adversarial_model = Model(inputs=[generator_input],
outputs=[discriminator_layers_for_generator,
rep_net_layers_for_generator,
cam_net_layers_for_generator])
而判别式模型就是discriminator网络。
训练时每个epoch对两个模型进行训练,先训练判别式,再训练生成式。
实验结果:
结果1
结果2
以上为对两篇论文的自己理解,如有问题还需分析指正
网友评论