《Learned Motion Matching》个人理解与翻译

2023-12-01 20:30

本文主要是介绍《Learned Motion Matching》个人理解与翻译,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Learned Motion Matching》个人理解与翻译

在这里插入图片描述

文章目录

  • 《Learned Motion Matching》个人理解与翻译
  • Basic Motion Matching
  • LMM (Learned Motion Maching)
    • Decompressor 解码特征向量
    • Stepper 负责帧的步进
    • Projector 寻找下一个最佳匹配特征
    • Training 训练相关信息
  • 训练结果
  • 性能评估与比较
    • 与其他模型比较结果和性能
    • LMM性能评估
  • Tips相关补充
    • OneHot编码
    • PFNN(Phase-Functioned Neural Networks for Character Control)
    • MANN(Memory-Augmented Neural Networks)

概要:

文中提出的LMM主要对比原有的Basic Motion Matching,核心优势在于通过三个神经网络实时生成数据的方式代替了原来的数据库DataBase查询生成数据的方式,优化了内存结构,从而大幅提高了MotionMatching时的内存利用率,整体速度上和BasicMotionMatching相差不大。

在这里插入图片描述
(上图里面,Pose Lookup为Basic Motion Matching的方式,Decompressor仅使用了文中提出的最核心的神经网络,LMM则使用了所有的三种神经网络)


算法的主要流程分为 P r o j e c t i o n \color{purple}Projection Projection S t e p p i n g \color{purple}Stepping Stepping D e c o m p r e s s i o n \color{Red}Decompression Decompression(最核心) 三个部分,这三个部分都使用了神经网络来优化内存利用率:

在这里插入图片描述

( 原论文中有很多表述使用英文理解更好并且也更加好理解对应的代码,所以对于这部分本文将使用英文原本的表述;)
( 对于翻译成中文之后理解稍微有点怪的词汇我会在翻译的中文之后使用括号附上原本的英文表述。)

Basic Motion Matching

定义运动控制的时候我们使用一下 特征向量(feature vector):

x = { t t t d f t f t ˙ h t ˙ } ∈ R 27 x=\{t^tt^df^t \dot{f^t}\dot{h^t} \} \in\mathbb{R}^{27} x={tttdftft˙ht˙}R27

其中,

t t ∈ R 6 : t^t \in \mathbb{R}^6: ttR6:2D future trajectory positions projected on the ground, 20, 40, and 60 frames inthe future (at 60Hz) local to the character

t d ∈ R 6 : t^d \in \mathbb{R}^6: tdR6:future trajectory facing directions 20, 40, and 60 frames in the future local to the character

f t ∈ R 6 : {f^t} \in \mathbb{R}^6: ftR6:the two foot joint positions local to the character

f t ˙ ∈ R 6 : \dot{f^t} \in \mathbb{R}^6: ft˙R6:the two foot joint velocities local to the character

h t ˙ ∈ R 3 : \dot{h^t}\in \mathbb{R}^3: ht˙R3:the hip joint velocity local to the character

可以结合代码里面从database提取出feature的部分来理解:

// Build all motion matching features and acceleration structure
// 生成所有mm的特征值feature(27维)以及加速结构(代码中使用的是AABB加速结构)
void database_build_matching_features(database& db,const float feature_weight_foot_position,const float feature_weight_foot_velocity,const float feature_weight_hip_velocity,const float feature_weight_trajectory_positions,const float feature_weight_trajectory_directions)
{//27维的特征值向量:3+3+3+3+3+6+6=27int nfeatures = 3 + // Left Foot Position3 + // Right Foot Position 3 + // Left Foot Velocity3 + // Right Foot Velocity3 + // Hip Velocity6 + // Trajectory Positions 2D6 ; // Trajectory Directions 2Ddb.features.resize(db.nframes(), nfeatures);db.features_offset.resize(nfeatures);db.features_scale.resize(nfeatures);int offset = 0;compute_bone_position_feature(db, offset, Bone_LeftFoot, feature_weight_foot_position);		//脚位置weight=0.75compute_bone_position_feature(db, offset, Bone_RightFoot, feature_weight_foot_position);	//脚位置weight=0.75compute_bone_velocity_feature(db, offset, Bone_LeftFoot, feature_weight_foot_velocity);		//脚速度weight=1.0compute_bone_velocity_feature(db, offset, Bone_RightFoot, feature_weight_foot_velocity);	//脚速度weight=1.0compute_bone_velocity_feature(db, offset, Bone_Hips, feature_weight_hip_velocity);			//髋速度weight=1.0compute_trajectory_position_feature(db, offset, feature_weight_trajectory_positions);	//轨迹位置nweight=1.0compute_trajectory_direction_feature(db, offset, feature_weight_trajectory_directions);	//轨迹方向nweight=1.5assert(offset == nfeatures);database_build_bounds(db);
}

