提交 b6a2ae18 编写于 作者: W wizardforcel

2020-09-07 22:32:21

上级 b34c8acd
......@@ -16,7 +16,7 @@
第 2 章“使用深度学习解决回归问题”,您可以构建非常简单的神经网络来解决回归问题,并研究更深更复杂的模型对这些问题的影响。
第 3 章“使用 TensorBoard 监视网络训练”让您立即开始使用 TensorBoard,这是监视和调试未来模型的绝佳应用程序
第 3 章“使用 TensorBoard 监视网络训练”让您立即开始使用 TensorBoard,这是监视和调试未来模型的绝佳应用。
第 4 章“使用深度学习解决二分类问题”帮助您使用深度学习解决二分类问题。
......@@ -26,7 +26,7 @@
第 7 章“从头开始训练 CNN”教您如何使用卷积网络对图像进行分类。
第 8 章“使用预训练的 CNN 的迁移学习”描述了如何应用迁移学习来从图像分类器中获得惊人的性能,即使数据很少。
第 8 章“使用预训练的 CNN 的迁移学习”描述了如何应用迁移学习来从图像分类器中获得惊人的表现,即使数据很少。
第 9 章“从头开始训练 RNN”,讨论 RNN 和 LSTMS,以及如何将其用于时间序列预测问题。
......@@ -34,7 +34,7 @@
第 11 章“训练 Seq2Seq 模型”帮助我们使用序列对模型进行序列化以进行机器翻译。
第 12 章“使用深度强化学习”引入了深度强化学习,并构建了可以为自治代理提供动力的深度 Q 网络。
第 12 章“使用深度强化学习”引入了深度强化学习,并构建了可以为自治智能体提供动力的深度 Q 网络。
第 13 章“生成对抗网络”解释了如何使用生成对抗网络生成令人信服的图像。
......
......@@ -23,7 +23,7 @@
神经元是神经网络的原子单位。 有时这是受到生物学启发的。 但是,这是另一本书的主题。 神经元通常排列成层。 在本书中,如果我指的是特定的神经元,则将使用符号`n[k]^l`,其中`l`是神经元所在的层, `k`是神经元编号 。 由于我们将使用遵循第 0 个表示法的编程语言,因此我的表示法也将基于第 0 个表示法。
大多数神经元的核心是两个共同起作用的功能:线性功能和激活函数。 让我们从较高的角度看一下这两个组成部分。
大多数神经元的核心是两个共同起作用的函数:线性函数和激活函数。 让我们从较高的角度看一下这两个组成部分。
# 神经元线性函数
......@@ -35,7 +35,7 @@
# 神经元激活函数
神经元的第二个功能是激活函数,其任务是在神经元之间引入非线性。 乙状结肠激活是一种常用的激活,您可能会通过逻辑回归来熟悉它。 它将神经元的输出压缩到输出空间,其中`z`的非常大的值被驱动为 1,而`z`的非常小的值被驱动为 0。
神经元的第二个函数是激活函数,其任务是在神经元之间引入非线性。 乙状结肠激活是一种常用的激活,您可能会通过逻辑回归来熟悉它。 它将神经元的输出压缩到输出空间,其中`z`的非常大的值被驱动为 1,而`z`的非常小的值被驱动为 0。
sigmoid 函数如下所示:
......@@ -143,7 +143,7 @@ RMSProp 是另一种算法,可以通过跨网络权重表示的多维空间,
# Adam 优化器
Adam 是已知性能最好的**优化器**之一,这是我的首选。 它可以很好地解决各种问题。 它将动量和 RMSProp 的最佳部分组合到一个更新规则中:
Adam 是已知表现最好的**优化器**之一,这是我的首选。 它可以很好地解决各种问题。 它将动量和 RMSProp 的最佳部分组合到一个更新规则中:
![](img/eef792ef-f454-4569-8c55-61286ccc904c.png)
......@@ -183,7 +183,7 @@ TensorFlow 是 Google 在 2015 年发布的一个开源项目。此后,它已
我最喜欢的 TensorFlow 替代品包括:
* **Apache MXNet**:一个非常高性能的框架,带有一个名为 [**Gluon**](https://mxnet.apache.org/) 的新命令式接口
* **Apache MXNet**:一个非常高表现的框架,带有一个名为 [**Gluon**](https://mxnet.apache.org/) 的新命令式接口
* [**PyTorch**](http://pytorch.org/):Facebook 最初开发的一种非常新颖且有希望的架构
* [**CNTK**](https://www.microsoft.com/en-us/cognitive-toolkit/):也可以与 Keras 一起使用的 Microsoft 深度学习框架
......@@ -383,7 +383,7 @@ pip install keras
* **偏差误差**:偏差误差是模型引入的误差。 例如,如果您尝试使用线性模型对非线性函数建模,则模型将在指定的下为,*并且偏差误差会很高*
* **方差误差**:方差误差是由训练数据中的随机性引起的误差。 当我们很好地拟合训练分布以至于我们的模型不再泛化时,我们就过拟合或引入了方差误差。
在大多数机器学习应用程序中,我们寻求找到一些折衷方案,以最小化偏差误差,同时引入尽可能小的方差误差。 我之所以这么说是因为深度神经网络的一大优点是,在很大程度上,偏差和方差可以彼此独立地进行操纵。 但是,这样做时,我们将需要非常谨慎地构造训练数据。
在大多数机器学习应用中,我们寻求找到一些折衷方案,以最小化偏差误差,同时引入尽可能小的方差误差。 我之所以这么说是因为深度神经网络的一大优点是,在很大程度上,偏差和方差可以彼此独立地进行操纵。 但是,这样做时,我们将需要非常谨慎地构造训练数据。
# 训练,验证和测试数据集
......@@ -395,11 +395,11 @@ pip install keras
验证数据集将用于查找理想的超参数并测量过拟合。 *在时期结束时*,即网络有机会观察训练集中的每个数据点时,我们将对验证集进行预测。 该预测将用于监视过拟合,并将帮助我们知道网络何时完成训练。 像这样在每个时期末尾使用验证设置与典型用法有些不同。 有关保留验证的更多信息,请参考 Hastie 和 Tibshirani 撰写的[《统计学习的要素》](https://web.stanford.edu/~hastie/ElemStatLearn)
一旦完成所有训练,就将使用测试数据集,以根据网络未看到的一组数据准确地测量模型性能
一旦完成所有训练,就将使用测试数据集,以根据网络未看到的一组数据准确地测量模型表现
验证和测试数据来自同一数据集非常重要。 火车数据集匹配验证和测试不太重要,尽管那仍然是理想的。 例如,如果使用图像增强功能(对训练图像进行较小的修改以尝试扩大训练集大小),则训练集分布可能不再与验证集分布匹配。 这是可以接受的,并且只要验证和测试来自同一分布,就可以充分测量网络性能
验证和测试数据来自同一数据集非常重要。 火车数据集匹配验证和测试不太重要,尽管那仍然是理想的。 例如,如果使用图像增强(对训练图像进行较小的修改以尝试扩大训练集大小),则训练集分布可能不再与验证集分布匹配。 这是可以接受的,并且只要验证和测试来自同一分布,就可以充分测量网络表现
在传统的机器学习应用程序中,习惯上将 10% 到 20% 的可用数据用于验证和测试。 在深度神经网络中,通常情况是我们的数据量很大,以至于我们可以用更小的验证和测试集来充分测量网络性能。 当数据量达到数以千万计的观测值时,将 98%,1%,1% 的拆分完全合适。
在传统的机器学习应用中,习惯上将 10% 到 20% 的可用数据用于验证和测试。 在深度神经网络中,通常情况是我们的数据量很大,以至于我们可以用更小的验证和测试集来充分测量网络表现。 当数据量达到数以千万计的观测值时,将 98%,1%,1% 的拆分完全合适。
# 在深度神经网络中管理偏差和方差
......@@ -427,6 +427,6 @@ pip install keras
我们讨论了 Keras 和 TensorFlow 的基础知识,以及为什么我们在本书中选择了这些框架。 我们还讨论了 CUDA,cuDNN,Keras 和 TensorFlow 的安装和配置。
最后,我们介绍了本书其余部分将使用的留出验证方法,以及为什么对于大多数深度神经网络应用程序,我们都更喜欢 K 折 CV。
最后,我们介绍了本书其余部分将使用的留出验证方法,以及为什么对于大多数深度神经网络应用,我们都更喜欢 K 折 CV。
当我们在以后的章节中重新审视这些主题时,我们将大量参考本章。 在下一章中,我们将开始使用 Keras 解决回归问题,这是构建深度神经网络的第一步。
\ No newline at end of file
# 二、使用深度学习解决回归问题
在本章中,我们将构建一个简单的**多层感知器****MLP**),它是具有单个隐藏层的神经网络的奇特名称,用于解决回归问题。 然后,我们将深入研究具有多个隐藏层的深度神经网络。 在此过程中,我们将探索模型的性能和过拟合。 所以,让我们开始吧!
在本章中,我们将构建一个简单的**多层感知器****MLP**),它是具有单个隐藏层的神经网络的奇特名称,用于解决回归问题。 然后,我们将深入研究具有多个隐藏层的深度神经网络。 在此过程中,我们将探索模型的表现和过拟合。 所以,让我们开始吧!
我们将在本章介绍以下主题:
......@@ -24,7 +24,7 @@
在本章的其余部分,我们将重点介绍使用深度神经网络进行预测。 与使用传统的多元线性回归进行比较时,您会很高兴地发现我们的神经网络具有以下优势:
* 我们不需要选择或筛选功能。 神经网络是功能强大的功能工程机器,可以了解哪些功能是相关的,而忽略了无关的功能
* 我们不需要选择或筛选特征。 神经网络是功能强大的特征工程机器,可以了解哪些特征是相关的,而忽略了无关的特征
* 给定足够复杂的网络,还可以学习特征交互(例如,除了`x[1]``x[2]`的独立效应,`x[1] * x[2]`的效应))
* 您可能现在已经猜到了,我们还可以学习更高阶的多项式关系(例如`x[2]^3`
* 最后,只要我们确保最终激活可以对分布进行建模,我们就不必只对正态分布建模或对非正态分布使用不同的模型。
......@@ -34,7 +34,7 @@
但这并不是所有的彩虹和小猫,使用神经网络解决这些真正简单的问题也有一些弊端。 最明显的缺点是:
* 如前所述,神经网络不容易解释。
* 当具有许多功能和大量数据时,神经网络最有效。 许多简单的回归问题还不够大,无法真正从神经网络中受益。
* 当具有许多特征和大量数据时,神经网络最有效。 许多简单的回归问题还不够大,无法真正从神经网络中受益。
* 在很多情况下,传统的多元回归或树模型(例如梯度提升树)在此类问题上的表现将优于神经网络。 越复杂,就越适合神经网络。
# 将深度神经网络用于回归
......@@ -102,7 +102,7 @@ def load_data():
当我从 csv,excel 甚至是 DBMS 中读取数据时,第一步通常是将其加载到 pandas 数据框中。
标准化我们的数据很重要,这样每个功能都应具有可比的范围,并且所有这些范围都应位于激活函数的范围之内。 在这里,我使用了 Scikit-Learn 的`StandardScaler`完成此任务。
标准化我们的数据很重要,这样每个特征都应具有可比的范围,并且所有这些范围都应位于激活函数的范围之内。 在这里,我使用了 Scikit-Learn 的`StandardScaler`完成此任务。
这为我们提供了一个形状完整的数据集`(4898, 10)`。 我们的目标变量`alcohol`的百分比介于 8% 和 14.2% 之间。
......@@ -128,13 +128,13 @@ def load_data():
Keras 使用模型对象的实例来包含神经网络。 对于熟悉 scikit-learn 的人来说,这可能是相当熟悉的。 略有不同的是 Keras 模型包含一组图层。 这一组层需要由我们定义。 只需很少的代码,就可以在网络架构中实现惊人的灵活性。
Keras 当前有两个用于构建模型的 API。 在我的示例中,我将使用功能性 API。 它稍微冗长一些,但可以提供更多的灵活性。 我建议尽可能使用功能性 API。
Keras 当前有两个用于构建模型的 API。 在我的示例中,我将使用函数式 API。 它稍微冗长一些,但可以提供更多的灵活性。 我建议尽可能使用函数式 API。
我们的 MLP 将需要一个输入层,一个隐藏层和一个输出层。
# 输入层形状
由于我们已经确定了输入,因此我们知道输入矩阵的行数等于数据集中的数据元素/观测值的数量,并且列数等于变量/功能的数量。 输入矩阵的形状为`(观察数量 x 10 个特征)`。 TensorFlow 和 Keras 可以在定义数据集中元素的数量时使用`None`作为占位符,而不是定义数据集中或小批量中的确切记录数。
由于我们已经确定了输入,因此我们知道输入矩阵的行数等于数据集中的数据元素/观测值的数量,并且列数等于变量/特征的数量。 输入矩阵的形状为`(观察数量 x 10 个特征)`。 TensorFlow 和 Keras 可以在定义数据集中元素的数量时使用`None`作为占位符,而不是定义数据集中或小批量中的确切记录数。
如果看到 Keras 或 TensorFlow 模型层形状中使用了`None`维度,则它实际上表示任意维度,该维度可以采用任何正整数值。
......@@ -207,9 +207,9 @@ model.fit(x=data["train_X"], y=data["train_y"], batch_size=32, epochs=200, verbo
* `validation_data`:在这里,我们指定验证集。 在每个阶段结束时,Keras 将在验证集上测试模型,并使用损失函数和您指定的任何其他指标输出结果。 另外,您可以将`validation_split`设置为浮点值,以指定要用于验证的火车组的百分比。 这两个选项都可以正常工作,但是在数据集拆分方面,我希望讲得很明确。
* `verbose`:这有点不言而喻; 但是,值得一提。 `verbose=1`输出一个进度条,显示当前纪元的状态,在纪元结束时,Keras 将输出训练和验证损失。 也可以将`verbose`设置为 2(每个小批量输出丢失信息),将其设置为 0(使 Keras 保持静音)。
# 评估模型的性能
# 评估模型的表现
现在我们的 MLP 已经过训练,我们可以开始了解它的性能。 为此,我将对`Train``Val``Test`数据集进行预测。 相同的代码如下:
现在我们的 MLP 已经过训练,我们可以开始了解它的表现。 为此,我将对`Train``Val``Test`数据集进行预测。 相同的代码如下:
```py
print("Model Train MAE: " + str(mean_absolute_error(data["train_y"], model.predict(data["train_X"]))))
......@@ -296,7 +296,7 @@ Model Test MAE: 0.190189985043
# 保存和加载经过训练的 Keras 模型
您不太可能会训练一个深层的神经网络,然后将其应用到同一脚本中。 最有可能的是,您将需要训练网络,然后保存结构和权重,以便可以将其用于设计用于对新数据进行评分的面向生产的应用程序中。 为此,您需要能够保存和加载模型。
您不太可能会训练一个深层的神经网络,然后将其应用到同一脚本中。 最有可能的是,您将需要训练网络,然后保存结构和权重,以便可以将其用于设计用于对新数据进行评分的面向生产的应用中。 为此,您需要能够保存和加载模型。
在 Keras 中保存模型非常简单。 您可以使用模型实例的`.save()`方法将网络结构和权重保存到`hdf5`文件,如以下代码所示:
......
......@@ -11,7 +11,7 @@
# TensorBoard 的简要概述
TensorBoard 是一个基于 Web 的应用程序,可以帮助您可视化 TensorFlow 中创建的深度神经网络的指标,参数和结构。 它将帮助您更快,更轻松地调试和优化深度神经网络。
TensorBoard 是一个基于 Web 的应用,可以帮助您可视化 TensorFlow 中创建的深度神经网络的指标,参数和结构。 它将帮助您更快,更轻松地调试和优化深度神经网络。
正如您现在可能已经猜到的那样,深度神经网络可能变得相当复杂。 不幸的是,这意味着很多事情可能出错。 众所周知,我时不时地会犯一个错误,而当错误发生在一个深度神经网络内部时,该深度神经网络位于一个框架内,该框架在另一个框架上运行,在一个 GPU 上运行,很难找到这些错误。 他们。 TensorBoard 可能是您需要在其他本来很暗的房间中发现问题的手电筒。 TensorBoard 将允许您在训练网络时监视指标和参数的变化,这可以大大加快故障排除速度。
......@@ -19,7 +19,7 @@ TensorBoard 也非常适合优化。 借助 TensorBoard,您可以直观地比
# 设置 TensorBoard
TensorBoard 是一个独立的 Web 应用程序。 您将通过网络浏览器使用它。 设置需要两个步骤。 首先,我们将设置 TensorBoard 以可视化在 TensorFlow 和 Keras 中构建的网络,然后我们将设置 Keras 与 TensorBoard 共享信息。
TensorBoard 是一个独立的 Web 应用。 您将通过网络浏览器使用它。 设置需要两个步骤。 首先,我们将设置 TensorBoard 以可视化在 TensorFlow 和 Keras 中构建的网络,然后我们将设置 Keras 与 TensorBoard 共享信息。
本节介绍 TensorBoard 的设置。 接下来的内容将涉及修改 Keras 代码以与 TensorBoard 共享信息。
......@@ -69,7 +69,7 @@ tensorboard --logdir ~/ch3_tb_log --port 6006
# 引入 Keras 回调
Keras 中的回调是可以在训练过程中运行的功能。 他们可以做各种伟大的事情,例如在某个时代之后节省模型权重,记录事情,更改超参数或方便地编写 TensorBoard 日志文件。 您甚至可以创建自己的自定义回调。
Keras 中的回调是可以在训练过程中运行的函数。 他们可以做各种伟大的事情,例如在某个时代之后节省模型权重,记录事情,更改超参数或方便地编写 TensorBoard 日志文件。 您甚至可以创建自己的自定义回调。
在下一节中,我们将使用 TensorBoard 回调。 但是,我鼓励您在[这个页面](https://keras.io/callbacks)上查看 Keras 中可用的所有回调。
......@@ -108,7 +108,7 @@ def create_callbacks():
由于 TensorFlow 会自动为您计算梯度,因此很少使用。 但是,如果您要使用自定义激活或费用,它可能是出色的故障排除工具。
TensorBoard 回调可以接受用于在图像上运行神经网络或通过使用嵌入式层的其他参数。 我们将在本书的后面介绍这两个方面。 如果您对这些功能感兴趣,请访问 [TensorBoard API 文档](https://keras.io/callbacks/#tensorboard)
TensorBoard 回调可以接受用于在图像上运行神经网络或通过使用嵌入式层的其他参数。 我们将在本书的后面介绍这两个方面。 如果您对这些函数感兴趣,请访问 [TensorBoard API 文档](https://keras.io/callbacks/#tensorboard)
现在,我们只需要创建回调列表,并将`mlp``callbacks`参数匹配即可。 看起来像这样:
......
......@@ -19,11 +19,11 @@
与更传统的分类器(例如逻辑回归模型)或什至基于树的模型(例如**随机森林****梯度提升机**)相比,深度神经网络有一些不错的优点。
与回归一样,在第 2 章“使用深度学习解决回归问题”中,我们不需要选择或筛选特征。 在本章选择的问题中,有 178 个输入变量。 每个输入变量都是来自标记为`x1..x178`**脑电图****EEG**)的特定输入。 即使您是医生,也很难理解这么多功能与目标变量之间的关系。 这些功能中的某些功能很可能是不相关的,而这些变量和目标之间可能存在一些更高级别的交互,这是一个更好的机会。 如果使用传统模型,则经过功能选择步骤后,我们将获得最佳模型性能。 使用深度神经网络时不需要这样做。
与回归一样,在第 2 章“使用深度学习解决回归问题”中,我们不需要选择或筛选特征。 在本章选择的问题中,有 178 个输入变量。 每个输入变量都是来自标记为`x1..x178`**脑电图****EEG**)的特定输入。 即使您是医生,也很难理解这么多特征与目标变量之间的关系。 这些特征中的某些特征很可能是不相关的,而这些变量和目标之间可能存在一些更高级别的交互,这是一个更好的机会。 如果使用传统模型,则经过特征选择步骤后,我们将获得最佳模型表现。 使用深度神经网络时不需要这样做。
# 深度神经网络的缺点
正如我们在第 2 章“使用深度学习解决回归问题”所述,深度神经网络不容易解释。 虽然深度神经网络是出色的预测器,但要理解它们为何得出自己的预测并不容易。 需要重复的是,当任务是要了解哪些功能与目标的变化最相关时,深度神经网络并不是工作的工具。 但是,如果目标是原始预测能力,则应考虑使用深度神经网络。
正如我们在第 2 章“使用深度学习解决回归问题”所述,深度神经网络不容易解释。 虽然深度神经网络是出色的预测器,但要理解它们为何得出自己的预测并不容易。 需要重复的是,当任务是要了解哪些特征与目标的变化最相关时,深度神经网络并不是工作的工具。 但是,如果目标是原始预测能力,则应考虑使用深度神经网络。
我们还应该考虑复杂性。 深度神经网络是具有许多参数的复杂模型。 找到最佳的神经网络可能需要花费时间和实验。 并非所有问题都能确保达到如此复杂的水平。
......@@ -41,7 +41,7 @@
# 加载数据
我们可以使用以下功能加载本章中使用的数据。 它与我们在第 2 章中使用的功能非常相似,但是适用于此数据集。
我们可以使用以下函数加载本章中使用的数据。 它与我们在第 2 章中使用的函数非常相似,但是适用于此数据集。
```py
from sklearn.preprocessing import StandardScaler
......@@ -104,7 +104,7 @@ def load_data():
# 使用指标评估表现
除了`loss`函数之外,Keras 还使我们可以使用度量标准来帮助判断模型的性能。 虽然最大程度地降低损失是有好处的,但在给定`loss`函数的情况下,我们如何期望模型执行效果并不是特别明显。 度量标准并不用于训练模型,它们只是用来帮助我们了解当前状态。
除了`loss`函数之外,Keras 还使我们可以使用度量标准来帮助判断模型的表现。 虽然最大程度地降低损失是有好处的,但在给定`loss`函数的情况下,我们如何期望模型执行效果并不是特别明显。 度量标准并不用于训练模型,它们只是用来帮助我们了解当前状态。
尽管损失对我们而言并不重要,但准确性却对我们而言意义重大。 我们人类非常了解准确性。
......@@ -126,7 +126,7 @@ def binary_accuracy(y_true, y_pred):
# 输入层
和以前一样,我们的输入层需要知道数据集的维度。 我喜欢在一个函数中构建整个 Keras 模型,并允许该函数传递回已编译的模型。 现在,此函数仅接受一个参数,即功能数。 以下代码用于定义输入层:
和以前一样,我们的输入层需要知道数据集的维度。 我喜欢在一个函数中构建整个 Keras 模型,并允许该函数传递回已编译的模型。 现在,此函数仅接受一个参数,即特征数。 以下代码用于定义输入层:
```py
def build_network(input_features=None):
......@@ -153,7 +153,7 @@ def build_network(input_features=None):
# 如果我们使用的神经元太少会怎样?
想象一下,我们没有隐藏层,只有输入和输出的情况。 我们在第 1 章“深度学习的基础知识”中讨论了该架构,在此我们展示了如何无法为`XOR`函数建模。 这样的网络架构无法对数据中的任何非线性进行建模,因此无法通过网络进行建模。 每个隐藏层都为功能工程越来越复杂的交互提供了机会。
想象一下,我们没有隐藏层,只有输入和输出的情况。 我们在第 1 章“深度学习的基础知识”中讨论了该架构,在此我们展示了如何无法为`XOR`函数建模。 这样的网络架构无法对数据中的任何非线性进行建模,因此无法通过网络进行建模。 每个隐藏层都为特征工程越来越复杂的交互提供了机会。
如果选择的神经元太少,则结果可能如下:
......@@ -308,7 +308,7 @@ def create_callbacks(data):
正如您可能对其他二分类器有丰富的经验一样,我认为用几句话讨论如何创建与更传统的二分类器一起使用的一些常规指标是明智的。
Keras 功能 API 与 scikit-learn 中可能使用的 API 之间的区别是`.predict()`方法的行为。 当使用 Keras 时,对于`n`个样本中的每个,`.predict()`将返回`k`类概率的`nxk`矩阵。 对于二分类器,将只有一列,即类别 1 的类别概率。这使 Keras `.predict()`更像 scikit-learn 中的`.predict_proba()`
Keras 函数式 API 与 scikit-learn 中可能使用的 API 之间的区别是`.predict()`方法的行为。 当使用 Keras 时,对于`n`个样本中的每个,`.predict()`将返回`k`类概率的`nxk`矩阵。 对于二分类器,将只有一列,即类别 1 的类别概率。这使 Keras `.predict()`更像 scikit-learn 中的`.predict_proba()`
在计算精度,召回率或其他基于类的指标时,您需要通过选择一些操作点来转换`.predict()`输出,如以下代码所示:
......@@ -331,6 +331,6 @@ print(classification_report(data["val_y"], y_hat_val))
在本章中,我们讨论了使用深度神经网络作为二分类器。 我们花了很多时间讨论网络架构的设计选择,并提出了这样的想法,即搜索和试验是当前选择架构的最佳方法。
我们学习了如何在 Keras 中使用检查点回调来使我们能够及时返回并找到具有所需性能特征的模型版本。 然后,我们在训练的模型中创建并使用了自定义回调来衡量 ROC AUC 得分。 我们总结了如何将 Keras `.predict()`方法与`sklearn.metrics`中的传统指标结合使用。
我们学习了如何在 Keras 中使用检查点回调来使我们能够及时返回并找到具有所需表现特征的模型版本。 然后,我们在训练的模型中创建并使用了自定义回调来衡量 ROC AUC 得分。 我们总结了如何将 Keras `.predict()`方法与`sklearn.metrics`中的传统指标结合使用。
在下一章中,我们将研究多分类,我们将更多地讨论如何防止过拟合。
\ No newline at end of file
......@@ -80,7 +80,7 @@
# 载入 MNIST
对我们来说幸运的是,在 Keras 中内置了一个 MNIST 加载功能,该功能可以检索 MNIST 数据并为我们加载。 我们需要做的就是导入`keras.datasets.mnist`并使用`load_data()`方法,如以下代码所示:
对我们来说幸运的是,在 Keras 中内置了一个 MNIST 加载函数,该函数可以检索 MNIST 数据并为我们加载。 我们需要做的就是导入`keras.datasets.mnist`并使用`load_data()`方法,如以下代码所示:
```py
(train_X, train_y), (test_X, test_y) = mnist.load_data()
......@@ -153,11 +153,11 @@ Softmax 压缩所有这些逻辑回归的输出,使它们的总和为 1,从
(对于`j = 1``k`类,其中`zj / zk`是属于`k`的逻辑回归)
因此,如果将`softmax`函数放在我们先前的回归集的前面,我们将得到一组类别概率,它们合计为 1,可以用作 k 个类别中成员资格的概率。 这改变了我们的整体功能,如下所示:
因此,如果将`softmax`函数放在我们先前的回归集的前面,我们将得到一组类别概率,它们合计为 1,可以用作 k 个类别中成员资格的概率。 这改变了我们的整体函数,如下所示:
![](img/dd793fbb-380f-4811-b53e-936c412a0595.png)
先前的功能通常称为多项式逻辑回归。 它有点像一层,仅输出和神经网络。 我们不再频繁使用多项式逻辑回归。 但是,我们当然可以一直使用`softmax`函数。 对于本书中的大多数多分类问题,我们将使用`softmax`,因此值得理解。
先前的函数通常称为多项式逻辑回归。 它有点像一层,仅输出和神经网络。 我们不再频繁使用多项式逻辑回归。 但是,我们当然可以一直使用`softmax`函数。 对于本书中的大多数多分类问题,我们将使用`softmax`,因此值得理解。
如果您像我一样,并且发现所有数学知识都难以阅读,那么在代码中查看`softmax`可能会更容易。 因此,在继续操作之前,请使用以下代码段进行操作:
......@@ -346,7 +346,7 @@ def build_network(input_features=None):
# 总结
在本章中,我们实际上已经开始了解深度神经网络在进行多分类时的功能。 我们详细介绍了`softmax`函数,然后我们构建并训练了一个网络来将手写数字分为 10 个各自的类别。
在本章中,我们实际上已经开始了解深度神经网络在进行多分类时的威力。 我们详细介绍了`softmax`函数,然后我们构建并训练了一个网络来将手写数字分为 10 个各自的类别。
最后,当我们注意到模型过拟合时,我们尝试同时使用丢弃和 L2 正则化来减少模型的方差。
......
# 六、超参数优化
使用深度神经网络的最大缺点之一是它们具有许多应优化的超参数,以使网络发挥最佳性能。 在前面的每个章节中,我们都遇到但没有涵盖超参数估计的挑战。 超参数优化是一个非常重要的话题。 在大多数情况下,这是一个未解决的问题,尽管我们不能涵盖本书的全部主题,但我认为它仍然值得一章。
使用深度神经网络的最大缺点之一是它们具有许多应优化的超参数,以使网络发挥最佳表现。 在前面的每个章节中,我们都遇到但没有涵盖超参数估计的挑战。 超参数优化是一个非常重要的话题。 在大多数情况下,这是一个未解决的问题,尽管我们不能涵盖本书的全部主题,但我认为它仍然值得一章。
在本章中,我将为您提供一些我认为是选择超参数的实用建议。 可以肯定的是,由于本章是基于我自己的经验,因此本章可能会有些偏颇和偏颇。 我希望经验会有所帮助,同时也带您进一步对该主题进行调查。
......@@ -76,7 +76,7 @@
网格搜索对于深度学习并不是很实用。 除了最基本的深度神经网络,我们无法现实地探索所有可能参数的每个可能值。 使用**随机搜索**,我们从每个参数分布中随机抽样,并尝试其中的`n`,其中(`n x`每个示例训练时间)是我们愿意分配给这个问题的时间预算。
**贝叶斯优化**方法使用以前的观察结果来预测接下来要采样的超参数集。 尽管贝叶斯优化方法通常胜过蛮力技术,但目前的研究表明,与穷举方法相比,性能提升较小。 此外,由于贝叶斯方法取决于先前的经验,因此无论如何都不会令人尴尬地并行进行。
**贝叶斯优化**方法使用以前的观察结果来预测接下来要采样的超参数集。 尽管贝叶斯优化方法通常胜过蛮力技术,但目前的研究表明,与穷举方法相比,表现提升较小。 此外,由于贝叶斯方法取决于先前的经验,因此无论如何都不会令人尴尬地并行进行。
**遗传算法**是机器学习中非常有趣且活跃的研究领域。 但是,我目前的观点是,它们也不是深度神经网络参数优化的理想选择,因为它们再次依赖于先前的经验。
......@@ -86,7 +86,7 @@
使用 scikit-learn 可以轻松实现网格搜索和随机搜索。 在此示例中,我们将使用 Keras 的`KerasClassifier`类包装模型并使其与 scikit-learn API 兼容。 然后,我们将使用 scikit-learn 的`RandomSearchCV`类进行超参数搜索。
为此,我们将从稍微更改现在熟悉的模型构建功能开始。 我们将使用我们要搜索的超参数对其进行参数化,如以下代码所示:
为此,我们将从稍微更改现在熟悉的模型构建函数开始。 我们将使用我们要搜索的超参数对其进行参数化,如以下代码所示:
```py
def build_network(keep_prob=0.5, optimizer='adam'):
......@@ -165,9 +165,9 @@ tensorflow/core/common_runtime/gpu/gpu_device.cc:1120] Creating TensorFlow devic
Hyperband 是一项超参数优化技术,由 Lisha Li,Kevin Jamieson,Guilia DeSalvo,Afshin Rostamizadeh 和 Ameet Talwalker 于 2016 年在伯克利开发。 您可以在[这里](https://arxiv.org/pdf/1603.06560.pdf)阅读他们的原始论文。
想象一下,就像我们在`RandomSearchCV`中所做的那样,随机采样许多潜在的超参数集。 完成`RandomSearchCV`后,它将选择一个单一的超参数配置作为其采样的*最优值*。 Hyperband 利用这样的思想,即即使经过少量迭代,最佳的超参数配置也可能会胜过其他配置。 Hyperband 中的乐队来自土匪,指的是基于多臂土匪技术(用于优化竞争选择之间的资源分配以优化性能为目标的技术)的勘探与开发。
想象一下,就像我们在`RandomSearchCV`中所做的那样,随机采样许多潜在的超参数集。 完成`RandomSearchCV`后,它将选择一个单一的超参数配置作为其采样的*最优值*。 Hyperband 利用这样的思想,即即使经过少量迭代,最佳的超参数配置也可能会胜过其他配置。 Hyperband 中的乐队来自土匪,指的是基于多臂土匪技术(用于优化竞争选择之间的资源分配以优化表现为目标的技术)的勘探与开发。
使用 Hyperband,我们可以尝试一些可能的配置集(`n`),仅训练一次迭代。 作者将迭代一词留作多种可能的用途。 但是,我将时代作为迭代。 一旦完成第一个训练循环,就将根据性能对结果进行配置。 然后,对该列表的上半部分进行大量迭代的训练。 然后重复进行减半和剔除的过程,我们得到了一些非常小的配置集,我们将针对在搜索中定义的完整迭代次数进行训练。 与在每种可能的配置中搜索最大周期相比,此过程使我们在更短的时间内获得了*最佳*超参数集。
使用 Hyperband,我们可以尝试一些可能的配置集(`n`),仅训练一次迭代。 作者将迭代一词留作多种可能的用途。 但是,我将时代作为迭代。 一旦完成第一个训练循环,就将根据表现对结果进行配置。 然后,对该列表的上半部分进行大量迭代的训练。 然后重复进行减半和剔除的过程,我们得到了一些非常小的配置集,我们将针对在搜索中定义的完整迭代次数进行训练。 与在每种可能的配置中搜索最大周期相比,此过程使我们在更短的时间内获得了*最佳*超参数集。
在本章的 GitHub 存储库中,我在`hyperband.py`中包括了`hyperband`算法的实现。 此实现主要源自 FastML 的实现,您可以在[这个页面](http://fastml.com/tuning-hyperparams-fast-with-hyperband/)中找到。 要使用它,您需要首先实例化一个`hyperband`对象,如以下代码所示:
......
......@@ -10,7 +10,7 @@
# 卷积介绍
经过训练的卷积层由称为过滤器的许多特征检测器组成,这些特征检测器在输入图像上滑动作为移动窗口。 稍后我们将讨论过滤器内部的内容,但现在它可能是一个黑匣子。 想象一个已经训练过的过滤器。 也许该过滤器已经过训练,可以检测图像中的边缘,您可能会认为这是黑暗与明亮之间的过渡。 当它经过图像时,其输出表示它检测到的特征的存在和位置,这对于第二层过滤器很有用。 稍微扩展一下我们的思想实验,现在想象第二个卷积层中的一个过滤器,它也已经被训练过了。 也许这个新层已经学会了检测直角,其中存在由上一层找到的两个边缘。 不断地我们去; 随着我们添加图层,可以了解更多复杂的功能。 特征层次结构的概念对于卷积神经网络至关重要。 下图来自 Honglak Lee 等人的《使用卷积深度信念网络的无监督学习层次表示》[2011],非常好地说明了特征层次结构的概念:
经过训练的卷积层由称为过滤器的许多特征检测器组成,这些特征检测器在输入图像上滑动作为移动窗口。 稍后我们将讨论过滤器内部的内容,但现在它可能是一个黑匣子。 想象一个已经训练过的过滤器。 也许该过滤器已经过训练,可以检测图像中的边缘,您可能会认为这是黑暗与明亮之间的过渡。 当它经过图像时,其输出表示它检测到的特征的存在和位置,这对于第二层过滤器很有用。 稍微扩展一下我们的思想实验,现在想象第二个卷积层中的一个过滤器,它也已经被训练过了。 也许这个新层已经学会了检测直角,其中存在由上一层找到的两个边缘。 不断地我们去; 随着我们添加图层,可以了解更多复杂的特征。 特征层次结构的概念对于卷积神经网络至关重要。 下图来自 Honglak Lee 等人的《使用卷积深度信念网络的无监督学习层次表示》[2011],非常好地说明了特征层次结构的概念:
![](img/c63ca1b1-5e19-423c-8174-d62c87d452bc.png)
......@@ -67,7 +67,7 @@ Conv2D(64, kernel_size=(3,3), activation="relu", name="conv_1")
# 本地连接
过滤器由于其固定大小而着重于相邻像素之间的连通性。 这意味着他们将最强烈地学习本地特征。 当与其他过滤器以及层和非线性结合使用时,这使我们逐渐关注更大,更复杂的功能。 确实需要这种局部化特征的堆叠,这也是卷积层如此之大的关键原因。
过滤器由于其固定大小而着重于相邻像素之间的连通性。 这意味着他们将最强烈地学习本地特征。 当与其他过滤器以及层和非线性结合使用时,这使我们逐渐关注更大,更复杂的特征。 确实需要这种局部化特征的堆叠,这也是卷积层如此之大的关键原因。
# 池化层
......@@ -90,7 +90,7 @@ pool1 = MaxPooling2D(pool_size=(2, 2), name="pool_1")
# 批量标准化
批量规范化有助于我们的网络整体表现更好,学习速度更快。 批量规范化在应用程序中也很容易理解。 但是,为什么它起作用,仍然受到研究人员的争议。
批量规范化有助于我们的网络整体表现更好,学习速度更快。 批量规范化在应用中也很容易理解。 但是,为什么它起作用,仍然受到研究人员的争议。
使用批量归一化时,对于每个小批量,我们可以在每个非线性之后(或之前)对那个批量进行归一化,使其平均值为 0,单位方差。 这使每一层都可以从中学习标准化输入,从而使该层的学习效率更高。
......@@ -156,7 +156,7 @@ pool2 = MaxPooling2D(pool_size=(2, 2), name="pool_2")(batch2)
经过两轮卷积和合并后,我们的张量变得相对较小和较深。 在`pool_2`之后,输出尺寸为`(n, 6, 6, 32)`
我们希望在这些卷积层中提取此`6 x 6 x 32`张量表示的相关图像特征。 为了使用这些功能对图像进行分类,在进入最终输出层之前,我们将将该张量连接到几个完全连接的层。
我们希望在这些卷积层中提取此`6 x 6 x 32`张量表示的相关图像特征。 为了使用这些特征对图像进行分类,在进入最终输出层之前,我们将将该张量连接到几个完全连接的层。
在此示例中,我将使用 512 神经元完全连接层,256 神经元完全连接层以及最后的 10 神经元输出层。 我还将使用辍学来帮助防止过拟合,但只有一点点! 该过程的代码如下,供您参考:
......@@ -192,7 +192,7 @@ model = multi_gpu_model(model, num_gpu)
# 训练
将模型放在一起,并结合我们新的酷多 GPU 功能,我们提出了以下架构:
将模型放在一起,并结合我们新的 CUDA GPU 功能,我们提出了以下架构:
```py
......
......@@ -11,7 +11,7 @@
# 迁移学习概述
在第 7 章和“卷积神经网络”中,我们训练了约 50,000 个观测值的卷积神经网络,并且由于网络和问题的复杂性,在开始训练的短短几个时期后,我们过拟合了。 如果您还记得的话,我曾评论说我们的训练集中有 50,000 个观察结果对于计算机视觉问题不是很大。 确实如此。 计算机视觉问题喜欢数据,而我们可以提供给他们的数据越多,它们的性能就越好。
在第 7 章和“卷积神经网络”中,我们训练了约 50,000 个观测值的卷积神经网络,并且由于网络和问题的复杂性,在开始训练的短短几个时期后,我们过拟合了。 如果您还记得的话,我曾评论说我们的训练集中有 50,000 个观察结果对于计算机视觉问题不是很大。 确实如此。 计算机视觉问题喜欢数据,而我们可以提供给他们的数据越多,它们的表现就越好。
我们可能认为计算机视觉技术最先进的深度神经网络通常在称为 **ImageNet** 的数据集上进行训练。 [`ImageNet`数据集](http://www.image-net.org/)是包含 120 万张图像的 1,000 个分类器。 这还差不多! 如此庞大的数据集使研究人员能够构建真正复杂的深度神经网络,以检测复杂的特征。 当然,在 120 万张图像上训练有时具有 100 多个图层的模型的价格很高。 训练可能需要数周和数月,而不是数小时。
......@@ -49,21 +49,21 @@
# 源/目标数量和相似性的影响
直到最近,很少有人研究数据量和源/目标域相似性对迁移学习性能的影响。 但是,这是一个对迁移学习的可用性很重要的主题,也是我撰写的主题。 在我的同事撰写的[《调查数据量和域相似性对迁移学习应用程序的影响》](https://arxiv.org/pdf/1712.04008.pdf)中,对这些主题进行了一些实验。 这就是我们发现的东西。
直到最近,很少有人研究数据量和源/目标域相似性对迁移学习表现的影响。 但是,这是一个对迁移学习的可用性很重要的主题,也是我撰写的主题。 在我的同事撰写的[《调查数据量和域相似性对迁移学习应用的影响》](https://arxiv.org/pdf/1712.04008.pdf)中,对这些主题进行了一些实验。 这就是我们发现的东西。
# 更多数据总是有益的
Google 研究人员在《重新研究深度学习时代数据的不合理有效性》中进行的几次实验中,构建了一个内部数据集,其中包含 3 亿个观测值,显然比`ImageNet`大得多。 然后,他们在该数据集上训练了几种最先进的架构,从而使模型显示的数据量从 1000 万增加到 3000 万,1 亿,最后是 3 亿。 通过这样做,他们表明模型性能随用于训练的观察次数的对数线性增加,这表明在源域中,更多的数据总是有帮助。
Google 研究人员在《重新研究深度学习时代数据的不合理有效性》中进行的几次实验中,构建了一个内部数据集,其中包含 3 亿个观测值,显然比`ImageNet`大得多。 然后,他们在该数据集上训练了几种最先进的架构,从而使模型显示的数据量从 1000 万增加到 3000 万,1 亿,最后是 3 亿。 通过这样做,他们表明模型表现随用于训练的观察次数的对数线性增加,这表明在源域中,更多的数据总是有帮助。
但是目标域呢? 我们使用了一些类似于我们在迁移学习过程中可能使用的类型的数据集重复了 Google 实验,包括我们将在本章稍后使用的`Dogs versus Cats`数据集。 我们发现,在目标域中,模型的性能随用于训练的观察次数的对数线性增加,就像在源域中一样。 更多数据总是有帮助的。
但是目标域呢? 我们使用了一些类似于我们在迁移学习过程中可能使用的类型的数据集重复了 Google 实验,包括我们将在本章稍后使用的`Dogs versus Cats`数据集。 我们发现,在目标域中,模型的表现随用于训练的观察次数的对数线性增加,就像在源域中一样。 更多数据总是有帮助的。
# 源/目标域相似度
迁移学习的独特之处在于您担心源域和目标域之间的相似度。 经过训练以识别人脸的分类器可能不会轻易转移到识别各种架构的目标领域。 我们进行了源和目标尽可能不同的实验,以及源和目标域非常相似的实验。 毫不奇怪,当迁移学习应用程序中的源域和目标域非常不同时,与相似时相比,它们需要更多的数据。 它们也需要更多的微调,因为当域在视觉上非常不同时,特征提取层需要大量的学习。
迁移学习的独特之处在于您担心源域和目标域之间的相似度。 经过训练以识别人脸的分类器可能不会轻易转移到识别各种架构的目标领域。 我们进行了源和目标尽可能不同的实验,以及源和目标域非常相似的实验。 毫不奇怪,当迁移学习应用中的源域和目标域非常不同时,与相似时相比,它们需要更多的数据。 它们也需要更多的微调,因为当域在视觉上非常不同时,特征提取层需要大量的学习。
# Keras 的迁移学习
与本书中的其他示例不同,在这里我们将需要涵盖目标域问题,源域问题以及我们正在使用的网络架构。 我们将从目标域的概述开始,这是我们要解决的问题。 然后,我们将介绍网络最初经过训练的源域,并简要介绍我们将使用的网络架构。 然后,我们将在本章的其余部分中将问题联系在一起。 我们需要分别考虑两个域,因为它们的大小和相似性与网络性能密切相关。 目标和源的类型越近,结果越好。
与本书中的其他示例不同,在这里我们将需要涵盖目标域问题,源域问题以及我们正在使用的网络架构。 我们将从目标域的概述开始,这是我们要解决的问题。 然后,我们将介绍网络最初经过训练的源域,并简要介绍我们将使用的网络架构。 然后,我们将在本章的其余部分中将问题联系在一起。 我们需要分别考虑两个域,因为它们的大小和相似性与网络表现密切相关。 目标和源的类型越近,结果越好。
# 目标域概述
......@@ -81,7 +81,7 @@ Google 研究人员在《重新研究深度学习时代数据的不合理有效
我们将使用 [**Inception-V3** 网络架构](https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Szegedy_Rethinking_the_Inception_CVPR_2016_paper.pdf)。 与您到目前为止在本书中所看到的相比,Inception 架构很有趣并且非常复杂。 如果您从第 7 章,“卷积神经网络”中回想起,我们必须围绕网络架构做出的决定之一就是选择过滤器大小。 对于每一层,我们必须决定是否应使用例如`3 x 3`过滤器,而不是`5 x 5`过滤器。 当然,也许根本就不需要另一次卷积。 也许像池化之类的东西可能更合适。 因此,如果我们在每一层都做所有事情,该怎么办? 这就是开始的动机。
该架构基于一系列模块或称为**初始模块**的构建块。 在每个初始模块中,先前的激活都赋予`1 x 1`卷积,`3 x 3`卷积,`5 x 5`卷积和最大池化层。 然后将输出串联在一起。
该架构基于一系列模块或称为**初始模块**的构建块。 在每个初始模块中,先前的激活都赋予`1 x 1`卷积,`3 x 3`卷积,`5 x 5`卷积和最大池化层。 然后将输出连接在一起。
Inception-V3 网络由几个相互堆叠的 Inception 模块组成。 最后两层都完全连接,输出层是 1,000 个神经元 softmax。
......@@ -194,7 +194,7 @@ print("Step 1 Scores: Loss: " + str(scores[0]) + " Accuracy: " + str(scores[1]))
![](img/ba99854e-0291-4744-b2ed-1b099411fa0c.png)
如您所见,即使经过一个时期,网络的性能仍然非常好。 直到大约第 7 个阶段,我们都取得了非常微弱的性能提升。在第 7 个阶段,我们达到了最佳性能,导致 0.9828 的精度和 0.0547 的损失。
如您所见,即使经过一个时期,网络的表现仍然非常好。 直到大约第 7 个阶段,我们都取得了非常微弱的表现提升。在第 7 个阶段,我们达到了最佳表现,导致 0.9828 的精度和 0.0547 的损失。
# 训练(微调)
......@@ -241,6 +241,6 @@ print("Step 2 Scores: Loss: " + str(scores[0]) + " Accuracy: " + str(scores[1]))
# 总结
在本章中,我们介绍了迁移学习,并演示了如何使用在源域上进行预训练的网络如何极大地缩短训练时间,并最终改善我们的深度神经网络的性能。 我希望您喜欢这项技术,它是我的最爱之一,因为它非常实用,而且我通常会从中获得很好的效果。
在本章中,我们介绍了迁移学习,并演示了如何使用在源域上进行预训练的网络如何极大地缩短训练时间,并最终改善我们的深度神经网络的表现。 我希望您喜欢这项技术,它是我的最爱之一,因为它非常实用,而且我通常会从中获得很好的效果。
在下一章中,我们将从计算机视觉过渡到可以记住先前输入的网络,使它们成为预测序列中下一项的理想选择。
\ No newline at end of file
......@@ -77,7 +77,7 @@ LSTM 的另一个关键特性是内部自循环,使设备可以长期积累信
该门的输出(将在 0 和 1 之间)逐点乘以`C[t-1]`。 这允许门调节从`C[t-1]``C[t]`的信息流。
下一个门,即输入门`i[t]`功能候选`C[t]`结合使用。 候选`C[t]`学习可以添加到内存状态的向量。 输入门了解总线`C`中的哪些值得到更新。 下式说明`i[t]`和候选`C[t]`
下一个门,即输入门`i[t]`函数候选`C[t]`结合使用。 候选`C[t]`学习可以添加到内存状态的向量。 输入门了解总线`C`中的哪些值得到更新。 下式说明`i[t]`和候选`C[t]`
![](img/ec04eb9a-48f5-45fd-af5c-812bf60c1288.png)
......@@ -143,7 +143,7 @@ LSTM 的另一个关键特性是内部自循环,使设备可以长期积累信
# ARIMA 和 ARIMAX 预测
值得一提的是**自回归综合移动平均值****ARIMA**)模型,因为它们传统上用于时间序列预测。 虽然我显然是深度神经网络的忠实拥护者(事实上,我写过关于它们的书),但我建议从 ARIMA 开始并逐步进行深度学习。 在许多情况下,ARIMA 的性能将优于 LSTM。 当数据稀疏时尤其如此。
值得一提的是**自回归综合移动平均值****ARIMA**)模型,因为它们传统上用于时间序列预测。 虽然我显然是深度神经网络的忠实拥护者(事实上,我写过关于它们的书),但我建议从 ARIMA 开始并逐步进行深度学习。 在许多情况下,ARIMA 的表现将优于 LSTM。 当数据稀疏时尤其如此。
从可能可行的最简单模型开始。 有时这将是一个深层的神经网络,但通常情况会更简单一些,例如线性回归或 ARIMA 模型。 该模型的复杂性应通过其提供的提升来证明,通常越简单越好。 尽管整本书中多次重申,但在时间序列预测中,这一说法比其他任何话题都更为真实。
......@@ -151,7 +151,7 @@ ARIMA 模型是三个部分的组合。 AR,即自回归部分,是根据自
ARIMA 模型在 R 的`auto.arima()`和预测包中实现得很好,这可能是使用 R 语言的唯一很好的理由之一。
ARIMAX 模型允许在时间序列模型中包含一个或多个协变量。 您问这种情况下的协变量是多少? 这是一个附加时间序列,也与因变量相关,可用于进一步改善预测性能
ARIMAX 模型允许在时间序列模型中包含一个或多个协变量。 您问这种情况下的协变量是多少? 这是一个附加时间序列,也与因变量相关,可用于进一步改善预测表现
交易员的常见做法是尝试通过使用另一种商品的一个或多个滞后以及我们预测的商品的自回归部分来预测某些商品的价值。 在这种情况下,ARIMAX 模型将很有用。
......@@ -243,7 +243,7 @@ def scale_data(df, scaler=None):
return scaler, scaled_df
```
请注意,此功能可以选择使用已经适合的缩放器。 这使我们能够将火车定标器应用到我们的测试仪上。
请注意,此函数可以选择使用已经适合的缩放器。 这使我们能够将火车定标器应用到我们的测试仪上。
# 创建滞后的训练集
......@@ -285,9 +285,9 @@ Keras 期望 LSTM 的输入是一个三维张量,看起来像:
第二维对应于使用`lag_dataframe`函数时我们选择的滞后次数。 这是我们要给 Keras 做出预测的时间步数。
第三维是该时间步中存在的特征数。 在我们的示例中,我们将使用一个,因为每个时间步只有一个功能,即该时间步的比特币价格。
第三维是该时间步中存在的特征数。 在我们的示例中,我们将使用一个,因为每个时间步只有一个特征,即该时间步的比特币价格。
在继续阅读之前,请仔细考虑此处定义三维矩阵给您的功能。 我们绝对可以将数百个其他时间序列作为预测该时间序列的功能。 通过这样做以及使用 LSTM,我们可以免费获得这些功能之间的功能工程。 正是这种功能使 LSTM 在金融领域变得如此令人兴奋。
在继续阅读之前,请仔细考虑此处定义三维矩阵给您的威力。 我们绝对可以将数百个其他时间序列作为预测该时间序列的特征。 通过这样做以及使用 LSTM,我们可以免费获得这些特征之间的特征工程。 正是这种功能使 LSTM 在金融领域变得如此令人兴奋。
对于当前的问题,我们将需要将二维矩阵转换为三维矩阵。 为此,我们将使用 NumPy 的便捷`reshape`函数,如以下代码所示:
......@@ -298,7 +298,7 @@ X_test = np.reshape(X_test.values, (X_test.shape[0], X_test.shape[1], 1))
# 数据准备
在此示例中,我们做了很多转换。 在继续进行训练之前,我认为最好将两者结合起来。 如此处所示,我们将使用另一个功能将所有这些步骤联系在一起:
在此示例中,我们做了很多转换。 在继续进行训练之前,我认为最好将两者结合起来。 如此处所示,我们将使用另一个函数将所有这些步骤联系在一起:
```py
def prep_data(df_train, df_test, lags):
......@@ -320,7 +320,7 @@ def prep_data(df_train, df_test, lags):
return X_train, X_test, y_train, y_test
```
功能采用训练和测试数据帧,并应用差分,缩放和滞后代码。 然后,将这些数据帧重新调整为我们熟悉的`X``y`张量,以进行训练和测试。
函数采用训练和测试数据帧,并应用差分,缩放和滞后代码。 然后,将这些数据帧重新调整为我们熟悉的`X``y`张量,以进行训练和测试。
现在,我们可以使用几行代码将这些转换粘合在一起,从而从加载数据到准备进行训练和测试,它们可以:
......@@ -403,17 +403,17 @@ model.save("lstm_model.h5")
![](img/e866b9d4-0486-4a35-8373-913744c3c687.png)
我们拥有一个合适的网络,似乎已经学到了一些东西。 现在,我们可以对比特币的价格流做出某种预测。 如果我们能做好,我们所有人都会非常富有。 在去买那栋豪宅之前,我们可能应该测量一下模型的性能
我们拥有一个合适的网络,似乎已经学到了一些东西。 现在,我们可以对比特币的价格流做出某种预测。 如果我们能做好,我们所有人都会非常富有。 在去买那栋豪宅之前,我们可能应该测量一下模型的表现
财务模型的最终检验是这个问题:“您愿意在上面花钱吗?”很难回答这个问题,因为在时间序列问题中衡量性能可能具有挑战性。
财务模型的最终检验是这个问题:“您愿意在上面花钱吗?”很难回答这个问题,因为在时间序列问题中衡量表现可能具有挑战性。
一种衡量性能的非常简单的方法是使用均方根误差来评估`y_test``X_test`预测之间的差异。 我们最肯定可以做到这一点,如以下代码所示:
一种衡量表现的非常简单的方法是使用均方根误差来评估`y_test``X_test`预测之间的差异。 我们最肯定可以做到这一点,如以下代码所示:
```py
RMSE = 0.0801932157201
```
0.08 是一个好分数吗? 让我们通过比较我们的预测与 6 月份比特币流量的实际值,开始对商品的调查。 这样做可能会使我们对模型的性能有直观的了解,这是我始终建议的一种做法:
0.08 是一个好分数吗? 让我们通过比较我们的预测与 6 月份比特币流量的实际值,开始对商品的调查。 这样做可能会使我们对模型的表现有直观的了解,这是我始终建议的一种做法:
![](img/92af7dd8-91fc-410a-bfc0-bbb0e36d4d6a.png)
......@@ -421,9 +421,9 @@ RMSE = 0.0801932157201
考虑到我们的预测,即仅给出比特币的先前价值,该模型就可以解释尽可能多的比特币价格。 我们可能在建模时间序列的自回归部分方面做得相当不错。 但是,可能有许多不同的外部因素影响比特币的价格。 美元的价值,其他市场的动向,也许最重要的是,围绕比特币的嗡嗡声或信息流通,都可能在美元的价格中发挥重要作用。
这就是 LSTM 用于时间序列预测的功能真正发挥作用的地方。 通过添加附加的输入功能,所有这些信息都可以在某种程度上轻松地添加到模型中,希望可以解释越来越多的整个图片。
这就是 LSTM 用于时间序列预测的功能真正发挥作用的地方。 通过添加附加的输入特征,所有这些信息都可以在某种程度上轻松地添加到模型中,希望可以解释越来越多的整个图片。
但是,让我再破一次您的希望。 对性能进行更彻底的调查还将包括考虑模型相对于某些幼稚模型所提供的提升。 此简单模型的典型选择可能包括称为**随机游走**模型,指数平滑模型的模型,或者可能使用天真的方法,例如使用上一个时间步长作为当前时间步长的预测。 如下图所示:
但是,让我再破一次您的希望。 对表现进行更彻底的调查还将包括考虑模型相对于某些幼稚模型所提供的提升。 此简单模型的典型选择可能包括称为**随机游走**模型,指数平滑模型的模型,或者可能使用朴素的方法,例如使用上一个时间步长作为当前时间步长的预测。 如下图所示:
![](img/afab68ad-33ef-49a9-8444-a4b7eeed2d8d.png)
......
......@@ -17,7 +17,7 @@ NLP 领域广阔而复杂。 从技术上讲,人类语言与计算机科学之
从计算机科学的起源开始,我们就对 NLP 着迷,因为它是通向强大人工智能的门户。 1950 年,艾伦·图灵(Alan Turing)提出了图灵测试,其中涉及一台计算机,它很好地模仿了一个人,使其与另一个人无法区分,以此作为机器智能的度量标准。 从那时起,我们一直在寻找帮助机器理解人类语言的聪明方法。 在此过程中,我们开发了语音到文本的转录,人类语言之间的自动翻译,文档的自动汇总,主题建模,命名实体标识以及各种其他用例。
随着我们对 NLP 的了解不断增长,我们发现 AI 应用在日常生活中变得越来越普遍。 聊天机器人作为客户服务应用程序已变得司空见惯,最近,它们已成为我们的个人数字助理。 在撰写本文时,我可以要求 Alexa 在我的购物清单中添加一些内容或演奏一些流畅的爵士乐。 自然语言处理以一种非常有趣和强大的方式将人类连接到计算机。
随着我们对 NLP 的了解不断增长,我们发现 AI 应用在日常生活中变得越来越普遍。 聊天机器人作为客户服务应用已变得司空见惯,最近,它们已成为我们的个人数字助理。 在撰写本文时,我可以要求 Alexa 在我的购物清单中添加一些内容或演奏一些流畅的爵士乐。 自然语言处理以一种非常有趣和强大的方式将人类连接到计算机。
在本章中,我将专注于理解人类语言,然后使用这种理解进行分类。 我实际上将进行两个分类案例研究,一个涉及语义分析,另一个涉及文档分类。 这两个案例研究为深度学习的应用提供了巨大的机会,而且它们确实非常相似。
......@@ -29,7 +29,7 @@ NLP 领域广阔而复杂。 从技术上讲,人类语言与计算机科学之
要成功解决此类问题,需要一个好的数据集。 虽然我们当然可以在整个互联网上找到大量的人类对话,但其中大多数没有标签。 查找带标签的病例更具挑战性。 解决此问题的早期尝试是收集包含表情符号的 Twitter 数据。 如果一条推文中包含:),则认为该推文是肯定的。 这成为 Jimmy Lin 和 Alek Kolcz 在 Twitter 上的[大规模机器学习中引用的知名表情符号技巧。](https://www.semanticscholar.org/paper/Large-scale-machine-learning-at-twitter-Lin-Kolcz/d192c32acab207b89fb11df88ef79c6ce5a69411)
这种类型的分类器的大多数业务应用程序都是二进制的,我们尝试在其中预测客户是否满意。 但是,那当然不是对这种语言模型的限制。 只要我们有用于此类事物的标签,我们就可以为其他音调建模。 我们甚至可能尝试衡量某人的声音或语言中的焦虑或困扰; 但是,解决音频输入超出了本章的范围。
这种类型的分类器的大多数业务应用都是二进制的,我们尝试在其中预测客户是否满意。 但是,那当然不是对这种语言模型的限制。 只要我们有用于此类事物的标签,我们就可以为其他音调建模。 我们甚至可能尝试衡量某人的声音或语言中的焦虑或困扰; 但是,解决音频输入超出了本章的范围。
进一步挖掘数据的尝试包括使用与正面和负面电影评论相关的语言以及与在线购物产品评论相关的语言。 这些都是很好的方法。 但是,在使用这些类型的数据源对来自不同域的文本进行分类时,应格外小心。 您可能会想到,电影评论或在线购买中使用的语言可能与 IT 帮助台客户支持电话中使用的语言完全不同。
......@@ -64,7 +64,7 @@ NLP 领域广阔而复杂。 从技术上讲,人类语言与计算机科学之
**词袋****BoW**)模型是 NLP 模型,实际上忽略了句子结构和单词放置。 在“单词袋”模型中,我们将每个文档视为单词袋。 很容易想到这一点。 每个文档都是一个包含大量单词的容器。 我们忽略句子,结构以及哪个词排在前或后。 我们对文档中包含“非常”,“很好”和“不好”这两个词的事实感到关注,但是我们并不真正在意“好”而不是“坏”。
词袋模型很简单,需要相对较少的数据,并且考虑到该模型的天真性,其运行效果非常好。
词袋模型很简单,需要相对较少的数据,并且考虑到该模型的朴素性,其运行效果非常好。
注意,这里使用模型表示表示。 我并不是在特定意义上指深度学习模型或机器学习模型。 相反,在这种情况下,模型是表示文本的一种方式。
......@@ -180,7 +180,7 @@ array([ 5.81600726e-01, 3.07168198e+00, 3.73339128e+00,
# 通过预测学习单词嵌入
单词嵌入是通过使用专门为该任务构建的神经网络来计算的。 我将在这里介绍该网络的概述。 一旦计算了某些语料库的词嵌入,它们便可以轻松地重用于其他应用程序,因此使该技术成为迁移学习的候选者,类似于我们在第 8 章“使用预先训练的 CNN 的迁移学习”中介绍的技术。
单词嵌入是通过使用专门为该任务构建的神经网络来计算的。 我将在这里介绍该网络的概述。 一旦计算了某些语料库的词嵌入,它们便可以轻松地重用于其他应用,因此使该技术成为迁移学习的候选者,类似于我们在第 8 章“使用预先训练的 CNN 的迁移学习”中介绍的技术。
当我们完成了对该词嵌入网络的训练后,我们网络中单个隐藏层的权重将成为我们词嵌入的查找表。 对于词汇表中的每个单词,我们将学习该单词的向量。
......@@ -218,7 +218,7 @@ Le 和 Mikolov 在[《句子和文档的分布式表示》](https://arxiv.org/ab
# Keras 嵌入层
**Keras 嵌入层**允许我们学习输入词的向量空间表示,就像我们在训练模型时在`word2vec`中所做的那样。 使用功能性 API,Keras 嵌入层始终是网络中的第二层,紧随输入层之后。
**Keras 嵌入层**允许我们学习输入词的向量空间表示,就像我们在训练模型时在`word2vec`中所做的那样。 使用函数式 API,Keras 嵌入层始终是网络中的第二层,紧随输入层之后。
嵌入层需要以下三个参数:
......@@ -242,7 +242,7 @@ Embedding(input_dim=10000, output_dim=128, input_length=10)
# 用于自然语言处理的一维 CNN
回顾第 7 章,“从头开始训练 CNN”时,我们使用了卷积在图像区域上滑动窗口以学习复杂的视觉特征。 这使我们能够学习重要的局部视觉功能,而不管这些功能在图片中的位置,然后随着我们的网络越来越深入,逐步地学习越来越复杂的功能。 我们通常在 2D 或 3D 图像上使用`3 x 3``5 x 5`过滤器。 如果您对卷积层及其工作原理的理解感到生疏,则可能需要阅读第 7 章“从头开始训练 CNN”。
回顾第 7 章,“从头开始训练 CNN”时,我们使用了卷积在图像区域上滑动窗口以学习复杂的视觉特征。 这使我们能够学习重要的局部视觉特征,而不管这些特征在图片中的位置,然后随着我们的网络越来越深入,逐步地学习越来越复杂的特征。 我们通常在 2D 或 3D 图像上使用`3 x 3``5 x 5`过滤器。 如果您对卷积层及其工作原理的理解感到生疏,则可能需要阅读第 7 章“从头开始训练 CNN”。
事实证明,我们可以对一系列单词使用相同的策略。 在这里,我们的 2D 矩阵是嵌入层的输出。 每行代表一个单词,并且该行中的所有元素都是其单词向量。 继续前面的示例,我们将有一个 10 x 128 的向量,其中连续有 10 个单词,每个单词都由 128 个元素的向量空间表示。 我们当然可以在这些单词上滑动过滤器。
......@@ -254,7 +254,7 @@ Embedding(input_dim=10000, output_dim=128, input_length=10)
由于我已经提出了两种可行的文档分类方法,因此本章将包含两个单独的文档分类示例。 两者都将使用嵌入层。 一个将使用 LSTM,另一个将使用 CNN。
我们还将比较学习嵌入层与从其他人的权重开始采用迁移学习方法之间的性能
我们还将比较学习嵌入层与从其他人的权重开始采用迁移学习方法之间的表现
这两个示例的代码都可以在本书的 Git 存储库中的`Chapter10`文件夹中找到。 某些数据和 GloVe 向量将需要分别下载。 有关说明,请参见代码中的注释。
......@@ -309,7 +309,7 @@ data = pad_sequences(data)
在上一章中,我们使用时间序列中的一组滞后训练了 LSTM。 在这里,我们的滞后实际上是序列中的单词。 我们将使用这些词来预测审阅者的情绪。 为了从单词序列到考虑这些单词的语义值的输入向量,我们可以使用嵌入层。
使用 Keras 功能 API,嵌入层始终是网络中输入层之后的第二层。 让我们看一下这两层如何结合在一起:
使用 Keras 函数式 API,嵌入层始终是网络中输入层之后的第二层。 让我们看一下这两层如何结合在一起:
```py
input = Input(shape=(sequence_length,), name="Input")
......@@ -390,9 +390,9 @@ model.fit(x=data["X_train"], y=data["y_train"],
callbacks=callbacks)
```
像这样将我所有的训练参数和数据保存在一个字典中,实际上只是一个样式问题,而与功能无关。 您可能希望单独处理所有事情。 我喜欢对所有内容使用字典,因为它使我无法来回传递大量参数。
像这样将我所有的训练参数和数据保存在一个字典中,实际上只是一个样式问题,而与函数无关。 您可能希望单独处理所有事情。 我喜欢对所有内容使用字典,因为它使我无法来回传递大量参数。
由于我们使用的是无状态 LSTM,因此我们将在每个批次中重置单元存储器。 我的信念是,我们可以在不损失任何罚款的情况下重置文档之间的单元状态,因此批量大小实际上与性能有关。 我在这里使用了 32 个观察批,但是只要 GPU 内存允许,128 个观察批会产生相似的结果,并且性能会有所提高。
由于我们使用的是无状态 LSTM,因此我们将在每个批次中重置单元存储器。 我的信念是,我们可以在不损失任何罚款的情况下重置文档之间的单元状态,因此批量大小实际上与表现有关。 我在这里使用了 32 个观察批,但是只要 GPU 内存允许,128 个观察批会产生相似的结果,并且表现会有所提高。
# 表现
......@@ -416,7 +416,7 @@ model.fit(x=data["X_train"], y=data["y_train"],
当使用这样的文本文档时,可能需要很多平凡的代码才能使您到达想要的位置。 我将这个示例作为解决问题的一种方式。 一旦了解了这里发生的事情,就可以在将来的问题中重用其中的大部分内容并缩短开发时间,因此值得考虑。
以下功能将进入 20 个新闻组文本所在的顶级目录。 在该目录中,将有 20 个单独的目录,每个目录都有文件。 每个文件都是新闻组帖子:
以下函数将进入 20 个新闻组文本所在的顶级目录。 在该目录中,将有 20 个单独的目录,每个目录都有文件。 每个文件都是新闻组帖子:
```py
def load_data(text_data_dir, vocab_size, sequence_length, validation_split=0.2):
......@@ -484,7 +484,7 @@ def tokenize_text(data):
在这里,我们获取该文本列表,并使用`keras.preprocessing.text.Tokenizer`将其标记化。 之后,我们将它们填充为相等的长度。 最后,我们将数字标签转换为`one_hot`格式,就像 Keras 在其他多分类问题中一样。
我们几乎完成了数据处理。 但是,最后,我们需要获取文本和标签,然后将数据随机分成训练,验证和测试集,如以下代码所示。 我没有太多数据需要处理,因此我将在此处选择`test``val`。 如果样本太小,可能无法很好地理解实际模型的性能,因此在执行此操作时要格外小心:
我们几乎完成了数据处理。 但是,最后,我们需要获取文本和标签,然后将数据随机分成训练,验证和测试集,如以下代码所示。 我没有太多数据需要处理,因此我将在此处选择`test``val`。 如果样本太小,可能无法很好地理解实际模型的表现,因此在执行此操作时要格外小心:
```py
def train_val_test_split(data):
......
......@@ -54,7 +54,7 @@
![](img/2a32ed66-4641-4bbf-9f24-77083ee3e768.png)
尽管此示例涵盖了机器翻译,但是序列到序列学习的其他应用程序却以相同的方式工作。
尽管此示例涵盖了机器翻译,但是序列到序列学习的其他应用却以相同的方式工作。
# 字符与文本
......@@ -84,7 +84,7 @@
# 翻译指标
知道翻译是否良好很难。 机器翻译质量的通用度量标准称为**双语评估研究****BLEU**),它最初是由 Papineni 等人在[《BLEU:一种自动评估机器翻译的方法》](http://aclweb.org/anthology/P/P02/P02-1040.pdf)中创建的。 BLEU 是基于 ngram 的分类精度的改进应用程序。 如果您想使用 BLEU 来衡量翻译质量,TensorFlow 团队已经发布了一个脚本,该脚本可以根据给定的地面真实翻译和机器预测翻译的语料来计算 BLEU 分数。 您可以在[这里](https://github.com/tensorflow/nmt/blob/master/nmt/scripts/bleu.py)找到该脚本。
知道翻译是否良好很难。 机器翻译质量的通用度量标准称为**双语评估研究****BLEU**),它最初是由 Papineni 等人在[《BLEU:一种自动评估机器翻译的方法》](http://aclweb.org/anthology/P/P02/P02-1040.pdf)中创建的。 BLEU 是基于 ngram 的分类精度的改进应用。 如果您想使用 BLEU 来衡量翻译质量,TensorFlow 团队已经发布了一个脚本,该脚本可以根据给定的地面真实翻译和机器预测翻译的语料来计算 BLEU 分数。 您可以在[这里](https://github.com/tensorflow/nmt/blob/master/nmt/scripts/bleu.py)找到该脚本。
# 机器翻译
......@@ -179,7 +179,7 @@ def load_data(num_samples=50000, start_char='\t', end_char='\n', data_path='data
# 单热编码
在此功能中,我们将使用刚刚构建的字典,并对每个短语的文本进行热编码。
在此函数中,我们将使用刚刚构建的字典,并对每个短语的文本进行热编码。
一旦完成,我们将剩下三个字典。 它们每个的尺寸为`[文本数 * 最大序列长度 * 标记]`。 如果您停顿一下,回想一下第 10 章“使用单词嵌入从零开始训练 LSTM”的更简单的时间,您会发现这确实与我们在其他 NLP 模型中使用的相同,我们在输入端完成它。 我们将使用以下代码定义单热编码:
......@@ -587,9 +587,9 @@ while not stop_condition:
# 总结
在本章中,我们介绍了序列到序列模型的基础知识,包括它们如何工作以及如何使用它们。 希望我们已经向您展示了一个功能强大的工具,可用于机器翻译,问题解答和聊天应用程序
在本章中,我们介绍了序列到序列模型的基础知识,包括它们如何工作以及如何使用它们。 希望我们已经向您展示了一个功能强大的工具,可用于机器翻译,问题解答和聊天应用。
如果您已经做到了,那就好。 您已经看到了很多深度学习的应用程序,并且发现自己正处于深层神经网络应用程序的最先进的钟形曲线的右边。
如果您已经做到了,那就好。 您已经看到了很多深度学习的应用,并且发现自己正处于深层神经网络应用的最先进的钟形曲线的右边。
在下一章中,我将向您展示另一个高级主题的示例,即深度强化学习或深度 Q 学习,并向您展示如何实现自己的深度 Q 网络。
......
# 十二、深度强化学习
在本章中,我们将以略有不同的方式使用深度神经网络。 我们将要构建一个智能代理,而不是预测一个类的成员,估算一个值,甚至生成一个序列。 尽管机器学习和人工智能这两个术语经常互换使用,但在本章中,我们将讨论人工智能作为一种可以感知其环境的智能代理,并采取步骤在该环境中实现某些目标。
在本章中,我们将以略有不同的方式使用深度神经网络。 我们将要构建一个智能体,而不是预测一个类的成员,估算一个值,甚至生成一个序列。 尽管机器学习和人工智能这两个术语经常互换使用,但在本章中,我们将讨论人工智能作为一种可以感知其环境的智能体,并采取步骤在该环境中实现某些目标。
想象一个可以玩象棋或围棋之类策略游戏的特工。 构建神经网络来解决此类游戏的一种非常幼稚的方法可能是使用一种网络架构,在该架构中,我们对每个可能的棋盘/棋子组合进行热编码,然后预测每个可能的下一个动作。 尽管该网络庞大而复杂,但可能做得并不好。 要很好地玩国际象棋,您不仅要考虑下一步,而且还要考虑接下来的步伐。 在不确定的情况下,我们的智能代理将需要考虑给定未来行动的最佳下一步行动。
想象一个可以玩象棋或围棋之类策略游戏的特工。 构建神经网络来解决此类游戏的一种非常幼稚的方法可能是使用一种网络架构,在该架构中,我们对每个可能的棋盘/棋子组合进行热编码,然后预测每个可能的下一个动作。 尽管该网络庞大而复杂,但可能做得并不好。 要很好地玩国际象棋,您不仅要考虑下一步,而且还要考虑接下来的步伐。 在不确定的情况下,我们的智能将需要考虑给定未来行动的最佳下一步行动。
这是一个令人兴奋的领域。 正是在智能代理领域,研究人员才朝着人工智能或强大的 AI 迈进,这是创建可以执行人类任何智力任务的智能代理的崇高目标。 强 AI 的概念通常与弱 AI 形成对比,弱 AI 是解决某些单个任务或应用程序的能力。
这是一个令人兴奋的领域。 正是在智能体领域,研究人员才朝着人工智能或强大的 AI 迈进,这是创建可以执行人类任何智力任务的智能体的崇高目标。 强 AI 的概念通常与弱 AI 形成对比,弱 AI 是解决某些单个任务或应用的能力。
对于作者(我)和读者(您)而言,本章将是一个挑战,因为强化学习理应拥有自己的书,并且需要总结在数学,心理学和计算机科学方面所做的工作。 因此,请原谅快速参考处理,并知道我在为您提供足够的信息,而在接下来的部分中将不多说。
强化学习,马尔可夫决策过程和 Q 学习是智能代理的基础,我们接下来将讨论这些内容。
强化学习,马尔可夫决策过程和 Q 学习是智能的基础,我们接下来将讨论这些内容。
我们将在本章中讨论以下主题:
......@@ -18,11 +18,11 @@
# 强化学习概述
强化学习基于智能代理的概念。 代理通过观察某种状态然后采取行动来与其环境进行交互。 当代理采取行动在状态之间移动时,它会以奖励信号的形式接收有关其行动良好性的反馈。 这个奖励信号是强化学习中的强化。 这是一个反馈循环,代理可以使用它来学习其选择的优势。 当然,奖励可以是正面的,也可以是负面的(惩罚)。
强化学习基于智能体的概念。 智能体通过观察某种状态然后采取行动来与其环境进行交互。 当智能体采取行动在状态之间移动时,它会以奖励信号的形式接收有关其行动良好性的反馈。 这个奖励信号是强化学习中的强化。 这是一个反馈循环,智能体可以使用它来学习其选择的优势。 当然,奖励可以是正面的,也可以是负面的(惩罚)。
想象一下,无人驾驶汽车是我们正在制造的代理商。 在行驶过程中,它不断收到动作的奖励信号。 留在车道内可能会产生积极的报酬,而在行人上奔跑可能会给代理商带来非常消极的报酬。 当面临选择留在行人或撞到行人的选择时,代理商将希望学会以避开行人为代价,避开行人,损失车道线奖励,以避免更大的行人碰撞惩罚。
想象一下,无人驾驶汽车是我们正在制造的智能体。 在行驶过程中,它不断收到动作的奖励信号。 留在车道内可能会产生积极的报酬,而在行人上奔跑可能会给智能体带来非常消极的报酬。 当面临选择留在行人或撞到行人的选择时,智能体将希望学会以避开行人为代价,避开行人,损失车道线奖励,以避免更大的行人碰撞惩罚。
强化学习概念的核心是状态,行为和奖励的概念。 我已经讨论过奖励,所以让我们谈谈行动和状态。 动作是代理在观察到某种状态时可以执行的操作。 如果我们的特工正在玩一个简单的棋盘游戏,那么该动作将由该特工轮到它来做。 然后转弯就是座席的状态。 为了解决这些问题,我们将在这里着眼于一个代理可以采取的行动始终是有限的和离散的。 下图说明了此概念:
强化学习概念的核心是状态,行为和奖励的概念。 我已经讨论过奖励,所以让我们谈谈行动和状态。 动作是智能体在观察到某种状态时可以执行的操作。 如果我们的特工正在玩一个简单的棋盘游戏,那么该动作将由该特工轮到它来做。 然后转弯就是座席的状态。 为了解决这些问题,我们将在这里着眼于一个智能体可以采取的行动始终是有限的和离散的。 下图说明了此概念:
![](img/dea6219b-2da7-405e-877e-c72c52b20210.png)
......@@ -30,7 +30,7 @@
![](img/e39144a7-9a97-4e55-8500-6f6a64fc8537.png)
动作会在原始状态`s`和下一个状态`s'`代理之间进行转换,代理会在其中获得一些奖励`r`。 代理选择动作的方式称为**代理策略**,通常称为`pi`
动作会在原始状态`s`和下一个状态`s'`智能体之间进行转换,智能体会在其中获得一些奖励`r`。 智能体选择动作的方式称为**智能体策略**,通常称为`pi`
强化学习的目的是找到一系列动作,使行动者从一个州到另一个州,并获得尽可能多的报酬。
......@@ -46,7 +46,7 @@
一旦我们有了确定每个状态要采取的操作的策略函数`pi`,MDP 就解决了,成为了马尔可夫链。
好消息是,有一个警告就完全有可能完美解决 MDP。 需要注意的是,必须知道 MDP 的所有回报和概率。 事实证明,这种警告相当重要,因为在大多数情况下,由于代理人的环境混乱或至少不确定,因此代理人不知道所有的回报和状态更改概率。
好消息是,有一个警告就完全有可能完美解决 MDP。 需要注意的是,必须知道 MDP 的所有回报和概率。 事实证明,这种警告相当重要,因为在大多数情况下,由于智能体的环境混乱或至少不确定,因此智能体不知道所有的回报和状态更改概率。
# Q 学习
......@@ -54,19 +54,19 @@
![](img/c0927993-35eb-4977-a4bc-ccd338f9fc95.png)
对于某些状态`s`以及动作`a`,它会根据状态为该动作生成奖励。 如果我们知道环境带来的所有回报,那么我们就可以遍历`Q`并选择能够为我们带来最大回报的行动。 但是,正如我们在上一节中提到的那样,我们的代理人不知道所有的奖励状态和状态概率。 因此,我们的`Q`函数需要尝试近似奖励。
对于某些状态`s`以及动作`a`,它会根据状态为该动作生成奖励。 如果我们知道环境带来的所有回报,那么我们就可以遍历`Q`并选择能够为我们带来最大回报的行动。 但是,正如我们在上一节中提到的那样,我们的智能体不知道所有的奖励状态和状态概率。 因此,我们的`Q`函数需要尝试近似奖励。
我们可以使用称为 **Bellman 公式**的递归定义的`Q`函数来近似此理想的`Q`函数:
![](img/92cb692e-ef61-427e-bd69-0e698f08f007.png)
在这种情况下, `r[0]`是下一个动作的奖励,然后在下一个动作上(递归地)递归使用`Q`函数确定该行动的未来奖励。 为此,我们将`γ`作为相对于当前奖励的未来奖励的折扣。 只要伽玛小于 1,它就不会使我们的奖励序列变得无限大。 更明显地,与当前状态下的相同奖励相比,未来状态下的奖励的值要低。 具体来说,如果有人今天给您 100 美元,明天给您 100 美元,您应该立即拿走这笔钱,因为明天不确定。
在这种情况下, `r[0]`是下一个动作的奖励,然后在下一个动作上(递归地)递归使用`Q`函数确定该行动的未来奖励。 为此,我们将`γ`作为相对于当前奖励的未来奖励的折扣。 只要伽玛小于 1,它就不会使我们的奖励序列变得无限大。 更明显地,与当前状态下的相同奖励相比,未来状态下的奖励的值要低。 具体来说,如果有人今天给您 100 美元,明天给您 100 美元,您应该立即拿走这笔钱,因为明天不确定。
如果我们尽最大的努力让我们的代理经历每种可能的状态转换,并使用此函数来估计我们的报酬,我们将得出我们试图近似的理想`Q`函数。
如果我们尽最大的努力让我们的智能体经历每种可能的状态转换,并使用此函数来估计我们的报酬,我们将得出我们试图近似的理想`Q`函数。
# 无限状态空间
`Q`函数的讨论使我们陷入了传统强化学习的重要局限。 您可能还记得,它假设状态空间是有限且离散的。 不幸的是,这不是我们生活的世界,也不是我们的代理商在很多时候会发现自己的环境。 考虑一个可以打乒乓球的经纪人。 状态空间的重要组成部分是乒乓球的速度,它当然不是离散的。 像我们不久将要看到的那样,可以看到的特工会看到一个图像,该图像是一个很大的连续空间。
`Q`函数的讨论使我们陷入了传统强化学习的重要局限。 您可能还记得,它假设状态空间是有限且离散的。 不幸的是,这不是我们生活的世界,也不是我们的智能体在很多时候会发现自己的环境。 考虑一个可以打乒乓球的经纪人。 状态空间的重要组成部分是乒乓球的速度,它当然不是离散的。 像我们不久将要看到的那样,可以看到的特工会看到一个图像,该图像是一个很大的连续空间。
我们讨论的 Bellman 方程将要求我们在州与州之间转移时保持经验奖励的大矩阵。 但是,当面对连续的状态空间时,这是不可能的。 可能的状态本质上是无限的,我们不能创建无限大小的矩阵。
......@@ -78,13 +78,13 @@
![](img/33ff32cb-b608-417d-afd0-60e35ff0f6d4.png)
我们可以使用深度神经网络作为函数来逼近该矩阵,而不是尝试存储一个无限大的矩阵,而是将奖励从连续状态空间映射到动作。 这样,我们可以将神经网络用作智能代理的大脑。 但这一切都导致我们提出一个非常有趣的问题。 我们如何训练这个网络?
我们可以使用深度神经网络作为函数来逼近该矩阵,而不是尝试存储一个无限大的矩阵,而是将奖励从连续状态空间映射到动作。 这样,我们可以将神经网络用作智能的大脑。 但这一切都导致我们提出一个非常有趣的问题。 我们如何训练这个网络?
# 在线学习
当我们的代理人通过采取行动从一个州过渡到另一个州时,它会得到奖励。 代理可以通过使用每个状态,动作和奖励作为训练输入来在线学习。 在执行每个操作后,该代理将更新其神经网络权重,并希望在此过程中变得更聪明。 这是在线学习的基本思想。 代理商就像您和我一样,不断学习。
当我们的智能体通过采取行动从一个州过渡到另一个州时,它会得到奖励。 智能体可以通过使用每个状态,动作和奖励作为训练输入来在线学习。 在执行每个操作后,该智能体将更新其神经网络权重,并希望在此过程中变得更聪明。 这是在线学习的基本思想。 智能体就像您和我一样,不断学习。
这种天真的在线学习的缺点有些明显,有两个方面:
这种朴素的在线学习的缺点有些明显,有两个方面:
* 经历之后,我们就会放弃经验。
* 我们所经历的经验彼此高度相关,我们将过度适应最新的经验。 有趣的是,这也是人类遭受的苦难,称为可用性偏差。
......@@ -93,17 +93,17 @@
# 记忆和经验重放
当我们引入有限存储空间的概念时,可以找到针对这两个问题的巧妙解决方案,该存储空间用于存储代理具有的一组经验。 在每个状态下,我们都可以借此机会记住状态,行动和奖励。 然后,代理可以通过从内存中采样一个随机小批量并使用该小批量更新 DQN 权重,定期重放这些经验。
当我们引入有限存储空间的概念时,可以找到针对这两个问题的巧妙解决方案,该存储空间用于存储智能体具有的一组经验。 在每个状态下,我们都可以借此机会记住状态,行动和奖励。 然后,智能体可以通过从内存中采样一个随机小批量并使用该小批量更新 DQN 权重,定期重放这些经验。
这种重放机制使代理能够以一般的方式从更长远的经验中学习,因为它是从内存中的那些经验中随机采样的,而不是仅使用最近的经验来更新整个网络。
这种重放机制使智能体能够以一般的方式从更长远的经验中学习,因为它是从内存中的那些经验中随机采样的,而不是仅使用最近的经验来更新整个网络。
# 利用与探索
通常,我们希望代理遵循*贪婪*策略,这意味着我们希望代理采取具有最大`Q`值的操作。 在学习网络的同时,我们不希望它总是贪婪地表现。 如果这样做,它将永远不会探索新的选择,也不会学习新的东西。 因此,我们需要我们的代理偶尔执行不符合规定的策略。
通常,我们希望智能体遵循*贪婪*策略,这意味着我们希望智能体采取具有最大`Q`值的操作。 在学习网络的同时,我们不希望它总是贪婪地表现。 如果这样做,它将永远不会探索新的选择,也不会学习新的东西。 因此,我们需要我们的智能体偶尔执行不符合规定的策略。
平衡这种探索的最佳方法是一个持续不断的研究主题,并且已经使用了很长时间。 但是,我们将使用的方法非常简单。 代理每次执行操作时,我们都会生成一个随机数。 如果该数字等于或小于某个阈值`ε`,则代理将采取随机措施。 这称为 **ε 贪婪策略**
平衡这种探索的最佳方法是一个持续不断的研究主题,并且已经使用了很长时间。 但是,我们将使用的方法非常简单。 智能体每次执行操作时,我们都会生成一个随机数。 如果该数字等于或小于某个阈值`ε`,则智能体将采取随机措施。 这称为 **ε 贪婪策略**
代理第一次启动时,对世界了解不多,应该探索更多。 随着代理变得越来越聪明,它可能应该减少探索并更多地使用其对环境的了解。 为此,我们只需要在训练时逐渐降低`ε`。 在我们的示例中,我们将每转降低`ε`的衰减率,以使它随每个动作线性减小。
智能体第一次启动时,对世界了解不多,应该探索更多。 随着智能体变得越来越聪明,它可能应该减少探索并更多地使用其对环境的了解。 为此,我们只需要在训练时逐渐降低`ε`。 在我们的示例中,我们将每转降低`ε`的衰减率,以使它随每个动作线性减小。
综上所述,我们有一个**线性退火 ε - 贪心 Q 策略**,说起来既简单又有趣。
......@@ -111,15 +111,15 @@
至少没有提到 Mnih 等人的论文[《和深度强化学习一起玩 Atari》](https://www.cs.toronto.edu/~vmnih/docs/dqn.pdf),就不会完成关于强化学习的讨论。 然后是 DeepMind,现在是 Google。 在这篇具有里程碑意义的论文中,作者使用了卷积神经网络来训练深度 Q 网络来玩 Atari 2600 游戏。 他们从 Atari 2600 游戏中获取原始像素输出,将其缩小一点,将其转换为灰度,然后将其用作网络的状态空间输入。 为了使计算机了解屏幕上对象的速度和方向,他们使用了四个图像缓冲区作为深度 Q 网络的输入。
作者能够创建一个代理,该代理能够使用完全相同的神经网络架构玩 7 个 Atari 2600 游戏,并且在其中三个游戏上,该代理要比人类更好。 后来又扩大到 49 场比赛,其中大多数比赛都比人类出色。 本文是迈向通用 AI 的非常重要的一步,它实际上是目前在强化学习中开展的许多研究的基础。
作者能够创建一个智能体,该智能体能够使用完全相同的神经网络架构玩 7 个 Atari 2600 游戏,并且在其中三个游戏上,该智能体要比人类更好。 后来又扩大到 49 场比赛,其中大多数比赛都比人类出色。 本文是迈向通用 AI 的非常重要的一步,它实际上是目前在强化学习中开展的许多研究的基础。
# Keras 强化学习框架
在这一点上,我们应该有足够的背景知识来开始建立深层的 Q 网络,但是仍然需要克服很大的障碍。
实施利用深度强化学习的代理可能是一个很大的挑战,但是最初由 Matthias Plappert 编写的 Keras-RL 库使其变得更加容易。 我将使用他的库来为本章介绍的代理提供支持。
实施利用深度强化学习的智能体可能是一个很大的挑战,但是最初由 Matthias Plappert 编写的 Keras-RL 库使其变得更加容易。 我将使用他的库来为本章介绍的智能体提供支持。
当然,如果没有环境,我们的经纪人将不会有太多的乐趣。 我将使用 OpenAI 体育馆,该体育馆提供许多环境,包括状态和奖励功能,我们可以轻松地使用它们来构建供代理商探索的世界。
当然,如果没有环境,我们的经纪人将不会有太多的乐趣。 我将使用 OpenAI 体育馆,该体育馆提供许多环境,包括状态和奖励函数,我们可以轻松地使用它们来构建供智能体探索的世界。
# 安装 Keras-RL
......@@ -143,7 +143,7 @@ pip install gym[Box2D]
# 使用 OpenAI Gym
使用 OpenAI 体育场确实使深度强化学习变得容易。 Keras-RL 将完成大部分艰苦的工作,但是我认为值得单独走遍体育馆,这样您才能了解代理如何与环境互动。
使用 OpenAI 体育场确实使深度强化学习变得容易。 Keras-RL 将完成大部分艰苦的工作,但是我认为值得单独走遍体育馆,这样您才能了解智能体如何与环境互动。
环境是可以实例化的对象。 例如,要创建`CartPole-v0`环境,我们只需要导入体育场并创建环境,如以下代码所示:
......@@ -152,24 +152,24 @@ import gym
env = gym.make("CartPole-v0")
```
现在,如果我们的代理想要在那种环境中行动,它只需要发送一个`action`并返回一个状态和一个`reward`,如下所示:
现在,如果我们的智能体想要在那种环境中行动,它只需要发送一个`action`并返回一个状态和一个`reward`,如下所示:
```py
next_state, reward, done, info = env.step(action)
```
代理可以通过使用循环与环境进行交互来播放整个情节。 此循环的每次迭代都对应情节中的单个步骤。 当代理从环境接收到“完成”信号时,情节结束。
智能体可以通过使用循环与环境进行交互来播放整个剧集。 此循环的每次迭代都对应剧集中的单个步骤。 当智能体从环境接收到“完成”信号时,剧集结束。
# 在 Keras 中建立强化学习智能体
好消息,我们终于可以开始编码了。 在本部分中,我将演示两种名为 **CartPole****Lunar Lander** 的 Keras-RL 代理。 我选择这些示例是因为它们不会消耗您的 GPU 和云预算来运行。 它们可以很容易地扩展到 Atari 问题,我在本书的 Git 存储库中也包括了其中之一。 您可以照常在`Chapter12`文件夹中找到所有这些代码。 让我们快速讨论一下这两种环境:
好消息,我们终于可以开始编码了。 在本部分中,我将演示两种名为 **CartPole****Lunar Lander** 的 Keras-RL 智能体。 我选择这些示例是因为它们不会消耗您的 GPU 和云预算来运行。 它们可以很容易地扩展到 Atari 问题,我在本书的 Git 存储库中也包括了其中之一。 您可以照常在`Chapter12`文件夹中找到所有这些代码。 让我们快速讨论一下这两种环境:
* **CartPole**:CartPole 环境由平衡在推车上的杆组成。 代理商必须学习如何在立柱下方的推车移动时垂直平衡立柱。 给智能体指定了推车的位置,推车的速度,杆的角度和杆的旋转速度作为输入。 代理可以在推车的任一侧施加力。 如果电线杆与垂直线的夹角下降超过 15 度,我们的经纪人就此告吹。
* **Lunar Lander**:Lunar Lander 的环境更具挑战性。 特工必须将月球着陆器降落在着陆垫上。 月亮的表面会发生变化,着陆器的方位也会在每个情节发生变化。 该代理将获得一个八维数组,用于描述每个步骤中的世界状态,并且可以在该步骤中执行四个操作之一。 代理可以选择不执行任何操作,启动其主引擎,启动其左向引擎或启动其右向引擎。
* **CartPole**:CartPole 环境由平衡在推车上的杆组成。 智能体必须学习如何在立柱下方的推车移动时垂直平衡立柱。 给智能体指定了推车的位置,推车的速度,杆的角度和杆的旋转速度作为输入。 智能体可以在推车的任一侧施加力。 如果电线杆与垂直线的夹角下降超过 15 度,我们的经纪人就此告吹。
* **Lunar Lander**:Lunar Lander 的环境更具挑战性。 特工必须将月球着陆器降落在着陆垫上。 月亮的表面会发生变化,着陆器的方位也会在每个剧集发生变化。 该智能体将获得一个八维数组,用于描述每个步骤中的世界状态,并且可以在该步骤中执行四个操作之一。 智能体可以选择不执行任何操作,启动其主引擎,启动其左向引擎或启动其右向引擎。
# CartPole
CartPole 代理将使用一个相当适度的神经网络,即使没有 GPU,您也应该能够相当迅速地进行训练。 我们将一如既往地从模型架构开始。 然后,我们将定义网络的内存,探索策略,最后训练代理
CartPole 智能体将使用一个相当适度的神经网络,即使没有 GPU,您也应该能够相当迅速地进行训练。 我们将一如既往地从模型架构开始。 然后,我们将定义网络的内存,探索策略,最后训练智能体
# CartPole 神经网络架构
......@@ -192,7 +192,7 @@ def build_model(state_size, num_actions):
# 记忆
Keras-RL 为我们提供了一个名为`rl.memory.SequentialMemory`的类,该类提供了快速有效的数据结构,我们可以将代理的经验存储在以下位置:
Keras-RL 为我们提供了一个名为`rl.memory.SequentialMemory`的类,该类提供了快速有效的数据结构,我们可以将智能体的经验存储在以下位置:
```py
memory = SequentialMemory(limit=50000, window_length=1)
......@@ -202,7 +202,7 @@ 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)
......@@ -212,7 +212,7 @@ policy = LinearAnnealedPolicy(EpsGreedyQPolicy(), attr='eps', value_max=1., valu
# 智能体
定义了模型,内存和策略后,我们现在就可以创建一个深度 Q 网络代理,并将这些对象发送给该代理。 Keras RL 提供了一个称为`rl.agents.dqn.DQNAgent`的代理类,我们可以为此使用它,如以下代码所示:
定义了模型,内存和策略后,我们现在就可以创建一个深度 Q 网络智能体,并将这些对象发送给该智能体。 Keras RL 提供了一个称为`rl.agents.dqn.DQNAgent`的智能体类,我们可以为此使用它,如以下代码所示:
```py
dqn = DQNAgent(model=model, nb_actions=num_actions, memory=memory, nb_steps_warmup=10,
......@@ -224,7 +224,7 @@ dqn.compile(Adam(lr=1e-3), metrics=['mae'])
此时,其中两个参数`target_model_update``nb_steps_warmup`可能还不熟悉:
* `nb_steps_warmup`:确定我们开始进行经验重放之前需要等待的时间,如果您还记得的话,这是我们实际上开始训练网络的时间。 这使我们积累了足够的经验来构建适当的小批量生产。 如果您为此参数选择的值小于批量大小,则 Keras RL 将抽样替换。
* `target_model_update``Q`函数是递归的,当代理更新它的网络以获取` Q(s, a)`时,更新也影响其对`Q(s', a)`所​​做的预测。 这会导致网络非常不稳定。 大多数深度 Q 网络实现解决此限制的方法是使用目标网络,该目标网络是未经训练的深度 Q 网络的副本,而经常被新副本替换。 `target_model_update`参数控制这种情况发生的频率。
* `target_model_update``Q`函数是递归的,当智能体更新它的网络以获取` Q(s, a)`时,更新也影响其对`Q(s', a)`所​​做的预测。 这会导致网络非常不稳定。 大多数深度 Q 网络实现解决此限制的方法是使用目标网络,该目标网络是未经训练的深度 Q 网络的副本,而经常被新副本替换。 `target_model_update`参数控制这种情况发生的频率。
# 训练
......@@ -248,19 +248,19 @@ dqn.fit(env, nb_steps=50000,
callbacks=callbacks)
```
一旦构建了代理的回调,我们就可以使用`.fit()`方法来拟合`DQNAgent`,就像使用 Keras 模型一样。 在此示例中,请注意`visualize`参数。 如果将`visualize`设置为`True`,我们将能够观察代理与环境的交互。 但是,这大大减慢了训练的速度。
一旦构建了智能体的回调,我们就可以使用`.fit()`方法来拟合`DQNAgent`,就像使用 Keras 模型一样。 在此示例中,请注意`visualize`参数。 如果将`visualize`设置为`True`,我们将能够观察智能体与环境的交互。 但是,这大大减慢了训练的速度。
# 结果
在前 250 个情节之后,我们将看到情节的总奖励接近 200,情节步骤的总奖励也接近 200。这意味着代理已学会平衡购物车上的杆位,直到环境结束最多 200 个步骤 。
在前 250 个剧集之后,我们将看到剧集的总奖励接近 200,剧集步骤的总奖励也接近 200。这意味着智能体已学会平衡购物车上的杆位,直到环境结束最多 200 个步骤 。
观看我们的成功当然很有趣,因此我们可以使用`DQNAgent` `.test()`方法评估某些情节。 以下代码用于定义此方法:
观看我们的成功当然很有趣,因此我们可以使用`DQNAgent` `.test()`方法评估某些剧集。 以下代码用于定义此方法:
```py
dqn.test(env, nb_episodes=5, visualize=True)
```
在这里,我们设置了`visualize=True`,以便我们可以看到我们的代理平衡杆位,如下图所示:
在这里,我们设置了`visualize=True`,以便我们可以看到我们的智能体平衡杆位,如下图所示:
![](img/b7cebe8d-49bf-4557-be22-f17d87109762.png)
......@@ -268,13 +268,13 @@ dqn.test(env, nb_episodes=5, visualize=True)
# Lunar Lander
感谢 Keras-RL,我们用于 Lunar Lander 的代理几乎与 CartPole 相同,除了实际的模型架构和一些超参数更改外。 Lunar Lander 的环境有八个输入而不是四个输入,我们的代理现在可以选择四个操作而不是两个。
感谢 Keras-RL,我们用于 Lunar Lander 的智能体几乎与 CartPole 相同,除了实际的模型架构和一些超参数更改外。 Lunar Lander 的环境有八个输入而不是四个输入,我们的智能体现在可以选择四个操作而不是两个。
如果您受到这些示例的启发,并决定尝试构建 Keras-RL 网络,请记住,超参数选择非常非常重要。 对于 Lunar Lander 代理,对模型架构的最小更改导致我的代理无法学习环境解决方案。 使网络正确运行是一项艰巨的工作。
如果您受到这些示例的启发,并决定尝试构建 Keras-RL 网络,请记住,超参数选择非常非常重要。 对于 Lunar Lander 智能体,对模型架构的最小更改导致我的智能体无法学习环境解决方案。 使网络正确运行是一项艰巨的工作。
# Lunar Lander 网络架构
我的 Lunar Lander 代理程序的架构仅比 CartPole 的架构稍微复杂一点,对于相同的三个隐藏层仅引入了几个神经元。 我们将使用以下代码来定义模型:
我的 Lunar Lander 智能体程序的架构仅比 CartPole 的架构稍微复杂一点,对于相同的三个隐藏层仅引入了几个神经元。 我们将使用以下代码来定义模型:
```py
def build_model(state_size, num_actions):
......@@ -289,11 +289,11 @@ def build_model(state_size, num_actions):
return model
```
在此问题的情况下,较小的架构会导致代理学习控制和悬停着陆器,但实际上并未着陆。 当然,由于我们要对每个情节的每个步骤进行小批量更新,因此我们需要仔细权衡复杂性与运行时和计算需求之间的关系。
在此问题的情况下,较小的架构会导致智能体学习控制和悬停着陆器,但实际上并未着陆。 当然,由于我们要对每个剧集的每个步骤进行小批量更新,因此我们需要仔细权衡复杂性与运行时和计算需求之间的关系。
# 记忆和策略
CartPole 的内存和策略可以重复使用。 我相信,通过进一步调整**线性退火策略**中的步骤,可能会提高代理训练的速度,因为该代理需要采取更多的步骤来进行训练。 但是,为 CartPole 选择的值似乎可以很好地工作,因此这是留给读者的练习。
CartPole 的内存和策略可以重复使用。 我相信,通过进一步调整**线性退火策略**中的步骤,可能会提高智能体训练的速度,因为该智能体需要采取更多的步骤来进行训练。 但是,为 CartPole 选择的值似乎可以很好地工作,因此这是留给读者的练习。
# 智能体
......@@ -306,11 +306,11 @@ dqn.compile(Adam(lr=0.00025), metrics=['mae'])
# 训练
在训练该特工时,您会注意到它学会做的第一件事是将着陆器悬停,并避免着陆。 当着陆器最终着陆时,它会收到非常高的奖励,成功着陆时为 +100,坠毁时为 -100。 这种 -100 的奖励是如此之强,以至于代理商一开始宁愿因悬停而受到小额罚款。 我们的探员要花很多时间才能得出这样的提示:良好的着陆总比没有良好着陆好,因为坠机着陆非常糟糕。
在训练该特工时,您会注意到它学会做的第一件事是将着陆器悬停,并避免着陆。 当着陆器最终着陆时,它会收到非常高的奖励,成功着陆时为 +100,坠毁时为 -100。 这种 -100 的奖励是如此之强,以至于智能体一开始宁愿因悬停而受到小额罚款。 我们的探员要花很多时间才能得出这样的提示:良好的着陆总比没有良好着陆好,因为坠机着陆非常糟糕。
可以塑造奖励信号来帮助座席更快地学习,但这超出了本书的范围。 有关更多信息,请查看奖励塑造。
由于这种对坠机着陆的极端负面反馈,网络需要花费相当长的一段时间才能学会着陆。 在这里,我们正在运行五十万个训练步骤,以传达我们的信息。 我们将使用以下代码来训练代理
由于这种对坠机着陆的极端负面反馈,网络需要花费相当长的一段时间才能学会着陆。 在这里,我们正在运行五十万个训练步骤,以传达我们的信息。 我们将使用以下代码来训练智能体
```py
callbacks = build_callbacks(ENV_NAME)
......
......@@ -103,7 +103,7 @@ DCGAN 框架是使用迷你批量来进行训练的,这与我之前在本书
# 模式崩溃
**模式崩溃**是 GAN 失败的类似且相关的方式。 在模式崩溃中,生成器在多模式分布中学习一种模式,并选择始终使用该方法来利用判别器。 如果您的训练集中有鱼和小猫,并且您的生成器仅生成奇怪的小猫而没有鱼,则您经历了模式崩溃。 在这种情况下,增加判别器的功能可能会有所帮助。
**模式崩溃**是 GAN 失败的类似且相关的方式。 在模式崩溃中,生成器在多模式分布中学习一种模式,并选择始终使用该方法来利用判别器。 如果您的训练集中有鱼和小猫,并且您的生成器仅生成奇怪的小猫而没有鱼,则您经历了模式崩溃。 在这种情况下,增加判别器的威力可能会有所帮助。
# GAN 的安全选择
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册