Orbit 使用指南 09 | 训练强化学习Agent | Isaac Sim | Omniverse
揭谛揭谛
有高士指点我一下Agent应该怎么翻译吗,我觉得翻译成智能体真的感觉太玄乎了。我理解的Agent 就是源自于动词act,agent就是什么玩应然后他能动。我就先翻译成代理了,各位同修一定能理解,大家加油。
如是我闻:
在之前的指南中,我们介绍了如何定义一个RL任务环境,如何将其注册到gym注册表中,以及如何使用随机代理与之交互。现在我们进入下一步:训练一个RL代理来解决这个任务。
尽管envs.RLTaskEnv符合gymnasium.Env接口,但它并不完全是一个gym环境。环境的输入和输出不是numpy数组,而是基于torch张量,其第一个维度是环境实例的数量。
此外,大多数RL库期望它们自己的环境接口变体。例如,Stable-Baselines3期望环境符合其VecEnv API,该API期望一个numpy数组列表而不是单个张量。同样,RSL-RL和RL-Games期望不同的接口。由于没有一种适合所有情况的解决方案,我们并不将envs.RLTaskEnv基于任何特定的学习库。相反,我们实现了包装器来将环境转换为预期的接口。这些在omni.isaac.orbit_tasks.utils.wrappers模块中指定。
在这个教程中,我们将使用Stable-Baselines3来训练一个RL代理来解决车杆平衡任务。
真的我为什么要用4090来训练车杆,有用orbit训练机械臂的朋友请打开麦克风交流,我真的很需要帮助
在本指南中,我们使用位于orbit/source/standalone/workflows/sb3目录中的Stable-Baselines3工作流的训练脚本。让我们先搂一眼完整的代码长什么样。
# Copyright (c) 2022-2024, The ORBIT Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
"""Script to train RL agent with Stable Baselines3.
Since Stable-Baselines3 does not support buffers living on GPU directly,
we recommend using smaller number of environments. Otherwise,
there will be significant overhead in GPU->CPU transfer.
"""
from __future__ import annotations
"""Launch Isaac Sim Simulator first."""
import argparse
import numpy as np
import os
from omni.isaac.orbit.app import AppLauncher
# add argparse arguments
parser = argparse.ArgumentParser(description="Train an RL agent with Stable-Baselines3.")
parser.add_argument("--video", action="store_true", default=False, help="Record videos during training.")
parser.add_argument("--video_length", type=int, default=200, help="Length of the recorded video (in steps).")
parser.add_argument("--video_interval", type=int, default=2000, help="Interval between video recordings (in steps).")
parser.add_argument("--cpu", action="store_true", default=False, help="Use CPU pipeline.")
parser.add_argument(
"--disable_fabric", action="store_true", default=False, help="Disable fabric and use USD I/O operations."
)
parser.add_argument("--num_envs", type=int, default=None, help="Number of environments to simulate.")
parser.add_argument("--task", type=str, default=None, help="Name of the task.")
parser.add_argument("--seed", type=int, default=None, help="Seed used for the environment")
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args()
# launch the simulator
config = {"headless": args_cli.headless}
# load cheaper kit config in headless
if args_cli.headless:
app_experience = f"{os.environ['EXP_PATH']}/omni.isaac.sim.python.gym.headless.kit"
else:
app_experience = f"{os.environ['EXP_PATH']}/omni.isaac.sim.python.kit"
# launch omniverse app
app_launcher = AppLauncher(args_cli, experience=app_experience)
simulation_app = app_launcher.app
"""Rest everything follows."""
import gymnasium as gym
import os
from datetime import datetime
from stable_baselines3 import PPO
from stable_baselines3.common.callbacks import CheckpointCallback
from stable_baselines3.common.logger import configure
from stable_baselines3.common.vec_env import VecNormalize
from omni.isaac.orbit.utils.dict import print_dict
from omni.isaac.orbit.utils.io import dump_pickle, dump_yaml
import omni.isaac.contrib_tasks # noqa: F401
import omni.isaac.orbit_tasks # noqa: F401
from omni.isaac.orbit_tasks.utils import load_cfg_from_registry, parse_env_cfg
from omni.isaac.orbit_tasks.utils.wrappers.sb3 import Sb3VecEnvWrapper, process_sb3_cfg
def main():
"""Train with stable-baselines agent."""
# parse configuration
env_cfg = parse_env_cfg(
args_cli.task, use_gpu=not args_cli.cpu, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
)
agent_cfg = load_cfg_from_registry(args_cli.task, "sb3_cfg_entry_point")
# override configuration with command line arguments
if args_cli.seed is not None:
agent_cfg["seed"] = args_cli.seed
# directory for logging into
log_dir = os.path.join("logs", "sb3", args_cli.task, datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
# dump the configuration into log-directory
dump_yaml(os.path.join(log_dir, "params", "env.yaml"), env_cfg)
dump_yaml(os.path.join(log_dir, "params", "agent.yaml"), agent_cfg)
dump_pickle(os.path.join(log_dir, "params", "env.pkl"), env_cfg)
dump_pickle(os.path.join(log_dir, "params", "agent.pkl"), agent_cfg)
# post-process agent configuration
agent_cfg = process_sb3_cfg(agent_cfg)
# read configurations about the agent-training
policy_arch = agent_cfg.pop("policy")
n_timesteps = agent_cfg.pop("n_timesteps")
# create isaac environment
env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None)
# wrap for video recording
if args_cli.video:
video_kwargs = {
"video_folder": os.path.join(log_dir, "videos"),
"step_trigger": lambda step: step % args_cli.video_interval == 0,
"video_length": args_cli.video_length,
"disable_logger": True,
}
print("[INFO] Recording videos during training.")
print_dict(video_kwargs, nesting=4)
env = gym.wrappers.RecordVideo(env, **video_kwargs)
# wrap around environment for stable baselines
env = Sb3VecEnvWrapper(env)
# set the seed
env.seed(seed=agent_cfg["seed"])
if "normalize_input" in agent_cfg:
env = VecNormalize(
env,
training=True,
norm_obs="normalize_input" in agent_cfg and agent_cfg.pop("normalize_input"),
norm_reward="normalize_value" in agent_cfg and agent_cfg.pop("normalize_value"),
clip_obs="clip_obs" in agent_cfg and agent_cfg.pop("clip_obs"),
gamma=agent_cfg["gamma"],
clip_reward=np.inf,
)
# create agent from stable baselines
agent = PPO(policy_arch, env, verbose=1, **agent_cfg)
# configure the logger
new_logger = configure(log_dir, ["stdout", "tensorboard"])
agent.set_logger(new_logger)
# callbacks for agent
checkpoint_callback = CheckpointCallback(save_freq=1000, save_path=log_dir, name_prefix="model", verbose=2)
# train the agent
agent.learn(total_timesteps=n_timesteps, callback=checkpoint_callback)
# save the final model
agent.save(os.path.join(log_dir, "model"))
# close the simulator
env.close()
if __name__ == "__main__":
# run the main function
main()
# close sim app
simulation_app.close()
代码解析
上述代码大部分是样板代码,用于创建日志目录、保存解析的配置以及设置不同的Stable-Baselines3组件。对于这个教程来说,重要的部分是创建环境并用Stable-Baselines3包装器包装它。
代码中使用了三个包装器:
gymnasium.wrappers.RecordVideo:这个包装器记录环境的视频并保存到指定目录。这对于在训练过程中可视化代理的行为很有用。wrappers.sb3.Sb3VecEnvWrapper:这个包装器将环境转换为与Stable-Baselines3兼容的环境。stable_baselines3.common.vec_env.VecNormalize:这个包装器标准化环境的观察和奖励。
这些包装器通过反复调用env = wrapper(env, *args, **kwargs)来相互包装。然后使用最终的环境来训练代理。有关这些包装器如何工作的更多信息,请参考包装环境文档。
代码执行
我们训练了一个来自Stable-Baselines3库的PPO Agent来解决车杆平衡任务。
训练代理
有三种主要方法来训练代理。每种方法都有其自身的优势和劣势。根据使用情况,决定更倾向于哪一种。
1. 无显示 (Headless) 执行
如果设置了--headless标志,那么在训练期间不会渲染模拟。当在远程服务器上训练或当你不想看到模拟时,这是很有用的。通常,它会加速训练过程,因为只执行物理模拟步骤。
./orbit.sh -p source/standalone/workflows/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 64 --headless
2. 无显示执行与离屏渲染
由于上述命令不渲染模拟,因此无法在训练期间可视化代理的行为。为了可视化代理的行为,我们传递--offscreen_render参数,它启用离屏渲染。此外,我们传递--video标志,它会记录训练期间代理行为的视频。
./orbit.sh -p source/standalone/workflows/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 64 --headless --offscreen_render --video
3. 交互式执行
虽然上述两种方法对训练代理很有用,但它们不允许我们在模拟交互上查看发生了什么。所以要是有钱有芯片,尊贵的您可以忽略--headless标志,按如下方式运行训练脚本:
./orbit.sh -p source/standalone/workflows/sb3/train.py --task Isaac-Cartpole-v0 --num_envs 64
这将打开Isaac Sim窗口,可以看到代理在环境中的训练。然而,这将减慢训练过程,因为模拟是在屏幕上渲染的。作为一种解决方法,可以在屏幕右下角停靠的“Orbit”窗口中切换不同的渲染模式。要了解更多关于这些渲染模式的信息,请查看sim.SimulationContext.RenderMode类。
查看日志
在另一个终端上,我们可以通过执行以下命令来监控训练进度:
# execute from the root directory of the repository
./orbit.sh -p -m tensorboard.main --logdir logs/sb3/Isaac-Cartpole-v0

播放训练好的代理
一旦训练完成,可以通过执行以下命令来可视化训练好的代理:
# execute from the root directory of the repository
./orbit.sh -p source/standalone/workflows/sb3/play.py --task Isaac-Cartpole-v0 --num_envs 32 --use_last_checkpoint

上述命令将从logs/sb3/Isaac-Cartpole-v0目录加载最新的检查点。也可以通过传递--checkpoint标志来指定特定的检查点。
愿本文除一切机器人模拟器苦
以上
更多推荐
所有评论(0)