本文记录第一次在 Isaac Lab 中完成强化学习训练、查看训练曲线、加载 checkpoint 推理、观察仿真效果,以及修改奖励函数做对照实验的完整过程。
这次学习的重点不是背诵算法公式,而是先打通以下闭环:
理解任务 → 启动训练 → 判断是否学会 → 找到模型
→ 加载模型推理 → 观察行为 → 修改一个变量 → 对照实验
实践目标与运行环境
远程服务器和 Isaac Lab 工作目录可按实际环境填写:
服务器:<username>@<server-host>
Isaac Lab:<isaac-lab-root>/IsaacLab
当前环境已经验证了以下能力:
- Isaac Lab 可以正常启动强化学习任务。
- RSL-RL 可以完成策略训练并保存模型。
- Newton/MJWarp 可以作为物理后端运行已验证任务。
- TensorBoard 可以显示奖励、回合长度和成功率等指标。
- Viser 可以把远程服务器上的仿真画面显示在局域网浏览器中。
- 训练和可视化进程可以分别启动、检查和停止。
局域网访问地址的格式如下:
Viser 仿真:http://<server-host>:8080
TensorBoard:http://<server-host>:6006
这些端口只应在可信局域网中开放,不建议直接暴露到公网。
核心概念:训练、推理与仿真
这三个概念最容易混淆。
训练
训练时,智能体在仿真环境中不断试错:
观察状态 → 策略产生动作 → 物理仿真执行动作
→ 获得奖励和下一状态 → 更新神经网络参数
训练的特点是:
- 需要物理仿真。
- 会不断采集新的经验。
- 会更新模型参数。
- 会定期保存 checkpoint。
推理
推理时加载已经训练好的 checkpoint,让策略根据当前观察产生动作:
加载 checkpoint → 获得观察 → 策略产生动作
→ 物理仿真执行动作 → 显示行为
推理不会继续更新参数。因此,model_9.pt 在 play 过程中不会自己变得更好。
仿真
仿真是虚拟世界中的物理运行过程。训练和推理都需要仿真:
- 训练:在仿真中大量试错并学习。
- 推理:在仿真中验证已经学到的策略。
Viser 展示的是仿真画面,不是训练本身。
Cartpole 任务结构
Cartpole 是强化学习的经典入门任务:
- 小车可以在轨道上左右移动。
- 杆通过转轴连接在小车上。
- 策略需要控制小车移动,使杆尽量保持竖直。
它虽然简单,但包含了机器人强化学习最重要的组成部分:
观察 Observation
动作 Action
奖励 Reward
终止条件 Done
重置 Reset
策略 Policy
任务代码位置
任务配置:
source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_env_cfg.py
任务逻辑:
source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_env.py
任务逻辑中四个关键函数:
_get_observations() # 获取策略看到的观察
_get_rewards() # 计算本步奖励
_get_dones() # 判断回合是否结束
_reset_idx() # 重置已经结束的环境
观察空间
Cartpole 的策略每一步看到 4 个数:
[杆角度, 杆角速度, 小车位置, 小车速度]
对应代码的核心形式:
obs = torch.cat(
(
pole_position,
pole_velocity,
cart_position,
cart_velocity,
),
dim=-1,
)
这里只有位置和速度,这是因为对这个任务来说,它们已经足以描述当前运动状态。
动作空间
动作空间只有 1 维,策略输出一个数,用于控制小车沿轨道左右运动。
配置中的:
action_scale = 100.0
表示策略输出还要乘以动作缩放系数,转换为施加给小车的力。它不是“小车每次移动 100 米”。
奖励函数
该任务的奖励可以概括为:
总奖励
= 存活奖励
+ 失败惩罚
+ 杆倾斜惩罚
+ 小车速度惩罚
+ 杆角速度惩罚
近似写成:
r = 1
- 杆角度²
- 0.01 × |小车速度|
- 0.005 × |杆角速度|
若任务失败,还会增加终止惩罚。
例如,杆角度为 0.5,两项速度都是 0,本步没有失败:
r = 1 - 0.5² = 0.75
这说明奖励函数不是直接告诉智能体“向左”还是“向右”,而是给行为打分。策略通过大量试错,逐渐发现哪些动作更容易获得高分。
终止、超时与重置
Cartpole 回合结束有两类原因:
- 失败终止:小车越界,或者杆倾斜过大。
- 时间用完:已经坚持到一个回合的最大时长。
当前主要终止阈值包括:
小车最大位置:3.0 m
杆最大倾角:90°
回合时长:5 s
仿真步长为 1/120 s,每两个物理步执行一次策略,所以策略频率约为 60 Hz:
5 s × 60 步/s = 300 个策略步
因此,平均回合长度接近 300,通常意味着杆能够坚持完整个回合。回合成功后也会重置,并不代表所有重置都是失败。
重置时会随机化初始杆角度。这样训练出的策略不只会处理一个固定姿态,而能适应一定范围内的初始状态。
首次训练与 Checkpoint
训练配置与结果
第一次独立训练使用了较短的 10 轮实验:
CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh train \
--rl_library rsl_rl \
--task=Isaac-Cartpole-Direct-v0 \
--num_envs=128 \
--max_iterations=10 \
--run_name=student_first_train \
--seed=7 \
physics=newton_mjwarp
训练结果:
reward:35.26
mean episode length:61.72
这说明策略已经开始学习,但还没有稳定掌握任务。此时平均每回合只能坚持约 62 步,距离最大 300 步还有明显差距。
查找 Checkpoint
find logs/rsl_rl/cartpole_direct \
-type f \
-path '*student_first_train*' \
-name 'model_*.pt'
找到了:
model_0.pt
model_9.pt
10 轮训练按 0~9 编号,因此本次最后一个 checkpoint 是 model_9.pt。
需要修正一个容易产生的误解:
model_0.pt不是严格意义上的“完全没有训练”。- 它通常是在第 0 次迭代完成后保存的早期状态。
model_9.pt经过了更多轮参数更新,一般比model_0.pt更成熟。
Checkpoint 的含义
Checkpoint 是训练过程在某个时刻保存的“模型快照”。
它主要包含:
- 神经网络已经学到的参数。
- 继续训练或恢复训练所需的状态。
- 与本次训练相关的部分配置和统计信息。
Checkpoint 不是仿真场景,也不是视频。可以把它理解为策略当时已经形成的“技能记忆”。
Checkpoint 有两个主要用途:
- 推理:加载它,直接验证已经学到的行为。
- 续训:从它的状态继续训练,使策略进一步改善。
模型推理与仿真可视化
CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh play \
--rl_library rsl_rl \
--task=Isaac-Cartpole-Direct-v0 \
--checkpoint logs/rsl_rl/cartpole_direct/2026-07-25_14-13-46_student_first_train/model_9.pt \
--num_envs=1 \
--viz viser \
--max_visible_envs=1 \
--real-time \
physics=newton_mjwarp
在浏览器中打开:
http://<server-host>:8080
观察到小车左右移动,杆没有立即倒下,说明:
- checkpoint 加载成功。
- 策略确实在根据观察输出动作。
- 物理仿真和局域网可视化链路正常。
停止推理时在服务器终端按:
Ctrl+C
终端出现 server stopped,一般表示 Viser 服务被正常停止,不代表模型损坏。
TensorBoard 与收敛判断
启动 TensorBoard:
./isaaclab.sh -p -m tensorboard.main \
--logdir logs/rsl_rl/cartpole_direct \
--host 0.0.0.0 \
--port 6006
浏览器打开:
http://<server-host>:6006
20 轮实验
day1_first_train 的结果大致为:
reward:-0.95 → 136.44
mean episode length:13 → 149.86
判断:模型明显在学习,但还未完全收敛。
100 轮实验
day2_convergence 的最终结果大致为:
reward:294.07
mean episode length:299
success rate:1.0
最终 checkpoint:model_99.pt
判断:该任务已经基本收敛。
多指标判断方法
较可靠的收敛判断需要同时考虑:
- 奖励总体上升,并在较高水平形成平台。
- 平均回合长度接近任务最大值。
- 成功率接近
1.0。 - 多轮之间波动较小。
- 加载 checkpoint 后,实际动作表现稳定。
对于这次 Cartpole 实验:
平均回合长度接近 300
+ 成功率接近 1.0
+ 奖励曲线已经平稳
= 可以停止训练并保存当前模型
继续训练不一定有明显收益,还会继续消耗计算资源。
并行环境与经验采集
--num_envs=128 表示一次并行运行 128 个独立的仿真环境。
它不是训练 128 个不同模型,而是:
1 个共享策略
↓
同时控制 128 个 Cartpole 环境
↓
快速采集大量不同经验
↓
共同用于更新这 1 个策略
若观察维度为 4,128 个环境的观察张量形状通常类似:
[128, 4]
动作维度为 1,则动作张量形状类似:
[128, 1]
如果每个环境每轮采集 16 步:
128 个环境 × 16 步 = 2048 条经验
若使用 256 个环境:
256 个环境 × 16 步 = 4096 条经验
增加并行环境通常能更快收集数据,但也会占用更多显存和计算资源。它不会自动保证策略更好,还要结合每轮步数、批大小、学习率等参数理解。
奖励参数对照实验
实验目标:增大小车速度惩罚,观察是否能让小车移动得更慢。
实验设计
基准参数:
rew_scale_cart_vel = -0.01
修改后:
rew_scale_cart_vel = -0.05
为了使比较尽量公平,保持以下条件一致:
任务:Isaac-Cartpole-Direct-v0
并行环境数:256
训练轮数:100
随机种子:42
训练命令:
CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh train \
--rl_library rsl_rl \
--task=Isaac-Cartpole-Direct-v0 \
--num_envs=256 \
--max_iterations=100 \
--run_name=student_cart_vel_penalty \
--seed=42 \
physics=newton_mjwarp \
env.rew_scale_cart_vel=-0.05
最终 checkpoint:
logs/rsl_rl/cartpole_direct/2026-07-25_15-40-14_student_cart_vel_penalty/model_99.pt
实验结果
平均奖励:287.98
平均回合长度:299
成功率:1.0
主观观察:小车移动速度与基准模型差不多
实验结论
可以确定:
- 将速度惩罚从
-0.01增强到-0.05,没有破坏模型完成 Cartpole 任务的能力。 - 修改后的模型仍然达到回合长度约 299、成功率 1.0。
暂时不能确定:
- 小车的实际平均速度是否降低。
- 动作是否变得更加平滑。
原因是本次没有记录速度和动作变化的量化指标,仅凭肉眼看“差不多”,证据还不够。
另外,修改奖励公式后,两个实验的奖励绝对值不能直接作完全等价的横向比较,因为它们使用的“计分尺”已经不同。
速度与动作平滑性的区别
判断速度是否降低,可以记录:
平均 |cart_velocity|
最大 |cart_velocity|
判断控制是否平滑,可以记录:
相邻动作变化:|action(t) - action(t-1)|
小车加速度
动作或加速度的最大值、均值和方差
策略可能移动速度不快,但频繁左右抖动;这种行为并不平滑。因此,后续实验必须让评价指标与实验目标一致。
强化学习实验方法
以后修改任务时,使用下面的模板。
明确实验问题
实验问题:
只修改哪个变量:
预期会出现什么变化:
可能带来什么副作用:
控制实验变量
除研究变量外,尽量保持以下设置一致:
任务
算法
并行环境数
训练轮数
随机种子
其他环境和算法参数
记录实验结果
训练是否成功:
平均奖励:
平均回合长度:
成功率:
目标指标:
仿真现象:
能确定的结论:
还不能确定的部分:
建立证据与结论的对应关系
例如:
“成功率为 1.0”
可以支持“模型能够完成任务”。
“肉眼看速度差不多”
不能支持“平均速度一定没有改变”。
这一区分是从“会运行命令”走向“会做强化学习实验”的关键。
参考资料
参考资料检索日期:2026-07-25。
评论