由于特征的大小可能有很大不同,因此对它们进行归一化很重要。在这里,我们通过数据集中的标准差来缩放每个特征(例如左脚位置)。然后可以通过用户权重进一步调整此缩放比例以调整其在搜索中的重要性,但是我们发现在大多数情况下,默认权重为 1 就足够了。

定义姿势的时候使用 姿势向量(pose vector):

y = { y t y r y t ˙ y r ˙ r t ˙ r r ˙ o ∗ } y=\{y^ty^r \dot{y^t}\dot{y^r}\dot{r^t}\dot{r^r} \ o^\ast \} y={ytyryt˙yr˙rt˙rr˙ o}

其中,

y t y r : y^ty^r: ytyr:the joint local translations and rotations

y t ˙ y r ˙ : \dot{y^t}\dot{y^r}: yt˙yr˙:the joint local translational and rotational velocities

r t ˙ r r ˙ : \dot{r^t}\dot{r^r}: rt˙rr˙:the character root translational and rotational velocity, local to the character forward facing direction

o ∗ : o^\ast: o: all the other additional task specific outputs, such as foot contact information, the position or trajectory of other characters in the scene, or the future positions of some joints of the character

每一帧 i i i 都需要计算 特征向量和姿态向量,并分别连接成一个大的矩阵: X = [ x 0 , x 1 , . . . , x n − 1 ] 和 Y = [ y 0 , y 1 , . . . , y n − 1 ] X = [x_0, x_1, ..., x_{n−1}] 和 Y = [y_0, y_1, ..., y_{n−1}] X=[x0,x1,...,xn1]Y=[y0,y1,...,yn1],这俩矩阵分别称作 匹配数据库 M a t c h i n g D a t a b a s e Matching Database MatchingDatabase 和 动画数据库 A n i m a t i o n D a t a b a s e Animation Database AnimationDatabase

在运行的时候,每隔 N N N 帧,或者当用户输入发生显着变化时,就去构造一个包含所需特征向量的 查询向量 x ^ \hat{x} x^ q u e r y v e c t o r query\ vector query vector)。
Pose-based features 通常可以从 Matching Database X X X 中与当前帧 i i i 对应的条目( e n t r y entry entry)中提取,而用户对于角色的其他控制可以通过其他方式 - 比如说当我们需要控制与未来轨迹位置和方向对应的特征的时候就可以使用一种基于弹簧阻尼器( s p r i n g − d a m p e r − b a s e d s y s t e m spring-damper-based \ system springdamperbased system)的系统,这个系统会根据操纵杆的当前状态生成所需的速度和方向。

然后我们的任务是在匹配数据库中找到最小化到查询向量的几何距离的条目( e n t r y entry entry):

k ∗ = a r g k m i n ∣ ∣ x ^ − x k ∣ ∣ 2 k^{\ast}=arg_k \ min ||\hat{x}-x_k||^2 k=argk minx^xk2

一旦找到这样的动作条目并且当前帧 i i i与最近的帧不匹配,即 i ≠ k ∗ i \neq k^{\ast} i=k的时候, 动画就会在 i i i 帧之后插入一个惯性混合过渡( i n e r t i a l i z a t i o n b l e n d i n g inertialization\ blending inertialization blending) 并开始播放 k ∗ k^* k 帧( i : = k ∗ i:=k^* i:=k);
之后每一帧我们增加帧变量 i : = i + 1 i := i + 1 i:=i+1并且在动画数据库Animation Database 中查找 姿势 y i y_i yi

