DDQN 代理的每次训练运行需要 2 天,最终仍以 -13 平均得分结束,但 OpenAi 基线 DQN 只需要一个小时即可收敛到 +18?

人工智能 深度学习 强化学习 dqn 开放式 深思熟虑
2021-11-12 09:17:24

状态

几个星期以来,我一直在为PongDeterministic-v4环境开发一个 Double DQN 代理,您可以在此处找到它。

在 Google Collab(K80 Tesla GPU 和 13 GB RAM)上,单次训练运行持续大约 7-8 百万个时间步(大约 7000 集),大约需要 2 天。起初,我认为这很正常,因为我看到很多帖子都在谈论 DQN 如何花费很长时间来训练 Atari 游戏。

启示录

但是在克隆了 OpenAI 基线repo之后,我尝试运行python -m baselines.run --alg=deepq --env=PongNoFrameskip-v4 ,这需要大约 500 集和一两个小时才能收敛到 +18 的好分数,而且毫不费力。现在我确信我做错了什么,但我不知道到底是什么。

调查

在浏览了 OpenAI 的 DQN 基线代码后,我注意到了一些差异:

  • 我使用PongDeterministic-v4环境,但他们使用PongNoFrameskip-v4环境
  • 我认为更大的重播缓冲区大小很重要,所以我努力(通过内存优化)确保将其设置为70000但他们将其设置为仅10000,并且仍然得到了惊人的结果。
  • 我使用的是普通的Double DQN,但他们似乎使用的是Dueling Double DQN

结果/结论

我对仅通过这些很少的更改就能大幅提高性能表示怀疑。所以我知道我现有的实现可能有问题。有人能指出我正确的方向吗?

任何形式的帮助将不胜感激。谢谢!

2个回答

决斗架构在状态空间中的动作值上产生了更大的差异。这是因为状态值V(s)函数是与状态动作值Q(s, a)分开估计的一个新的量,一个动作的优势,可以定义为A(s, a) = Q(s, a) - V(s)

然而,Q 函数测量在此状态下选择特定动作的价值。优势函数从 Q 函数中减去状态的值,以获得每个动作的重要性的相对度量。

用于深度强化学习的决斗网络架构


为了更好地指导您,这里有 2 个资源可以真正帮助您理解为什么这些差异很重要。

在 PyTorch 上加速 DQN:如何在 30 分钟内解决 Pong

博客的主要观点是:

  1. 使用更大的批量大小并在更新之前播放几个步骤
  2. 在单独的过程中玩耍和训练
  3. 使用异步 cuda 传输

强化学习冒险

这个 github 库具有易于遵循的 jupyter 笔记本和所有论文的链接。这包括:

  • DQN
  • 双DQN
  • 决斗DQN
  • 优先体验重播
  • 用于探索的噪声网络
  • 分布式强化学习
  • Rainbow(deepmind 制作的那个网络,里面有很多东西,他们找不到好名字)
  • 带有分位数回归的分布 RL
  • 分层深度强化学习

尽管@Jaden 所说的本身可能是正确的,但它并不能真正回答我的问题,正如我在进行大量实验后所看到的那样,最终使用普通的双 DQN (DDQN) 达到了接近决斗网络的性能。

在仔细检查 OpenAI 基线代码后,我对我的代码进行了以下更改:

  • 用来PongFrameskip-v4代替PongDeterministic-v4
  • 使用大小为10000的小型重放缓冲区
  • step_update()orreplay()调用期间,将 a 的条件更改为 returnfrombuffer_fill_size < learn_startt < learn_start,其中t是当前时间步长,buffer_fill_size是已被经验元组填充的缓冲区的当前大小,并且learn_start是开始从收集的经验中学习之前等待的时间步长.
  • 确保make_atari()包装函数也被调用env

    ENV_GYM = 'PongFrameskip-v4'
    env = make_atari(ENV_GYM)
    env = wrap_deepmind(env, frame_stack=True, scale=False)
    

    这些包装器可以从头开始实现,也可以从OpenAI 基线 Atari 包装器中获得。我个人使用后者,因为重新发明轮子没有意义。

结论

我忽略的最大步骤,或者说没有太多关注的是输入预处理。这几处改变将我的 DDQN 从近 5000 集的平均分数饱和度 -13 提高到大约 700-800 集的 +18。这确实是一个巨大的差异。你可以在这里查看我的实现