【问题标题】:Deep Q-learning modification深度 Q 学习修改
【发布时间】:2018-10-04 22:25:34
【问题描述】:

@编辑:

我正在尝试创建一个代理来玩俄罗斯方块游戏,使用将棋盘状态 + 当前棋子作为输入的卷积网络。根据我的阅读,Deep Q-learning 在这方面不是很擅长,我刚刚证实了这一点。

@end 编辑

假设一个代理正在学习一个策略来玩一个游戏,其中每个游戏步骤都可以表示为

s, a, r, s', 完成

代表

状态、动作、奖励、下一个状态、游戏结束

Deep Q-learning算法中,代理处于s状态并采取一些动作a(跟随一个epsilon -greedy 策略),观察到奖励 r 并进入下一个状态 s'

代理的行为如下:

# returns an action index
get_action(state, epsilon)
   if random() < epsilon
       return random_action_index
   else
      return argmax(nnet.predict(state))

通过贪婪地观察状态s'中的最大Q值来更新参数,所以我们有

# action taken was 'a' in state 's' leading to 's_'
prediction = nnet.predict(s)
if done
   target = reward
else
   target = reward + gamma * max(nnet.predict(s_))

prediction[a] = target

[prediction, target] 被馈送到一些 nnet 以进行权重更新。所以这个 nnet 得到一个状态 s 作为输入,并输出一个维度为 n_actions 的 q 值向量。这一点我都清楚。

现在,假设我的状态动作非常嘈杂,以至于这种方法根本行不通。因此,我的 nnet 输出不是输出维度为 n_actions 的向量,而是单个值,表示“状态质量”(该状态有多理想)。

现在我的代理是这样的:

# returns an action based on how good the next state is
get_action(state, epsilon):
    actions = []
    for each action possible in state:
         game.deepcopy().apply(action)
         val = nnet.predict(game.get_state())
         action.value = val
         actions.append(action)

    if random() < epsilon
        return randomChoice(actions)
    else
        return action with_max_value from actions

而我的[预测,目标]是这样的:

# action taken was 'a' in state 's' leading to 's_'
prediction = nnet.predict(s)
if done
   target = reward
else
   target = reward + gamma * nnet.predict(s_)

我对第二种算法有一些疑问:

a) 有时不贪婪是否有意义?

直觉上不是,因为如果我进入一个糟糕的状态,可能是因为一个糟糕的随机动作,而不是因为之前的状态是“糟糕”。 Q-learning 更新会调整坏动作,但是第二个算法会错误地调整之前的状态。

b) 这是什么算法?它适用于强化学习的什么地方?

c) 在俄罗斯方块的情况下,状态几乎从不重复,那么在这种情况下我该怎么办?这就是深度 q 学习在这里失败的原因吗?

这可能看起来令人困惑,但该算法确实有效。如有需要,我可以提供更多详细信息,谢谢!

【问题讨论】:

  • 我决定现在在这里写一个问题的答案。为了将来参考,我怀疑这类问题在ai.stackexchange.com 上会比在 * 上更热门。

标签: python machine-learning deep-learning reinforcement-learning


【解决方案1】:

现在,假设我的状态动作非常嘈杂,以至于这种方法根本行不通。因此,我的 nnet 输出不是输出维度为 n_actions 的向量,而是单个值,表示“状态质量”(该状态有多理想)。

现在我的代理是这样的:

# returns an action based on how good the next state is
get_action(state, epsilon):
    actions = []
    for each action possible in state:
         game.apply(action)
         val = nnet.predict(game.get_state())
         action.value = val
         actions.append(action)

    if random() < epsilon
        return randomChoice(actions)
    else
        return action with_max_value from actions

首先简要说明一下该伪代码:我认为这行不通,因为您不会模拟不同操作对游戏状态的副本的影响,而只是在直接游戏状态。您可能希望先创建游戏状态的单独副本,然后在不同的副本上运行每个操作一次。

无论如何,这种算法通常被认为在强化学习设置中是不可能的。在 RL 中,我们通常在没有“模拟器”或“前向模型”或类似的东西的假设下进行操作。我们通常假设我们有一个位于真实环境中的代理,我们可以在其中生成可用于学习的经验。在这种假设下,我们无法实现那种for each action possible in state 循环来模拟如果我们在相同的游戏状态下执行不同的动作会发生什么。假设是我们首先必须选择一个动作,执行它,然后从特定的经验轨迹中学习; 我们不能再“回去”,想象我们选择了不同的动作,并从那个轨迹中学习。

当然,在实践中这样做通常是可能的,因为我们通常确实有一个模拟器(例如机器人模拟器或游戏等)。 RL 的大多数研究仍然假设我们没有这样的模拟器,因为这导致算法最终可能在“现实世界”情况下可用(例如,现实世界的物理机器人)。实现你上面描述的想法实际上意味着你更多地转向搜索算法(例如蒙特卡洛树搜索),而不是强化学习算法。这意味着您的方法仅限于您确实有可用模拟器的场景(例如游戏)。


a) 有时不贪婪是否有意义?

即使您包含循环所有操作并模拟其所有效果的类似搜索的过程,我怀疑如果您想要收敛到好的策略,您仍然需要进行某种形式的探索,因此您将拥有有时不贪婪地行事。是的,看起来这会导致您的算法收敛到与“最佳策略”的传统解释不同的东西。不过,如果您的 epsilon 相当低,这不是什么大问题。在实践中,它可能会倾向于是一种稍微“更安全”的策略。另见my answer to this other question

b) 这是什么算法?它适用于强化学习的什么地方?

除了我上面关于这实际上是如何向搜索算法而不是 RL 算法领域移动的讨论之外,在我看来这也是一个 on-policy 算法而不是一个off-policy 算法(标准 Q-learning 是 off-policy,因为它在学习贪婪策略的同时通过非贪婪策略生成经验)。我上面链接的问题的大多数答案也详细讨论了这种区别。

【讨论】:

  • 可能我的伪代码不是很清楚,但我不是在模拟,我只是得到一个随机动作或最佳动作然后使用它,就像q-learning一样。
  • 顺便说一句,我已经编辑了帖子,我会检查你的链接,tks!
  • @Fernando 这不是我的代码。您有一个通过动作的 for 循环,对于每个 action,您模拟执行该动作(使用 game.apply(action))并评估后续状态(使用 val = nnet.predict(game.get_state()))。 game.apply(action) 本质上不是执行一步前瞻,如果您要在当前状态下执行 action,这不是给您最终会进入的后继状态吗?
  • 在实际代码中我实际上撤消了移动,我编辑了帖子以反映这一点。我循环应用这些动作只是为了获得它们的价值,就像 q-learning 在单个 model.predict(state) 中所做的那样。很抱歉造成混乱!
  • @Fernando 好的,对。但是game.deepcopy().apply(action) 本质上确实执行了模拟,不是吗?否则,不可能仅根据状态的价值估计来选择“最佳”行动。如果您希望能够在没有模拟的情况下选择“最佳”动作,则需要状态-动作对的值估计