快捷方式

调试强化学习的注意事项

通用

您是否在一些具有已知最优回报的简单玩具问题(例如,网格世界、爬山问题)上验证了您的算法实现?

  • 原因:这将揭示您实现中的任何极端错误。

您是否可视化了您的代理?

  • 原因:这将揭示学习曲线无法告诉您的内容(例如,视频游戏中的错误或漏洞)。

请非常谨慎地对待任何数据增强。

  • 原因:数据增强不能以与计算机视觉相同的方式应用于强化学习,因为代理需要根据观察来采取行动。例如,翻转图像可能相应地“翻转”适当的动作。

策略 (Policy)

您的策略熵收敛过快、过慢或变化剧烈吗?

  • 原因:这可能取决于算法,但策略熵大致与动作的期望值成反比。

  • 建议:调整熵奖励的系数(例如 PPO 中的 beta)可以帮助熵收敛过快/过慢。或者,如果收敛过快/过慢,减小/增大奖励的幅度也可能有所帮助。熵曲线的阶跃变化通常是问题表述(例如,观察或动作空间)、学习率、梯度范数或实现中的错误等问题导致的。

奖励(除了“向上”之外)

代理是否偏向于奖励函数的单个分量(例如,速度与 L2 动作幅度)?

  • 原因:奖励函数的某个分量可能“更容易”优化,因此代理会发现该行为是局部最优解。

  • 建议:除了调整奖励分量的系数外,还可以使用分量乘积代替求和。跟踪每个奖励分量的统计数据也可能提供洞察。或者,如果某些分量被视为“辅助”的,随着时间的推移衰减其权重可能会有所帮助。

任务时限是否非常长?

  • 原因:信用分配(即,将未来的/价值奖励归因于过去的状态/动作)在动作和相应奖励之间的时间越长,难度越大。在稀疏奖励环境中,这可能导致训练效率低下,需要与环境进行多次交互。

  • 建议:为有助于最终目标的行为添加中间奖励可以极大地提高训练速度(例如,在足球环境中,为踢球添加中间奖励可以增加代理发现得分有奖励的可能性)。但这可能会产生不期望的最优解,因为利用中间奖励可能会无意中比真实奖励更有价值,或导致不期望的特有行为。可以使用步长或基于奖励的课程将此中间奖励的值衰减为零。或者,如果存在许多子任务,则可以使用分层或选项式框架,其中为不同的子任务(例如,踢球、传球、跑步)学习单独的策略,然后一个更高级的代理从这些低级策略中选择作为其动作空间。请注意,这个问题也可能属于“探索”部分,需要明确的探索机制,例如内在好奇心模块

您的奖励是否已进行归一化/标准化?

  • 原因:幅度较大的奖励将支配较小的奖励。此外,如果每步奖励变得非常大,价值函数的学习目标将变得巨大,因为它们是每步奖励的总和。

  • 建议:一般来说,将奖励保持在 [-1,1] 范围内是良好做法。或者,您可以使用运行均值/标准差实例归一化(例如,TorchRL 的实现或 Gym 的实现)。

探索

价值损失在训练早期是否在上升?

  • 原因:通常,在初始化时,价值估计约为 0.0。在训练早期,代理可能会遇到新的、未见过的外部奖励,因为它在探索,因此价值估计将是错误的,并且损失会增加。

  • 建议:通过内在奖励或熵奖励来增加探索。或者,通过添加中间奖励来使奖励函数更密集。

在训练早期,动作(大致)是均匀/正态随机的吗?

  • 原因:如果没有使用先验知识,新初始化的网络应该接近随机。这对于代理实现适当的探索很重要。

  • 建议:检查策略网络是否已适当初始化,并且策略熵没有非常快速地下降。

在单例任务中,内在奖励是否随着学习的进行而衰减?

  • 原因:内在奖励旨在鼓励探索,通常通过某种新颖性度量。随着代理的探索,额外探索(或重新访问先前探索过的状态-动作)的价值会随着新颖性的降低而减小。理想情况下,随着内在奖励开始下降,外部奖励应该开始增加。

  • 建议:内在奖励应进行归一化。如果内在奖励已变为 0,但代理尚未学到任何东西,可以尝试减慢内在模块的动态(即,降低随机网络蒸馏的学习率或添加噪声)。