为了支持像是步态(gaits,只有两种状态 走/跑)或者其他非此即彼的 二进制的特征标签(tags),我们可以把他们当作是 OneHot编码的向量 添加进特征向量 x \bf{x} x,或者也可以预先计算动画和匹配数据库中的范围,当需要某些步态或标签时,搜索限制在这些范围内。

由于对 x \bf{x} x 的每个条目进行暴力搜索太慢,因此通常需要加速结构,例如 KD-Tree、基于体素的查找表(voxel-based lookup tabl)或 聚类算法(clustering)。我们发现自定义的 两层 轴对齐的层次包围结构(bounding volume hierarchy )对于 16 帧和 64 帧的数据特别简单且有效。

最后,可以使用主成分分析法 PCA 来对特征数据库 x \bf{x} x 和其他特征向量( 如 x \bf{x} x )进行降维。这个非必要步骤不会改变算法的整体行为,但请注意,它可能是一种有用的方法当使用大量冗余或相关特征时,以牺牲一些搜索准确性为代价减少内存使用并提高性能。

LMM (Learned Motion Maching)

通过观察图 2,我们可以总结出MM算法的三个关键步骤:

  • 投影( P r o j e c t i o n \color{purple}Projection Projection):使用最近邻搜索 在 MatchingDatabase 中拿到与查询向量最匹配的特征向量
  • 步进( S t e p p i n g \color{purple}Stepping Stepping):递增 MatchingDatabase 的索引(++index的过程)
  • 解压缩( D e c o m p r e s s i o n \color{red}Decompression Decompression):我们在 AnimationDatabase 中查找与 MatchingDatabase当前索引 对应的姿势(因为这个过程本质上是从 含有少量信息的低维度特征向量 提取出 含有大量信息的动作姿势的高纬矩阵,所以这里名字叫做解压缩)

这些阶段每 N N N 帧简单地重复一次,并可以插入混合来消除帧与帧之间的不连续性。

在运算速度方面,现有MM系统的核心问题是对参数 X X X Y Y Y 的依赖导致产生了大量的内存开销,并且随着添加额外的动画、姿势特征或匹配特征越来越多,运算时间也会越来越长,这一点是Basic Motion Matching最大的问题所在。

在本节的其余部分,我们将为三个关键阶段中的每一个都创建一个可学习的 神经网络来解决这个问题,并且我们也不再需要在内存中存储之前我们提到的Animation和Pose 的DataBase了。

  1. 首先,我们来消除对 Y Y Y 的依赖:为此我们需要训练一个称为 D e c o m p r e s s o r \color{red}Decompressor Decompressor的解码器网络,这个解码器网络需要两个输入:一个是特征向量 x x x ,另一个是 附加的潜在变量 z z z, 这个变量 z z z我们通过 C o m p r e s s o r Compressor Compressor 编码器网络找到的,然后解码器会输出姿势向量 y y y
  2. 接下来,我们来消除对 X X X 的依赖:同样我们需要训练两个一起工作的网络(称为 S t e p p e r \color{purple}Stepper Stepper P r o j e c t o r \color{purple}Projector Projector)。
    • S t e p p e r Stepper Stepper 负责学习系统的动态部分,同时推动整个matching 特征向量和潜在特征向量一同随着着时间往前走,最终输出一个加在 x i x_i xi z i z_i zi上的差量 d e l t a delta delta来生成新的 x i + 1 x_{i+1} xi+1 z i + 1 z_{i+1} zi+1
    • P r o j e c t o r Projector Projector则在模拟最近邻搜索 的同时将一些query向量 x ^ \hat{x} x^ 作为输入,并将其映射到数据库中最近匹配的特征向量和潜在变量 x k ∗ x_{k^∗} xk z k ∗ z_{k^∗} zk

L e a r n e d M o t i o n M a t c h i n g Learned\ Motion\ Matching Learned Motion Matching 算法的主要流程如Figure2中所示:

在这里插入图片描述

我们在用户输入 x ^ \hat{x} x^ 上使用 P r o j e c t o r Projector Projector网络 将其投影到匹配数据库中最近的特征向量和相关的潜在变量上。然后使用 S t e p p e r Stepper Stepper 将这组特征向量和潜在变量及时向前移动,并使用 D e c o m p r e s s o r Decompressor Decompressor 生成完整的角色姿势。与基本运动匹配一样,此过程每 N N N 帧重复一次,并插入混合过渡以消除不连续性。

