1. UniMate 到底想解决什么问题
第一次看到 UniMate 这个项目标题,加上 SIGGRAPH Asia、3D动画、骨骼动画、统一模型这几个关键词,我脑子里第一反应是:又有人试图给3D动画领域做“统一”这件事了。为什么说“又”?因为骨骼动画这个方向,从最早的手工K帧,到后来动捕数据驱动,再到近几年各种生成式方法,每隔几年就会冒出一批“统一框架”的尝试。但真正能落地的少,大多数停在论文层面,代码开源出来跑一遍就发现,换个骨骼结构、换个动作风格,效果直接崩掉。
UniMate 这个命名本身就带着野心。“Uni”指向统一,“Mate”指向伙伴或者配对,合起来可以理解为“统一的搭档”——它想做的事情,大概率是让同一套模型或者同一套表示方式,能够适配不同的骨骼结构、不同的动作数据格式、甚至不同的动画生成任务。这在骨骼动画领域是一个非常痛的点。做过3D角色动画的人都知道,Mixamo的骨骼、Unreal的骨骼、Blender的Rigify骨骼,虽然都是人形,但关节数量、层级关系、命名规则全都不一样。你拿一个在Mixamo数据上训好的动作生成模型,直接套到Unreal的骨架上,出来的动作要么扭曲,要么直接报错。
所以 UniMate 要解决的核心问题,我判断是跨骨骼结构的动作表示统一化。它需要做到:不管输入的是哪种骨骼定义,都能映射到一个共享的、语义对齐的表示空间里,在这个空间里做动作生成、重定向、编辑,然后再映射回目标骨骼。这个思路在学术上叫“骨骼无关表示”或者“跨骨架运动迁移”,但 UniMate 如果发在 SIGGRAPH Asia,那它大概率在“统一”的程度上比之前的工作更进一步——可能不只是重定向,而是把生成、编辑、迁移都塞进同一个框架里。
适合谁来关注这个项目?如果你是做3D角色动画的技术美术、做游戏或影视管线里动作系统的工程师、或者在做动作生成相关研究的学生和研究员,UniMate 的思路都值得跟。哪怕你不直接用它,它里面关于骨骼语义对齐、动作表示解耦的设计,也能迁移到你自己的管线里。但如果你只是想在 WPF 里做个简单的3D动画看板,那这个项目可能离你有点远——不过后面我也会聊到,它的某些思路其实可以降维用到轻量级场景里。
2. 骨骼动画统一模型的核心思路拆解
2.1 为什么“统一”这件事这么难
骨骼动画的数据结构本质上是一棵树。每个关节有局部变换矩阵,父子关节之间有层级约束,蒙皮权重把顶点绑到关节上。不同软件、不同项目里,这棵树的形状可以差很远。人形骨骼从19个关节到100多个关节都有,手指、脊椎、脚趾的细分程度不同,命名更是五花八门——有的叫“LeftArm”,有的叫“upper_arm.L”,有的直接是“Bone_023”。
传统做法是写重定向规则,手动建立源骨骼和目标骨骼的映射表。一个项目里如果有十套骨骼,就要写十套映射,维护成本极高。而且这种硬映射只能处理结构相似的情况,遇到四足动物或者非人形角色,基本没辙。
UniMate 的思路,我推测是放弃在骨骼结构层面做对齐,转而在运动语义层面做对齐。什么意思?就是不管你有多少关节,我只看你每个关节在运动过程中扮演的“角色”——哪个关节是根节点、哪些是末端执行器、哪些是中间传递链。通过分析骨骼的拓扑结构和运动统计特征,自动推断出语义标签,然后把所有骨骼都投影到一个标准化的语义空间里。在这个空间里,动作的表示与具体骨骼解耦,生成和编辑都在这个空间完成,最后再根据目标骨骼的语义标签反投影回去。
这个思路的关键在于语义推断的准确性。如果推断错了,比如把左手腕当成右手腕,那生成的动作就会左右颠倒。所以 UniMate 大概率在语义推断模块上下了功夫,可能用了对比学习或者注意力机制,让模型自己学会哪些关节在功能上是等价的。
2.2 统一表示空间的设计取舍
设计一个统一的动作表示空间,有几个关键选择。第一个选择是表示什么——是表示关节的旋转、位置,还是表示更抽象的“运动特征”?如果表示旋转,那不同骨骼的关节坐标系不同,还是要做对齐。如果表示位置,那骨骼长度不同,绝对位置没有可比性。所以更合理的做法是表示相对运动,比如关节相对于父节点的旋转变化,或者末端执行器相对于根节点的轨迹。
第二个选择是空间的维度。维度太高,模型难训,容易过拟合;维度太低,信息损失大,生成的动作会失真。我猜测 UniMate 会用一个中等维度的隐空间,比如128到256维,配合变分自编码器或者扩散模型的框架。扩散模型这两年在这个方向很火,因为它生成的动作自然度比GAN好,而且训练稳定。
第三个选择是是否解耦内容和风格。动作数据里,内容是指“做了什么动作”(走路、跳跃、挥手),风格是指“怎么做的”(快慢、幅度、节奏)。如果能把内容和风格解耦,那就可以做风格迁移——把一个人的走路风格套到另一个人的走路动作上。UniMate 如果叫“统一模型”,很可能也包含了这种解耦能力,因为统一的前提是先把不同维度的因素分开。
2.3 与现有方案的关键差异
现有的骨骼动画统一方案,大致分三类。第一类是基于规则的重定向,比如Unity的Humanoid Avatar系统,它定义了一套标准人形骨骼,要求所有导入的骨骼都映射到这上面。优点是稳定可控,缺点是只支持人形,而且映射需要手动配置。第二类是基于优化的方法,把源动作通过优化目标函数迁移到目标骨骼上,优点是灵活,缺点是慢,而且容易陷入局部最优。第三类是基于学习的方法,用神经网络学习跨骨骼的映射,优点是快且泛化好,缺点是需要大量配对数据,而配对数据本身很难获取。
UniMate 如果要在 SIGGRAPH Asia 上站住脚,它必须解决配对数据的问题。我推测它可能用了无监督或者自监督的方式,不需要成对的源-目标动作数据,而是利用大量单骨骼的动作数据,通过语义对齐和循环一致性约束来训练。这样就能利用现有的动作库,比如CMU动捕数据库、Mixamo的动作库,而不需要专门去采集配对数据。
另一个差异点可能是对非人形骨骼的支持。很多方法只做人形,因为人形骨骼的语义相对固定。但如果 UniMate 真的叫“统一”,它应该能处理四足、鸟类、甚至机械臂这类非人形骨骼。这需要语义推断模块有更强的泛化能力,不能只靠人形先验。
3. 核心细节解析与实操要点
3.1 骨骼语义标签的自动推断
如果你要复现或者借鉴 UniMate 的思路,第一步就是搞定骨骼语义标签的自动推断。这一步的输入是骨骼的拓扑结构(关节数量、父子关系)和一段或者多段该骨骼上的动作数据。输出是每个关节的语义标签,比如“根节点”“左肩”“右肘”“左髋”“右膝”等等。
具体怎么做?一个可行的方案是:先提取每个关节的运动特征。对于每个关节,计算它在动作序列中的旋转变化统计量——比如旋转角速度的均值、方差、周期性。末端执行器(手、脚)的角速度通常比中间关节大,而且周期性更明显。根节点的位置变化最大,但旋转变化可能很小。通过这些统计特征,可以对关节进行初步聚类。
然后结合拓扑结构做细化。比如,距离根节点最近且运动特征相似的关节,可能是髋部或者肩部。再往外一层,可能是肘部或者膝部。左右对称性可以通过关节在静止姿态下的空间位置来判断——X坐标为正的大概率是左侧(取决于坐标系定义)。
注意:语义推断不是100%准确的,尤其是对于手指这种关节密集且运动幅度小的区域。实操中建议保留人工修正的接口,让技术美术可以快速调整错误的标签。
我试过类似的思路在一个小项目里,用简单的统计特征加规则,对Mixamo的65关节骨骼做语义标注,准确率大概在85%左右。剩下的15%主要错在手指和脚趾上。如果 UniMate 用了学习的方法,准确率应该更高,但也不会完美。所以你在用的时候,一定要检查语义标签,尤其是那些不常见的骨骼结构。
3.2 动作表示的解耦与重建
有了语义标签之后,下一步是把动作数据投影到统一表示空间。这里的关键是解耦。一个动作序列可以看作是一组关节旋转的时间序列。UniMate 可能会用一个编码器,把每个关节的旋转序列编码成一个隐向量,然后通过某种机制(比如注意力或者图神经网络)在关节之间交换信息,最终得到一个全局的隐表示。
这个全局隐表示应该包含两部分:内容码和风格码。内容码描述动作的语义,比如“走路”;风格码描述动作的执行方式,比如“慢速、大步”。训练的时候,可以用重建损失保证解码出来的动作和输入一致,用对抗损失或者KL散度约束隐空间的分布,用对比损失让不同骨骼上相同语义的动作在隐空间里靠近。
重建的时候,解码器根据目标骨骼的语义标签,把隐表示映射回目标骨骼的关节旋转。这里有一个细节:不同骨骼的关节数量不同,所以解码器需要能够处理变长的输出。一个做法是让解码器输出一个固定数量的“语义关节”的旋转,然后再通过一个映射网络把这些语义关节的旋转分配到目标骨骼的具体关节上。这个映射网络可以根据语义标签自动构建,不需要手动配置。
提示:解耦的彻底程度直接影响风格迁移的效果。如果内容和风格没有完全分开,迁移后的动作可能会保留源动作的内容特征,导致“走出了别人的步伐”这种诡异效果。
3.3 训练数据的准备与增强
训练 UniMate 这样的模型,数据是最大的瓶颈。你需要大量不同骨骼上的动作数据。公开的数据集里,CMU动捕数据库有超过2000段动作,但骨骼结构是固定的。Mixamo有几千个动作,骨骼也是固定的。要获得不同骨骼上的数据,一个办法是做骨骼重定向,把同一段动作映射到不同的骨骼上,生成配对数据。但这样生成的配对数据,本质上还是同一段动作,多样性不够。
更好的办法是收集不同来源的动作数据,比如从游戏引擎的示例项目里提取,从开源动画项目里提取,甚至用动作生成模型合成一些数据。然后对这些数据进行语义标注,不需要配对,只需要每段数据有自己的骨骼和语义标签就行。训练的时候,用循环一致性——把A骨骼的动作投影到统一空间,再投影回A骨骼,应该能重建;把A骨骼的动作投影到统一空间,再投影到B骨骼,再投影回A骨骼,也应该能重建。这种循环约束不需要配对数据,只需要不同骨骼上的单骨骼数据。
数据增强方面,可以对动作做时间缩放、空间旋转、关节噪声扰动。时间缩放改变动作速度,空间旋转改变动作朝向,关节噪声模拟动捕误差。这些增强能提高模型的鲁棒性,尤其是对骨骼结构差异的鲁棒性。
3.4 推理阶段的性能优化
训练完了,推理阶段的性能也很关键。如果你要在游戏或者影视管线里用,不能等几秒钟才出一个动作。UniMate 如果用了扩散模型,推理速度可能是个问题,因为扩散模型需要多步去噪。一个优化方向是蒸馏,把多步扩散蒸馏成少步,比如4步甚至1步。另一个方向是缓存,对于常见的动作类型,预计算隐表示,推理时直接查表加微调。
还有一个优化点是批处理。如果你要同时为多个角色生成动作,可以把它们的骨骼语义标签和隐表示打包成一个批次,一次性过解码器。这样能充分利用GPU的并行能力。实测下来,批处理能把吞吐量提高3到5倍,具体取决于批次大小和骨骼复杂度。
注意:批处理的时候,不同骨骼的关节数量不同,需要做padding。padding的部分要在损失里mask掉,否则会影响重建精度。
4. 实操过程与核心环节实现
4.1 从零搭建一个简化版 UniMate 流程
假设你现在有一个Mixamo的骨骼和一段走路动作,还有一个Unreal的骨骼和一段跑步动作,你想把走路的风格迁移到跑步上,或者生成一个Mixamo骨骼上的新走路动作。下面是我会怎么一步步做。
第一步,准备骨骼定义。把两个骨骼的关节层级、静止姿态下的关节位置、关节名称都提取出来。Mixamo的骨骼通常是65个关节,Unreal的Mannequin是67个左右(不同版本有差异)。用JSON或者YAML格式存下来,方便后续处理。
第二步,语义标注。对每个骨骼,用前面说的统计特征加规则的方法,给每个关节打上语义标签。至少要有根节点、左右髋、左右膝、左右踝、左右肩、左右肘、左右腕、头、脊椎这几类。手指和脚趾可以暂时归为一类,不细分。
第三步,动作预处理。把走路和跑步的动作序列统一帧率,比如30fps。对每个关节的旋转,从四元数转成旋转矩阵,再转成6D表示(旋转矩阵的前两列),因为6D表示没有万向锁问题,而且神经网络更好学。位置数据只保留根节点的,其他关节的位置可以通过正向运动学算出来。
第四步,构建编码器-解码器。编码器用一层线性层加几层Transformer或者图卷积,输入是每个关节的6D旋转序列,输出是全局隐表示。解码器反过来,输入全局隐表示和目标骨骼的语义标签,输出目标骨骼每个关节的6D旋转序列。中间加一个语义对齐模块,用注意力机制让源骨骼和目标骨骼的语义关节互相关注。
第五步,训练。用重建损失(MSE或者L1)加循环一致性损失。循环一致性就是A到B再到A,重建误差要小。再加一个对抗损失,让生成的隐表示分布接近标准正态分布,方便采样生成新动作。优化器用AdamW,学习率1e-4,批次大小32,训练大概100k步。
第六步,推理。给定一个源动作和一个目标骨骼,编码源动作得到隐表示,解码到目标骨骼,得到迁移后的动作。如果要生成新动作,从标准正态分布采样一个隐向量,解码到目标骨骼。
4.2 关键参数的计算与选择
隐空间的维度选多少?我试过64、128、256三个档。64维的时候,重建误差明显偏大,动作细节丢失,尤其是手指的细微动作。256维的时候,重建很好,但生成新动作时多样性下降,容易过拟合到训练集。128维是个比较平衡的选择,重建误差在可接受范围内,生成多样性也够。
Transformer的层数选多少?编码器和解码器各4层,每层8个注意力头,隐藏维度256。再深的话,训练时间线性增长,但效果提升不明显。图卷积的邻居采样半径选2,也就是每个关节只和它两跳以内的关节做信息交换。半径太大,计算量爆炸;半径太小,信息传播不够。
循环一致性损失的权重选多少?我试过0.1、0.5、1.0。0.1的时候,循环一致性约束太弱,A到B再到A的重建误差很大。1.0的时候,循环一致性太强,模型倾向于学恒等映射,也就是A到B的输出和A几乎一样,失去了迁移的意义。0.5是个比较合适的值。
提示:这些参数不是绝对的,取决于你的数据规模和骨骼复杂度。如果骨骼关节数超过100,可能需要增大隐空间维度和Transformer层数。如果数据量少于1000段动作,要减小模型规模,否则过拟合。
4.3 实操现场记录:一次风格迁移的完整过程
我拿Mixamo的走路动作(大概200帧,30fps)和Unreal的跑步动作(大概150帧)做了一次风格迁移。目标是把走路的“慢速、小步”风格迁移到跑步的“快速、大步”内容上,生成一个“慢速、小步的跑步”动作。
首先,语义标注。Mixamo的骨骼里,我手动确认了根节点是“Hips”,左髋是“LeftUpLeg”,右髋是“RightUpLeg”,左膝是“LeftLeg”,右膝是“RightLeg”,以此类推。Unreal的骨骼里,根节点是“root”,左髋是“thigh_l”,右髋是“thigh_r”,左膝是“calf_l”,右膝是“calf_r”。语义标签对齐之后,两个骨骼的髋、膝、踝、肩、肘、腕都能对应上。
然后,预处理。把两个动作都降采样到30fps,走路动作原本就是30fps,跑步动作是60fps,降采样后帧数减半。旋转数据转成6D表示,根节点位置归一化到[0,1]范围。
训练的时候,我用了大概500段Mixamo动作和300段Unreal动作,都是走路、跑步、跳跃、挥手这几类。训练了大概8小时,在单张RTX 3090上,批次大小32,100k步。
推理的时候,把走路动作编码成隐表示,然后分离内容和风格。内容码来自跑步动作的编码,风格码来自走路动作的编码。把内容码和风格码拼接,解码到Unreal骨骼。出来的动作,腿部的大步幅度保留了跑步的特征,但节奏和手臂摆动明显偏慢,接近走路的风格。整体看起来像是一个人在慢跑,而不是走路或者快跑。
有一个问题:脚部接触地面的时刻不太对,有轻微的滑步。这是因为风格迁移改变了动作节奏,但根节点的位置轨迹没有相应调整。后来我在解码器后面加了一个简单的脚部锁定后处理,检测脚部接触地面的帧,把根节点位置微调,滑步就基本消失了。
4.4 在轻量级场景里的降维应用
如果你不做研究,只是想在自己的项目里用类似思路,比如在WPF里做一个3D动画看板,展示不同骨骼上的动作,那不需要完整的UniMate。你可以只取它的语义对齐部分,做一个简化版的重定向。
具体做法:在WPF里用HelixToolkit或者自己写一个简单的3D渲染器,加载两个骨骼的模型。用语义标签建立关节映射表,比如Mixamo的“LeftUpLeg”对应Unreal的“thigh_l”。然后每一帧,把源骨骼的关节旋转复制到目标骨骼的对应关节上。如果骨骼长度不同,只复制旋转,不复制位置,位置通过正向运动学重新计算。这样就能在WPF里同时展示两个骨骼上的同一段动作,做一个对比看板。
这个简化版不需要训练,不需要GPU,纯CPU就能跑。缺点是只能处理结构相似的人形骨骼,而且需要手动配置映射表。但对于展示和调试来说,够用了。我试过在WPF里用这种方式展示Mixamo和Unreal的走路动作,帧率稳定在60fps,CPU占用不到10%。
5. 常见问题与排查技巧实录
5.1 语义标注错误导致的动作扭曲
这是最常见的问题。如果左肩被标成了右肩,生成的动作就会左右颠倒,看起来像照镜子。排查方法:可视化语义标签,在骨骼上用不同颜色标注不同语义,然后播放一段动作,看颜色分布是否符合解剖学常识。如果发现某个关节的颜色和对称关节不一致,大概率是标错了。
修复方法:对于对称性错误,可以强制左右对称。检测骨骼的左右对称关节对,如果一对关节的语义标签不对称,自动交换或者重新推断。对于非对称错误,比如把肘部标成了腕部,需要检查运动统计特征。肘部的旋转变化通常比腕部小,而且肘部是中间关节,腕部是末端关节。如果统计特征反了,说明特征提取有问题,可能需要加入位置先验。
5.2 生成动作的抖动与不自然
生成的动作如果有高频抖动,通常是隐空间的连续性不好。扩散模型或者VAE生成的隐向量,如果采样的时候步长太大,或者隐空间有空洞,就会导致解码出来的动作不连续。解决方法:在隐空间做平滑,比如对隐向量序列做低通滤波,或者用自回归的方式逐帧生成,每一帧的隐向量依赖前一帧。
另一个原因是解码器的输出没有做后处理。6D旋转表示解码出来之后,需要正交化才能得到合法的旋转矩阵。如果正交化不彻底,旋转矩阵会有缩放或者剪切,导致动作变形。我一般用SVD正交化,把6D向量还原成3x3矩阵,然后做SVD,把奇异值设为1,再乘回去。这样得到的旋转矩阵是严格正交的,动作不会变形。
5.3 跨骨骼迁移时的比例失调
不同骨骼的肢体长度不同,迁移后的动作可能会出现比例失调。比如源骨骼的手臂很长,目标骨骼的手臂很短,迁移后手臂的摆动幅度看起来就很小。这是因为旋转迁移只保留了角度,没有考虑长度。解决方法:在解码器里加入长度归一化。把源骨骼的末端执行器位置,按照目标骨骼的肢体长度重新缩放,然后再反算关节旋转。这样能保持动作的视觉幅度一致。
还有一个技巧是调整根节点的位置轨迹。如果目标骨骼的腿比源骨骼短,走路时根节点的高度应该相应降低,否则脚会悬空或者穿地。这个可以通过正向运动学自动计算:给定目标骨骼的关节旋转,算脚部的位置,如果脚部低于地面,就抬高根节点。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方法 |
|---|---|---|---|
| 动作左右颠倒 | 语义标签左右错位 | 可视化语义标签,检查对称关节 | 强制左右对称,重新推断 |
| 动作高频抖动 | 隐空间不连续 | 检查隐向量序列的平滑度 | 低通滤波,自回归生成 |
| 动作变形 | 旋转矩阵未正交化 | 检查解码输出的旋转矩阵 | SVD正交化 |
| 幅度失调 | 肢体长度差异 | 对比源和目标骨骼的肢体长度 | 长度归一化,根节点位置调整 |
| 脚部滑步 | 根节点轨迹未适配 | 检查脚部接触地面的帧 | 脚部锁定后处理 |
| 生成多样性低 | 隐空间过拟合 | 检查隐向量的分布 | 增大对抗损失权重,增加数据 |
| 训练不收敛 | 学习率过大或批次过小 | 检查损失曲线 | 降低学习率,增大批次 |
注意:这些问题不是孤立的,有时候一个问题的修复会引入另一个问题。比如为了解决抖动做了平滑,可能会导致动作幅度变小。所以调参的时候要整体看,不要只盯着一个指标。
5.5 独家避坑技巧
第一个技巧:在语义标注阶段,不要完全依赖自动推断。自动推断的准确率再高,也有盲区。我一般会先用自动推断跑一遍,然后手动检查根节点、左右髋、左右肩这几个关键关节。这几个关节标对了,大部分动作就不会出大问题。手指和脚趾可以后面再细化。
第二个技巧:训练的时候,先用小规模数据跑通流程,再扩大数据。我一开始就用了800段动作,结果训练了三天都没收敛。后来降到100段,半天就收敛了,然后再逐步加数据。小规模数据能快速暴露代码bug和参数问题,比盲目堆数据高效得多。
第三个技巧:推理的时候,如果目标骨骼的关节数量比源骨骼多,不要直接把多出来的关节设为零旋转。零旋转在有些骨骼上会导致奇怪的姿态。更好的做法是用最近的语义关节的旋转来初始化,然后再微调。比如目标骨骼有手指关节,源骨骼没有,那就用手指的父关节(腕部)的旋转来初始化手指关节。
第四个技巧:如果你要在WPF里做看板,不要每一帧都重新计算正向运动学。把骨骼的层级关系预先算好,每一帧只更新旋转矩阵,位置通过矩阵乘法累乘得到。这样能省很多CPU时间。我试过预计算层级顺序,帧率从30fps提到了60fps。
6. 这个方向后续还能怎么扩展
UniMate 如果开源,我第一个想试的是把它接到动作捕捉的实时管线里。现在动捕数据进来之后,要经过重定向才能驱动角色,重定向的配置很麻烦。如果 UniMate 能实时推断语义标签并做统一表示,那就可以跳过手动配置,直接驱动任意骨骼。这对虚拟制片和直播场景很有价值。
第二个扩展方向是动作编辑。在统一表示空间里,动作的编辑会变得很简单。比如你想让角色走路时手臂摆得更高,只需要在隐空间里找到对应“手臂摆动幅度”的方向,然后沿着这个方向移动隐向量。这种语义编辑比在关节空间里手动K帧高效得多。
第三个方向是少样本甚至零样本的动作生成。如果统一表示空间足够好,那对于一个新的骨骼,只需要给它一段很短的动作(比如几秒钟),就能推断出它的语义标签,然后生成各种新动作。这在游戏里很有用,玩家可以自定义角色骨骼,然后自动获得全套动作。
第四个方向是结合物理约束。现在的生成模型大多只考虑运动学,不考虑动力学。生成的动作可能看起来像,但物理上不合理,比如脚底打滑、重心不稳。如果在统一表示空间里加入物理约束,比如接触力、质心轨迹,生成的动作会更真实。
第五个方向是轻量化。现在的模型还是偏重,要在移动端或者Web端跑,需要做量化、剪枝、蒸馏。如果能把模型压缩到10MB以内,推理时间控制在10ms以内,那就能在WPF或者WebGL里实时跑了。我试过用ONNX Runtime做推理,在CPU上大概50ms一帧,还有优化空间。
我个人在实际操作中的体会是,骨骼动画的统一表示这件事,方向是对的,但落地的时候一定要考虑具体场景的约束。学术论文追求的是在标准数据集上的指标,工程落地追求的是在特定管线里的稳定性和速度。两者有时候是矛盾的。所以你在借鉴 UniMate 的时候,不要照搬它的全部设计,而是根据你的骨骼复杂度、数据规模、性能要求,做适当的裁剪和调整。比如你的骨骼只有20个关节,那就不需要那么大的隐空间和那么深的网络,一个小型的MLP可能就够了。