如何在近端策略优化中实现可变动作空间?

人工智能 强化学习 近端策略优化 离散动作空间 行动空间 张量力
2021-10-31 20:53:41

我正在使用Tensorforce 库(构建在 TensorFlow 之上)编写近端策略优化 (PPO) 代理。

第一个环境非常简单。现在,我正潜入一个更复杂的环境,其中所有操作在每一步都不可用。

假设有 5 个动作,它们的可用性取决于内部状态(由先前的动作和/或新的状态/观察空间定义):

  • 2 个动作(0 和 1)始终可用
  • 2 个动作(2 和 3)仅在内部状态为 0 时可用
  • 1 动作 (4) 仅在内部状态为 1 时可用

因此,当内部状态为 0 时,有 4 个动作可用,而当内部状态为 1 时,有 3 个动作可用。

我正在考虑实现这一点的几种可能性:

  1. 根据内部状态改变每一步的动作空间。我认为这是胡说八道。

  2. 什么都不做:让模型明白选择一个不可用的动作没有影响。

  3. 几乎什么都不做:当模型选择不可用的操作时,对奖励产生轻微的负面影响。

  4. 帮助模型:通过将整数合并到状态/观察空间中,告知模型内部状态值是什么 + 要点 2 或 3

还有其他方法可以实现吗?根据您的经验,哪一个是最好的?

3个回答

最直接的解决方案是简单地使每个行为“合法”,但实施从潜在非法行为到不同合法行为的一致、确定性映射。每当您使用的 PPO 实现选择了非法操作时,您只需将其替换为它所映射到的合法操作即可。然后,您的 PPO 算法仍然可以自我更新,就好像选择了非法操作一样(非法操作简单地变成......代替合法操作的“昵称”)。

例如,在您描述的情况下:

  • 2 个动作(0 和 1)始终可用
  • 2 个动作(2 和 3)仅在 internal_state == 0 时可用
  • 1 个动作 (4) 仅在 internal_state == 1 时可用

在这种情况下internal_state == 0,如果4选择了动作(非法动作),您始终可以将其换成其他动作之一,并改为使用该动作。选择哪一个并不重要(理论上),只要您对此保持一致即可。该算法不必知道它选择了非法行为,只要它在未来再次在相似状态下选择相同的非法行为,它将始终映射到相同的合法行为,因此您只需根据该行为进行强化。


上面描述的解决方案非常简单,可能是最简单的实现,但当然它......“闻起来”有点“hacky”。更清洁的解决方案将涉及网络中的一个步骤,该步骤将非法行为的概率输出设置为0, 并将其余部分重新归一化以求和1再次。这需要更加小心,以确保您的学习更新仍然正确执行,并且在诸如 Tensorforce 之类的现有框架之上实现可能要复杂得多(如果还没有以某种方式支持开箱即用)。


对于第一个“解决方案”,我在上面写道,“理论上”你如何选择映射并不重要。不过,我绝对希望您在这里的选择会对实践中的学习速度产生影响。这是因为,在学习过程的初始阶段,您可能会选择接近随机的动作。如果某些动作在输出中“多次出现”,则它们将更有可能被初始 close-tor-andom 动作选择选中。因此,这将对您的初始行为产生影响,这会影响您收集的经验,而这反过来也会影响您学到的东西。

internal_state如果您可以包含变量的输入特征,我当然希望它对性能有益。

如果可以识别出某些法律行为在某种程度上与某些非法行为“语义上接近”,那么如果您选择将“映射”中的那些“类似”行为从非法行为与合法行为联系起来,这也可能对性能有益。该解决方案。例如,如果您的“向前跳跃”动作在上限非常低的州(因为您会撞到头)变得非法,则最好将该动作映射到“向前移动”动作(即仍然有点相似,它们都在前进),而不是将其映射到“向后移动”动作。这种“相似”动作的想法将仅适用于某些领域,但在某些领域中,动作之间可能没有这种相似性。

根据 internal_state 更改每一步的操作空间。我认为这是胡说八道。

是的,这似乎有点矫枉过正,使问题变得不必要地复杂,您还可以做其他事情。

什么都不做:让模型明白选择一个不可用的动作没有影响。

虽然这不会对您的模型造成负面影响,但无论如何,这样做的负面影响是模型可能需要很长时间才能理解某些操作对某些状态值无关紧要。

几乎什么都不做:当模型选择不可用的动作时,对奖励产生轻微的负面影响。

与前一点的响应相同,只是这可能会对您的模型产生负面影响(但不确定这是否重要)。假设你对每一个非法行为给予 -100 的奖励。只看负面奖励,我们有:

  • -100 当 initial_state == 0
  • -200 当初始状态 == 1 通过这样做,你可能会隐含地支持状态 == 0 的情况。另外,我看不出 -100 奖励的意义,因为一旦他们进入状态 0,他们将不得不选择一个非法行为的价值(这不像他们可以忽略行为的价值并逃脱 -100 奖励)

帮助模型:通过将整数合并到状态/观察空间中,告知模型什么是 internal_state 值 + 要点 2 或 3

对我来说,这似乎是最理想的做法。您可以将(您的 ActorCritic 代理的)最终输出层分支为 2 而不是 1。

像:输入层,fc1(来自输入层),输出1(来自fc1),输出2(来自fc1)基于initial_state,您可以从输出1或输出2获得输出。

通常,代理可以执行的一组动作不会随着时间而改变,但有些动作在不同的状态下可能会变得不可能(例如,在井字游戏的任何位置,并非每一步都是可能的)。

以代码https://github.com/haje01/gym-tictactoe/blob/master/examples/base_agent.py为例

ava_actions = env.available_actions()
action = agent.act(state, ava_actions)
state, reward, done, info = env.step(action)