xbpeng / DeepMimic

Motion imitation with deep reinforcement learning.
https://xbpeng.github.io/projects/DeepMimic/index.html
MIT License
2.27k stars 485 forks source link

Motions weights clarification #163

Open AGPX opened 2 years ago

AGPX commented 2 years ago

Hi @xbpeng,

I wish to train the agent with custom motion capture animations, but I wish to understand better how to tune the motion dataset weights. I mean the following weights (from 'humanoid3d_clips_walk_punch.txt'):

{
    "Motions": 
    [
        {"Weight": 3, "File": "data/motions/sie/sie_humanoid3d_punch_forward00.txt"},
        {"Weight": 3, "File": "data/motions/sie/sie_humanoid3d_punch_forward01.txt"},
        {"Weight": 3, "File": "data/motions/sie/sie_humanoid3d_punch_forward02.txt"},
        {"Weight": 3, "File": "data/motions/sie/sie_humanoid3d_punch_left00.txt"},

        {"Weight": 2, "File": "data/motions/amass/humanoid3d_ready_to_walk_mirror.txt"},
        {"Weight": 2, "File": "data/motions/amass/humanoid3d_walk_to_ready_mirror.txt"},

        {"Weight": 1, "File": "data/motions/humanoid3d_walk.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk0.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk1.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk2.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk3.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk0_mirror.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk1_mirror.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk2_mirror.txt"},
        {"Weight": 1, "File": "data/motions/long/humanoid3d_long_walk3_mirror.txt"}
    ]
}

The weights must be assigned based on "how difficult" the movement is (i.e.: the more difficult a movement is to learn, the greater the weight needed) or they only affect the selection of the movement (i.e.: greater weight => greater probability that the movement will be used during test)? Or something else?

In any case, can you give me some guideline on how to choose such weights?

In my case, I have the following movements:

{
    "Motions": 
    [
        {"Weight": 2, "File": "data/motions/AGPX/JabL.txt"},
        {"Weight": 2, "File": "data/motions/AGPX/JabR.txt"},

        {"Weight": 1, "File": "data/motions/AGPX/TurnL90.txt"},
        {"Weight": 1, "File": "data/motions/AGPX/TurnR90.txt"},
        {"Weight": 1, "File": "data/motions/AGPX/TurnL180.txt"},
        {"Weight": 1, "File": "data/motions/AGPX/TurnR180.txt"},

        {"Weight": 1, "File": "data/motions/AGPX/WalkFwd.txt"}
    ]
}

I've seen that the "TurnL/R" movements are more difficult to learn than the others. With the weights above, the agent finds awkward strategies to make a turn, using Jab or even a backward walk (like a moonwalk!) instead of simply turn and going towards the goal like it does in your example (I'm using the SceneStrikeAMP as scene). The example you provided for this scene works well, but with my MOCAP files I can't get a decent result and I believe the weights can be one of the problems.

Another difference is that you also have a long walk animation, where the actor walks continuously (with turns), instead in mine I've separate files that model the turn (note that all the animations listed above start and end in the same pose). I believe a long walk gives better results, but unfortunately I'm using already existing MOCAP files and I couldn't find a long walk animation that fit my purposes (and building one through motion blending is quite a nightmare), so I can only rely on these separate moves.

I also seen that setting the 'sync_char_root_rot' flag to true is useful in my case (although I'm not 100% sure what it does... maybe when a looped animation ends, the kinematic actor restarts from the current rigid body actor orientation?), probably because the turning animations ends in a different orientation (however in your example this flag is set to false).

So many questions... but we have soo many parameters and achieving a decent result is amazingly difficult (especially since each attempt takes so long to evaluate). Maybe it would be useful to add a functionality to the software that help visualize the impact of these flags/parameters on training.

Thanks in advance,

AGPX

xbpeng commented 2 years ago

We mostly choose the weights so that different types of actions will be roughly sampled with equal probability. So in the punching task, we have a lot more locomotion clips than punching clips, so we assign a higher weight to the punch clips. For your clips, i think the weights you have is a reasonable start. But if that doesn't work well, increasing the weight on motions that seem more challenging could help.

Having separate motion clips for turning and walking forward should work just as well as one long clip that contains walking and turning behaviors. The disciminator only sees transitions, so how long the original clip is doesn't really effect the observations.

'sync_char_root_rot', you are right, this flag will have it so that when at the end of a motion clip, the kinematic character will restart from the current simulated character's orientation.

AGPX commented 2 years ago

Ok, but when 2 actions can be considered different/same? For example, in my case, which of the following groupings is more correct in your opinion?

Case 1:
group 1) TurnL90, TurnL180, TurnR90, TurnR180, WalkFwd
group 2) JabL, JabR
Case 2:
group 1) TurnL90, TurnL180, TurnR90, TurnR180
group 2) WalkFwd
group 3) JabL, JabR
Case 3:
group 1) TurnL90, TurnL180
group 2) TurnR90, TurnR180
group 3) WalkFwd
group 4) JabL, JabR
Case 4:
group 1) TurnL90, TurnR90
group 2) TurnL180, TurnR180
group 3) WalkFwd
group 4) JabL, JabR

Another question: with the current shape/size of the network, how many actions can I expect the network will be able to learn? I mean, by increasing the number of actions, will it be better to "enhance" the network? If yes, looking at the following code (in build_net):

layers = [1024, 512]
gate_common_layers = [128]
gate_layers = [64]

in your opinion, is better to increase the number of layers (e.g. layers = [1024, 1024, 512]), the size (e.g. layers = [2048, 1024]), or even both?

Thanks.

xbpeng commented 2 years ago

I think case 1 should be alright. I usually just group all of the locomotion clips together. Have you tried visualizing what the retargeted motions look like in deepmimic?

You don't have a lot of motion clips, so I think the original network architecture should be more than enough. But you could try a larger network in case it might help.

AGPX commented 2 years ago

Thanks for reply. Yes, I have visualized the motion in DeepMimic (here an example: https://youtu.be/bf_kVcij0Q0), it seems ok to me. However, looks like that this animation is a bit difficult to be learned by DeepMimic (look the training attempt: https://www.youtube.com/watch?v=9GRANYCWPGw), maybe the issue is in the ankles? Or maybe due to the fact that the feet intersect the floor a bit and the agent is unable to rotate due to the left foot stuck in the floor? (I'm start to think that I definitely need a way to adjust the feet in the animation, in order to avoid floor intersections)

Btw, for now I have only few animations, but I'm planning to increase them a lot.

xbpeng commented 2 years ago

can you share the motion file for the turning motion?

AGPX commented 2 years ago

File sent (via e-mail).