StableBaselines3二次调用model.learn()为何性能骤降失稳?
PPO二次调用
model.learn()出现性能骤降的原因 该现象由Stable Baselines3中PPO算法的默认运行逻辑导致,不属于代码bug,核心诱因共三点:
- 归一化统计量重置:如果训练时使用
VecNormalize包装环境实现观测/奖励归一化,二次调用learn()时,默认不会继承上一轮训练累计的观测、奖励滑动均值与标准差统计值,输入分布突然偏移会直接让已收敛的策略输出错乱,引发奖励跳水。 - 学习率调度器重启动:PPO默认使用线性衰减学习率,调度器的步长计数与单次
learn()调用绑定。第一次训练结束时学习率已经衰减到预设最小值,第二次调用learn()时调度器会直接回到初始最大学习率,过大的更新步长会破坏已收敛的模型权重,造成训练初期剧烈震荡。 - 同策略缓冲区清空:PPO是同策略算法,每次调用
learn()都会清空之前存储的轨迹滚动缓冲区,二次训练刚启动时缓冲区仅存极少量新收集的样本,策略更新的梯度估计方差极高,自然会出现不稳定情况,待收集到足量同策略样本后波动才会逐步收敛。
修复方案
- 最稳妥的方案是避免拆分多次调用
model.learn(),直接将总训练步数设置为目标值一次性跑完,完全规避状态重置问题。 - 如果必须拆分调用实现断点续训,第一次训练结束后要单独保存
VecNormalize的统计参数,第二次训练启动时优先加载对应统计值;同时替换默认的线性衰减学习率调度器,自定义跨次调用不重置的调度逻辑。 - 续训初期可设置1000~5000步的纯样本收集阶段,暂时关闭参数更新,等滚动缓冲区攒够足量同策略轨迹后再开启梯度更新,可大幅降低初始阶段的性能波动幅度。
内容的提问来源于stack exchange,提问作者Vladimir Belik
相关产品推荐
相关产品推荐