Decompressor 解码特征向量

D e c o m p r e s s o r Decompressor Decompressor 的目标是通过取特定帧 x i x_i xi 的特征向量并直接生成相应的姿势 y i y_i yi 来避免将 Y Y Y 存储在内存中。虽然特征向量通常包含有关相应姿势的关键信息,例如脚的位置和速度(使这种映射部分成为可能),但特征向量所包含的信息还不够完全推出关节的位置和速度。为了想办法补足这些信息,我们引入了额外的潜在变量 z i z_i zi z i z_i zi是我们通过类似自动编码器的结构发现的。 C o m p r e s s o r Compressor Compressor 网络会把姿势 y i y_i yi 映射到低维的 z i z_i zi上,然后将 z i z_i zi关联到 x i x_i xi上,并作为之后Decompressor 的输入来重建原始的姿势 y i yi yi 。通过这种方式,我们可以了解特征向量 x x x 中缺少哪些附加信息,并把这些附加信息编码到 z z z里面。

D e c o m p r e s s o r Decompressor Decompressor 的一个关键部分是 l o s s loss loss 损失函数。如果使用朴素的均方误差来作为loss函数的话,会出现抖动、低质量的运动。为此我们自己设计了一个损失函数用来 最小化视觉感知上的误差,这个loss函数主要使用正向运动学FK来评估计算人物空间中的loss 以及基于速度的loss 来确保输出姿势及时平滑地变化。并且我们还在 Z Z Z 上添加了一些额外的正则化的loss来保证稀疏性和平滑性。
具体的训练过程见下图中的Algorithm1:

在这里插入图片描述

图中假设我们从Animation Database Y Y Y和Matching Database X X X中给定了两帧数据,我们用Compressor C \color{Orange}\mathcal{C} C来找到潜在的变量 Z Z Z,用Decompressor D \color{Orange}\mathcal{D} D 来重新构建原始的姿势。虽然我们只介绍了单个训练样本(一共两帧,即一对数据)的过程,但我们将其应用于小批量mini-batch中的每个元素,并在更新神经网络中的参数 θ C \color{Orange}\theta_{\mathcal{C}} θC θ D \color{Orange}\theta_{\mathcal{D}} θD 时对结果进行平均。 ⊖ \color{Orange}⊖ 算子用来计算两个pose之间的差异,所有的姿势差异基本都定义为基本减法,唯一的例外是 y r y^r yr旋转差异的计算, y r y^r yr需要先转换为旋转矩阵形式然后相减来计算的。还有需要注意的是,在速度loss L l v e l \mathcal{L}_{lvel} Llvel 和 $\mathcal{L}_{cvel} $的时候,我们尽量不去计算pose的速度 y ˙ r \dot{y}_r y˙r y ˙ t \dot{y}_t y˙t的差异,因为它们的加速度噪声太大了所以基本没什么用。还有就是我们 所有基于姿势(pose-based)的loss损失权重 w ∗ w_∗ w 设置的基本相等,正则化loss损失权重的话一般设置的比较小。

我们发现给 Compressor 提供本地和人物空间输入 能够提高准确性,因为如果这个输入的特征是真实有效的话,Compressor就能直接把它们复制到潜在空间(the latent space)。例如,人物空间脚关节速度是预测关节接触信息的有用特征,这些特征就会被直接复制到潜在空间。

一旦经过训练,Compressor在没有其他神经网络的情况下就已经能够发挥很大作用了。我们通过计算每帧 i i i 的低维特征 z i z_i zi得到 Z = [ z 0 , z 1 , . . . , z n − 1 ] Z = [z0, z1, ..., zn−1] Z=[z0,z1,...,zn1] 来代替原本的 Y Y Y,就已经可以在不影响所有行为的情况下实现显着的内存节省运动匹配算法。所以,即便没有找到匹配的特征,Compressor 和 Decompressor 也可以用作动画数据的一种相当有效的通用压缩方法。(详情见Table3)
在这里插入图片描述

虽然 Decompressor 不再需要将 Y Y Y 存储在内存中,但我们仍然必须存储 X X X Z Z Z,当使用许多匹配特征或潜在变量时,两者仍然有可能比较大。在之后的两节内容里,我们讲说明如何消除存储这两个附加的DataBase。

