深度强化学习在足式机器人中的应用 (五) 模仿学习与敏捷运动

目录

5.3 RL + IL 混合方法:利用示范数据加速 RL 训练并学习更自然的动作

5.3.1 设计思路

5.3.2 代码实现(PyTorch + Stable-Baselines3)

关键实现细节

常见挑战与解决方案

5.4 敏捷技能学习:跑、跳、后空翻等高动态动作的建模与训练

5.4.1 动作建模

5.4.2 奖励设计

5.4.3 网络结构

5.4.4 训练策略

5.4.5 完整代码示例:后空翻训练

1. 完整代码

2. 如何准备演示数据

3. 常见问题

5.5 实验:少量专家数据 → 行为克隆初始化 → 强化学习微调

1. 背景与动机

2. 实验设计

3. 数据预处理

数据结构

4. 行为克隆(Behavior Cloning)

4.1 网络结构

4.2 损失与优化

4.3 训练与保存

5. 强化学习微调(PPO 示例)

5.1 环境包装

5.2 PPO 初始化

5.3 训练循环

5.4 微调后的评估

6. 性能对比与分析

常见挑战与解决方案

7. 代码优化技巧

8. 小结


5.3 RL + IL 混合方法:利用示范数据加速 RL 训练并学习更自然的动作

目标 – 在典型的连续控制环境(如 Humanoid、Walker2D 等)中,结合强化学习 (RL) 与行为克隆 (IL) 的思路,让智能体在少量示范数据下快速收敛,并获得更加平滑、符合物理约束的运动轨迹。
核心思想 – 先用演示数据做预训练(Behavior Cloning, BC),再通过带有“行为克隆奖励”或“KL 限制”的策略梯度方法继续优化,最终得到既高效又自然的控制策略。

5.3.1 设计思路

步骤 说明
1. 数据收集 使用运动捕捉、MotionBuilder 或者手工动画生成演示轨迹。每条轨迹为 state → action 对序列,长度可根据动作复杂度调整(如跑步 5s→250帧)。
2. BC 预训练 用交叉熵或均方误差 (MSE) 损失把策略网络参数初始化为能够模仿演示。
3. RL 细化 采用 PPO / SAC 等连续控制算法,加入 行为克隆奖励 或 KL 限制,保证在优化过程中不偏离演示轨迹太远。
4. 终端策略 在训练完成后,可进一步做微调或使用多任务学习(不同动作共享网络)。

为什么要这样做?

  • RL 的探索往往导致极端、不可预期的姿态,尤其在高维关节空间。
  • 直接从随机初始化开始收敛耗时长且不稳定。
  • 演示数据提供了“先验”,使智能体在起始阶段就能产生符合物理与美学的动作,从而减少梯度噪声、加速学习。

5.3.2 代码实现(PyTorch + Stable-Baselines3)

下面给出完整可跑的示例,演示如何在 Humanoid-v4 环境中使用 PPOBehavior Cloning 混合训练。我们将:

  1. 用 BC 学习一个初始策略。
  2. 在 PPO 的 loss 里加入 KL 惩罚(或行为克隆奖励)。

注意:为了演示,示例演示数据会用随机生成的“近似跑步”轨迹代替真实 mocap 数据;实际使用时请自行准备 demo_states.npydemo_actions.npy

# ====================== 1. 环境与依赖 ======================
import gym, numpy as np, torch, os, pathlib
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv, VecNormalize
from stable_baselines3.common.policies import ActorCriticPolicy
from stable_baselines3.common.callbacks import BaseCallback

# 让 SB3 能够使用自定义 loss(见后面)
class CustomActorCriticPolicy(ActorCriticPolicy):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

# ====================== 2. 数据准备 ======================
def load_demo_data(path="demo"):
    """
    加载演示数据。这里用随机生成的示例,实际请替换为 mocap 数据。
    """
    demo_states = np.load(os.path.join(path, "demo_states.npy"))
    demo_actions = np.load(os.path.join(path, "demo_actions.npy"))
    return demo_states, demo_actions

# ====================== 3. BC 预训练 ======================
def bc_pretrain(policy, states, actions, lr=1e-4, epochs=5):
    """
    用均方误差(MSE)做行为克隆。  
    - policy: SB3 的 ActorCriticPolicy 实例
    - states, actions: numpy arrays shape (N, state_dim) / (N, act_dim)
    """
    optimizer = torch.optim.Adam(policy.parameters(), lr=lr)

    for epoch in range(epochs):
        perm = np.random.permutation(len(states))
        states_shuf = torch.tensor(states[perm], dtype=torch.float32).to(policy.device)
        actions_shuf = torch.tensor(actions[perm], dtype=torch.float32).to(policy.device)

        # 前向
        with torch.no_grad():
            mean, log_std = policy.forward(states_shuf)
        std = (log_std.exp()).clamp(min=1e-3)   # 防止除零

        # 计算 MSE 损失
        loss = ((mean - actions_shuf)**2).mean()

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if epoch % 1 == 0:
            print(f"[BC] Epoch {epoch+1}/{epochs} | Loss: {loss.item():.4f}")

