写在前面
做强化学习实验时,很容易陷入一种状态:
TensorBoard / WandB 里曲线很多,但不知道哪条最重要;reward 抖得很厉害,也不知道算不算正常;loss 没有下降,又担心是不是训练坏了。
这篇笔记想整理一个更实用的问题:
看到 reward、episode length、noise_std、entropy、KL、value loss、FPS 这些曲线时,怎么判断训练是在变好、没学到东西,还是已经崩了?又该补记什么,才能验证自己的判断?
本文以连续动作的四足机器人 PPO 为主,也保留 off-policy 算法的对照。每个指标都尽量回答四件事:它到底统计什么、正常变化可能是什么、什么组合值得怀疑、下一步怎样验证。
代码名称以配套笔记使用的 rsl_rl v1.0.2 / legged_gym 固定版本为主;与 SB3 或新版实现不同的地方会单独说明。公式与完整调用链见:PPO、rsl_rl 与 legged_gym 训练闭环。
一句话结论
强化学习曲线不能只看某一条线,尤其不能只看 loss。更靠谱的方式是组合判断:
效果指标:eval reward / success rate 是否变好 |
如果这些信号方向一致,才比较能说明实验真的在变好。
0. 先接受一个事实:RL 曲线天然很吵
强化学习不像监督学习那样,loss 平滑下降通常就说明模型在学习。RL 里面经常出现:
- reward 抖动很大;
- loss 不一定单调下降;
- policy 变好时,value loss 反而可能短时间变大;
- episode length 变长不一定是好事;
- 一个 seed 跑成功,不代表算法稳定;
- train reward 很高,不代表 eval 也好。
所以看 RL 曲线时,重点不是问:
这条 loss 有没有下降?
而是问:
agent 的行为是不是真的变好了?训练是否稳定?这个结果是否可复现?
1. 最应该先看的几条曲线
如果 dashboard 里曲线很多,我会优先按这个顺序看:
- eval reward / success rate:最终任务效果有没有变好。
- train reward:训练过程中是不是在学。
- episode length:是在活得更久、完成得更快,还是更快失败。
- noise_std / entropy / 动作饱和率:策略分布有多宽,探索是否真正作用到了机器人。
- KL / clip fraction:PPO 更新是否过猛或过弱。
- value loss / explained variance:critic 是否靠谱。
- FPS / SPS:训练系统有没有卡住。
- 多个 seed 的均值和方差:结果是否稳定。
- 视频 / 轨迹:曲线看不清时,行为最真实。
先看日志口径,再看曲线形状
同样叫 reward 或 std,不一定是在统计同一个量。读图前先确认:
- 横轴:iteration、环境 transition 数,还是 wall-clock time?固定 个环境、每轮 步时,一轮收集 个 transition;物理子步数不是策略交互步数。
- 聚合范围:每个 step、mini-batch、已结束 episode,还是最近若干 episode 的滑动平均?长短 episode 的权重会不同。
- 处理顺序:reward 是否加权、乘控制周期、归一化或截断?action 在裁剪前还是裁剪后?
- 运行阶段:这是采样所用旧策略的统计,还是 optimizer 更新后的参数?一个 iteration 标签不保证所有指标来自同一时刻。
- 比较条件:环境数量、horizon、控制频率、reward 权重、课程难度是否一致?保留原始曲线,避免高平滑度掩盖尖峰。
下面是经典 rsl_rl v1.0.2 runner 的实际对应关系:
| 日志名称 | 它统计什么 | 容易误读的地方 |
|---|---|---|
Train/mean_reward |
最近最多 100 个结束 episode 的累计回报均值 | 不是当前所有环境的单步 reward 均值 |
Train/mean_episode_length |
同一窗口内的 episode 步数 | 并行环境多时,窗口可能很快被刷新 |
Policy/mean_noise_std |
更新后各动作维可学习 std 的算术平均 | 不是观测噪声,也不是动作轨迹的经验标准差 |
Loss/surrogate、Loss/value_function |
本轮 mini-batch 更新的平均 loss | 目标和采样数据每轮都在变化 |
Loss/learning_rate |
当前学习率 | adaptive schedule 下可能一轮内调整多次 |
Perf/total_fps |
除以采样与学习耗时之和 | 不等于渲染 FPS,也未覆盖所有保存/日志开销 |
这版 runner 默认没有记录 entropy、KL、clip fraction、explained variance。 算法内部计算某个量,不代表 TensorBoard 一定有对应曲线。下文把这些列为“建议补记”,不要把缺失曲线理解成数值为零。新版库和项目分支应重新核对 logger。
2. Reward 曲线怎么看
Reward 是最直观的指标,但也是最容易误导人的指标。
好的迹象
如果 reward 曲线满足下面几点,通常说明训练在正常学习:
- 长期趋势向上;
- eval reward 也跟着上升;
- 多个 seed 都能上升;
- 后期波动范围逐渐变小;
- 最终能稳定在较高水平。
注意这里说的是趋势,不是单个最高点。RL 中短时间冲到一个高 reward,然后马上掉下来,并不一定代表策略真的变强。
Reward 一直不动
如果 reward 长时间没有明显变化,常见原因包括:
- 奖励太稀疏;
- exploration 不够;
- learning rate 太低,几乎没更新;
- learning rate 太高,策略乱跳;
- action scale 不对;
- observation 有 bug;
- reward 没有正确返回;
- reset / done 逻辑写错。
我会优先排查这些东西:
- 随机策略的 reward 分布是否正常;
- agent 输出的 action 是否长期接近常数;
- reward 是否长期为 0、NaN 或固定值;
- observation 里有没有 NaN / inf;
- done mask 是否和环境终止逻辑一致。
Reward 先升后崩
这种情况很常见:一开始看起来学得不错,后面突然掉下去。
可能原因:
- policy update 太激进;
- learning rate 太高;
- PPO 的 KL 或 clip fraction 控制不住;
- value function 崩了;
- reward hacking;
- off-policy 算法里 replay buffer 分布变坏。
如果是 PPO,我会马上去看:
- KL 有没有突然升高;
- clip fraction 是否长期偏大;
- value loss 是否爆炸;
- gradient norm 是否异常。
调参方向通常是:
- 降低 learning rate;
- 减小 clip range;
- 减少 update epochs;
- 增大 batch size;
- 加 target KL early stopping;
- 检查 advantage / reward normalization。
Train reward 高,但 eval reward 低
这通常说明训练环境里的表现不能直接泛化到评估环境。
可能原因:
- train / eval 环境 wrapper 不一致;
- train / eval 的动作采样方式不同,却被直接比较;
- 训练环境初始状态太单一;
- 策略 overfit 到某些随机种子;
- reward 被训练环境里的某个漏洞 hack 了。
排查建议:
- 分别做确定性评估和采样评估,并明确标记动作模式;
- 核对 observation、归一化、动作缩放和控制频率一致;有意设置的难度差异则单独报告;
- 多个 seed、多种初始状态评估;
- 录视频看策略到底在做什么。
总 Reward 上升,究竟是哪一项在变好
机器人任务通常优化的是多项加权和:
必须把原始任务量和加权后的奖励贡献一起看。比如速度误差变小是物理效果;tracking_lin_vel 奖励变大还可能来自权重、误差核宽度或命令分布变化。
| 一组现象 | 可能解释 | 用什么验证 |
|---|---|---|
| 总 reward 升高,速度误差不降,动作惩罚变得没那么负 | 机器人少动了,但没有更好地跟踪命令 | 速度分桶误差、站立比例、视频 |
| 存活时间上升,单步任务收益不变 | 更多回报来自活得久 | 同时看累计回报和单位时间任务量 |
| 跟踪奖励变好,力矩/打滑也增加 | 用更激烈的动作换取跟踪性能 | 力矩分位数、足端滑移、跌倒率 |
| 升级地形后 reward 暂降 | 数据分布变难,未必是策略退化 | 固定难度评估集与 terrain level |
经典 legged_gym 会把非零 reward scale 乘以控制周期 dt;Episode/rew_* 又将结束 episode 的分项累计值除以配置的最大 episode 秒数,不是逐个除以该 episode 实际时长。若启用 only_positive_rewards,总 reward 还会先截断再添加 termination 项。因此不能直接把这些分项相加,要求它们等于 runner 的 Train/mean_reward。口径见 compute_reward()、reset_idx() 与 reward 初始化。
3. Episode length 怎么看
Episode length 不能孤立看,要结合任务类型。
越长越好型任务
比如 CartPole、机器人不摔倒、生存类任务。episode length 变长一般是好事,说明 agent 活得更久。
好的组合是:
episode length 上升 + reward 上升 + reset 变少 |
但如果 episode length 上升,reward 不升,就要小心:agent 可能只是学会了拖时间,而不是完成任务。
越短越好型任务
比如导航、到达目标、抓取成功后结束。这类任务里,episode length 下降可能是好事,也可能是坏事。
好的组合是:
success rate 上升 + episode length 下降 |
坏的组合是:
success rate 下降 + episode length 下降 |
后者通常说明 agent 更快失败了。
固定 horizon 任务
很多 RL 环境有最大步数限制。如果 episode length 总是等于 max steps,不一定说明策略好,也可能是它一直没完成任务,只是拖到了时间上限。
这时要结合:
- success rate;
- final distance;
- command tracking error;
- reset reason;
- task completion bonus。
终止原因和 timeout 必须拆开
建议分别记录跌倒、非法接触、越界、任务成功和时间上限,占全部结束 episode 的比例;必要时再补每千个环境步的失败次数。单看“reset 次数变少”会受到吞吐量与 episode 长度影响。
还要核对 critic 的 bootstrap:真实终止通常不接后续价值;对仍在继续的任务,外部时间限制造成的截断通常需要 bootstrap。有限时域任务若时间上限本来就是任务终点,则要按其 MDP 定义处理。自动 reset 的环境尤其要分清终止前的 observation 和新 episode 初始 observation,不能把后者的价值接到前一条轨迹上。参见 Gymnasium 时间限制说明。
4. Loss 曲线怎么看
RL 里的 loss 和监督学习里的 loss 很不一样。监督学习里 loss 下降通常是好事,但 RL 里不能这样简单判断。
Policy loss
Policy loss 是采样数据上的策略优化目标,其符号取决于实现约定,数值大小不直接等于策略更新幅度。它可能是负数,也不需要单调下降。
单独看 policy loss 意义有限,更应该和 reward、KL、entropy 一起看。
危险信号:
- policy loss 突然爆炸;
- policy loss 长期接近 0,同时 reward 也不变;
- policy loss 异常时 KL 也异常。
可能解释:
- 爆炸:学习率过大,或者 advantage scale 有问题;
- 接近 0:可能是优势正负抵消。特别是 advantage 已标准化、首次更新时 ratio 约为 1,均值接近 0 很常见;只有同时 KL、参数变化和任务效果都停滞,才进一步怀疑更新没有发生。
Value loss
Value loss 表示 critic / value function 预测回报的误差。
比较健康的状态是:
- 初期较大;
- 后期逐渐稳定;
- 没有持续爆炸;
- reward 改变时,value 能逐渐跟上。
危险信号:
- value loss 持续爆炸;
- value estimate 极端大或极端小;
- reward 变好,但 value 一直乱跳;
- explained variance 长期接近 0 或为负。
常见原因:
- reward scale 太大;
- bootstrap / done mask 写错;
- value learning rate 太高;
- value loss coefficient 不合适;
- reward normalization 缺失。
比较 value loss 前先对齐目标尺度:如果 return 和预测一起放大 倍,普通 MSE 会放大 倍。跨 reward scale、跨任务直接比 loss 高低通常没有意义;clipped value loss 与普通 MSE 的数值也不能混比。
5. Noise std 与 Entropy:探索到底在怎样变化
noise_std 应当和 reward、KL 一起看。它直接描述连续动作策略的采样尺度,但不能单凭它判断策略好坏,更不能把它当作模型预测错误的置信度。
5.1 noise_std 到底是什么
对角高斯策略通常写成:
采样某个动作维时:
- :当前状态下策略给出的动作中心。
- :围绕这个中心采样的标准差,也就是这里讨论的 action noise std。
- :每次采样的标准正态随机数,不是日志里的
noise_std。
例如同一状态下 、,一维高斯约 68% 的采样落在 。这里是裁剪前的单维概率,并不表示一个 12 维动作有 68% 的概率所有维度都落在各自区间里。高斯策略的两种 std 参数化可对照 Spinning Up 的策略说明。
经典 ActorCritic 的 std 是每个动作维一个可学习参数、与状态无关。init_noise_std 只设置初值,训练后不会固定等于初值。runner 的 Policy/mean_noise_std 将这 个值取算术平均:
日志中的一个标量,并不意味着策略只学习一个共享 std。 新实现也可能固定 std、学习 log_std,或者由网络输出状态相关的 。读取日志前,要确认实际使用哪一种;状态相关策略的均值还受采样状态分布影响。新版分布类型可参考 rsl_rl v5.5.0 distribution。
5.2 几个带 std 的量不能混用
| 名称 | 含义 | 诊断时注意 |
|---|---|---|
init_noise_std |
创建策略时的初始采样标准差 | 加载 checkpoint 通常会恢复已训练的参数,修改初值不一定影响续训 |
noise_std / action_std |
策略分布的标准差,具体名称依实现 | 确认是全局参数、状态相关输出,还是实际动作统计 |
log_std |
某些实现优化的 | log_std = -2 对应 ,std 本身应严格为正 |
| rollout action 的经验 std | 不同状态、环境和时刻的动作离散程度 | 同时包含策略均值变化与采样随机性 |
| observation noise | 加在观测上的扰动 | 不等于策略的动作探索噪声 |
| domain randomization | 质量、摩擦、延迟等环境随机化 | 改变任务分布,不直接等于 |
裁剪前,根据全方差公式,对 rollout 访问的状态分布有:
所以确定性步态的动作也可以随时间大幅变化。把整段关节动作的 std() 当作策略探索 std,会把正常摆腿误判成“噪声很大”。
5.3 从 std 到实际关节动作,中间还有缩放和裁剪
对于位置目标控制,可以用下面的接口理解噪声传播:
策略均值 μ(s) + σ × 随机数 |
假设某关节 action_scale = 0.25 rad,且尚未触及任何裁剪边界:
noise_std = 0.8 对应目标角噪声约 0.20 rad(11.5°);降到 0.2 时约为 0.05 rad(2.9°)。这是目标角的采样尺度,不是实际关节角或力矩的标准差;实际运动还受 PD、惯量、接触与限幅影响。经典实现的缩放、PD 与力矩裁剪见 _compute_torques()。
因此不存在跨机器人通用的“std 小于 0.1 就正常”。至少还要知道动作单位、各维 scale、控制频率、动作延迟和裁剪范围。
特别要补记动作裁剪率:原始动作分量中超出执行区间的比例,并区分逐维比例和“一整个动作向量至少一维越界”的比例。若 已贴近边界,即使 std 不大也可能大量裁剪;若 std 持续增大而执行动作早已饱和,参数空间的随机性增加不代表有效探索增加。使用 tanh 时则记录接近边界的饱和比例,阈值要写清楚。
5.4 std 为什么会下降、上升或不动
对于可学习高斯策略,std 通过策略目标和 entropy 项共同更新,不是 PPO 自动执行的一条“从大到小”的退火计划。常见最小化目标的符号为:
提高 entropy_coef 通常更鼓励保持随机性,但 std 还受 advantage、奖励设计、优化器和参数约束影响;entropy_coef = 0 也不意味着 std 会立即变成零。
| 曲线组合 | 可以提出的假设 | 优先验证什么 |
|---|---|---|
| std 缓慢下降,评估效果上升,跌倒减少 | 策略可能正在学会更稳定的动作 | 固定评估集、采样/确定性差距、逐维 std |
| std 很快变小,reward 与跟踪误差停滞 | 探索过早收缩,或奖励偏爱少动 | 任务奖励与动作惩罚贡献、动作尺度、参数梯度 |
| std 持续升高,动作裁剪率与跌倒率一起升高 | 随机扰动过强或优化不稳 | entropy 权重、KL、学习率、裁剪前动作 |
| std 平稳,但机器人仍然抖动 | 噪声可能不是主要来源 | 均值动作的变化率、观测噪声、延迟、PD 与控制频率 |
| mean std 下降,但某条腿异常 | 均值掩盖了维度差异 | 每关节 std 和动作/力矩统计 |
| std 长期一条直线 | 可能是固定配置、约束边界或未更新 | 是否可学习、optimizer 是否包含该参数、梯度、logger 精度 |
| std 出现 NaN、inf 或非正值 | 分布或数值计算已异常 | 最后正常 checkpoint、输入有限性、参数化与优化步 |
先验证假设,再调整参数。例如确认过早收缩后,可以比较较小学习率或较大 entropy 系数的短实验;若本质是动作惩罚压住了任务奖励,只改 entropy 不一定解决。恢复训练时还要确认 std 和 optimizer 状态是否正确加载。
5.5 Entropy 与 noise_std 的定量关系
对未经过 tanh 或裁剪的 维对角高斯,按动作维求和、使用自然对数时:
这说明 entropy 与 std 相关,但不是简单看 mean_noise_std 就能完全还原。entropy 取决于各维 std 的对数和;平均 std 取决于算术平均。比如 [0.2, 0.8] 和 [0.5, 0.5] 的 mean std 都是 0.5,前者的 entropy 却更低。
更重要的是:连续分布的微分熵可以为负,entropy = 0 不等于确定性策略。 一维高斯在 时熵就是 0,仍然有明显随机性。确定性极限 对应微分熵趋向负无穷,不能套用离散动作熵接近 0 的解释。公式也可核对 PyTorch Normal.entropy()。
以 12 个动作维、每维 std 相同为例,按上式计算:
| 每维 std | 联合 entropy(nats) | 应怎样解读 |
|---|---|---|
| 1.0 | 17.03 | 分布较宽,仍需看动作尺度与边界 |
| 0.5 | 8.71 | 随机性减小,但不是“探索消失” |
| 0.2 | -2.29 | 负微分熵完全合法 |
| 0.1 | -10.60 | 分布更窄,是否过窄取决于任务 |
日志还可能记录 entropy_loss = -H,或者 -entropy_coef × H;它们的数值和升降方向不同。跨实验比较时应对齐动作维数、求和/平均方式、正负号和缩放。高斯经 tanh 变换后的熵要计入变换的 Jacobian;直接 clip 后也不再是原来的高斯,不能把上式当作最终执行动作的熵。
5.6 为什么还要记录逐关节 std
12 维 mean std 为 0.3,可能是每维都为 0.3,也可能是若干维已经很小、另一些仍然很大。均值相似的两条曲线,可以对应完全不同的步态。
下面是针对经典 rsl_rl v1.0.2 全局 std 的补充日志示例。放在 runner 的日志位置,用本轮 iteration 作为 step;仅在日志周期执行。动作索引必须对照环境的关节顺序,不能假设第 0 维必然是哪条腿。
# 已有 torch、writer、actor_critic 和 step;不适用于状态相关 std。 |
若使用 log_std,应取实际分布采用的 std,包括实现中的 clamp/变换;状态相关 std 则要在注明的观测批次上逐维聚合并保留分位数。均值动作、采样动作、执行动作分别记录,才能知道变化发生在哪一层。
5.7 确定性评估能隔离什么问题
在同一组命令、初始条件和环境随机化设置下,分别运行:
- 采样评估:,保留策略探索随机性。
- 确定性评估:对这里的未变换高斯取 ,再经过相同的动作处理链。
每个条件都应重复足够多 episode。采样评估差、确定性评估好,支持“动作随机性正在损害当前表现”的假设;两者都差则要继续查均值策略、观测和任务设计。确定性评估仍可保留物理随机化与传感器噪声,关闭动作采样不等于关闭一切噪声。
对普通高斯策略,直接用均值推理即可,不需要把分布 std 硬设为 0;这样做会制造无效的 Normal 参数。SAC 等变换策略应使用实现提供的 deterministic 推理接口。也不要只保留确定性评估:训练策略的随机行为同样需要被检查。
6. PPO 里特别重要的曲线
如果用的是 PPO,除了 reward 和 loss,我会特别看 KL、clip fraction 和 explained variance。
KL divergence
KL 表示新旧策略在同一批状态上的分布差异。它同时受均值与 std 变化影响,日志需要注明 KL 方向、解析计算还是采样估计,以及在各 epoch/mini-batch 上怎样聚合。
常见判断:
- KL 突然很大:更新太激进,容易崩;
- KL 长期接近 0:更新太保守,学得很慢;
- KL 很大但 reward 不升:策略在乱变。
调参方向:
- KL 太大:降低 learning rate,减小 clip range,减少 epoch,增大 batch size;
- KL 太小:适当提高 learning rate,增加 epoch,或检查 advantage 是否正常。
这些调整要建立在评估停滞或退化的证据上;已经收敛时 KL 小并不异常,也没有适用于所有动作维数的 KL 阈值。PPO clip 不是 KL 的硬上限,减小 clip range 也不保证 KL 必然变小。
在经典 rsl_rl PPO 中,开启 adaptive schedule 后,KL 超过 2 × desired_kl 会下调学习率;低于 desired_kl / 2 且为正时会上调。这是学习率调度,不是自动终止本轮更新。 因此 learning_rate 连续下降是值得追踪的信号,但不能替代 KL 曲线。补记时可保留本轮 KL 均值、最大值、各 epoch 均值和最终学习率,避免均值掩盖单次过冲。
Clip fraction
常见实现(如 SB3)将 clip fraction 定义为概率比超出区间的样本比例:
这是概率比越界比例,不是动作被裁剪的比例,也不严格等于 surrogate 中裁剪分支真正生效的比例;后者还与 advantage 正负有关。定义可核对 SB3 PPO 源码。
粗略理解:
- 长期接近 0:更新可能太小;
- 长期很高:新旧策略概率比在大量样本上越界,需要结合 KL 和评估结果判断。
如果 clip fraction 很高,同时 reward 还不稳定,我会优先降低 learning rate 或减少 update epochs。
Explained variance
Explained variance 用来看 value function 对 return target 变化的解释能力。用同一批数据中的目标 和预测 计算:
一般来说:
- 越接近 1 越好;
- 接近 0,说明残差方差接近目标方差;
- 为负,说明残差方差比目标方差还大。
它不检查固定偏差:即使预测整体多了 10,残差方差也可能为 0,EV 仍为 1。所以 EV 高还要配合 MSE 和平均残差看;当目标方差接近 0 时,EV 会不稳定或没有定义,不能只看负值就判定训练崩溃。记录 return mean/std、value mean/std 与二者差值,再定位 reward scale、bootstrap 或拟合问题。
Advantage 与梯度:区分“正常归一化”和“没有信号”
- 同时记录标准化前的 advantage mean/std 与异常值比例。标准化后均值约 0、std 约 1 本来就是预期结果,不能证明 critic 正常,也不能证明没有学习信号。
grad norm应注明在梯度裁剪前还是裁剪后测量。长期显示恰好等于max_grad_norm,可能只是记录了裁剪后数值;要结合裁剪前 norm 和触发裁剪的更新比例。- 若 std 不动,单独检查 std 参数梯度以及 optimizer 参数组;若所有参数都不动,再查学习率、反向传播和有效 batch。
- 先检查 NaN/inf、observation 归一化统计漂移、过大的 return,再用学习率或 gradient clipping 处理;裁剪不能修复输入或目标的定义错误。
7. Off-policy 算法看什么
如果是 DQN、DDPG、TD3、SAC 这类 off-policy 算法,还要关注 replay buffer 和 Q function。
这里的“探索”也要按算法区分:DDPG/TD3 常在确定性 actor 外加动作噪声;TD3 的 target policy smoothing noise 用于构建 critic 目标,与采集数据的探索噪声分开。SAC 通常学习经 tanh 变换的随机策略,需结合 log-prob、temperature 和饱和率。DQN 常用 epsilon-greedy,应看 epsilon 及动作访问情况。不能把这些量一律当成 PPO 的可学习 noise_std。 可对照 DDPG、TD3 与 SAC 的算法说明。
Q loss / critic loss
危险信号:
- critic loss 爆炸;
- Q value 越来越离谱;
- reward 没升,但 Q value 很高;
- target Q 和 current Q 差距越来越大。
可能原因:
- Q overestimation;
- target network 更新太快;
- reward scale 有问题;
- replay buffer 数据质量差;
- bootstrapping 逻辑有 bug。
SAC 的 alpha / temperature
SAC 里还要看 alpha,也就是 entropy temperature。
- alpha 太高:策略可能过随机;
- alpha 太低:探索可能不足;
- alpha 剧烈波动:reward scale 或 entropy target 可能不合适。
Replay buffer
可以检查:
- buffer size 是否正常增长;
- reward 分布是否合理;
- done 比例是否异常;
- observation/action 是否有 NaN;
- sampling 是否覆盖足够多样的数据。
再记录 update-to-data ratio(每新增多少 transition 做多少次梯度更新)、样本新旧程度和 warm-up 阶段。吞吐量或并行环境数量变化时,若更新与采样比例一起改变,效果变化不能仅归因于 buffer 大小。
8. Perf / FPS / SPS 怎么看
训练曲线不只是算法指标,也要看系统性能。
常见指标包括:
- FPS / SPS:每秒环境步数;
- samples per second;
- environment time;
- learner update time;
- GPU utilization;
- CPU utilization。
FPS 越跑越低
可能原因:
- 内存泄漏;
- 日志或视频保存太频繁;
- replay buffer 变大后采样变慢;
- environment reset 泄漏资源;
- 多进程 worker 卡住。
GPU 很闲,CPU 很满
说明瓶颈可能在环境模拟或数据预处理。
优化方向:
- 增加 vectorized env 数量;
- 减少 Python 端开销;
- 并行采样;
- 简化 observation preprocessing。
GPU 很满,但 FPS 低
说明模型或 learner update 太重。
优化方向:
- 减小模型;
- 调整 batch size;
- 减少 update epochs;
- 使用混合精度;
- profile learner。
9. 常见曲线组合诊断
下面这些组合用来提出排查假设,不是仅凭曲线就能确定原因。先对齐指标口径与异常发生时间,再做一次只改变一个主要因素的验证。
reward 不升 + entropy 快速下降
判断:可能探索过早收缩;连续策略还需确认逐维 std、动作尺度及 entropy 的记录符号。
优先尝试:
- 提高 entropy coefficient;
- 降低 learning rate;
- 增加 reward shaping;
- 增加随机初始化;
- 检查 action scale。
reward 上升后突然崩 + KL 暴涨
判断:优先怀疑 policy update 过激,同时核对课程难度、reward 和观测归一化是否在该时刻改变。
优先尝试:
- 降低 learning rate;
- 减小 PPO clip range;
- 加 target KL early stopping;
- 减少 update epochs;
- 增大 batch size。
reward 不升 + value loss 爆炸
判断:critic 可能学坏了,并且影响 actor。
优先尝试:
- 检查 reward scale;
- 核对并按实现需要调整 reward/value normalization,避免重复归一化;
- 降低 critic learning rate;
- 检查 done mask;
- 使用 gradient clipping。
train reward 高 + eval reward 低
判断:泛化或评估设置有问题。
优先尝试:
- 检查 train/eval wrapper;
- 同条件比较采样评估与确定性评估;
- 多 seed、多初始状态评估;
- 录视频看行为;
- 避免只看训练环境奖励。
episode length 变短 + reward 变低
判断:agent 更快失败。
优先尝试:
- 看 termination reason;
- 检查是否学到提前结束;
- 检查失败惩罚和存活收益的相对量级,确认是否奖励了提前结束;
- 检查 reset 条件是否太敏感。
episode length 变长 + reward 不变
判断:agent 可能只是在拖延,没有完成目标。
优先尝试:
- 单独记录 success rate;
- 记录 distance-to-goal;
- 单独记录 completion bonus;
- 看视频确认行为。
多个 seed 方差巨大
判断:算法不稳定,单次成功不可靠。
优先尝试:
- 至少跑 3 到 5 个 seed;
- 降低 learning rate;
- 增大 batch size;
- 调整 reward scale;
- 检查初始化和环境随机性。
三个带数值的排查例子
以下数字是教学用假设数据,不是实测结果,也不是通用阈值。 各案例中的阶段使用相同日志口径。
案例 A:std 降下来了,机器人却只会少动
| 观测项 | 前一阶段 | 后一阶段 |
|---|---|---|
| mean noise std | 0.80 | 0.06 |
| 固定评估集速度 MAE | 0.45 m/s | 0.44 m/s |
| episode length | 850 步 | 990 步(上限 1000) |
| 每步平均任务奖励贡献 | +0.40 | +0.41 |
| 每步平均动作惩罚贡献 | -0.30 | -0.04 |
总 reward 可能上升,但证据更支持“减少动作、活得更久”,尚不支持“更会跟踪速度”。先检查非零命令下是否站立、每个动作维是否收缩,以及动作惩罚的权重。然后固定环境与初始 checkpoint,对一个主要因素做小规模对照。不要看到 std 小就直接宣布收敛,也不要立即同时修改 entropy、reward 和 learning rate。
案例 B:mean std 没变,KL 却突然变大
假设两次更新前后 mean std 都约 0.30,KL 从 0.006 跳到 0.08,概率比越界比例从 0.12 升到 0.65,固定评估回报下降。std 不变无法排除均值策略移动过大;甚至各维 std 变化也可能相互抵消。
先补看同一批 observation 上的均值动作变化、逐维 std、各 epoch KL、更新前 advantage 和裁剪前 grad norm。若排除了输入与奖励跳变,再从减少学习率或 epoch 的单因素实验开始;回退到崩溃前 checkpoint 保持对照起点一致。
案例 C:课程升级后 reward 下降,但策略没有退步
假设 terrain level 从 2 升到 5,训练回报从 25 降到 21,而固定地形评估成功率从 80% 升到 88%,跌倒率下降。更合理的解释是训练分布变难,而不是优化器突然失效。
保留课程等级、命令范围、推扰强度的时间线;将评估按速度区间、地形和扰动分桶。若困难桶仍差,就针对该桶分析,不能因为一个混合均值下降便重置 noise std 或把学习率整体调小。
10. 建议记录的最小指标集
通用指标
- train episode reward mean / median / std;
- eval episode reward mean / median / std;
- success rate;
- episode length;
- total environment steps;
- wall-clock time;
- FPS / SPS;
- learning rate;
- gradient norm;
- action mean / std / min / max;
- observation mean / std / min / max;
- reward mean / std / min / max;
- termination reason。
PPO / A2C 类
- policy loss;
- value loss;
- noise std 的逐维值、mean/min/max;状态相关策略补分位数与采样状态说明;
- entropy,明确符号、动作维求和还是平均;
- KL divergence;
- clip fraction;
- explained variance;
- advantage mean / std,区分标准化前后;
- return 与 value prediction 的 mean / std;
- 当前 learning rate、entropy coefficient、实际 update epochs;
- 裁剪前 grad norm 与触发梯度裁剪的更新比例。
四足机器人再加一组物理指标
- 线速度/角速度 tracking error,按命令速度和地形分桶;
- 每项原始 reward term 与加权贡献,标明时间归一化口径;
- 均值动作、原始采样动作、执行动作的范围与变化率;
- 逐关节动作裁剪率、力矩饱和率、关节限位触发情况;
- 非法接触、跌倒、timeout 等结束原因的比例及样本数;
- 足端滑移、机身姿态、步态视频或轨迹;
- terrain level、command range、随机化强度与配置改变时间。
日志分成五组会更容易读:效果、探索与执行动作、策略更新、critic、环境与性能。预算有限时先保留每组关键标量,对 per-joint 分布、视频和 histogram 降低记录频率;不要为了补日志显著拖慢训练。
SAC / TD3 / DDPG / DQN 类
- actor loss(适用的 actor-critic 算法);
- critic / Q loss;
- Q value mean / max / min;
- target Q;
- replay buffer size;
- alpha / temperature(SAC),探索噪声(TD3/DDPG)或 epsilon(DQN);
- TD error。
评估协议也是指标的一部分
保存曲线时一并保存配置、代码版本、seed、checkpoint、动作模式、episode 数、命令分布、随机化范围和归一化状态。归一化统计按评估协议固定,不能在不知情的情况下被评估数据继续更新。
横轴同时保留环境 transition 数和真实耗时:前者衡量样本效率,后者衡量计算代价。同一 iteration 下更大的 已经消耗更多样本,不能直接说“学得更快”。
多 seed 时区分两类波动:同一策略跨评估 episode 的波动,以及独立训练 seed 之间的波动。展示每个训练 seed 的曲线与跨 seed 汇总,说明阴影是标准差还是置信区间;同一次训练的很多 episode 不能冒充很多独立训练实验。3~5 个 seed 可作初步比较,高波动任务可能需要更多。
确定 checkpoint 的选择规则,例如固定验证集上的均值、成功率或约束下的跟踪误差;最终测试使用另外的评估条件或随机种子。不要在测试集上挑出最高点后,再把它当作无偏的最终性能。
11. 我以后可以怎么写实验结论
看完曲线后,按“观察 → 假设 → 验证 → 下一步”的方式写,避免把可能性直接写成结论。
实验条件:代码版本、配置、训练 seed、环境步数、checkpoint。 |
或者:
noise std 很快下降,速度误差停滞,动作惩罚贡献明显减小。 |
总结
看强化学习训练曲线时,不要只盯着 reward 的最高点,也不要用监督学习的直觉去理解 loss。
我觉得更靠谱的判断顺序是:
任务效果是否提升 |
RL 曲线的核心不是“漂亮”,而是:策略真的变强,并且训练过程可复现、可解释、可继续优化。
继续对照代码与任务设计
- PPO、rsl_rl 与 legged_gym 训练闭环:定位 rollout、GAE、Gaussian、loss 和 mini-batch 更新。
- 四足机器人 Action 笔记:核对动作空间、缩放与控制接口。
- 经典 rsl_rl runner:核对实际日志字段与聚合时机。
- SB3 logger 说明:阅读 SB3 曲线时对照字段;含义以所用版本源码为准。