在情景任务中,情景内在奖励是否保持不变或随着学习的进行而增加?

  • 原因:内在奖励旨在鼓励探索,通常通过某种新颖性度量。在情景任务中,由于新颖性可能不会降低,并且探索性行为实际上可能会改善,因此内在奖励应保持不变或增加。

  • 建议:外部奖励本身也应该增加。如果不是这种情况,可能意味着这两个目标不一致,并且两者之间存在权衡。如果这种权衡是不可避免的,那么外部奖励就需要优先于情景奖励。实现这一目标的一些方法是使用情景奖励的衰减计划,拥有单独的探索(仅情景奖励)和利用(仅外部奖励)策略,并使用探索策略为利用策略生成更多样的起始状态,或者使用行为克隆来引导训练。此外,内在奖励应进行归一化。

环境动力学

您能否训练一个低熵的前向动力学和/或奖励模型(也适用于离线 RL)?

  • 原因:下一个状态和奖励用于生成强化学习算法中价值学习的目标。如果这些目标非常嘈杂,那么目标就会嘈杂,学习可能会缓慢或不稳定。环境可能是固有随机的(例如,敌人的随机生成),观察空间的表述可能缺少一个变量(例如,POMDP),或者对先前状态的依赖性非常松散甚至不存在。

  • 建议:根据噪声的来源,可能需要重新审视观察的表述以确保它包含所有必要的信息,使用可以处理先前状态序列而非仅最后一个状态的网络架构(例如 LSTM、Transformer),甚至使用分布强化学习算法来显式地建模价值的分布(而非仅期望值)。

观察空间

您的观察是否已进行归一化/标准化?

  • 原因:具有相同相对尺度的输入和输出目标往往更稳定,因为网络权重不需要变得非常大/小来补偿。出于同样的原因,学习往往更快,因为网络权重是以适当的尺度初始化的,并且不需要通过梯度下降来达到该尺度。此外,如果观察特征之间存在极大的尺度差异(例如,[-1,+1] vs. [-1000, 1000]),则在权重能够补偿之前,较大的尺度可能会支配较小的尺度。

  • 建议:如果您知道这些值的最小/最大范围,您可以手动将其归一化到 [0,1] 的范围。或者,您可以使用运行均值/标准差实例归一化(例如,TorchRL 的实现或 Gym 的实现)。均值和标准差在训练初期会发生剧烈变化,但随后会随着更多数据缓慢收敛。如果稳定性有问题,可以收集一个大的缓冲区,然后再进行任何更新以计算起始均值和标准差。

动作空间

在同一情节中,动作的影响是否会发生剧烈变化?

  • 原因:如果某个动作在训练早期导致失败,代理可能会学会从不执行它,并且这可能会完全阻止它解决任务(例如,“提交工作”动作)。

  • 建议:问题可能应该以分层方式表述(即,一个学习“提交工作”的代理)。此外,在这种情况下,充分的探索变得非常重要。

动作空间是否维度过高?

  • 原因:如果动作空间非常大(例如,推荐系统),那么充分探索整个动作空间可能是不可行的。

  • 建议:为缓解此问题,可以手动修剪动作空间,或开发依赖于状态的启发式方法来屏蔽/过滤代理可用的动作(例如,在某些 Atari 游戏中屏蔽“射击”动作,或在国际象棋中屏蔽非法走法),或组合动作/动作序列(例如,操纵任务中的抓取和释放动作可以是同一个动作,也可以是原始动作序列)。如果这不可能,还存在其他方法,例如top-p 采样,即从累积概率为 p 的最顶部动作中进行采样。

您的动作是否已进行归一化/标准化?

  • 原因:具有相同相对尺度的输入和输出目标往往更稳定,因为网络权重不需要变得非常大/小来补偿。出于同样的原因,学习往往更快,因为网络权重是以适当的尺度初始化的,并且不需要通过梯度下降来达到该尺度。在某些算法中,动作可以输入到 Q 函数中,而在其他算法中,梯度可以直接通过动作输出流向策略(例如,软 Actor-Critic 中的重参数化),因此合理的动作尺度很重要。

  • 建议:通常会裁剪策略的动作输出到合理的范围。请注意,此裁剪后的动作(与原始动作相反)不应用于训练,因为裁剪操作不属于计算图,梯度将是错误的。这应该被视为环境的一部分,因此策略会学到有界区域内的动作会带来更高的回报。您还可以使用类似 tanh 的压缩函数。这可以是计算图的一部分,并且为了高效地做到这一点,应该更正 log 概率,就像这里所做的那样。请记住,如果动作在环境端进行了归一化,则将其重新映射到原始动作空间。

文档

访问全面的 PyTorch 开发者文档

查看文档

教程

为初学者和高级开发者提供深入的教程

查看教程

资源

查找开发资源并让您的问题得到解答

查看资源