# ====================== 4. PPO + KL 限制 ======================
class KLLossCallback(BaseCallback):
    """
    每一步计算 KL 损失并写回到 policy 的属性 `kl_loss`,让 PPO 使用。
    """
    def __init__(self, kl_coeff=1e-3, verbose=0):
        super().__init__(verbose)
        self.kl_coeff = kl_coeff

    def _on_step(self) -> bool:
        # 计算当前策略与上一策略的 KL
        pi_old_logp = self.model.policy.log_prob(self.model._last_obs)
        pi_new_logp = self.model.policy.log_prob(self.training_env.get_attr('observation'))
        kl = (pi_old_logp - pi_new_logp).mean()
        self.model.policy.kl_loss = kl * self.kl_coeff
        return True

# ====================== 5. 主训练流程 ======================
def main():
    env_id = "Humanoid-v4"
    vec_env = DummyVecEnv([lambda: gym.make(env_id)])
    vec_env = VecNormalize(vec_env, norm_obs=True, norm_reward=False)

    # 1) 初始化策略网络
    policy_kwargs = dict(activation_fn=torch.nn.Tanh,
                         net_arch=[dict(pi=[256, 128], vf=[256, 128])])
    model = PPO(CustomActorCriticPolicy, vec_env,
                learning_rate=2.5e-4,
                n_steps=2048,
                batch_size=64,
                gamma=0.99,
                gae_lambda=0.95,
                clip_range=0.2,
                policy_kwargs=policy_kwargs,
                verbose=1)

    # 2) 加载演示数据并预训练
    demo_states, demo_actions = load_demo_data()
    bc_pretrain(model.policy, demo_states, demo_actions, lr=3e-4, epochs=10)

    # 3) 开始 PPO + KL 限制训练
    kl_cb = KLLossCallback(kl_coeff=1e-3)
    model.learn(total_timesteps=int(5e6), callback=[kl_cb])

    # 4) 保存模型
    os.makedirs("trained_models", exist_ok=True)
    model.save("trained_models/ppo_humanoid_bc_kl")

if __name__ == "__main__":
    main()

关键实现细节

模块 说明
BC 损失 采用 MSE 而不是交叉熵,原因是动作连续。可根据需要改为 GaussianPolicy 的负对数似然 (NLL)。
KL 限制 在 KLLossCallback 中,每一步计算旧策略与当前策略的 KL,然后乘以系数写回到 policy 里;PPO 在内部会把这个值加到 loss。这样可以在探索时保持对演示轨迹的“温和”偏离。
VecNormalize 对观测进行归一化,提升训练稳定性。注意 RL 与 IL 的数据分布差异,最好先用 BC 训练后再开启 normalize
网络结构 net_arch=[dict(pi=[256,128], vf=[256,128])] 是典型的两层全连接。可以进一步改为 LSTM 或 Transformer,以捕捉时序依赖。

常见挑战与解决方案

  1. 演示数据质量不佳

    • 症状:BC 训练后策略抖动、收敛慢。
    • 对策:使用数据增强(噪声注入、时间拉伸)或在 BC 损失中加入 KL 正则化,限制离演示的距离。
  2. KL 过大导致探索受限

    • 症状:收敛速度慢,无法超越演示表现。
    • 对策:动态调节 kl_coeff(如根据当前 KL 与目标值做比例),或采用 Adaptive KL 机制。
  3. 奖励与行为克隆冲突

    • 症状:在某些状态下,RL 想要做非演示动作导致奖励下降。
    • 对策:把行为克隆奖励设为负的 KL 或加权到总 reward,或使用 Replay Buffer 将 BC 数据混入 RL 经验。
  4. 高维观测导致过拟合

    • 症状:BC 在训练集上表现好,但在环境中泛化差。
    • 对策:加入 Dropout、L2 正则,或采用 Curriculum Learning 从简单到复杂的演示。

5.4 敏捷技能学习:跑、跳、后空翻等高动态动作的建模与训练

在真实机器人或游戏角色中,高动态动作(如跑步、跳跃、后空翻)需要时序一致性冲击容忍能量效率 的平衡。以下从建模、奖励设计、网络结构与训练策略四个维度给出实践指南。

5.4.1 动作建模

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值