Stepper 负责帧的步进

假设已经给定了初始matching和latent特征向量 x i x_i xi z i z_i zi ,我们还需要向前逐帧推进并且取出 x i + 1 x_{i+1} xi+1 z i + 1 z_{i+1} zi+1。在basic Motion Matching算法里面,逐帧推进是很简单的————我们只要增加索引 i i i 并查找新的 X X X Z Z Z就行了。但是,如果我们想要规避存储 X X X Z Z Z的话,我们就不能使用这种简单的步进规则。

所以,我们引入了 Stepper,Stepper是一个经过训练的网络,在给定的帧 x i x_i xi z i z_i zi 处将匹配和潜在特征向量作为输入,并输出一个增量delta,我们用delta来生成 x i + 1 x_{i+1} xi+1 z i + 1 z_{i+1} zi+1 处的特征向量。具体的训练过程见Algorithm2

在这里插入图片描述

在Algorithm2中,我们用一种自回归(auto-refressive)式的训练方法,在一个给定的 s s s帧的窗口里面 我们逐帧推进生成 X X X Z Z Z
虽然我们介绍的是单个样本的训练过程,但对于每个元素我们都进行这样的小批量mini-batch训练,并在更新 θ S \theta _{\mathcal{S}} θS 时对结果进行平均。权重 w ∗ w_* w被设置为对所有损失给予大致相等的权重。

经过训练后,Stepper 可以用作管道中 Stepping 部分的替代品,并生成匹配和潜在特征向量流,而不依赖于 X X X Z Z Z。虽然可以使用 C o m p r e s s o r Compressor Compressor 找到初始起始状态,但近邻搜索的时候仍然需要将 X X X Z Z Z保存在内存中。在下一节内容里,我们将说明如何使用经过训练的网络把query向量 x ^ \hat{x} x^ 直接映射到 x x x z z z来消除这种限制。

Projector 寻找下一个最佳匹配特征

尽管 S t e p p e r Stepper Stepper 允许我们更快地推进特征向量,但在query向量 x ^ \hat{x} x^ 上执行的最近邻搜索仍然需要匹配数据库 X X X
为了最终避免在内存中存储 X X X Z Z Z ,我们引入训练的网络 P r o j e c t o r Projector Projector用于从 x ^ \hat{x} x^ 中模拟最近邻搜索行为来找到匹配的最近条目 x k ∗ x_{k^*} xk

具体的细节可以看Algorithm3:

在这里插入图片描述

在Algorithm3中,给定来自 Matching Database x x x 的特征向量,我们对噪声幅度 n σ n^\sigma nσ 进行采样,并使用它来缩放高斯噪声向量 n n n。我们将其添加到 x x x 来产生 x ^ \hat{x} x^ 并找到最近邻 k ∗ k^* k。然后训练 Projector 来输出相关的特征向量 x k ∗ x_{k^*} xk和潜在变量 z k ∗ z_{k^*} zk
虽然我们介绍的是单个样本的训练过程,但对于每个元素我们都进行这样的小批量mini-batch训练,并在更新 θ P \theta _{\mathcal{P}} θP 时对结果进行平均。通过采样不同等级的噪声等级,我们最终能提高 P r o j e c t o r Projector Projector的稳定性。我们在设定各个loss的权重 w ∗ w_* w的时候使用的是基本相等的权重。

Projector训练好之后我们就完成了 Learned Motion Matching 的管线:

  • 我们在生成姿势的时候不再使用最近邻搜索,而是每隔 N N N帧就把 user query x ^ \hat{x} x^传递给 P r o j e c t o r P Projector \ \mathcal{P} Projector P
  • 之后每一帧的我们用 S t e p p e r S Stepper \mathcal{S} StepperS来步进已经搜索到的 matching向量和latent向量。
  • 最后我们用 D e c o m p r e s s o r D Decompressor\ \mathcal{D} Decompressor D来解码并且生成pose。

Training 训练相关信息

所有网络都使用 RAdam 优化器在 PyTorch 中进行训练:

batch size = 32,
learning rate = 0.001, 每 1000 次迭代衰减 0.99 倍。

