rllib 中的复杂动作掩码

问题描述

rllib 示例中提供了参数/可变长度动作模型。该示例假设输出是单个 Categorical action dist 的 logits。如何使用更复杂的输出完成这项工作?

例如,一个盒子里有 200 个不同的球。每步 2 个球被捡起并放回原处。 动作空间可以定义为 Multidiscrete([200,200]) 或 Tuple((spaces.discrete(200),spaces.discrete(200))).

有 3 个限制会使某些操作无效。

  1. 每次两个球都不一样。所以像 (1,1) 或 (2,2) 这样的操作是无效的。
  2. 颜色相同的球不允许一起捡。比如2号球和3号球都是黄色的,在某种状态下是不能一起捡的。所以 action(1,2) 在那个状态下是无效的。
  3. 某些球在特定状态下是不允许捡球的。例如,当2号球标记为不允许采摘时,所有与2号球相关的动作(1,n)或(n,1)均无效。

如何通过 rllib 中的动作屏蔽来强制执行这 3 个约束。

假设我们的 obs 空间有 2 个部分。 第一个约束是隐含的。可以在没有观察空间的情况下确定无效动作。 对于第二个约束,A real_obs一个数字标记每个球,以指示其颜色。同一号码的球不允许一起捡。 对于第三个约束条件,action_mask 指示是否允许捡球。

具体来说,如何在自定义模型中实现动作/观察空间和forward功能

如果我对 obs 空间的假设不可行。您可以定义您的 obs 空间和相应的自定义模型

ParametricActionsModel example in rllib

解决方法

我遇到了同样的问题。最大的问题是你的两个动作之间的依赖性(例如不能两次拿同一个球)。 所以你可以做的一件事就是将它们相乘,这样你就有了一个 200x200=40000 的大动作空间。然后您就可以在 env 中创建完整的掩码并将其传递给前向函数进行掩码。 否则,您需要使用相关动作采样和分布。

对我来说,乘法不是一种选择,因为它会很大。 所以我采用以下方式:

  1. Env 为 Action 1 创建了一个掩码,并为依赖的 Action 2 创建了一个 XXX 掩码。
  2. 在模型中,您将使用操作 1 掩码对操作 1(使用 tf.random.categorical)进行采样
  3. 根据操作 1,您为操作 2 (tf.where) 和示例操作 2 选择掩码。
  4. 模型的输出应该是 logits 和采样的动作。
  5. 您需要实现自己的 MultiCategorical 操作分布以使用您已经采样的操作。