处理时间限制

在使用 Gymnasium 环境与强化学习代码时,常见问题之一是时间限制的错误处理。从 env.step 收到的 done 信号(在 OpenAI Gym < 0.26 的先前版本中)表示一个回合是否已结束。但是,此信号没有区分回合结束是由于 termination 还是 truncation

终止

终止是指在到达环境定义中定义的终止状态后回合结束。例如,任务成功、任务失败、机器人跌倒等。值得注意的是,这还包括由于环境固有的时间限制而导致的有限范围环境中的回合结束。请注意,为了保持马尔可夫特性,在有限范围环境中,代理观察中必须包含剩余时间的表示。(参考)

截断

截断是指在外部定义的条件(超出马尔可夫决策过程范围)后回合结束。这可能是时间限制、机器人超出边界等。

无限范围环境是需要此功能的明显示例。我们不能永远等待回合完成,因此我们设置了一个实际的时间限制,在此限制之后我们强制停止回合。在这种情况下,最后一个状态不是终止状态,因为它根据定义 RL 问题的马尔可夫决策过程,具有转移到另一个状态的非零概率。这与有限范围环境中的时间限制也不同,因为在这种情况下,代理不知道此时间限制。

学习代码中的重要性

自举(使用一个或多个变量的估计值来更新同一变量的估计值)是强化学习的关键方面。价值函数会告诉你,如果你遵循某个策略,从特定状态开始你会获得多少折现奖励。当一个回合在任何给定点停止时,通过查看最终状态的价值,代理能够估计如果回合继续,可以获得多少折现奖励。这是处理截断的一个例子。

更正式地说,RL 中自举的一个常见示例是更新 Q-value 函数的估计值,

\[Q_{target}(o_t, a_t) = r_t + \gamma . \max_a(Q(o_{t+1}, a_{t+1}))\]

在经典 RL 中,新的 Q 估计值是先前 Q 估计值和 Q_target 的加权平均值,而在深度 Q 学习中,最小化 Q_target 与先前 Q 估计值之间的误差。

但是,在终止状态,不会进行自举,

\[Q_{target}(o_t, a_t) = r_t\]

这就是终止和截断之间的区别变得很重要的原因。当一个回合由于终止而结束时,我们不会进行自举,当它由于截断而结束时,我们进行自举。

在使用 gymnasium 环境时,done 信号(< v0.26 的默认值)经常用于确定是否进行自举。但是,这是不正确的,因为它没有区分终止和截断。

下面展示了一个简单价值函数示例。这是一个说明性示例,不属于任何特定算法。

# INCORRECT
vf_target = rew + gamma * (1 - done) * vf_next_state

在回合由于截断而结束的情况下,这是不正确的,因为需要进行自举,但却没有。

解决方案

从 v0.26 开始,Gymnasium 的 env.step API 明确返回终止和截断信息。在以前的版本中,截断信息通过信息键 TimeLimit.truncated 提供。现在,处理终止和截断的正确方法是,

# terminated = done and 'TimeLimit.truncated' not in info
# This was needed in previous versions.

vf_target = rew + gamma * (1 - terminated) * vf_next_state