S t e p p e r Stepper Stepper 网络使用 2 N 2N 2N 帧的窗口大小 s s s 进行训练,其中 N N N 是每次搜索之间的帧数(通常约为 10 10 10)。我们使用的潜在变量latent z ∈ R 32 z \in \mathbb{R}^{32} zR32 。对于所有网络,在Intel Xeon 3.5Ghz 12 核 CPU 上进行多达 500,000 次单线程迭代的训练。

所有三种网络的训练都在 Intel Xeon 3.5Ghz 12 核 CPU 上进行(500,000 次单线程迭代)。我们发现使用较小的网络规模的话在CPU上的训练效率基本上都要比在 GPU 上的训练效率更高。

在这里插入图片描述

一般训练几个小时也能拿到结果,但是我们还是建议训练的久一点来达到最优效果。需要注意的是 尽管必须先训练 Decompressor 才能允许计算潜在变量 Z Z Z,但之后的 Stepper 和 Projector是可以并行训练的。有关所用网络架构的具体详细信息,(参见Table1)

训练结果

在这里插入图片描述
在本节中,我们展示了LMM在各种运动匹配场景中的应用结果,其概述如Figure 1所示,其数值细节如Table2 所示:

在这里插入图片描述

在这里插入图片描述

Figure 4 展示了LMM应用于角色运动的方法。在图中,我们无需相位或其他附加变量即可生成高质量、自然且响应迅速的运动。在这种情况下,匹配特征是相对于根部的足部位置和速度、髋部速度、未来 20、40 和 60 帧(60Hz)的未来轨迹位置和方向,以及步态角色(走路、跑步或蹲伏)。除了姿势之外,我们还从 Decompressor 输出二进制接触信息并应用逆运动学来消除脚部滑动。我们将此演示扩展到在崎岖地形上的运动,包括将来在 0、15、30 和 45 帧脚趾下的地形高度等附加特征。这个高度是相对于角色臀部的当前高度记录的。因此,在运行时,我们需要从 Decompressor 输出未来脚趾位置 15、30 和 45 帧,以便我们可以找到它们下方的高度,而在训练时,我们需要找到运动中地形的高度捕获数据。有关我们如何执行此操作的更多信息,请参阅附录D

在这里插入图片描述

在Figure 5 中,我们展示了LMM应用于坐下和从椅子上起身时候的场景。

在图中,我们使用前面展示的标准运动控制器,但另外也会定时尝试从一组使用相对椅子位置和方向的坐下和起身动画中进行匹配。如果找到matching的时间花费低于切换到控制器的阈值,我们就尝试重新搜索(re-search)来查看能不能找到更好的matching。

除此之外还应用了轨迹变形(Trajectory warping)和IK,这样角色就能准确地到达椅子位置而不会脚滑。对于站起动画,我们同样会把动画结束时角色的位置和方向与新放置的椅子相匹配做matching。

图里还展示了我们的技术在角色交互时的应用,玩家控制的角色使用包括其他角色的位置、面向方向和速度在内的特征来匹配最合适的交互。非玩家控制的角色与玩家控制的角色播放的同步动画中存在的轨迹相匹配。这个同步轨迹必须得是玩家控制角色的Decompressor得到的输出,否则在运行时没法用。

在这里插入图片描述

图 6展示了我们的方法应用于在原始非结构化( raw unstructured motion) 动捕数据的数据库上训练的狗狗 的角色上。在这里,我们匹配所有四只爪子的位置和速度以及未来的轨迹 (future trajectory) 和步态(gait,走或者跑两种步态)。我们的方法完全可以扩展到四足动物,并产生高质量的运动,而不会损失保真度或不需要状态信息或特定的门控网络。

图里面还展示了在崎岖的地面上散步的熊。通过使用称为 carpet unrolling 的数据增强的技术,只要大约一分钟的关键帧动画数据(3581 帧),我们就能产生各种各样的转弯以及 在崎岖地形上的运动数据。最终我们能拿到一个包含约 700000 帧动画的通用的数据库。如果使用basic Motion Matching的话,这个大型的增强的数据库的运行效率会非常低,但LMM的方法效果就很好。


性能评估与比较

与其他模型比较结果和性能

