深度强化学习之DQN编写与调试经验总结

写在开头的话

从头开始进行DQN编写与调试,中间对神经网络结构、参数调整与流程调整等多种问题进行了分析与研究。在学习过程中,参考了github上相关的代码以及相关经验分析,同时与同学进行了多次交流讨论,收获很多。当你真的从一个论文开始,对作者思路和算法流程进行深入思考时,你会对如何研究进步有更好认识。

内容目录

  1. DQN内容
  2. 深度学习内容
  3. Pytorch1.0及以上的内容
  4. 论文引用

1. DQN有关强化学习内容

       这里介绍与最简单的DQN有关的内容,其他博客中包含的到处可见的内容都不会赘述。

1.1 神经网络有关内容

       首先是对DQN构建时几个重要模块的介绍,分别为DQN神经网络模型、记忆回放存储器、Agent类(实例化前两个内容,并实现act、store_memory、learn、model_load\save、e-greedy方法)。然后通过实例化Agent与env进行交互,不断存储序列化经验。
       当你在脑海里面过一遍这些东西时,你会觉得每一部分的东西说起来你都很清楚,但是当你真的把他们从头开始写一遍,你会发现你好像认识的不是那么全面。下面让我们一个个回味下我踩过的坑。
       首先是关于DQN的两个网络,分别为target_net和policy_net,需要用一样的结构。但是在训练过程中,我们不必计算target_net的梯度,即只梯度反向计算policy_net即可,然后在一定步数的学习之后,直接把policy_net的参数赋值到target_net上面即可。

self.target_net.load_state_dict(self.policy_net.state_dict())

       在开始时,最好设置self.target_net为eval() 模式,告诉pytorch该网络不参与训练。

1.2 Agent中有关具体methods的内容

       接下来我们分析Agent实现中具体的方法。

1.2.1 Agent.act

       该函数被main函数调用,与环境交互时输入环境观测值给该函数获取Agent推断出的动作值。

1.2.2 Agent.e-greedy

       该函数被act类函数调用,这里要着重说一下,其中的epsilon在DQN的原始论文中是用线性衰减的方法更新的,我用的指数衰减方式,不过效果感觉差不多。主要是为了实现前期随机探索多一点,后期经验利用多一点。注意这里检查好你的逻辑!!不要弄反。

1.2.3 Agent.store_memory

       该函数的实现需要先定义memory实例,这里就涉及具体的memory管理方法了。需要明确,当初提出经验集的目的是减少序列化经验之间的相关性!,其次才是提高哦了样本的利用率。关于第一个的深意我还没完全摸透,不赘述。这里要强调的是,你在DQN原始论文中,数据集的数量为100w,但每次batch只有32,你设置对应参数时候好好考虑一下人家设计这个方法的出发点和对应的参数,你就有一定的方向了。
       再说一下random选取样本和基于优先级的样本选取方法,openai的baseline开源库中有对应的优先级样本选取方法,可以参照人家的自己写一个,对应原始论文中的讲述也比较清楚。但是你的问题不是很复杂就不要去给自己添麻烦,直接用人家的或者就用random。
       这里又得提一下经验集添加数据的问题,python一般用list数据结构实现。目前为止我见了两个添加方法,一个是每次出现一个添加一个,经验集的总尺寸设置的很大,然后学习的频率为一个固定值,常见的为这种;另一个是经验集的大小和周期性任务的所需step大小有关,以mountain-car为例,设置经验集大小为9999,在前期探索时,9999的大小与该任务的random探索有一定比例关系。

2. DQN有关深度学习内容

2.1 神经网络的选取

       这里着重强调一下,我们用神经网络的目的是为了拟合值函数(动作-状态值函数)
       那么我们应该使用什么样的网络呢?当你在网上搜索DQN代码时,主要有以下几个版本的复制:基于gym中倒立摆与过山车的DQN,用的为一个隐藏层的全连接;基于原始图像输入如Atari中的游戏,用的为深度卷积神经网络。因此,当你把DQN应用到具体的应用时,首先考虑一下是不是真的需要使用深度卷积神经网络。当你的特征可以直接提取并可以根据得到的特征计算值函数时,就不需要使用卷积神经网络,只有当你的Agent输入为原始图像,需要提取图像特征时再考虑使用卷积神经网络。
       如果你要问神经元的数量以及层数,大致的思路是层数越深,每层神经元数据可以相应减少;层数越浅,每层神经元数量就稍微增多一点
       激活函数这里要注意一下,如果你的环境奖励为负值,那么要注意:Relu可能会使你的神经元不激活,从而导致反向传播无法更新大量的参数。Relu的变种或者Sigmoid变种(tanh)等都可以考虑,但是sigmoid在一定区域也会出于无梯度状态。

2.2 优化方法的选取

       9102了,就不谈这个了。

3. Pytorch有关内容

       为什么写pytorch?因为我用的pytorch。
       仅限于1.0版本之后。在往经验集储存数据时,可以直接传递为tensor,但是全部存储为numpy可以会更好一点,毕竟你是用的list数据结构。这样后面读取了批量数据之后,可以直接使用torch.tensor转换过来。
       在计算值函数时,torch中很多操作方法是和numpy相近的,推荐直接使用tensor处理。例如gather、max等。
       pytorch的编写与调试确实很灵活方便。

4. 论文及相关引用

  1. Mnih, Volodymyr, et al. “Human-level control through deep reinforcement learning.” Nature 518.7540 (2015): 529.
  2. Schaul, Tom, et al. “Prioritized experience replay.” arXiv preprint arXiv:1511.05952 (2015).
  3. openai baseline https://github.com/openai/baselines
  4. openai gym https://gym.openai.com/
  5. pytorch手册 https://pytorch.org/docs/stable/index.html

你可能感兴趣的:(国科大学习)