本文为 AI 研习社编译的技术博客,原标题 :
An introduction to Deep Q-Learning: let’s play Doom
作者 | Thomas Simonini
翻译 | 斯蒂芬•二狗子
校对 | 酱番梨 整理 | 菠萝妹
原文链接:
https://medium.freecodecamp.org/an-introduction-to-deep-q-learning-lets-play-doom-54d02d8017d8
深度强化学习从入门到大师:以Doom为例一文带你读懂深度Q学习(第三部分)
本文是Tensorflow深度强化学习课程的一部分。点击这里查看教学大纲。
上一次,我们学习了Q-Learning:一种算法,它生成一个Q表,Agent用它来查找给定状态时采取的最佳动作。
但正如我们所看到的,状态空间是大型环境时,生成和更新Q表可能会失效。
本文是关于深度强化学习的一系列博客文章的第三部分。有关更多信息和更多资源,请查看 课程的教学大纲。
今天,我们将创建一个Deep Q神经网络。我们通过一个神经网络实现,而不是使用Q表,该神经网络获取智能体的状态并为该状态的每个动作计算Q值。
多亏了这个模型,我们将能够创建一个学习如何玩Doom的智能体 !
我们的DQN智能体
在本文中,您将学习:
什么是Deep Q-Learning(DQL)?
使用DQL的最佳策略是什么?
如何处理时间限制问题
为什么我们使用经验回放
DQL背后的数学是什么?
如何在Tensorflow中实现它
为Q-Learning添加“深度”
在 上一篇文章中,我们通过Q学习算法创建了一个扮演Frozen Lake的智能体。
我们实现了Q-learning函数来创建和更新Q表。根据到当前的状态,可以将此视为“作弊表”,以帮助我们找到行动的最大预期未来奖励。这是一个很好的策略 - 但是,这种方法不可扩展。
想象一下我们今天要做的事情。我们将创建一个学习玩Doom的智能体。
Doom是一个拥有巨大状态空间(数百万不同state)的大环境。为该环境创建和更新Q表的效率可想而知。
在这种情况下,最好的想法是创建一个神经网络 ,这个网络在给定状态的情况下 ,将近似每个动作的不同Q值。
Deep Q-Learning是如何工作的?
深度Q学习的架构:
这看起来很复杂,但我会逐步解释这个架构。
我们的深度Q学习神经网络以四个图像帧的堆叠作为输入。它们通过其网络,并在给定状态下为每个可能的动作输出Q值向量。我们需要采用此向量的最大Q值来找到我们最好的行动。
一开始,智能体的表现非常糟糕。但随着时间的推移,它开始将 图像帧(状态)与最佳动作联系起来。
预处理部分
预处理是重要的一步。我们希望降低状态的复杂性,以减少培训所需的计算时间。
首先,我们可以对每个state进行灰度化。颜色不会添加重要信息(在我们的例子中,我们只需要找到敌人并杀死他,我们不需要颜色来找到他)。这是一个重要的节省,因为我们将三种颜色通道(RGB)减少到1(灰度)。
然后,我们裁剪图像。在我们的例子中,看到屋顶并不是真的有用。
然后我们减小每帧图的大小,并将四个子帧叠加在一起。
时间限制的问题
Arthur Juliani 在他的文章中对这个主题给出了一个很棒的解释 。他有一个聪明的主意:使用 LSTM神经网络 来处理。
但是,我认为初学者使用堆叠图像会更好。
您可能问的第一个问题是我们为什么要将图像帧叠加在一起?
我们将帧堆叠在一起,因为它有助于我们处理时间限制(temporal limitation)的问题。
让我们举一个例子,在 Pong 游戏中。当你看到这个图片时:
你能告诉我球在哪里吗?
不能,因为一帧图片不足以产生运动感!
但是,如果我再添加三个帧怎么办?在这里你可以看到球向右移动。
这对我们的Doom智能体来说是一样的。如果我们一次只给他一帧图片,它就不知道该如何行动了。如果不能确定物体移动的位置和速度,它怎么能做出正确的决定呢?
使用卷积网络
帧由三个卷积层处理。这些图层允许您利用图像中的空间关系。但是,因为帧堆叠在一起,您可以利用这些帧的一些空间属性。
如果你不熟悉卷积,请仔细阅读 Adam Geitgey 的 文章 。
每个卷积层将使用 ELU 作为激活函数。ELU已被证明是卷积层的较好 激活函数。
我们设定一个具有ELU激活函数的完全连接层和一个输出层(具有线性激活函数的完全连接层),其输出为每个动作的Q值估计。
经验回放:更有效地利用观察到的体验
经验回放将帮助我们处理两件事:
避免忘记以前的经历。
减少经验之间的相关性。
我将解释这两个概念。
这部分和插图的灵感来自Udacity的Deep Learning Foundations Nanodegree的Deep Q Learning章节中的重要解释 。
避免忘记以前的经历
我们有一个很大的问题:权重的可变性,因为行动和状态之间存在高度相关性。
请记住在第一篇文章(强化学习简介)中,我们谈到了强化学习过程:
在每个时间步,得到一个元组(state, action, reward, new_state)。从(这个元组)中学习,然后扔掉这个经验。
问题是将智能体与环境相互作用的得到序列样本输入到神经网络进行训练过程中。 神经网络往往会忘记以前的经历,因为它的参数会被新的经验覆盖。
例如,当前超级玛丽的的第一关,然后是第二关(这个环境是完全不同的),我们的智能体就会忘记如何在第一关中进行行动。
通过学习如何在水中玩,我们的智能体会忘记如何在第一关发挥
因此,通过多次学习,可以更有效地利用以前的经验。
我们的解决方案:创建一个“replay buffer”存盘。在智能体与环境交互时存储经验元组,然后我们用小批量元组数据a small batch of tuple来训练神经网络。
“replay buffer”可以看成一个文件夹,其中每个工作表都是经验元组。通过智能体与环境交互来产生。然后你拿其中的一些随机表来训练神经网络
这可以防止网络只学习智能体当前的经验。
减少经验之间的相关性
我们还有另一个问题 - 我们知道每个行动都会影响下一个状态。行动过程得到了一个序列的经验元组,这些元组可能会高度相关。
如果按序列顺序训练网络,这种相关性会影响我们的智能体。
通过在replay buffer随机抽取,我们可以打破这种相关性。可以防止动作值发生振荡或发散。
通过一个例子来理解它会更容易。假设我们玩第一人称射击游戏,怪物不断出现左边或右边。智能体的目标是射击怪物。它有两个枪和两个动作:向左射击或向右射击。
该表表示Q值近似值
我们学习有序的经验。假设我们知道如果我们射击怪物,下一个怪物来自同一方向的概率是70%。在我们的例子中,这是我们的经验元组之间的相关性。
开始训练吧。智能体看到了右边的怪物,并用右枪射击它。这是对的!
然后下一个怪物也来自右边(概率为70%),智能体将使用右枪射击。再次命中,这很好!
等等......
红枪是采取的行动
问题是,这种方法增加了在整个状态空间使用右枪的权重值。
我们可以看到怪物在左边并用右枪射击的Q值是正的(即使它不合理)
如果网络没有看到很多左边的例子(因为只有30%可能来自左边), 智能体 只会选择右边而不管怪物来自哪里。这根本不合理。
即使怪物出现在左侧,我们的经纪人也会用右枪射击
我们有两个并行的策略来处理这个问题。
首先,在与环境交互的时必须停止学习。我们应该尝试探索不同的东西并随意玩一下来探索状态空间。我们可以将这些经验保存在replay buffer中。
然后,可以回放这些经历并从中学习。之后,继续玩返回更新值函数。
因此,我们将有一套更好的样本。通过这些示例能够概括游戏的真实模式,以任何顺序回放。
这有助于避免被固定在状态空间的一个区域上。这可以防止反复强化相同的动作。
这种方法可以看作是监督学习的一种形式。
我们将在以后的文章中看到我们也可以使用“优先级经验回放”。这让我们可以更频繁地向神经网络呈现罕见或“重要”的元组。
我们的深度Q-Learning算法
首先是一点点数学:
记得,我们使用Bellman方程更新给定状态和动作的Q值:
在我们的例子中,更新的神经网络权重以减少错误。
时序差分误差(或TD误差)是通过Q_target(来自下一个状态的最大可能值)和Q_value(我们当前预测的Q值)之间的差来计算的。
Initialize Doom Environment E
Initialize replay Memory M with capacity N (= finite capacity)
Initialize the DQN weights w
for episode in max_episode:
s = Environment state
for steps in max_steps:
Choose action a from state s using epsilon greedy.
Take action a, get r (reward) and s' (next state)
Store experience tuple in M
s = s' (state = new_state)
Get random minibatch of exp tuples from M
Set Q_target = reward(s,a) + γmaxQ(s')
Update w = α(Q_target - Q_value) * ∇w Q_value
此算法中有两个过程:
我们对执行操作的环境进行采样,并将观察存储在回放内存中的经验元组。
选择小批量的元组随机梯度下降(batch SGD)进行学习。
让我们实现我们的Deep Q神经网络
我们制作了一个视频,用Tensorflow实现了一个深度Q学习agent,学习玩Atari Space Invaders ️ 。
使用 Tensorflow 和Space Invaders进行深度Q学习 - (教程)
现在我们知道它是如何工作的,我们将逐步实现我们的Deep Q神经网络。代码的每个步骤和每个部分都直接在下面链接的Jupyter笔记本中解释。
您可以在Deep Reinforcement Learning Course repo 中访问它:
https://gist.github.com/simoninithomas/7611db5d8a6f3edde269e18b97fa4d0c#file-deep-q-learning-with-doom-ipynb
就这样!您刚刚创建了一个学习玩Doom的智能体。真棒!
不要忘记自己实现代码的每个部分。尝试修改我给你的代码非常重要。尝试添加epochs,更改架构architecture,,添加固定的Q值,更改学习率,使用更难的环境(例如Health Gathering)......等等。玩得开心!
在下一篇文章中,我将讨论Deep Q-learning的最新改进:
Fixed Q-values
Prioritized Experience Replay
Double DQN
Dueling Networks
但是下次我们将通过训练一个扮演毁灭战士的智能体来研究策略梯度,将通过收集“health”来尝试在恶劣的环境中生存。
想要继续查看该篇文章相关链接和参考文献?
长按链接点击打开或点击底部【深度强化学习从入门到大师:以Doom为例一文带你读懂深度Q学习(第三部分】:
https://ai.yanxishe.com/page/TextTranslation/1395
AI研习社每日更新精彩内容,观看更多精彩内容:雷锋网雷锋网(公众号:雷锋网)雷锋网
用PyTorch来做物体检测和追踪
用 Python 做机器学习不得不收藏的重要库
初学者怎样使用Keras进行迁移学习
一文带你读懂 WaveNet:谷歌助手的声音合成器
等你来译:
强化学习:通往基于情感的行为系统
如何用Keras来构建LSTM模型,并且调参
高级DQNs:利用深度强化学习玩吃豆人游戏
用于深度强化学习的结构化控制网络 (ICML 论文讲解)