在本节中,我们将我们的方法与basic Motion Matching和其他最先进的基于神经网络的模型进行比较,包括Phase-Functioned Neural Networks (PFNN) 和Mode-Adaptive Neural Networks (MANN)。在所有比较中,我们使用相同的数据进行训练,使用相同的输入特征,并应用相同的预处理和后处理步骤(例如清除脚部滑动 foot sliding clean-up),但动画混合除外,因为PFNN 或 MANN不需要做动画混合。

在这里插入图片描述

在Figure7 里,我们看到了我们的方法和basic Motion Matching之间的比较:当触发搜索时,我们为两个系统提供相同的输入并并行评估它们,直到触发下一个搜索。即使LMM在内存消耗上有很大优势,单纯从动画结果上来看LMM和basic Motion Matching相差不多。

在这里插入图片描述

在Figure 8 中,我们将我们的方法与在崎岖地形数据集上训练的 PFNN 进行比较。虽然 PFNN 产生适应地形的运动,但LMM保留了原始数据中的更多细节,整体看起来更平滑、更多样化。

我们还将LMM与在我们的四足数据集上训练的 MANN 进行比较。同样,虽然 MANN 产生自然运动,但它没有保留与我们的方法相同的细节或质量水平,而我们的方法更接近于原始训练数据。如需更好的视觉比较,请参阅补充视频。

LMM性能评估

在本节中,我们评估LMM的性能和内存使用情况。有关完整详细信息,请参Table 3。

在这里插入图片描述

包括神经网络推算在内的所有性能测量均使用定制的优化神经网络推算库(network inference library) 在 Intel Xeon 3.5Ghz 12 核 CPU 上进行单线程处理。

在动画数据库 Y Y Y 中,速度的刻画我们使用的不是速度信息,而是使用有限差分去做即时计算,有限差分运算的时候那些不发生变化的关节位移只需要存储一次就行,这样就能够降低整体数据的内存占用。

LMM的一个核心优势就是它在估算时间(evaluation time)和内存使用方面的性能。我们发现我们的方法比其他最先进的基于神经网络的模型具有更快的估算时间,同时使用的内存也更少。与basic Motion Matching相比,LMM的估算时间慢一些,但是大大提高了内存使用率。此外,如果需要更快的计算时间,或者动画数据库很小(例如在椅子示例中),则使用 Decompressor 本身可以在两者之间提供折衷。虽然我们没有在这里展示它,但我们发现神经网络权重可以有效地压缩为 16 位整数,而不会显着降低精度或运行时的性能,这可能会将学习运动匹配的内存使用量进一步减少两倍。

我们注意到,当我们将我们的方法与未压缩的动画数据进行比较时,最先进的动画压缩技术通常可以实现以上述方式存储的数据库的 ∼5 倍压缩比,每帧的解压缩时间为∼20μs [Frechette 2019 ]。

此外,虽然我们的方法需要混合,但其他基于自回归神经网络的模型不需要。在我们的实验中,混合通常每帧耗时 20μs。即使考虑到这些差异,我们的算法与其他算法相比的整体特征也不会改变。最后,需要注意的重要一点是,尽管与basic Motion Matching(不需要训练)相比,我们的方法的训练时间很长,但我们的框架仍然允许艺术家和设计师快速迭代,因为他们可以使用基本运动匹配直到他们满意为止与他们的结果,然后简单地切换到学习运动匹配作为后处理。


Tips相关补充

OneHot编码

假设“花”的特征可能的取值为daffodil(水仙)、lily(百合)、rose(玫瑰)。

one hot编码将其转换为三个特征:is_daffodil、is_lily、is_rose,这些特征都是二进制的。

一句话概括:one hot编码是将类别变量转换为机器学习算法易于利用的一种二进制码 的过程。

PFNN(Phase-Functioned Neural Networks for Character Control)

论文源自SIGGRAPH 2017《Phase-Functioned Neural Networks for Character Control》

论文地址:https://theorangeduck.com/media/uploads/other_stuff/phasefunction.pdf
知乎相关博客:https://zhuanlan.zhihu.com/p/430442398

MANN(Memory-Augmented Neural Networks)

论文地址:https://arxiv.org/pdf/1605.06065v1.pdf
知乎相关博客:https://zhuanlan.zhihu.com/p/116813200

这篇关于《Learned Motion Matching》个人理解与翻译的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/442603

相关文章

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念