深度 Q 网络(DQN)是将 Q learning 和卷积神经网络(CNN)结合在一起,由 Mnih 等人在 2013 年首次提出(https://arxiv.org/pdf/1312.5602.pdf)。
CNN 由于能够提取空间信息,能够从原始像素数据中学习得到控制策略。由于前面已经介绍了卷积神经网络,所以本节不再介绍基础知识。
正如上一节提到的那样,对于像 Pac-Man 或 Breakout 这样的 Atari 游戏,需要预处理观测状态空间,它由 33600 个像素(RGB 的 3 个通道)组成。这些像素中的每一个都可以取 0~255 之间的任意值。preprocess 函数需要能够量化可能的像素值,同时减小观测状态空间。
这里利用 Scipy 的 imresize 函数来下采样图像。函数 preprocess 会在将图像输入到 DQN 之前,对图像进行预处理:
IM_SIZE 是一个全局参数,这里设置为 80。该函数具有描述每个步骤的注释。下面是预处理前后的观测空间:
另外需要注意的是当前观测空间并没有给出完整的游戏画面,例如,只看上图不能确定下面的板子是向左还是向右。因此,要完全理解游戏的当前状态,需要考虑动作和观测的序列。
本节考虑四个动作和观测序列来确定当前情况并训练智能体。update_state 函数用来将当前观测状态附加到以前的状态,从而产生状态序列:
最后,为了训练稳定性,使用 target_network(目标网络)的概念,这是 DQN 的副本,但并不如同 DQN 一样更新。这里使用目标网络为 DQN 网络生成目标价值函数,在每一步中正常更新 DQN,同时在规律性的时间间隔之后更新 target_network(与 DQN 相同)。由于所有更新都在 TensorFlow 会话中进行,因此需要使用名称作用域来区分 target_network 和 DQN 网络。
训练智能体需要运行很多次游戏,消耗大量的时间和内存。OpenAI Gym 提供了一个封装,将游戏保存为一个视频,因此,无须 render 函数,你可以使用这个封装来保存视频并在以后查看智能体是如何学习的。AI 工程师和爱好者可以上传这些视频来展示他们的结果。
要使用的话,首先要导入 wrappers,然后创建环境并调用 wrappers。默认情况下,它会存储 1,8,27,64 等次的视频,1000 次训练以后将每 1000 次的视频(次数是整数立方)默认保存在一个文件夹中。为此添加的代码如下所示:
如果你想在下次训练中使用相同的文件夹,可以在 Monitor 中传入参数 force=True。