提交 d167b170 编写于 作者: W wizardforcel

2020-09-07 16:55:05

上级 56697002
......@@ -56,7 +56,7 @@
尽管此示例涵盖了机器翻译,但是序列到序列学习的其他应用程序却以相同的方式工作。
# 人物与文字
# 字符与文本
可以在字符级别或单词级别建立序列到序列模型。 单词级序列到序列模型将单词作为输入的原子单位,而字符级模型将字符作为输入的原子单位。
......@@ -66,7 +66,7 @@
对于本章中提出的问题,我将使用字符级模型,因为我重视您的 AWS 预算。 转换为单词非常简单,其中大部分复杂性都在数据准备中,这是留给读者的练习。
# 老师强迫
# 监督强迫
如上图所示,当预测序列`y[t(n)]`某个位置的输出时,我们使用`y[t(n-1)]`作为 LSTM 的输入。 然后,我们使用此时间步骤的输出来预测`y[t(n+1)]`
......@@ -120,7 +120,7 @@ Go now. Vas-y maintenant.
由于我们正在构建一个字符级序列到序列模型,因此需要将数据加载到内存中,然后对每个输入和输出在字符级进行热编码。 那是困难的部分。 让我们接下来做。
# 加载数据
# 加载数据
加载此数据涉及很多工作。 阅读本文时,您可能想参考代码块。
......@@ -132,7 +132,7 @@ Go now. Vas-y maintenant.
* 我们将每一行分为英语输入和其各自的法语翻译。 这些存储在列表`input_texts``target_texts`中。
* 最后,我们将输入文本和目标文本的每个字符添加到一个集合中。 这些集称为`input_characters``target_characters`。 当需要对短语进行热编码时,我们将使用这些集合。
循环完成后,我们会将字符集转换为排序列表。 我们还将创建名为`num_encoder_tokens``num_decoder_tokens`的变量,以保存每个列表的大小。 稍后我们也将需要这些以进行一种热编码。
循环完成后,我们会将字符集转换为排序列表。 我们还将创建名为`num_encoder_tokens``num_decoder_tokens`的变量,以保存每个列表的大小。 稍后我们也将需要这些以进行热编码。
为了将输入和目标输入矩阵,我们需要像上一章一样,将短语填充到最长短语的长度。 为此,我们需要知道最长的短语。 我们将其存储在`max_encoder_seq_length``max_decoder_seq_length`中,如以下代码所示:
......@@ -177,11 +177,11 @@ def load_data(num_samples=50000, start_char='\t', end_char='\n', data_path='data
加载数据后,我们将在字典中返回所有这些信息,这些信息可以传递给一个函数,该函数将对每个短语进行热编码。 让我们接下来做。
# 一种热编码
# 热编码
在此功能中,我们将使用刚刚构建的字典,并对每个短语的文本进行热编码。
一旦完成,我们将剩下三个字典。 它们每个的尺寸为`[文本数 * 最大序列长度 * 标记]`。 如果您停顿一下,回想一下第 10 章“使用单词嵌入从零开始训练 LSTM”的更简单的时间,您会发现这确实与我们在其他 NLP 模型中使用的相同,我们在输入端完成它。 我们将使用以下代码定义一种热编码:
一旦完成,我们将剩下三个字典。 它们每个的尺寸为`[文本数 * 最大序列长度 * 标记]`。 如果您停顿一下,回想一下第 10 章“使用单词嵌入从零开始训练 LSTM”的更简单的时间,您会发现这确实与我们在其他 NLP 模型中使用的相同,我们在输入端完成它。 我们将使用以下代码定义热编码:
```py
def one_hot_vectorize(data):
......@@ -237,7 +237,7 @@ def one_hot_vectorize(data):
终于完成了数据准备,因此我们可以开始构建序列到序列的网络架构。
# 训练网络架构
# 用于训练的网络架构
在此示例中,我们实际上将使用两种单独的架构,一种用于训练,另一种用于推理。 我们将从推理模型训练中使用训练过的层。 虽然实际上我们为每种架构使用了相同的部分,但是为了使事情更清楚,我将分别展示每个部分。 以下是我们将用来训练网络的模型:
......@@ -283,7 +283,7 @@ decoder_outputs, _, _ = LSTM(lstm_units, return_sequences=True,
最后,我们将定义训练模型,我将其创造性地称为`model`,该模型将`encoder_input_data``decoder_input`数据作为输入并预测`decoder_output_data`
# 网络架构(用于推理)
# 用于推理的网络架构
为了在给定输入序列的情况下预测整个序列,我们需要稍微重新安排一下架构。 我怀疑在 Keras 的未来版本中,这将变得更简单,但是从今天起这是必需的步骤。
......@@ -403,7 +403,7 @@ decoder_model.save('char_s2s_decoder.h5')
4. 将状态和`<SOS>`字符`'\t'`发送到解码器。
5. 循环,获取每个下一个字符,直到解码器生成`<EOS>``'\n'`
# 加载数据
# 加载数据
我们可以从训练脚本中导入`load_data``one_hot_vectorize`函数,以相同的方式调用这些方法,如以下代码所示:
......@@ -526,7 +526,7 @@ while not stop_condition:
我们的解码器将遵循此过程,直到生成解码序列为止。
# 翻译
# 翻译
只是为了好玩,我在这里提供了一些尝试的翻译。 所有这些都来自训练集的前面,这意味着我正在对`training`数据集进行预测,因此这些转换可能会使模型看起来比实际更好。
......
......@@ -86,20 +86,20 @@
这种天真的在线学习的缺点有些明显,有两个方面:
* 验之后,我们就会放弃经验。
* 验之后,我们就会放弃经验。
* 我们所经历的经验彼此高度相关,我们将过度适应最新的经验。 有趣的是,这也是人类遭受的苦难,称为可用性偏差。
我们可以通过使用内存和体验重播来解决这些问题。
我们可以通过使用内存和经验重放来解决这些问题。
# 记忆和体验重播
# 记忆和经验重放
当我们引入有限存储空间的概念时,可以找到针对这两个问题的巧妙解决方案,该存储空间用于存储代理具有的一组经验。 在每个状态下,我们都可以借此机会记住状态,行动和奖励。 然后,代理可以通过从内存中采样一个随机小批量并使用该小批量更新 DQN 权重,定期重播这些体验。
当我们引入有限存储空间的概念时,可以找到针对这两个问题的巧妙解决方案,该存储空间用于存储代理具有的一组经验。 在每个状态下,我们都可以借此机会记住状态,行动和奖励。 然后,代理可以通过从内存中采样一个随机小批量并使用该小批量更新 DQN 权重,定期重放这些经验。
这种重机制使代理能够以一般的方式从更长远的经验中学习,因为它是从内存中的那些经验中随机采样的,而不是仅使用最近的经验来更新整个网络。
这种重机制使代理能够以一般的方式从更长远的经验中学习,因为它是从内存中的那些经验中随机采样的,而不是仅使用最近的经验来更新整个网络。
# 开发与探索
# 利用与探索
通常,我们希望代理遵循*贪婪*策略,这意味着我们希望代理采取具有最大`Q`值的操作。 在学习网络的同时,我们不希望它总是贪婪地表现。 如果这样做,它将永远不会探索新的选择,也不会学习新的东西。 因此,我们需要我们的代理偶尔执行不符合规定的政策
通常,我们希望代理遵循*贪婪*策略,这意味着我们希望代理采取具有最大`Q`值的操作。 在学习网络的同时,我们不希望它总是贪婪地表现。 如果这样做,它将永远不会探索新的选择,也不会学习新的东西。 因此,我们需要我们的代理偶尔执行不符合规定的策略
平衡这种探索的最佳方法是一个持续不断的研究主题,并且已经使用了很长时间。 但是,我们将使用的方法非常简单。 代理每次执行操作时,我们都会生成一个随机数。 如果该数字等于或小于某个阈值`ε`,则代理将采取随机措施。 这称为 **ε 贪婪策略**
......@@ -107,7 +107,7 @@
综上所述,我们有一个**线性退火 ε - 贪心 Q 策略**,说起来既简单又有趣。
# 深心
# DeepMind
至少没有提到 Mnih 等人的论文[《和深度强化学习一起玩 Atari》](https://www.cs.toronto.edu/~vmnih/docs/dqn.pdf),就不会完成关于强化学习的讨论。 然后是 DeepMind,现在是 Google。 在这篇具有里程碑意义的论文中,作者使用了卷积神经网络来训练深度 Q 网络来玩 Atari 2600 游戏。 他们从 Atari 2600 游戏中获取原始像素输出,将其缩小一点,将其转换为灰度,然后将其用作网络的状态空间输入。 为了使计算机了解屏幕上对象的速度和方向,他们使用了四个图像缓冲区作为深度 Q 网络的输入。
......@@ -141,7 +141,7 @@ pip install gym[atari]
pip install gym[Box2D]
```
# 使用 OpenAI 体育馆
# 使用 OpenAI Gym
使用 OpenAI 体育场确实使深度强化学习变得容易。 Keras-RL 将完成大部分艰苦的工作,但是我认为值得单独走遍体育馆,这样您才能了解代理如何与环境互动。
......@@ -160,14 +160,14 @@ next_state, reward, done, info = env.step(action)
该代理可以通过使用循环与环境进行交互来播放整个情节。 此循环的每次迭代都对应情节中的单个步骤。 当代理从环境接收到“完成”信号时,情节结束。
# 在 Keras 中建立强化学习代理
# 在 Keras 中建立强化学习智能体
好消息,我们终于可以开始编码了。 在本部分中,我将演示两种名为 **CartPole****Lunar Lander** 的 Keras-RL 代理。 我选择这些示例是因为它们不会消耗您的 GPU 和云预算来运行。 它们可以很容易地扩展到 Atari 问题,我在本书的 Git 存储库中也包括了其中之一。 您可以照常在`Chapter12`文件夹中找到所有这些代码。 让我们快速讨论一下这两种环境:
* **CartPole**:CartPole 环境由平衡在推车上的杆组成。 代理商必须学习如何在立柱下方的推车移动时垂直平衡立柱。 给智能体指定了推车的位置,推车的速度,杆的角度和杆的旋转速度作为输入。 代理可以在推车的任一侧施加力。 如果电线杆与垂直线的夹角下降超过 15 度,我们的经纪人就此告吹。
* **Lunar Lander**:Lunar Lander 的环境更具挑战性。 特工必须将月球着陆器降落在着陆垫上。 月亮的表面会发生变化,着陆器的方位也会在每个情节发生变化。 该代理将获得一个八维数组,用于描述每个步骤中的世界状态,并且可以在该步骤中执行四个操作之一。 代理可以选择不执行任何操作,启动其主引擎,启动其左向引擎或启动其右向引擎。
# 购物车杆
# CartPole
CartPole 代理将使用一个相当适度的神经网络,即使没有 GPU,您也应该能够相当迅速地进行训练。 我们将一如既往地从模型架构开始。 然后,我们将定义网络的内存,探索策略,最后训练代理。
......@@ -198,11 +198,11 @@ Keras-RL 为我们提供了一个名为`rl.memory.SequentialMemory`的类,该
memory = SequentialMemory(limit=50000, window_length=1)
```
我们需要为此存储对象指定一个最大大小,它是一个超参数。 随着新的体验添加到该内存中并变得完整,旧的体验会被遗忘。
我们需要为此存储对象指定一个最大大小,它是一个超参数。 随着新的经验添加到该内存中并变得完整,旧的经验会被遗忘。
# 政策
# 策略
Keras-RL 提供了一个称为`rl.policy.EpsGreedyQPolicy`的 ε-贪婪 Q 策略,我们可以用来平衡勘探和开发。 当代理程序向世界前进时,我们可以使用`rl.policy.LinearAnnealedPolicy`来衰减`ε`,如以下代码所示:
Keras-RL 提供了一个称为`rl.policy.EpsGreedyQPolicy`的 ε-贪婪 Q 策略,我们可以用来平衡利用与探索。 当代理程序向世界前进时,我们可以使用`rl.policy.LinearAnnealedPolicy`来衰减`ε`,如以下代码所示:
```py
policy = LinearAnnealedPolicy(EpsGreedyQPolicy(), attr='eps', value_max=1., value_min=.1, value_test=.05, nb_steps=10000)
......@@ -210,7 +210,7 @@ policy = LinearAnnealedPolicy(EpsGreedyQPolicy(), attr='eps', value_max=1., valu
在这里我们要说的是,我们要从`ε`的值 1 开始,并且不小于 0.1,同时测试我们的随机数是否小于 0.05。 我们将步数设置为 .1 到 10,000 之间,Keras-RL 为我们处理衰减数学。
# 代理商
# 智能体
定义了模型,内存和策略后,我们现在就可以创建一个深度 Q 网络代理,并将这些对象发送给该代理。 Keras RL 提供了一个称为`rl.agents.dqn.DQNAgent`的代理类,我们可以为此使用它,如以下代码所示:
......@@ -223,7 +223,7 @@ dqn.compile(Adam(lr=1e-3), metrics=['mae'])
此时,其中两个参数`target_model_update``nb_steps_warmup`可能还不熟悉:
* `nb_steps_warmup`:确定我们开始进行体验重播之前需要等待的时间,如果您还记得的话,这是我们实际上开始训练网络的时间。 这使我们积累了足够的经验来构建适当的小批量生产。 如果您为此参数选择的值小于批量大小,则 Keras RL 将抽样替换。
* `nb_steps_warmup`:确定我们开始进行经验重放之前需要等待的时间,如果您还记得的话,这是我们实际上开始训练网络的时间。 这使我们积累了足够的经验来构建适当的小批量生产。 如果您为此参数选择的值小于批量大小,则 Keras RL 将抽样替换。
* `target_model_update``Q`函数是递归的,当代理更新它的网络以获取` Q(s, a)`时,更新也影响其对`Q(s', a)`所​​做的预测。 这会导致网络非常不稳定。 大多数深度 Q 网络实现解决此限制的方法是使用目标网络,该目标网络是未经训练的深度 Q 网络的副本,而经常被新副本替换。 `target_model_update`参数控制这种情况发生的频率。
# 训练
......@@ -266,7 +266,7 @@ dqn.test(env, nb_episodes=5, visualize=True)
我们走了,那是一根平衡杆! 好吧,我知道,我承认平衡手推车上的电线杆并不是那么酷,所以让我们再做一个轻量级的例子。 在此示例中,我们将把月球着陆器降落在月球上,希望它将给您留下深刻的印象。
# 月球着陆器
# Lunar Lander
感谢 Keras-RL,我们用于 Lunar Lander 的代理几乎与 CartPole 相同,除了实际的模型架构和一些超参数更改外。 Lunar Lander 的环境有八个输入而不是四个输入,我们的代理现在可以选择四个操作而不是两个。
......@@ -291,11 +291,11 @@ def build_model(state_size, num_actions):
在此问题的情况下,较小的架构会导致代理学习控制和悬停着陆器,但实际上并未着陆。 当然,由于我们要对每个情节的每个步骤进行小批量更新,因此我们需要仔细权衡复杂性与运行时和计算需求之间的关系。
# 记忆和政策
# 记忆和策略
CartPole 的内存和策略可以重复使用。 我相信,通过进一步调整**线性退火策略**中的步骤,可能会提高代理训练的速度,因为该代理需要采取更多的步骤来进行训练。 但是,为 CartPole 选择的值似乎可以很好地工作,因此这是留给读者的练习。
# 代理商
# 智能体
从以下代码中可以看出,Lunar Lander `DQNAgent`再次相同,只是学习率小得多。
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册