提交 6291f709 编写于 作者: W wizardforcel

2021-01-16 18:12:37

上级 15b093d5
# 前言
*PyTorch 深度学习动手*非常适合初学者,也可以帮助读者快速进入深度学习的深度。 在过去的几年中,我们已经看到了深度学习成为新的力量。 它已经从学术界进入工业界,帮助解决了成千上万的谜团,如果没有它,人类将无法想象解决。 深度学习作为首选实现方式的主流采用主要是由一堆框架驱动的,这些框架可靠地将复杂算法作为有效的内置方法提供。 本书展示了 PyTorch 在构建深度学习模型原型,构建深度学习工作流程以及将原型模型投入生产中的优势。 总体而言,这本书着重于 PyTorch 的实际实现,而不是解释其背后的数学原理,但是,它还将您链接到一些概念上可能落后的地方。
《PyTorch 深度学习实用指南》非常适合初学者,也可以帮助读者快速进入深度学习的深度。 在过去的几年中,我们已经看到了深度学习成为新的力量。 它已经从学术界进入工业界,帮助解决了成千上万的谜团,如果没有它,人类将无法想象解决。 深度学习作为首选实现方式的主流采用主要是由一堆框架驱动的,这些框架可靠地将复杂算法作为有效的内置方法提供。 本书展示了 PyTorch 在构建深度学习模型原型,构建深度学习工作流程以及将原型模型投入生产中的优势。 总体而言,这本书着重于 PyTorch 的实际实现,而不是解释其背后的数学原理,但是,它还将您链接到一些概念上可能落后的地方。
## 这本书适合谁
......@@ -8,21 +8,21 @@
## 这本书涵盖的内容
第 1 章,*深度学习演练和 PyTorch 简介*是对 PyTorch 进行深度学习的方式以及 PyTorch 的基本 API 的介绍。 它首先显示了 PyTorch 的历史以及为什么 PyTorch 应该成为深度学习开发的必备框架。 它还介绍了不同的深度学习方法,我们将在接下来的章节中介绍这些方法。
第 1 章,“深度学习演练和 PyTorch 简介”是对 PyTorch 进行深度学习的方式以及 PyTorch 的基本 API 的介绍。 它首先显示了 PyTorch 的历史以及为什么 PyTorch 应该成为深度学习开发的必备框架。 它还介绍了不同的深度学习方法,我们将在接下来的章节中介绍这些方法。
第 2 章*一个简单的神经网络*可帮助您构建第一个简单的神经网络,并展示如何连接神经网络,优化器和参数更新之类的点点滴滴来构建一个 新手深度学习模型。 它还介绍了 PyTorch 如何进行反向传播,这是所有最新的深度学习算法的关键。
第 2 章,“一个简单的神经网络”可帮助您构建第一个简单的神经网络,并展示如何连接神经网络,优化器和参数更新之类的点点滴滴来构建一个 新手深度学习模型。 它还介绍了 PyTorch 如何进行反向传播,这是所有最新的深度学习算法的关键。
第 3 章,*深度学习工作流程*深入研究了深度学习工作流程的实现和有助于构建工作流程的 PyTorch 生态系统。 如果您打算为即将进行的项目建立深度学习团队或开发渠道,那么这可能是最关键的一章。 在本章中,我们将遍历深度学习管道的不同阶段,并了解 PyTorch 社区如何通过制作适当的工具在工作流程的每个阶段中不断改进。
第 3 章,“深度学习工作流程”深入研究了深度学习工作流程的实现和有助于构建工作流程的 PyTorch 生态系统。 如果您打算为即将进行的项目建立深度学习团队或开发渠道,那么这可能是最关键的一章。 在本章中,我们将遍历深度学习管道的不同阶段,并了解 PyTorch 社区如何通过制作适当的工具在工作流程的每个阶段中不断改进。
第 4 章,*计算机视觉*是迄今为止深度学习最成功的结果,它讨论了成功背后的关键思想,并贯穿了使用最广泛的视觉算法– **卷积神经网络(CNN)**。 我们将逐步实现 CNN 以了解其工作原理,然后使用 PyTorch 的 nn 包中预定义的 CNN。 本章可帮助您制作简单的 CNN 和基于高级 CNN 的视觉算法,称为语义分割。
第 4 章,“计算机视觉”是迄今为止深度学习最成功的结果,它讨论了成功背后的关键思想,并贯穿了使用最广泛的视觉算法– **卷积神经网络(CNN)**。 我们将逐步实现 CNN 以了解其工作原理,然后使用 PyTorch 的 nn 包中预定义的 CNN。 本章可帮助您制作简单的 CNN 和基于高级 CNN 的视觉算法,称为语义分割。
第 5 章,*顺序数据处理*着眼于循环神经网络,它是目前最成功的顺序数据处理算法。 本章向您介绍主要的 RNN 组件,例如**长短期内存****LSTM**)网络和**门控循环单元****GRU**)。 然后,在探索循环神经网络之前,我们将经历 RNN 实现中的算法更改,例如双向 RNN,并增加层数。 为了理解递归网络,我们将使用斯坦福大学 NLP 小组的著名示例(堆栈增强的解析器-解释器神经网络(SPINN)),并将其在 PyTorch 中实现。
第 5 章,“序列数据处理”着眼于循环神经网络,它是目前最成功的顺序数据处理算法。 本章向您介绍主要的 RNN 组件,例如**长短期记忆****LSTM**)网络和**门控循环单元****GRU**)。 然后,在探索循环神经网络之前,我们将经历 RNN 实现中的算法更改,例如双向 RNN,并增加层数。 为了理解递归网络,我们将使用斯坦福大学 NLP 小组的著名示例(堆栈增强的解析器-解释器神经网络(SPINN)),并将其在 PyTorch 中实现。
第 6 章,*生成网络,*简要讨论了生成网络的历史,然后解释了各种生成网络。 在这些不同的类别中,本章向我们介绍了自回归模型和 GAN。 我们将研究作为自动回归模型一部分的 PixelCNN 和 WaveNet 的实现细节,然后详细研究 GAN。
第 6 章,“生成网络”,简要讨论了生成网络的历史,然后解释了各种生成网络。 在这些不同的类别中,本章向我们介绍了自回归模型和 GAN。 我们将研究作为自动回归模型一部分的 PixelCNN 和 WaveNet 的实现细节,然后详细研究 GAN。
第 7 章,*强化学习*介绍了强化学习的概念,它实际上并不是深度学习的子类。 我们首先来看定义问题陈述。 然后,我们将探讨累积奖励的概念。 我们将探索 Markov 决策过程和 Bellman 方程,然后转向深层 Q 学习。 我们还将看到由 OpenAI 开发的工具包 Gym 的介绍,该工具包用于开发和尝试强化学习算法。
第 7 章,“强化学习”介绍了强化学习的概念,它实际上并不是深度学习的子类。 我们首先来看定义问题陈述。 然后,我们将探讨累积奖励的概念。 我们将探索 Markov 决策过程和 Bellman 方程,然后转向深层 Q 学习。 我们还将看到由 OpenAI 开发的工具包 Gym 的介绍,该工具包用于开发和尝试强化学习算法。
第 8 章*PyTorch 到生产*着眼于在将深度学习模型部署到生产过程中人们甚至是深度学习专家所面临的困难。 我们将探索用于生产部署的不同选项,包括使用围绕 PyTorch 的 Flask 包装器以及使用 RedisAI,RedisAI 是高度优化的运行时,用于在多集群环境中部署模型,并且每秒可以处理数百万个请求。
第 8 章,“生产中的 PyTorch”着眼于在将深度学习模型部署到生产过程中人们甚至是深度学习专家所面临的困难。 我们将探索用于生产部署的不同选项,包括使用围绕 PyTorch 的 Flask 包装器以及使用 RedisAI,RedisAI 是高度优化的运行时,用于在多集群环境中部署模型,并且每秒可以处理数百万个请求。
## 要充分利用这本书
......
......@@ -32,7 +32,7 @@ Python 在深度学习社区中的广泛接受使一些研究人员和开发人
作为 **Python 优先框架**,PyTorch 大大超越了在整体 C ++或 C 引擎上实现 Python 包装器的其他框架。 在 PyTorch 中,您可以继承 PyTorch 类并根据需要进行自定义。 内置于 PyTorch 核心的命令式编码风格仅由于 Python 优先方法才有可能。 尽管诸如 TensorFlow,MXNet 和 CNTK 的某些符号图框架提出了一种强制性方法,但由于社区的支持及其灵活性,PyTorch 仍能保持领先地位。
基于磁带的**自动分级**系统使 PyTorch 具有**动态图**功能。 这是 PyTorch 与其他流行的符号图框架之间的主要区别之一。 基于磁带的 autograd 也支持 Chainer,autograd 和 Torch-autograd 的反向传播算法。 具有动态图功能,您的图将在 Python 解释器到达相应行时创建。 与 TensorFlow 的*定义并运行*方法不同,这称为通过运行定义的*。*
基于磁带的**自动分级**系统使 PyTorch 具有**动态图**功能。 这是 PyTorch 与其他流行的符号图框架之间的主要区别之一。 基于磁带的 autograd 也支持 Chainer,autograd 和 Torch-autograd 的反向传播算法。 具有动态图功能,您的图将在 Python 解释器到达相应行时创建。 与 TensorFlow 的*定义并运行*方法不同,这称为*通过运行定义*
基于磁带的 autograd 使用反向模式自动微分,在前进过程中,图形将每个操作保存到磁带中,然后在磁带中向后移动以进行反向传播。 动态图和 Python 优先方法使**易于调试**,您可以在其中使用常用的 Python 调试器,例如 Pdb 或基于编辑器的调试器。
......@@ -198,7 +198,7 @@ for epoch in range(epochs):
在 PyTorch 代码中,输入变量定义未创建占位符。 而是将变量对象包装到您的输入上。 图形定义不会执行一次; 相反,它在循环内,并且每次迭代都在构建图形。 您在每个图实例之间共享的唯一信息是您要优化的权重矩阵。
在这种方法中,如果您在遍历数据时改变了数据大小或形状,则在图形中运行新形状的数据绝对好,因为新创建的图形可以接受新形状。 可能性不止于此。 如果要动态更改图形的行为,也可以这样做。 在第 5 章,*顺序数据处理,*中的循环神经网络会话中给出的示例均基于此思想。
在这种方法中,如果您在遍历数据时改变了数据大小或形状,则在图形中运行新形状的数据绝对好,因为新创建的图形可以接受新形状。 可能性不止于此。 如果要动态更改图形的行为,也可以这样做。 在第 5 章,“序列数据处理”中的循环神经网络会话中给出的示例均基于此思想。
## 探索深度学习
......@@ -256,7 +256,7 @@ for epoch in range(epochs):
如果您能够训练一个可以做到这一点的神经网络,那么 voilà,您将找到一个很好的压缩算法,可以将高维输入以一个数量级的幅度传输到低维向量 获得。
如今,自动编码器被用于不同的情况和行业。 当我们讨论语义分割时,您将在第 4 章,*计算机视觉*中看到类似的架构。
如今,自动编码器被用于不同的情况和行业。 当我们讨论语义分割时,您将在第 4 章,“计算机视觉”中看到类似的架构。
![Encoders and decoders](img/B09475_01_12.jpg)
......@@ -264,7 +264,7 @@ for epoch in range(epochs):
#### 循环神经网络
RNN 是最常见的深度学习算法之一,它们席卷全球。 我们现在在自然语言处理或理解中几乎拥有所有最先进的性能,这是由于 RNN 的变体。 在循环网络中,您尝试识别数据中的最小单位,并使数据成为这些单位的组。 在自然语言的示例中,最常见的方法是使一个单词成为一个单元,并在处理该句子时将其视为一组单词。 您展开整个句子的 RNN,然后一次处理一个单词。 RNN 具有适用于不同数据集的变体,有时,选择变体时可以考虑效率。 **短期记忆****LSTM**)和**门控循环单元****GRU**)细胞是最常见的 RNN 单元。
RNN 是最常见的深度学习算法之一,它们席卷全球。 我们现在在自然语言处理或理解中几乎拥有所有最先进的性能,这是由于 RNN 的变体。 在循环网络中,您尝试识别数据中的最小单位,并使数据成为这些单位的组。 在自然语言的示例中,最常见的方法是使一个单词成为一个单元,并在处理该句子时将其视为一组单词。 您展开整个句子的 RNN,然后一次处理一个单词。 RNN 具有适用于不同数据集的变体,有时,选择变体时可以考虑效率。 **长短期记忆****LSTM**)和**门控循环单元****GRU**)细胞是最常见的 RNN 单元。
![Recurrent neural networks](img/B09475_01_13.jpg)
......@@ -274,7 +274,7 @@ RNN 是最常见的深度学习算法之一,它们席卷全球。 我们现在
顾名思义,循环神经网络是树状网络,用于了解序列数据的层次结构。 递归网络已在**自然语言处理**应用程序中大量使用,尤其是 Salesforce 首席科学家 Richard Socher 及其团队。
词向量,我们将在第 5 章,*顺序数据处理*中很快看到,它们能够将词的含义有效地映射到向量空间中,但是涉及到含义 在整个句子中,没有像 word2vec 这样的单词适合的解决方案。 循环神经网络是此类应用最常用的算法之一。 递归网络可以创建一个解析树和组成向量,并映射其他层次关系,这反过来又帮助我们找到了结合单词和句子的规则。 **斯坦福自然语言推断**小组发现了一种著名的且使用良好的算法,称为 **SNLI** ,这是递归网络使用的一个很好的例子。
词向量,我们将在第 5 章,“序列数据处理”中很快看到,它们能够将词的含义有效地映射到向量空间中,但是涉及到含义 在整个句子中,没有像 word2vec 这样的单词适合的解决方案。 循环神经网络是此类应用最常用的算法之一。 递归网络可以创建一个解析树和组成向量,并映射其他层次关系,这反过来又帮助我们找到了结合单词和句子的规则。 **斯坦福自然语言推断**小组发现了一种著名的且使用良好的算法,称为 **SNLI**,这是递归网络使用的一个很好的例子。
![Recursive neural networks](img/B09475_01_14.jpg)
......@@ -532,7 +532,7 @@ print(with_fake_dimension) # added a fake zeroth dimension
图 1.19:THTensor 到 THStorage 到原始数据
正如您可能已经假设的那样, **THStorage** 层不是一个智能数据结构,它实际上并不知道张量的元数据。 **THStorage** 层负责保持指向原始数据和分配器的指针。 分配器完全是另一个主题,中有用于 CPU,GPU,共享内存等的不同分配器。 来自 **THStorage** 的指向**原始数据**的指针是互操作性的关键。 **原始数据**是存储实际数据的位置,但没有任何结构。 每个张量对象的这种三层表示使 PyTorch 的实现内存效率更高。 以下是一些示例。
正如您可能已经假设的那样,`THStorage`层不是一个智能数据结构,它实际上并不知道张量的元数据。 `THStorage`层负责保持指向原始数据和分配器的指针。 分配器完全是另一个主题,中有用于 CPU,GPU,共享内存等的不同分配器。 来自`THStorage`的指向**原始数据**的指针是互操作性的关键。 **原始数据**是存储实际数据的位置,但没有任何结构。 每个张量对象的这种三层表示使 PyTorch 的实现内存效率更高。 以下是一些示例。
将变量`x`创建为 2 x 2 的张量,并填充 1s。 然后,我们创建另一个变量`xv`,它是同一张量`x`的另一个视图。 我们将 2 x 2 张量展平为大小为 4 的单维张量。我们还通过调用`.NumPy()`方法并将其存储在变量`xn`中来创建 NumPy 数组:
......
......@@ -22,11 +22,11 @@
建立数据管道与网络的架构一样重要,尤其是在实时训练网络时。 从野外获得的数据永远不会干净,在将其扔到网络之前,您必须对其进行处理。 例如,如果我们要收集数据以预测某人是否购买产品,那么最终将出现异常值。 离群值可以是任何种类且不可预测的。 例如,某人可能不小心下了订单,或者他们可以访问后来下订单的朋友,依此类推。
从理论上讲,深度神经网络非常适合从数据集中查找模式和解,因为它们应该模仿人的大脑。 但是,实际上,情况并非总是如此。 如果您的数据干净且格式正确,您的网络将能够通过找到模式来轻松解决问题。 PyTorch 开箱即用地提供了数据预处理包装器,我们将在第 3 章和*深度学习工作流程*中进行讨论。 除此之外,我们将讨论如何格式化或清除数据集。
从理论上讲,深度神经网络非常适合从数据集中查找模式和解,因为它们应该模仿人的大脑。 但是,实际上,情况并非总是如此。 如果您的数据干净且格式正确,您的网络将能够通过找到模式来轻松解决问题。 PyTorch 开箱即用地提供了数据预处理包装器,我们将在第 3 章和“深度学习工作流程”中进行讨论。 除此之外,我们将讨论如何格式化或清除数据集。
为简单起见,我们将使用一些简单的函数来生成数据。 让我们开始为 *FizzBu​​zz* 模型构建简单的数据集。 当我们的模型得到一个数字时,它应该预测下一个输出,就好像是在玩游戏的人一样。 例如,如果输入为三,则模型应预测下一个数字为四。 如果输入为八,则模型应显示“嘶嘶声”,因为九可以被三整除。
我们不希望我们的模型遭受复杂的输出。 因此,为使我们的模型更容易,我们将问题描述为一个简单的分类问题,其中模型将输出分为四个不同类别:**嘶嘶声****嗡嗡声****fizzbuzz****Continue_without_change** 。 对于任何输入模型,我们都将尝试在这四个类别上进行概率分布,而在训练下,我们可以尝试使概率分布集中在正确类别上。
我们不希望我们的模型遭受复杂的输出。 因此,为使我们的模型更容易,我们将问题描述为一个简单的分类问题,其中模型将输出分为四个不同类别:`fizz``buzz``fizzbuzz``Continue_without_change`。 对于任何输入模型,我们都将尝试在这四个类别上进行概率分布,而在训练下,我们可以尝试使概率分布集中在正确类别上。
我们还将输入的数字转换为二进制编码的形式,这使网络比整数更容易处理。
......@@ -60,14 +60,14 @@ def get_numpy_data(input_size=10, limit=1000):
return training_test_gen(np.array(x), np.array(y))
```
编码器功能将输入编码为二进制数,从而使神经网络易于学习。 将数值直接传递到神经网络会对网络施加更多约束。 不要担心最后一行中的`training_test_gen`功能; 我们将在第 3 章和*深度学习工作流程*中进行更多讨论。 现在,请记住,它将数据集拆分为训练和测试集,并将其作为 NumPy 数组返回。
编码器功能将输入编码为二进制数,从而使神经网络易于学习。 将数值直接传递到神经网络会对网络施加更多约束。 不要担心最后一行中的`training_test_gen`功能; 我们将在第 3 章和“深度学习工作流程”中进行更多讨论。 现在,请记住,它将数据集拆分为训练和测试集,并将其作为 NumPy 数组返回。
利用到目前为止我们拥有的关于数据集的信息,我们可以按以下方式构建网络:
* 我们将输入转换为 10 位二进制数,因此我们的第一个输入层需要 10 个神经元才能接受这 10 位数字。
* 由于我们的输出始终是大小为 4 的向量,因此我们需要有四个输出神经元。
* 看来我们要解决的问题很简单:比较深度学习在当今世界中产生的虚构冲动。 首先,我们可以有一个大小为 100 的隐藏层。
* 由于在处理之前批量数据总是更好,为了获得良好的结果,我们将对输入的批量添加 64 个数据点。 请查看本章末尾的*查找错误*部分,以了解批量为什么更好。
* 由于在处理之前批量数据总是更好,为了获得良好的结果,我们将对输入的批量添加 64 个数据点。 请查看本章末尾的“查找错误”部分,以了解批量为什么更好。
让我们定义超参数并调用我们先前定义的函数以获取训练和测试数据。 我们将为各种神经网络模型定义五个典型的超参数:
......@@ -89,11 +89,13 @@ for i in epoch:
**学习率**决定了我们希望我们的网络从每次迭代的错误中获取反馈的速度。 它通过忘记网络从所有先前迭代中学到的知识来决定从当前迭代中学到的知识。 将学习率保持为 1 可使网络考虑完全错误,并根据完全错误调整权重。 学习速率为零意味着向网络传递的信息为零。 学习率将是神经网络中梯度更新方程式中的选择因子。 对于每个神经元,我们运行以下公式来更新神经元的权重:
*重量-= lr *损失*
```py
weight -= lr * loss
```
较低的学习率可帮助网络沿着山路走很小的步,而较高的学习率可帮助网络沿山路走。 但是,这是有代价的。 一旦损失接近最小值,较高的学习率可能会使网络跳过最小值,并导致网络永远找不到最小值。 从技术上讲,在每次迭代中,网络都会对近似值进行线性近似,而学习率将控制该近似值。
如果损失函数高度弯曲,则以较高的学习率进行较长的步骤可能会导致模型变坏。 因此,理想的学习率始终取决于问题陈述和当前的模型架构。 *深度学习书* [4]的第四章是了解学习重要性的好资料。 来自 Coursera 上著名的吴恩达(Andrew Ng)课程的精美图片代表清楚地了解了学习率如何影响网络学习。
如果损失函数高度弯曲,则以较高的学习率进行较长的步骤可能会导致模型变坏。 因此,理想的学习率始终取决于问题陈述和当前的模型架构。 《深度学习》[4]的第四章是了解学习重要性的好资料。 来自 Coursera 上著名的吴恩达(Andrew Ng)课程的精美图片代表清楚地了解了学习率如何影响网络学习。
![Dataset](img/B09475_02_02.jpg)
......@@ -129,7 +131,9 @@ b2 = torch.zeros(1, output_size, requires_grad=True, device=device, dtype=dtype)
磁带或内存的写操作可忽略不计,PyTorch 通过将操作写到磁带上并在向后遍历后销毁磁带来利用每次正向遍历中的行为。 尽管我会在本书中尽量避免使用尽可能多的数学方法,但是有关自动毕业如何工作的数学示例绝对可以为您提供帮助。 在下面的两个图中,说明了反向传播算法和使用链规则的 autograd 的方法。 下图中我们有一个小型网络,其中有一个乘法节点和一个加法节点。 乘法节点获取输入张量和权重张量,将其传递到加法节点以进行加法运算。
*输出= X * W + B*
```py
output = X * W + B
```
由于将方程分为几步,因此我们可以根据下一阶段找到每个阶段的斜率,然后使用链式规则将其链接在一起,从而根据最终输出获得权重的误差。 第二张图显示了 autograd 如何将这些导数项中的每一个链接起来以获得最终误差。
......@@ -162,7 +166,7 @@ tensor([1.])
#### 张量的 Autograd 属性
当成为图形的一部分时,张量需要存储 autograd 自动区分所需的信息。 张量充当计算图中的一个节点,并通过功能模块实例连接到其他节点。 Tensor 实例主要具有支持 autograd 的三个属性:`.grad``.data``grad_fn()`(注意字母大小写:**函数**代表 PyTorch `Function`模块,而**函数[** 代表 Python 函数)。
当成为图形的一部分时,张量需要存储 autograd 自动区分所需的信息。 张量充当计算图中的一个节点,并通过功能模块实例连接到其他节点。 Tensor 实例主要具有支持 autograd 的三个属性:`.grad``.data``grad_fn()`(注意字母大小写:`Function`代表 PyTorch `Function`模块,而`function`代表 Python 函数)。
`.grad`属性在任何时间点存储渐变,所有向后调用将当前渐变累积到`.grad`属性。 `.data`属性可访问其中包含数据的裸张量对象。
......@@ -172,7 +176,7 @@ tensor([1.])
如果您想知道,前面的代码片段中的`required_grad`参数会通知张量或 autograd-engine 在进行反向传播时需要渐变。 创建张量时,可以指定是否需要该张量来承载渐变。 在我们的示例中,我们没有使用梯度更新输入张量(输入永远不会改变):我们只需要更改权重即可。 由于我们没有在迭代中更改输入,因此不需要输入张量即可计算梯度。 因此,在包装输入张量时,我们将`False`作为`required_grad`参数传递,对于权重,我们传递`True`。 检查我们之前创建的张量实例的`grad``data`属性。
Tensor 和`Function`实例在图中时是相互连接的,并且一起构成了非循环计算图。 除了用户明确创建的张量以外,每个张量都连接到一个函数。 (如果用户未明确创建张量,则必须通过函数创建张量。例如,表达式 *c = a + b* 中的`c`由加法函数创建。 )您可以通过在张量上调用`grade_fn`来访问创建器功能。 打印`grad``.data``.grade_fn()`的值可得到以下结果:
Tensor 和`Function`实例在图中时是相互连接的,并且一起构成了非循环计算图。 除了用户明确创建的张量以外,每个张量都连接到一个函数。 (如果用户未明确创建张量,则必须通过函数创建张量。例如,表达式`c = a + b`中的`c`由加法函数创建。 )您可以通过在张量上调用`grade_fn`来访问创建器功能。 打印`grad``.data``.grade_fn()`的值可得到以下结果:
```py
print(x.grad, x.grad_fn, x)
......@@ -222,7 +226,7 @@ for epoch in range(epochs):
b2 -= lr * b2.grad
```
前面的代码段与在第 1 章,*深度学习演练和 PyTorch 简介*中看到的相同,其中解释了静态和动态计算图,但在这里我们来看一下 从另一个角度看代码:模型说明。 它从循环遍历每个时期的批量开始,并使用我们正在构建的模型处理每个批量。 与基于静态计算图的框架不同,我们尚未构建图。 我们刚刚定义了超参数,并根据我们的数据制作了张量。
前面的代码段与在第 1 章,“深度学习演练和 PyTorch 简介”中看到的相同,其中解释了静态和动态计算图,但在这里我们来看一下 从另一个角度看代码:模型说明。 它从循环遍历每个时期的批量开始,并使用我们正在构建的模型处理每个批量。 与基于静态计算图的框架不同,我们尚未构建图。 我们刚刚定义了超参数,并根据我们的数据制作了张量。
##### 建立图表
......@@ -232,7 +236,7 @@ for epoch in range(epochs):
图 2.6:网络架构
第一层由批量输入矩阵,权重和偏差之间的矩阵乘法和加法组成。 此时,`a2`张量应具有一个`grad_fn`,这应该是矩阵加法的后向操作。 但是,由于我们还没有进行反向传递,因此`.grad`应该返回`None``.data`,并且将一如既往地返回张量,以及矩阵乘法和偏差加法的结果。 神经元活动由 S 形激活函数定义,它以 **h2** (代表第二层中的隐藏单位)的输出形式提供给我们。 第二层采用相同的结构:矩阵乘法,偏差加法和 S 形。 最后得到`hyp`,它具有预期的结果:
第一层由批量输入矩阵,权重和偏差之间的矩阵乘法和加法组成。 此时,`a2`张量应具有一个`grad_fn`,这应该是矩阵加法的后向操作。 但是,由于我们还没有进行反向传递,因此`.grad`应该返回`None``.data`,并且将一如既往地返回张量,以及矩阵乘法和偏差加法的结果。 神经元活动由 S 形激活函数定义,它以`h2`(代表第二层中的隐藏单位)的输出形式提供给我们。 第二层采用相同的结构:矩阵乘法,偏差加法和 S 形。 最后得到`hyp`,它具有预期的结果:
```py
print(a2.grad, a2.grad_fn, a2)
......@@ -462,9 +466,9 @@ with torch.no_grad():
##### 其他层
*nn* 模块具有丰富的,具有不同的层,您需要使用当前的深度学习技术来构建几乎所有内容。
`nn`模块具有丰富的,具有不同的层,您需要使用当前的深度学习技术来构建几乎所有内容。
`nn.Module`附带的一个重要层是顺序容器,如果模型的结构是连续且直接的,则它提供了一个易于使用的 API 来制作模型对象而无需用户编写类结构。 `FizBuzNet`结构为**线性** | **Sigmoid** | **线性** | **Sigmoid** 可以通过单行代码用 Sequential 实现,这就像我们之前构建的`FizBuzNet`网络一样:
`nn.Module`附带的一个重要层是顺序容器,如果模型的结构是连续且直接的,则它提供了一个易于使用的 API 来制作模型对象而无需用户编写类结构。 `FizBuzNet`结构为**线性 | Sigmoid | 线性 | Sigmoid**可以通过单行代码用 Sequential 实现,这就像我们之前构建的`FizBuzNet`网络一样:
```py
import torch.nn as nn
......
......@@ -12,7 +12,7 @@ PyTorch 最初是由 Facebook 实习生作为研究框架开始的,现已发
先前的深度学习工作流程几乎等同于业内几乎每个人所实现的工作流程,即使对于高度复杂的实现,也略有不同。 本章简要说明了第一和最后一个阶段,并进入了中间三个阶段的核心,即设计和实验,模型实现以及训练和验证。
工作流的最后阶段通常是人们很费劲的,尤其是在应用程序规模很大的情况下。 之前我曾提到,尽管 PyTorch 是作为面向研究的框架构建的,但是社区设法将 Caffe2 集成到 PyTorch 的后端,这为 Facebook 使用的数千种模型提供了支持。 因此,在第 8 章, *PyTorch 到生产*中详细讨论了将模型交付生产的过程,并举例说明了如何使用 ONNX,PyTorch JIT 等来展示如何交付用于服务的 PyTorch 模型 数百万个请求,以及将模型迁移到单板计算机和移动设备。
工作流的最后阶段通常是人们很费劲的,尤其是在应用程序规模很大的情况下。 之前我曾提到,尽管 PyTorch 是作为面向研究的框架构建的,但是社区设法将 Caffe2 集成到 PyTorch 的后端,这为 Facebook 使用的数千种模型提供了支持。 因此,在第 8 章, “生产中的 PyTorch”中详细讨论了将模型交付生产的过程,并举例说明了如何使用 ONNX,PyTorch JIT 等来展示如何交付用于服务的 PyTorch 模型 数百万个请求,以及将模型迁移到单板计算机和移动设备。
## 构思和计划
......
......@@ -10,7 +10,7 @@
尽管原始 RNN(在输入中为每个单元展开一个简单的 RNN 单元)是一个革命性的想法,但未能提供可用于生产的结果。 主要障碍是长期依赖问题。 当输入序列的长度增加时,网络到达最后一个单元时将无法从初始单位(单词,如果是自然语言)中记住信息。 我们将在接下来的部分中看到 RNN 单元包含的内容以及如何将其展开。
几次迭代和多年的研究得出了 RNN 架构设计的几种不同方法。 最新的模型现在使用**长短期内存****LSTM**)实现或**门控循环单元****GRU**)。 这两种实现都将 RNN 单元内的门用于不同目的,例如遗忘门,它使网络忘记不必要的信息。 这些架构具有香草 RNN 所存在的长期依赖性问题,因此使用门不仅要忘记不必要的信息,而且要记住在长距离移动到最后一个单元时所必需的信息。
几次迭代和多年的研究得出了 RNN 架构设计的几种不同方法。 最新的模型现在使用**长短期记忆****LSTM**)实现或**门控循环单元****GRU**)。 这两种实现都将 RNN 单元内的门用于不同目的,例如遗忘门,它使网络忘记不必要的信息。 这些架构具有香草 RNN 所存在的长期依赖性问题,因此使用门不仅要忘记不必要的信息,而且要记住在长距离移动到最后一个单元时所必需的信息。
注意是下一个重大发明,它可以帮助网络将注意力集中在输入的重要部分上,而不是搜索整个输入并试图找到答案。 实际上,来自 Google Brain 和多伦多大学的一个团队证明,注意力可以击败 LSTM 和 GRU 网络[1]。 但是,大多数实现都同时使用 LSTM / GRU 和注意力。
......
......@@ -31,7 +31,7 @@ GAN 的创建者 Ian Goodfellow 描述了几类生成网络:
* 自回归模型
*
自回归模型是从先前的值推断当前值的模型,正如我们在第 5 章,*顺序数据处理*中使用 RNN 所讨论的那样。 **可变自动编码器****VAE**)是自动编码器的一种变体,由编码器和解码器组成,其中编码器将输入编码为低维潜在空间向量, 解码器解码潜向量以生成类似于输入的输出。
自回归模型是从先前的值推断当前值的模型,正如我们在第 5 章,“序列数据处理”中使用 RNN 所讨论的那样。 **可变自动编码器****VAE**)是自动编码器的一种变体,由编码器和解码器组成,其中编码器将输入编码为低维潜在空间向量, 解码器解码潜向量以生成类似于输入的输出。
整个研究界都同意,GAN 是人工智能世界中的下一个重要事物之一。 GAN 具有生成网络和对抗网络,并且两者相互竞争以生成高质量的输出图像。 GAN 和自回归模型都基于不同的原理工作,但是每种方法都有其自身的优缺点。 在本章中,我们将使用这两种方法开发一个基本示例。
......
......@@ -72,7 +72,7 @@ flask run
```
我们已经建立了简单的 Flask 应用程序。 现在,将 fizzbuzz 模型引入我们的应用程序。 以下代码片段显示了与第 2 章和*简单神经网络*相同的模型,供您参考。 该模型将从路由器功能中调用。 我们已经在第 2 章和*一个简单的神经网络*中对模型进行了训练,因此,我们将在这里加载训练后的模型,而不是再次对其进行训练:
我们已经建立了简单的 Flask 应用程序。 现在,将 fizzbuzz 模型引入我们的应用程序。 以下代码片段显示了与第 2 章和*简单神经网络*相同的模型,供您参考。 该模型将从路由器功能中调用。 我们已经在第 2 章和“一个简单的神经网络”中对模型进行了训练,因此,我们将在这里加载训练后的模型,而不是再次对其进行训练:
```py
import torch.nn as nn
......
......@@ -499,7 +499,7 @@ Xavier 初始化是神经网络中权重的初始化,是遵循高斯分布的
RNN 实际上无法处理**长期依赖项**。 随着输出序列中的输出数据点与输入序列中的输入数据点之间的距离增加,RNN 无法在两者之间连接信息。 这通常发生在基于文本的任务中,例如机器翻译,音频到文本,以及序列长度较长的更多任务。
**长短期内存网络**也称为 **LSTM** (由 Hochreiter 和 Schmidhuber 引入),能够处理这些长期依赖性。 看一下此处给出的图像:
**长短期记忆网络**也称为 **LSTM** (由 Hochreiter 和 Schmidhuber 引入),能够处理这些长期依赖性。 看一下此处给出的图像:
![](img/3822e6c5-1056-44e1-ad43-c0b7c68a00e0.png)
......
......@@ -12,7 +12,7 @@
诸如处理连续动作空间域的策略梯度之类的算法归为**连续动作空间****CAS**)算法。 因此,在行动空间上提供随机表示的基于策略的方法解决了该问题,而不是 DAS 算法中的离散化。 CAS 算法最初是开发并用于低维状态空间,后来使用基于 CNN 的架构扩展到高维状态空间。 CAS 算法分为两个子类别:**随机连续动作空间****SCAS**)和**确定性连续动作空间****DCAS**)算法。 它们之间的主要区别在于复杂性,因为 SCAS 算法提供了更好的覆盖范围,因此需要大量的训练样本来学习更好的策略。 在现实世界的机器人应用中获取大量训练样本是非常不可行的,因此,仿真必须以尽可能最佳的方式表示现实世界,否则生成现实世界的数据将非常昂贵。
确定性策略梯度的发现超过了随机策略算法,如 [Silver 等人](http://proceedings.mlr.press/v32/silver14.pdf)所述,该技术已包含在[附录 A](../Text/15.html) 中, *强化学习*中的其他主题。 在本章中,我们将介绍机器人强化学习背后的挑战以及当前如何实施机器人强化学习。
确定性策略梯度的发现超过了随机策略算法,如 [Silver 等人](http://proceedings.mlr.press/v32/silver14.pdf)所述,该技术已包含在[附录 A](../Text/15.html) 中, “强化学习”中的其他主题。 在本章中,我们将介绍机器人强化学习背后的挑战以及当前如何实施机器人强化学习。
本章将讨论的主题包括:
......@@ -75,7 +75,7 @@
机器人与现实世界互动。 因此,机器人强化学习的真正问题是应对这些现实问题。 这是因为在现实世界中机器人组件的定期磨损非常昂贵。 连续的维护和修理在劳力和维护和修理的时间损失方面付出了巨大的代价。 因此,安全探索是机器人强化学习过程中的关键问题。
Perkins 和 Barto(2002)提出了一种基于 Lyapunov 函数构造强化学习主体的方法([附录 A](../Text/15.html)*强化学习*中的其他主题)。 现实世界带来的挑战包括环境因素的变化,即气候,温度,光线等。 结果,由于温度和气候的极端影响,机器人的动力学将受到影响,并且将避免学习过程的收敛。 现实环境是不确定的。 结果,由于气候,温度,光线等外部因素,无法产生过去的学习时间。 因此,状态是不确定的,因此很难模拟真实的真实场景。 因此,大多数模拟器都没有考虑气候,温度和光的要素。 因此,这对要解决的算法提出了严峻的挑战。 除此之外,传感器噪声测量的不确定性导致无法直接用传感器观察所有状态。
Perkins 和 Barto(2002)提出了一种基于 Lyapunov 函数构造强化学习主体的方法([附录 A](../Text/15.html)“强化学习”中的其他主题)。 现实世界带来的挑战包括环境因素的变化,即气候,温度,光线等。 结果,由于温度和气候的极端影响,机器人的动力学将受到影响,并且将避免学习过程的收敛。 现实环境是不确定的。 结果,由于气候,温度,光线等外部因素,无法产生过去的学习时间。 因此,状态是不确定的,因此很难模拟真实的真实场景。 因此,大多数模拟器都没有考虑气候,温度和光的要素。 因此,这对要解决的算法提出了严峻的挑战。 除此之外,传感器噪声测量的不确定性导致无法直接用传感器观察所有状态。
现实世界中的大多数机器人学习任务都需要人工监督,而获取现实世界中的样本在时间,劳动力和金钱方面都非常昂贵。 在机器人强化学习中,无法使用诸如模拟器之类的情景设置,因为它们在时间,维修和金钱上都花费很多。 机器人需要在严格的约束下与现实世界互动,以免造成重大破坏。
......
......@@ -8,7 +8,7 @@
* 面向 NLP 的系统(例如文本摘要,对话框生成,问题解答,机器翻译等)确实具有典型的强化学习场景。 例如,对话系统具有增强型学习代理,该学习代理根据接收到的查询生成响应,其中接收到的查询可以是代表当前状态的信号,并且可以采取某种行动来生成响应,代理可以对此进行反馈 以奖励的形式。
* 有很多隐藏变量,它们以隐藏状态的形式存在,还有更多。 决定要包括哪个潜在变量也可以表示为与某些奖励相关的动作。
* 当前,对于序列到序列模型,我们有一个 BLEU 分数(请参见[附录 A](../Text/15.html)*强化学习*中的其他主题),该分数用于评估生成的语言和实际语言之间的错误分数 输出,但 BLEU 分数只能在生成输入的整个预测语言之后进行评估。 它无法评估代持续进行的时间; 因此,它无法改善旅途中的流程。
* 当前,对于序列到序列模型,我们有一个 BLEU 分数(请参见[附录 A](../Text/15.html)“强化学习”中的其他主题),该分数用于评估生成的语言和实际语言之间的错误分数 输出,但 BLEU 分数只能在生成输入的整个预测语言之后进行评估。 它无法评估代持续进行的时间; 因此,它无法改善旅途中的流程。
根据迄今为止进行的积极研究,强化学习为破坏和增强 NLP 下列领域的成果提供了机会:
......@@ -31,7 +31,7 @@
* **提取摘要**:通过复制输入文本中的部分文本来创建摘要
* **抽象性摘要**:通过改写文本或使用输入文本中未包含的新词来生成新文本
为机器翻译创建的基于注意力的编码器解码器模型(Bahdanau 等,2014)是一个序列到序列模型,能够通过获得良好的 ROUGE 得分来生成具有良好性能的抽象摘要(请参见[附录 A](../Text/15.html)*强化学习*中的其他主题)。 在短输入序列上的性能很好,并且随着输入文本序列长度的增加而降低。
为机器翻译创建的基于注意力的编码器解码器模型(Bahdanau 等,2014)是一个序列到序列模型,能够通过获得良好的 ROUGE 得分来生成具有良好性能的抽象摘要(请参见[附录 A](../Text/15.html)“强化学习”中的其他主题)。 在短输入序列上的性能很好,并且随着输入文本序列长度的增加而降低。
在 CNN /每日邮件数据集的更大输入序列和输出摘要数据集上(Hermann 等,2015),Nallapati 等人提出了抽象摘要模型。 (2016)的应用,其中输入序列最多为 800 个令牌,而摘要最多为 100 个令牌。 对本实验的分析表明,与较大输入序列的基于注意力的编码器-解码器模型相关的问题是,它们通常会生成异常摘要,这些摘要通常由重复的短语组成。 这是因为仅通过监督学习方法进行训练的编码器解码器模型通常会遭受曝光偏差,即在训练过程中的每个时间步骤都提供了地面真相(实际文本)的假设。
......@@ -55,7 +55,7 @@
# 神经内注意模型
本节说明了编码器-解码器网络上的神经内注意模型。 此处,![](img/854a7ddc-0625-4736-b366-910857f25226.png)代表输入(文章)令牌的序列,![](img/e02447f3-d66c-484b-adb0-e1dc426b51e5.png)代表输出(摘要)令牌的序列。 网络的编码器部分由双向 LSTM 组成(请参见[附录 A](../Text/15.html)*强化学习*中的其他主题)。 因此,使用双向 LSTM 读取输入序列`x`,该 LSTM 从![](img/f25db2d7-ce50-4b2e-951a-809217f5d3f4.png)的嵌入向量计算隐藏状态![](img/a30dc36d-fe5e-4660-ad70-f9dc529e6650.png),其中||。 表示向量的串联。
本节说明了编码器-解码器网络上的神经内注意模型。 此处,![](img/854a7ddc-0625-4736-b366-910857f25226.png)代表输入(文章)令牌的序列,![](img/e02447f3-d66c-484b-adb0-e1dc426b51e5.png)代表输出(摘要)令牌的序列。 网络的编码器部分由双向 LSTM 组成(请参见[附录 A](../Text/15.html)“强化学习”中的其他主题)。 因此,使用双向 LSTM 读取输入序列`x`,该 LSTM 从![](img/f25db2d7-ce50-4b2e-951a-809217f5d3f4.png)的嵌入向量计算隐藏状态![](img/a30dc36d-fe5e-4660-ad70-f9dc529e6650.png),其中||。 表示向量的串联。
在框架的解码器部分,使用单个 LSTM,该 LSTM 从![](img/5ba77ef5-982e-4a34-83e0-9b3458143c64.png)的嵌入向量计算隐藏状态![](img/8a85c52e-c80d-4e61-9e7a-7ea72560da10.png)。 在时间步零处的初始隐藏状态(即![](img/3acb7be9-9441-42fd-9bd0-e5ecbfb0a922.png))使用编码器的最后一个隐藏状态(即![](img/046773a8-466d-4c5e-b7a3-4a6e90ab83de.png))进行初始化。 因此,![](img/e260025c-5c07-4766-992e-1f8e2fd73844.png)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册