提交 3df28485 编写于 作者: W wizardforcel

2021-01-21 16:14:40

上级 1979e35c
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
《PyTorch 深度学习研讨会》首先介绍了深度学习及其应用。 您将探索 PyTorch 的语法,并学习如何定义网络架构和训练模型。 接下来,您将学习三种主要的神经网络架构-卷积,人工和循环-甚至使用这些网络解决实际数据问题。 后面的章节将向您展示如何创建样式转换模型以从两个图像中开发一个新图像,最后再带您了解 RNN 如何存储内存以解决关键数据问题。 《PyTorch 深度学习研讨会》首先介绍了深度学习及其应用。 您将探索 PyTorch 的语法,并学习如何定义网络架构和训练模型。 接下来,您将学习三种主要的神经网络架构-卷积,人工和循环-甚至使用这些网络解决实际数据问题。 后面的章节将向您展示如何创建样式转换模型以从两个图像中开发一个新图像,最后再带您了解 RNN 如何存储内存以解决关键数据问题。
到本书结尾,您将掌握 PyTorch 的基本概念,工具和库,以开发自己的深度神经网络和智能应用程序 到本书结尾,您将掌握 PyTorch 的基本概念,工具和库,以开发自己的深度神经网络和智能应用。
## 受众群体 ## 受众群体
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
总览 总览
本章介绍了本书的两个主要主题:深度学习和 PyTorch。 在这里,您将能够探索深度学习的一些最受欢迎的应用程序,了解什么是 PyTorch,并使用 PyTorch 构建单层网络,这将是您将学习应用于现实生活的起点 数据问题。 在本章结束时,您将能够使用 PyTorch 的语法来构建神经网络,这在后续章节中将是必不可少的。 本章介绍了本书的两个主要主题:深度学习和 PyTorch。 在这里,您将能够探索深度学习的一些最受欢迎的应用,了解什么是 PyTorch,并使用 PyTorch 构建单层网络,这将是您将学习应用于现实生活的起点 数据问题。 在本章结束时,您将能够使用 PyTorch 的语法来构建神经网络,这在后续章节中将是必不可少的。
# 简介 # 简介
...@@ -52,7 +52,7 @@ PyTorch 于 2017 年推出,其主要特点是它使用**图形处理单元** ...@@ -52,7 +52,7 @@ PyTorch 于 2017 年推出,其主要特点是它使用**图形处理单元**
* **自动驾驶汽车**:诸如 Google 之类的多家公司一直在致力于开发部分或全部自动驾驶汽车,这些汽车通过使用数字传感器识别周围的物体来学习驾驶。 * **自动驾驶汽车**:诸如 Google 之类的多家公司一直在致力于开发部分或全部自动驾驶汽车,这些汽车通过使用数字传感器识别周围的物体来学习驾驶。
* **医学诊断**:深度学习通过提高诸如脑和乳腺癌等绝症的诊断准确率,正在对该行业产生影响。 这是通过根据以前有或没有癌症的患者的标记 X 射线对新患者的 X 射线(或其他诊断影像机制)进行分类来完成的。 * **医学诊断**:深度学习通过提高诸如脑和乳腺癌等绝症的诊断准确率,正在对该行业产生影响。 这是通过根据以前有或没有癌症的患者的标记 X 射线对新患者的 X 射线(或其他诊断影像机制)进行分类来完成的。
* **语音助手**:由于各种语音激活的智能助手(例如 Apple 的 Siri,Google Home 和亚马逊的 Alexa)的激增,它可能是当今最受欢迎的应用程序之一。 * **语音助手**:由于各种语音激活的智能助手(例如 Apple 的 Siri,Google Home 和亚马逊的 Alexa)的激增,它可能是当今最受欢迎的应用之一。
* **自动生成文本**:这意味着根据输入的句子生成新文本。 这通常用于电子邮件编写中,其中电子邮件提供者根据已编写的文本向用户建议接下来的几个单词。 * **自动生成文本**:这意味着根据输入的句子生成新文本。 这通常用于电子邮件编写中,其中电子邮件提供者根据已编写的文本向用户建议接下来的几个单词。
* **广告**:在商业世界中,深度学习通过瞄准合适的受众并制作更有效的广告来帮助提高广告系列的投资回报。 这样的一个例子是生成内容,以产生最新的和信息丰富的博客,以帮助吸引当前客户并吸引新客户。 * **广告**:在商业世界中,深度学习通过瞄准合适的受众并制作更有效的广告来帮助提高广告系列的投资回报。 这样的一个例子是生成内容,以产生最新的和信息丰富的博客,以帮助吸引当前客户并吸引新客户。
* **价格预测**:对于初学者来说,这是使用机器学习算法可以实现的典型示例。 价格预测包括根据实际数据训练模型。 例如,在房地产领域,这将包括提供具有房地产特征及其最终价格的模型,以便能够仅基于房地产特征来预测未来入场券的价格。 * **价格预测**:对于初学者来说,这是使用机器学习算法可以实现的典型示例。 价格预测包括根据实际数据训练模型。 例如,在房地产领域,这将包括提供具有房地产特征及其最终价格的模型,以便能够仅基于房地产特征来预测未来入场券的价格。
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
概述 概述
本章介绍了神经网络的主要组成部分,并解释了当今的三种主要神经网络架构。 此外,它解释了训练任何人工智能模型之前数据准备的重要性,并最终解释了解决回归数据问题的过程。 在本章的最后,您将牢固地掌握不同网络架构及其不同应用程序的学习过程。 本章介绍了神经网络的主要组成部分,并解释了当今的三种主要神经网络架构。 此外,它解释了训练任何人工智能模型之前数据准备的重要性,并最终解释了解决回归数据问题的过程。 在本章的最后,您将牢固地掌握不同网络架构及其不同应用的学习过程。
# 简介 # 简介
...@@ -736,7 +736,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过 ...@@ -736,7 +736,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过
在本活动中,我们将准备一个数据集,其中包含歌曲列表,每首歌曲具有几个有助于确定其发行年份的属性。 数据准备步骤对于本章的下一个活动至关重要。 让我们看一下以下情况。 在本活动中,我们将准备一个数据集,其中包含歌曲列表,每首歌曲具有几个有助于确定其发行年份的属性。 数据准备步骤对于本章的下一个活动至关重要。 让我们看一下以下情况。
您在一家音乐唱片公司工作,您的老板想揭示表不同时间段唱片的细节,这就是为什么他们汇总了一个包含 515,345 条唱片的数据的数据集,发布年份从 1922 年到 2011 年。 要求您准备数据集,以便准备将其馈送到神经网络。 执行以下步骤以完成此活动: 您在一家音乐唱片公司工作,您的老板想揭示表不同时间段唱片的细节,这就是为什么他们汇总了一个包含 515,345 条唱片的数据的数据集,发布年份从 1922 年到 2011 年。 要求您准备数据集,以便准备将其馈送到神经网络。 执行以下步骤以完成此活动:
注意 注意
...@@ -768,7 +768,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过 ...@@ -768,7 +768,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过
PyTorch 的构建考虑了该领域许多开发人员的意见,其优点是可以将两个近似值放在同一位置。 正如我们前面提到的,它具有一个神经网络模块,该模块被构建为允许使用顺序容器对简单架构进行简单的预定义实现,同时允许创建自定义模块,从而为构建非常复杂的架构的过程引入灵活性 。 PyTorch 的构建考虑了该领域许多开发人员的意见,其优点是可以将两个近似值放在同一位置。 正如我们前面提到的,它具有一个神经网络模块,该模块被构建为允许使用顺序容器对简单架构进行简单的预定义实现,同时允许创建自定义模块,从而为构建非常复杂的架构的过程引入灵活性 。
在本节中,我们将讨论使用顺序容器开发深度神经网络,以揭开其复杂性。 不过,在本书的后续章节中,我们将继续研究更复杂和抽象的应用程序,而这些应用程序也可以非常轻松地实现。 在本节中,我们将讨论使用顺序容器开发深度神经网络,以揭开其复杂性。 不过,在本书的后续章节中,我们将继续研究更复杂和抽象的应用,而这些应用也可以非常轻松地实现。
正如我们前面提到的,顺序容器是一个模块,它被构建为包含遵循顺序的模块序列。 它包含的每个模块都将对给定的输入进行一些计算以得出结果。 正如我们前面提到的,顺序容器是一个模块,它被构建为包含遵循顺序的模块序列。 它包含的每个模块都将对给定的输入进行一些计算以得出结果。
......
...@@ -695,9 +695,9 @@ batch_size = 100 ...@@ -695,9 +695,9 @@ batch_size = 100
到目前为止,您已经学习并实践了为常规回归和分类问题构建出色的深度学习模型的关键概念和技巧。 在现实生活中,模型不仅仅是为了学习而构建的。 相反,当出于研究目的以外的目的训练模型时,主要思想是能够在将来重用它们以对新数据进行预测,尽管该模型未经过训练,但该模型应具有相似的良好性能。 到目前为止,您已经学习并实践了为常规回归和分类问题构建出色的深度学习模型的关键概念和技巧。 在现实生活中,模型不仅仅是为了学习而构建的。 相反,当出于研究目的以外的目的训练模型时,主要思想是能够在将来重用它们以对新数据进行预测,尽管该模型未经过训练,但该模型应具有相似的良好性能。
在小型组织中,可以对模型进行序列化和反序列化。 但是,当模型要由大型公司,用户使用或更改非常重要的大型任务时,将模型转换为可以在大多数生产环境中使用的格式(例如 API, 网站以及在线和离线应用程序)。 在小型组织中,可以对模型进行序列化和反序列化。 但是,当模型要由大型公司,用户使用或更改非常重要的大型任务时,将模型转换为可以在大多数生产环境中使用的格式(例如 API, 网站以及在线和离线应用)。
在本节中,我们将学习如何保存和加载模型,以及如何使用 PyTorch 的最新功能将我们的模型转换为高度通用的 C++ 应用程序。 我们还将学习如何创建 API 以利用经过训练的模型。 在本节中,我们将学习如何保存和加载模型,以及如何使用 PyTorch 的最新功能将我们的模型转换为高度通用的 C++ 应用。 我们还将学习如何创建 API 以利用经过训练的模型。
## 保存和加载模型 ## 保存和加载模型
...@@ -766,7 +766,7 @@ prediction = traced_script(input) ...@@ -766,7 +766,7 @@ prediction = traced_script(input)
## 构建 API ## 构建 API
**应用程序编程接口****API**)包含一个专门创建供其他程序使用的程序(与网站或界面相反,后者是由人为操纵的) 。 据此,API 在创建要在生产环境中使用的深度学习解决方案时使用,因为它们允许通过其他方式(例如网站)访问从运行模型(例如预测)获得的信息。 **应用编程接口****API**)包含一个专门创建供其他程序使用的程序(与网站或界面相反,后者是由人为操纵的) 。 据此,API 在创建要在生产环境中使用的深度学习解决方案时使用,因为它们允许通过其他方式(例如网站)访问从运行模型(例如预测)获得的信息。
在本节中,我们将探讨 Web API(通过互联网与其他程序共享信息的 API)的创建。 该 API 的功能是加载先前保存的模型并根据一组给定的功能进行预测。 向 API 发出 HTTP 请求的程序可以访问此预测。 在本节中,我们将探讨 Web API(通过互联网与其他程序共享信息的 API)的创建。 该 API 的功能是加载先前保存的模型并根据一组给定的功能进行预测。 向 API 发出 HTTP 请求的程序可以访问此预测。
...@@ -791,7 +791,7 @@ prediction = traced_script(input) ...@@ -791,7 +791,7 @@ prediction = traced_script(input)
import final_model import final_model
``` ```
2. 初始化 Flask 应用程序 2. 初始化 Flask 应用:
```py ```py
app = flask.Flask(__name__) app = flask.Flask(__name__)
...@@ -836,7 +836,7 @@ prediction = traced_script(input) ...@@ -836,7 +836,7 @@ prediction = traced_script(input)
app.run(debug=True, use_reloader=False) app.run(debug=True, use_reloader=False)
``` ```
同样,在开发过程中,`DEBUG`设置为`True`。 `use_reloader`参数设置为`False`,以允许该应用程序在 Jupyter 笔记本上运行。 但是,不建议从 Jupyter 笔记本运行该应用程序。 这仅出于教学目的。 在现实生活中,应将`use_reloader`设置为`True`,并且应通过命令提示符实例或终端将应用程序作为 Python 文件运行。 同样,在开发过程中,`DEBUG`设置为`True`。 `use_reloader`参数设置为`False`,以允许该应用在 Jupyter 笔记本上运行。 但是,不建议从 Jupyter 笔记本运行该应用。 这仅出于教学目的。 在现实生活中,应将`use_reloader`设置为`True`,并且应通过命令提示符实例或终端将应用作为 Python 文件运行。
## 练习 3.03:创建 Web API ## 练习 3.03:创建 Web API
...@@ -876,7 +876,7 @@ prediction = traced_script(input) ...@@ -876,7 +876,7 @@ prediction = traced_script(input)
图 3.11:执行代码后的警告 图 3.11:执行代码后的警告
它包含一些警告,这些警告指定了正在运行的 Flask 应用程序的条件,以及包含类似于以下内容的 URL 的一行文本: 它包含一些警告,这些警告指定了正在运行的 Flask 应用的条件,以及包含类似于以下内容的 URL 的一行文本:
```py ```py
http://127.0.0.1:5000/ http://127.0.0.1:5000/
...@@ -934,11 +934,11 @@ prediction = traced_script(input) ...@@ -934,11 +934,11 @@ prediction = traced_script(input)
3. 定义 API 的路由,使其为`/prediction`,并定义方法为`POST`。 然后,定义将接收`POST`数据并将其馈送到模型以执行预测的函数。 3. 定义 API 的路由,使其为`/prediction`,并定义方法为`POST`。 然后,定义将接收`POST`数据并将其馈送到模型以执行预测的函数。
4. 运行 Flask 应用。 4. 运行 Flask 应用。
运行后,该应用程序将如下所示: 运行后,该应用将如下所示:
![Figure 3.13: A screenshot of the app after running it ](img/B15778_03_13.jpg) ![Figure 3.13: A screenshot of the app after running it ](img/B15778_03_13.jpg)
图 3.13:应用程序运行后的屏幕截图 图 3.13:应用运行后的屏幕截图
注意 注意
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
在本章中,我们将使用这种经过预训练的模型来解决计算机视觉问题,该问题由于专门用于共享图像的社交媒体渠道的普及而特别著名。 它包括执行样式转换,以便使用一个图像的样式(颜色和纹理)以及另一个图像的内容(形状和对象)创建新图像。 在本章中,我们将使用这种经过预训练的模型来解决计算机视觉问题,该问题由于专门用于共享图像的社交媒体渠道的普及而特别著名。 它包括执行样式转换,以便使用一个图像的样式(颜色和纹理)以及另一个图像的内容(形状和对象)创建新图像。
每天对常规图像应用滤镜以提高其质量和吸引力,同时在社交媒体个人资料上发布时,每天执行数百万次此任务。 尽管这看起来很简单,但本章将解释这些图像编辑应用程序幕后发生的魔术。 每天对常规图像应用滤镜以提高其质量和吸引力,同时在社交媒体个人资料上发布时,每天执行数百万次此任务。 尽管这看起来很简单,但本章将解释这些图像编辑应用幕后发生的魔术。
注意 注意
......
...@@ -292,7 +292,7 @@ for i in range(1, epochs+1): ...@@ -292,7 +292,7 @@ for i in range(1, epochs+1):
## LSTM 网络的应用 ## LSTM 网络的应用
除了我们先前解释的应用程序之外,LSTM 网络存储长期信息的能力还使数据科学家能够处理复杂的数据问题,这些问题利用大数据序列作为输入,下面将对其中的一些问题进行说明: 除了我们先前解释的应用之外,LSTM 网络存储长期信息的能力还使数据科学家能够处理复杂的数据问题,这些问题利用大数据序列作为输入,下面将对其中的一些问题进行说明:
* **文本生成**:生成任何文本,例如您在此处阅读的文本,都可以转换为 LSTM 网络的任务。 通过基于所有先前字母选择每个字母来工作。 使用大型文本(例如著名书籍的文本)来训练执行此任务的网络。 这是因为最终模型将创建一个文本,该文本类似于受其训练的文本的书写样式。 例如,以诗训练的模型将具有与您在与邻居交谈中期望的叙事不同的叙事。 * **文本生成**:生成任何文本,例如您在此处阅读的文本,都可以转换为 LSTM 网络的任务。 通过基于所有先前字母选择每个字母来工作。 使用大型文本(例如著名书籍的文本)来训练执行此任务的网络。 这是因为最终模型将创建一个文本,该文本类似于受其训练的文本的书写样式。 例如,以诗训练的模型将具有与您在与邻居交谈中期望的叙事不同的叙事。
* **音乐生成**:就像可以将文本序列输入到网络中以生成相似的新文本一样,也可以将一系列音符输入网络以生成新的音符序列。 跟踪先前的音符将有助于获得和谐的旋律,而不仅仅是一系列随机的音符。 例如,用披头士乐队的一首流行歌曲来馈送音频文件,将产生一系列音符,这些音符类似于乐队的和声。 * **音乐生成**:就像可以将文本序列输入到网络中以生成相似的新文本一样,也可以将一系列音符输入网络以生成新的音符序列。 跟踪先前的音符将有助于获得和谐的旋律,而不仅仅是一系列随机的音符。 例如,用披头士乐队的一首流行歌曲来馈送音频文件,将产生一系列音符,这些音符类似于乐队的和声。
...@@ -853,7 +853,7 @@ class LSTM(nn.Module): ...@@ -853,7 +853,7 @@ class LSTM(nn.Module):
在本章中,我们讨论了 RNN。 开发这种类型的神经网络是为了解决与序列数据有关的问题。 这意味着单个实例不包含所有相关信息,因为这取决于先前实例中的信息。 在本章中,我们讨论了 RNN。 开发这种类型的神经网络是为了解决与序列数据有关的问题。 这意味着单个实例不包含所有相关信息,因为这取决于先前实例中的信息。
有几种适合这种类型描述的应用程序。 例如,如果没有文本其余部分的上下文,则文本(或语音)的特定部分可能意义不大。 但是,即使 NLP 在 RNN 中得到了最多的研究,在其他应用中,文本的上下文也很重要,例如预测,视频处理或音乐相关的问题。 有几种适合这种类型描述的应用。 例如,如果没有文本其余部分的上下文,则文本(或语音)的特定部分可能意义不大。 但是,即使 NLP 在 RNN 中得到了最多的研究,在其他应用中,文本的上下文也很重要,例如预测,视频处理或音乐相关的问题。
RNN 的工作方式非常聪明。 网络不仅输出结果,而且还输出一个或多个通常称为内存的值。 该内存值用作将来预测的输入。 RNN 的工作方式非常聪明。 网络不仅输出结果,而且还输出一个或多个通常称为内存的值。 该内存值用作将来预测的输入。
......
...@@ -786,7 +786,7 @@ ...@@ -786,7 +786,7 @@
![Figure 3.20: A screenshot of the app after running it ](img/B15778_03_13.jpg) ![Figure 3.20: A screenshot of the app after running it ](img/B15778_03_13.jpg)
图 3.20:应用程序运行后的屏幕截图 图 3.20:应用运行后的屏幕截图
注意 注意
......
...@@ -157,7 +157,7 @@ ...@@ -157,7 +157,7 @@
# 应用领域 # 应用领域
通常,可以使用各种方法解决问题。 例如我们手机上的人脸检测。 图像分类是一种需要大量数据点的方法,而如果使用单次学习的连体网络架构,则仅需几个数据点就可以实现更高的准确率。 连体网络架构已成为软件行业采用的最流行的一次学习架构之一。 它可用于各种其他应用程序,例如面部检测,手写检测和垃圾邮件检测。 但是仍然有很多改进的余地,并且各种各样的研究者正在为此努力。 在下一节中,以相似的主题进行工作,我们将学习匹配的网络架构,该架构使用注意力机制和不同的训练过程来学习训练集标签上的概率分布。 通常,可以使用各种方法解决问题。 例如我们手机上的人脸检测。 图像分类是一种需要大量数据点的方法,而如果使用单次学习的连体网络架构,则仅需几个数据点就可以实现更高的准确率。 连体网络架构已成为软件行业采用的最流行的一次学习架构之一。 它可用于各种其他应用,例如面部检测,手写检测和垃圾邮件检测。 但是仍然有很多改进的余地,并且各种各样的研究者正在为此努力。 在下一节中,以相似的主题进行工作,我们将学习匹配的网络架构,该架构使用注意力机制和不同的训练过程来学习训练集标签上的概率分布。
# 了解匹配网络 # 了解匹配网络
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* 对于每个新任务,神经网络必须从其参数的随机初始化开始,这会导致后期收敛。 迁移学习已通过使用预训练的网络来缓解此问题,但由于数据应具有相似的域而受到限制。 * 对于每个新任务,神经网络必须从其参数的随机初始化开始,这会导致后期收敛。 迁移学习已通过使用预训练的网络来缓解此问题,但由于数据应具有相似的域而受到限制。
* 即使是梯度下降的权重更新步骤方法(例如 AdaGrad,Adam,RMS 等)的变体也无法在较少的时期内表现良好。 这些算法不能保证收敛,特别是在用于非凸优化时。 * 即使是梯度下降的权重更新步骤方法(例如 AdaGrad,Adam,RMS 等)的变体也无法在较少的时期内表现良好。 这些算法不能保证收敛,特别是在用于非凸优化时。
真正有用的是学习一些可以在所有域中使用的通用初始化,这是初始化的一个好地方。 梯度下降算法的关键思想是基于下一步的方向,该方向是根据概率分布假设选择的。 因此,如果我们能够以某种方式完全近似概率分布,则仅需几个步骤就可以优化网络。 这是一次/几次学习基于优化的算法的基本思想。 真正有用的是学习一些可以在所有域中使用的通用初始化,这是初始化的一个好地方。 梯度下降算法的关键思想是基于下一步的方向,该方向是根据概率分布假设选择的。 因此,如果我们能够以某种方式完全近似概率分布,则仅需几个步骤就可以优化网络。 这是一次/小样本学习基于优化的算法的基本思想。
# 了解模型不可知的元学习 # 了解模型不可知的元学习
...@@ -44,7 +44,7 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的 ...@@ -44,7 +44,7 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的
# 算法 # 算法
要了解 MAML 的一次学习/几次学习,首先,我们需要学习某些术语。 这些类似于我们在匹配网络时学到的知识: 要了解 MAML 的一次学习/小样本学习,首先,我们需要学习某些术语。 这些类似于我们在匹配网络时学到的知识:
* `T`:这表示各种任务-例如,我们希望我们的模型学习识别猫,狗,马等,以及`T[i]`代表一种识别猫的训练模型。 在此,`T[i] ∈ T` * `T`:这表示各种任务-例如,我们希望我们的模型学习识别猫,狗,马等,以及`T[i]`代表一种识别猫的训练模型。 在此,`T[i] ∈ T`
* `P(T)`:这表示所有任务之间的概率分布。 我们的目标是通过 MAML 学习`P(T)` * `P(T)`:这表示所有任务之间的概率分布。 我们的目标是通过 MAML 学习`P(T)`
...@@ -78,7 +78,7 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的 ...@@ -78,7 +78,7 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的
对于 Omniglot 和 mini-ImageNet 数据集,MAML 能够实现比连体网络,匹配网络和内存增强神经网络更好的性能。 由于事实证明 MAML 的性能更好,因此还有许多其他任务可以使用 MAML。 让我们来看一个这样的变体-**域自适应元学习****DAML**)。 对于 Omniglot 和 mini-ImageNet 数据集,MAML 能够实现比连体网络,匹配网络和内存增强神经网络更好的性能。 由于事实证明 MAML 的性能更好,因此还有许多其他任务可以使用 MAML。 让我们来看一个这样的变体-**域自适应元学习****DAML**)。
# MAML 应用程序–领域自适应元学习 # MAML 应用域自适应元学习
当涉及到模仿学习时,机器人需要接收适当的数据,这些数据包括有关动觉变化(有关其身体部位运动的意识),遥距操作(控制)和其他类型输入的信息。 另一方面,人脑只需观看一些视频即可学习。 DAML 尝试通过使用元学习(MAML)解决模仿学习的问题。 它提出了一种仅通过利用从不同任务的数据中提取的强大先验知识(例如,关于动觉学习的信息)就可以从人类的单个视频中学习机器人操纵技能的系统,如下图所示: 当涉及到模仿学习时,机器人需要接收适当的数据,这些数据包括有关动觉变化(有关其身体部位运动的意识),遥距操作(控制)和其他类型输入的信息。 另一方面,人脑只需观看一些视频即可学习。 DAML 尝试通过使用元学习(MAML)解决模仿学习的问题。 它提出了一种仅通过利用从不同任务的数据中提取的强大先验知识(例如,关于动觉学习的信息)就可以从人类的单个视频中学习机器人操纵技能的系统,如下图所示:
...@@ -183,7 +183,7 @@ LSTM 元学习器的总体思路非常引人注目。 您可能想知道为什 ...@@ -183,7 +183,7 @@ LSTM 元学习器的总体思路非常引人注目。 您可能想知道为什
在本节中,我们将首先使用 MAML 进行正弦数据回归的简单练习。 在本节中,我们将首先使用 MAML 进行正弦数据回归的简单练习。
# 与模型无关的元学习的简单实现 # 模型无关元学习的简单实现
在本教程中,我们将展示如何应用 MAML 来学习正弦数据的简单曲线。 本教程的第二部分在 GitHub 上可用,我们可以在其中学习如何使用 torch-meta 库在 mini-ImageNet 上训练 MAML。 在本教程中,我们将展示如何应用 MAML 来学习正弦数据的简单曲线。 本教程的第二部分在 GitHub 上可用,我们可以在其中学习如何使用 torch-meta 库在 mini-ImageNet 上训练 MAML。
...@@ -556,4 +556,4 @@ plt.savefig('daml-sine.png') ...@@ -556,4 +556,4 @@ plt.savefig('daml-sine.png')
有关本章中介绍的一些架构的更多详细信息,建议阅读以下论文: 有关本章中介绍的一些架构的更多详细信息,建议阅读以下论文:
* [《与模型无关的元学习》](https://arxiv.org/pdf/1703.03400.pdf) * [《与模型无关的元学习》](https://arxiv.org/pdf/1703.03400.pdf)
* [《作为几次学习模型的优化》](https://openreview.net/pdf?id=rJY0-Kcll) * [《作为小样本学习模型的优化》](https://openreview.net/pdf?id=rJY0-Kcll)
\ No newline at end of file \ No newline at end of file
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
本章将涵盖以下主题: 本章将涵盖以下主题:
* 贝叶斯学习概述 * 贝叶斯学习概述
* 了解定向图形模型 * 了解有向图模型
* 概率方法概述 * 概率方法概述
* 贝叶斯程序学习 * 贝叶斯程序学习
* 判别式 k 次学习 * 判别式 K 次学习
# 技术要求 # 技术要求
...@@ -46,9 +46,9 @@ ...@@ -46,9 +46,9 @@
因此,在贝叶斯学习中,重点是解决后验参数 <sub>![](img/1df7ccef-e62d-415b-8374-c4abefa20f71.png)</sub> ,以明确地对参数中的不确定性建模。 因此,在贝叶斯学习中,重点是解决后验参数 <sub>![](img/1df7ccef-e62d-415b-8374-c4abefa20f71.png)</sub> ,以明确地对参数中的不确定性建模。
# 了解定向图形模型 # 了解有向图模型
现在,在深入研究用于单次学习的概率模型之前,我们将简要研究定向图形模型。 有向图形模型(也称为贝叶斯网络)由与有向边相连的随机变量定义,如在父子关系中。 下图显示了一个这样的贝叶斯网络: 现在,在深入研究用于单次学习的概率模型之前,我们将简要研究有向图模型。 有向图形模型(也称为贝叶斯网络)由与有向边相连的随机变量定义,如在父子关系中。 下图显示了一个这样的贝叶斯网络:
![](img/169cea75-5669-4783-a7c4-a4b77f185c91.png) ![](img/169cea75-5669-4783-a7c4-a4b77f185c91.png)
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
前面方程右侧的条件分布具有大量参数。 这是因为每个分布都以许多变量为条件,并且每个条件变量都有其自己的结果空间。 如果我们在有大量条件变量的情况下在图表中走得更远,则这种影响会更加突出。 因此,要学习每种条件分布的庞大参数集,我们需要大量的标记数据,这在现代机器学习任务中通常是不可用的。 前面方程右侧的条件分布具有大量参数。 这是因为每个分布都以许多变量为条件,并且每个条件变量都有其自己的结果空间。 如果我们在有大量条件变量的情况下在图表中走得更远,则这种影响会更加突出。 因此,要学习每种条件分布的庞大参数集,我们需要大量的标记数据,这在现代机器学习任务中通常是不可用的。
这是定向图形模型进入图片的地方。 它断言了概率的一些条件独立性,从而简化了前面描述的方程式。 有向图模型中的每个变量在条件上独立于给定其父对象的非后代。 定向图形模型不过是条件独立性的表示。 更正式地讲,如果 <sub>![](img/20f73768-ea0a-4718-8951-942b861b9a51.png)</sub> 是有向图中的顶点,则 <sub>![](img/a10513e9-4297-48e5-945d-752c9dd567e8.png)</sub> 是顶点数, <sub>![](img/7d96d230-244e-4a7c-9ef1-640b7e312eda.png)</sub> 都是 顶点 <sub>![](img/40503166-9131-4476-b15a-3296d42e6125.png)</sub> 的父级,则所有顶点上的联合概率分布可写为: 这是有向图模型进入图片的地方。 它断言了概率的一些条件独立性,从而简化了前面描述的方程式。 有向图模型中的每个变量在条件上独立于给定其父对象的非后代。 有向图模型不过是条件独立性的表示。 更正式地讲,如果 <sub>![](img/20f73768-ea0a-4718-8951-942b861b9a51.png)</sub> 是有向图中的顶点,则 <sub>![](img/a10513e9-4297-48e5-945d-752c9dd567e8.png)</sub> 是顶点数, <sub>![](img/7d96d230-244e-4a7c-9ef1-640b7e312eda.png)</sub> 都是 顶点 <sub>![](img/40503166-9131-4476-b15a-3296d42e6125.png)</sub> 的父级,则所有顶点上的联合概率分布可写为:
![](img/4bb469f5-c12f-455b-9a29-06e6eff50baa.png) ![](img/4bb469f5-c12f-455b-9a29-06e6eff50baa.png)
...@@ -114,7 +114,7 @@ ...@@ -114,7 +114,7 @@
2. 每个字符部分都是通过对预定义集合中的子部分进行采样而产生的,因此对下一个子部分进行采样的概率取决于前一个子部分。 2. 每个字符部分都是通过对预定义集合中的子部分进行采样而产生的,因此对下一个子部分进行采样的概率取决于前一个子部分。
3. 为零件![](img/926c9082-f02f-433c-b3e1-573e94e9d7da.png)采样了关系 <sub>![](img/28e359de-d165-4b4c-8034-d123dd8730a5.png)</sub> ,该关系定义了该零件与先前零件的连接方式。 3. 为零件![](img/926c9082-f02f-433c-b3e1-573e94e9d7da.png)采样了关系 <sub>![](img/28e359de-d165-4b4c-8034-d123dd8730a5.png)</sub> ,该关系定义了该零件与先前零件的连接方式。
# 代币生成 # 标记生成
字符标记 <sub>![](img/64c5d9e3-84b6-4eb5-bc34-815982591e9c.png)</sub> 是通过对墨水从笔到纸的流动方式进行建模而由零件和关系生成的。 用于令牌生成的伪代码在上图的 B 侧进行了描述。 首先,将噪声(此处称为运动方差)添加到子零件的比例尺和控制点,以定义冲程(或零件)轨迹 <sub>![](img/2f393738-87bd-4110-aa8a-111d12ad37ee.png)</sub> 。 轨迹的精确开始位置 <sub>![](img/e50475f0-4cb3-4366-b921-914e606d0e42.png)</sub> 由关系 <sub>![](img/3d4cd9b5-2fcd-4be5-9b8d-33bdd263c77b.png)</sub> 决定。 最后,将变换 <sub>![](img/92d0def5-ef1f-4670-a510-e5d83f77e0ac.png)</sub> 用于减轻概率推断。 字符标记 <sub>![](img/64c5d9e3-84b6-4eb5-bc34-815982591e9c.png)</sub> 是通过对墨水从笔到纸的流动方式进行建模而由零件和关系生成的。 用于令牌生成的伪代码在上图的 B 侧进行了描述。 首先,将噪声(此处称为运动方差)添加到子零件的比例尺和控制点,以定义冲程(或零件)轨迹 <sub>![](img/2f393738-87bd-4110-aa8a-111d12ad37ee.png)</sub> 。 轨迹的精确开始位置 <sub>![](img/e50475f0-4cb3-4366-b921-914e606d0e42.png)</sub> 由关系 <sub>![](img/3d4cd9b5-2fcd-4be5-9b8d-33bdd263c77b.png)</sub> 决定。 最后,将变换 <sub>![](img/92d0def5-ef1f-4670-a510-e5d83f77e0ac.png)</sub> 用于减轻概率推断。
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
BPL 是一种高度直观的模型,可以在贝叶斯框架下使用简单的程序为概念建模。 从训练数据中学习概率分布的参数。 在分类和生成的单次计算机视觉任务上,该模型的性能与人类水平的性能相当,其数据需求远低于某些最新的深度学习模型。 这里研究的概率程序非常基础,适合于相当容易的字符识别任务。 BPL 框架支持设计更复杂的程序,这些程序可以对各种对象的复杂表示进行建模。 例如,可以使用此框架对在零件和关系方面具有清晰直观描述的对象(例如车辆,食品,动物,甚至人脸)进行建模。 为此,BPL 框架甚至支持建模抽象知识,例如自然语言语义和物理理论。 然而,这些概率程序需要对数据及其部分,子部分和关系进行手动标记,这是一个耗时的过程,而深度学习方法则是自己学习这些人类直观特征和深层抽象特征。 BPL 是一种高度直观的模型,可以在贝叶斯框架下使用简单的程序为概念建模。 从训练数据中学习概率分布的参数。 在分类和生成的单次计算机视觉任务上,该模型的性能与人类水平的性能相当,其数据需求远低于某些最新的深度学习模型。 这里研究的概率程序非常基础,适合于相当容易的字符识别任务。 BPL 框架支持设计更复杂的程序,这些程序可以对各种对象的复杂表示进行建模。 例如,可以使用此框架对在零件和关系方面具有清晰直观描述的对象(例如车辆,食品,动物,甚至人脸)进行建模。 为此,BPL 框架甚至支持建模抽象知识,例如自然语言语义和物理理论。 然而,这些概率程序需要对数据及其部分,子部分和关系进行手动标记,这是一个耗时的过程,而深度学习方法则是自己学习这些人类直观特征和深层抽象特征。
# 判别式 k 次学习 # 判别式 K 次学习
K 次学习的一种非常常见的方法是训练具有相关任务的大型模型,而我们为此拥有大型数据集。 然后,通过 K 次特定任务对该模型进行微调。 因此,来自大型数据集的知识被*提炼为*到模型中,这仅从几个示例中增加了对新相关任务的学习。 2003 年,Bakker 和 Heskes 提出了一种用于 K 次学习的概率模型,其中所有任务共享一个公共特征提取器,但具有各自的线性分类器,其中仅包含几个特定于任务的参数。 K 次学习的一种非常常见的方法是训练具有相关任务的大型模型,而我们为此拥有大型数据集。 然后,通过 K 次特定任务对该模型进行微调。 因此,来自大型数据集的知识被*提炼为*到模型中,这仅从几个示例中增加了对新相关任务的学习。 2003 年,Bakker 和 Heskes 提出了一种用于 K 次学习的概率模型,其中所有任务共享一个公共特征提取器,但具有各自的线性分类器,其中仅包含几个特定于任务的参数。
...@@ -132,7 +132,7 @@ K 次学习的一种非常常见的方法是训练具有相关任务的大型模 ...@@ -132,7 +132,7 @@ K 次学习的一种非常常见的方法是训练具有相关任务的大型模
学习框架包括四个阶段: 学习框架包括四个阶段:
*学习 *学习
* 概念学习 * 概念学习
* K 次学习 * K 次学习
* K 次测试 * K 次测试
...@@ -141,7 +141,7 @@ K 次学习的一种非常常见的方法是训练具有相关任务的大型模 ...@@ -141,7 +141,7 @@ K 次学习的一种非常常见的方法是训练具有相关任务的大型模
![](img/5f07d8c6-f555-4b6f-89a9-72d141ed72f9.png) ![](img/5f07d8c6-f555-4b6f-89a9-72d141ed72f9.png)
# 代表性学习 # 表示学习
在第一阶段(表示学习),使用大型数据集 <sub>![](img/4447bed3-8a05-47f1-9571-c7c71b113318.png)</sub> 训练 CNN( <sub>![](img/1b08704a-7c19-4972-bded-7880a2ed97ce.png)</sub> ),该数据集训练参数 <sub>![](img/171fc491-a5e2-4039-bd11-fed0c0df33c9.png) 网络的</sub><sub>![](img/22e5e308-79ce-4488-9661-eb1506788bcc.png)</sub> 。 此后,这些参数 <sub>![](img/984695cc-d7a0-4b0f-950a-a5cd284a0eea.png)</sub> 是固定的,并在以后的阶段中共享。 来自 CNN 最后一层的激活被映射到两组 softmax 层,由 <sub>![](img/e76ccc98-babb-4f2a-a1ff-91620dbfeb0f.png)</sub><sub>![](img/39ddcb33-0e04-4bc1-9b29-fdbcbf1b1930.png)</sub> 参数化。 参数 <sub>![](img/db026aae-0c13-4adf-9284-11c1eed3b0dd.png)</sub> 对应于大型数据集![](img/b5d92f8c-1cde-48fb-9597-ed1cc4ffeb8c.png)中的 <sub>![](img/7f499eb0-1597-4e09-a4b1-9cb696ad3663.png)</sub> 类,参数 <sub>![](img/920e25fb-08d6-463f-b6be-f900401ef7b4.png)</sub> 对应于 <sub>![](img/6a2a899f-e2b7-4fa9-959c-9fbf693499b7.png) K 次任务的数据集中的</sub><sub>![](img/d7d76711-7d54-477b-b992-047094305586.png)</sub> 。 如下图所示: 在第一阶段(表示学习),使用大型数据集 <sub>![](img/4447bed3-8a05-47f1-9571-c7c71b113318.png)</sub> 训练 CNN( <sub>![](img/1b08704a-7c19-4972-bded-7880a2ed97ce.png)</sub> ),该数据集训练参数 <sub>![](img/171fc491-a5e2-4039-bd11-fed0c0df33c9.png) 网络的</sub><sub>![](img/22e5e308-79ce-4488-9661-eb1506788bcc.png)</sub> 。 此后,这些参数 <sub>![](img/984695cc-d7a0-4b0f-950a-a5cd284a0eea.png)</sub> 是固定的,并在以后的阶段中共享。 来自 CNN 最后一层的激活被映射到两组 softmax 层,由 <sub>![](img/e76ccc98-babb-4f2a-a1ff-91620dbfeb0f.png)</sub><sub>![](img/39ddcb33-0e04-4bc1-9b29-fdbcbf1b1930.png)</sub> 参数化。 参数 <sub>![](img/db026aae-0c13-4adf-9284-11c1eed3b0dd.png)</sub> 对应于大型数据集![](img/b5d92f8c-1cde-48fb-9597-ed1cc4ffeb8c.png)中的 <sub>![](img/7f499eb0-1597-4e09-a4b1-9cb696ad3663.png)</sub> 类,参数 <sub>![](img/920e25fb-08d6-463f-b6be-f900401ef7b4.png)</sub> 对应于 <sub>![](img/6a2a899f-e2b7-4fa9-959c-9fbf693499b7.png) K 次任务的数据集中的</sub><sub>![](img/d7d76711-7d54-477b-b992-047094305586.png)</sub> 。 如下图所示:
...@@ -198,7 +198,7 @@ K 次学习(等式 2)期间新权重![](img/211df3d3-5161-4ea1-9817-744ffa03 ...@@ -198,7 +198,7 @@ K 次学习(等式 2)期间新权重![](img/211df3d3-5161-4ea1-9817-744ffa03
在讨论了先前模型的机制之后,以下小节总结了判别式 K 次模型的四个阶段中的所有计算和近似。 在讨论了先前模型的机制之后,以下小节总结了判别式 K 次模型的四个阶段中的所有计算和近似。
# 第一阶段–表征​​学习 # 第一阶段–表学习
最初,深度学习训练特征提取器 CNN <sub>![](img/457cb4e7-fafd-4698-9478-df8cee1a2017.png)</sub> 。 在以下阶段中使用输入图像(![](img/2aaaf738-92eb-4c77-86ce-f2740aee9a7a.png))的最后一层的激活 <sub>![](img/705b9f61-e64b-4a40-b3cd-dcb288d7b11c.png)</sub> 。 原始数据集中类别的 softmax 权重为 MAP 估计值 <sub>![](img/39788ebc-9ed9-4e50-b21d-b9f60b471c8c.png)</sub> 最初,深度学习训练特征提取器 CNN <sub>![](img/457cb4e7-fafd-4698-9478-df8cee1a2017.png)</sub> 。 在以下阶段中使用输入图像(![](img/2aaaf738-92eb-4c77-86ce-f2740aee9a7a.png))的最后一层的激活 <sub>![](img/705b9f61-e64b-4a40-b3cd-dcb288d7b11c.png)</sub> 。 原始数据集中类别的 softmax 权重为 MAP 估计值 <sub>![](img/39788ebc-9ed9-4e50-b21d-b9f60b471c8c.png)</sub>
...@@ -206,15 +206,15 @@ K 次学习(等式 2)期间新权重![](img/211df3d3-5161-4ea1-9817-744ffa03 ...@@ -206,15 +206,15 @@ K 次学习(等式 2)期间新权重![](img/211df3d3-5161-4ea1-9817-744ffa03
概率模型直接适合于 MAP 权重 <sub>![](img/01b11f3a-0686-4edc-b119-3eccb26d356b.png)</sub> 。 对于共轭模型,后验分布是通过解析获得的。 否则,将使用 <sub>![](img/520f8b84-704b-4501-b74d-294304b03b84.png)</sub> 的 MAP 估算值。 概率模型直接适合于 MAP 权重 <sub>![](img/01b11f3a-0686-4edc-b119-3eccb26d356b.png)</sub> 。 对于共轭模型,后验分布是通过解析获得的。 否则,将使用 <sub>![](img/520f8b84-704b-4501-b74d-294304b03b84.png)</sub> 的 MAP 估算值。
# 第三阶段– k 次学习 # 第三阶段– K 次学习
在 softmax 权重![](img/95e5adea-fdbb-436c-88f6-f09289f49929.png)<sub>,![](img/61d62897-a8a3-40e0-921a-874ff6675301.png)</sub>上的后缀是难以处理的。 通过使用 MAP 估计 <sub>![](img/753955cd-a77f-44a0-9416-1c544281ad1f.png)</sub> 或通过采样 <sub>![](img/8d7be54d-e3d8-433a-b254-f77d0ab6bc06.png)</sub> 可以近似得出。 必须注意, <sub>![](img/56b110e9-b61a-43f4-bb35-e01064a4f8bf.png)</sub> 是针对共轭模型的分析。 但是,如果在阶段 2 中根据 MAP 估计来估计 <sub>![](img/8b45bb65-bd49-4e47-aab4-7b7202c19589.png)</sub> ,则如等式 4 中所述使用 <sub>![](img/9cbd85bb-2d4e-4eea-9724-09693a33bce5.png)</sub> 在 softmax 权重![](img/95e5adea-fdbb-436c-88f6-f09289f49929.png)<sub>,![](img/61d62897-a8a3-40e0-921a-874ff6675301.png)</sub>上的后缀是难以处理的。 通过使用 MAP 估计 <sub>![](img/753955cd-a77f-44a0-9416-1c544281ad1f.png)</sub> 或通过采样 <sub>![](img/8d7be54d-e3d8-433a-b254-f77d0ab6bc06.png)</sub> 可以近似得出。 必须注意, <sub>![](img/56b110e9-b61a-43f4-bb35-e01064a4f8bf.png)</sub> 是针对共轭模型的分析。 但是,如果在阶段 2 中根据 MAP 估计来估计 <sub>![](img/8b45bb65-bd49-4e47-aab4-7b7202c19589.png)</sub> ,则如等式 4 中所述使用 <sub>![](img/9cbd85bb-2d4e-4eea-9724-09693a33bce5.png)</sub>
# 阶段 4 – K 次测试 # 第四阶段 – K 次测试
K 次测试时间 <sub>![](img/c3734ba9-5a51-47ff-84f2-54c038662868.png)</sub> 的推论是难以理解的,因此此处使用近似值。 如果从阶段 3 开始使用 <sub>![](img/8ad46a3a-039b-4f21-9049-c640cc90b96b.png)</sub><sub>![](img/e631a1e5-efaa-41e0-b3af-d080d5df4b7a.png)</sub> )的 MAP 估计值,则 <sub>![](img/52f71d1d-16a5-446e-9276-d0e2faedd10c.png)</sub> 。 如果在阶段 3 中重新采样,则使用 <sub>![](img/858ad399-04bb-4869-aa0e-88ba105b2300.png)</sub> K 次测试时间 <sub>![](img/c3734ba9-5a51-47ff-84f2-54c038662868.png)</sub> 的推论是难以理解的,因此此处使用近似值。 如果从阶段 3 开始使用 <sub>![](img/8ad46a3a-039b-4f21-9049-c640cc90b96b.png)</sub><sub>![](img/e631a1e5-efaa-41e0-b3af-d080d5df4b7a.png)</sub> )的 MAP 估计值,则 <sub>![](img/52f71d1d-16a5-446e-9276-d0e2faedd10c.png)</sub> 。 如果在阶段 3 中重新采样,则使用 <sub>![](img/858ad399-04bb-4869-aa0e-88ba105b2300.png)</sub>
在 miniImageNet 数据集(由 100 个类组成,每个类中包含 600 个图像)上,此方法可以一次学习一次和五次学习获得最先进的结果。 离统一概率模型和深度学习的领域又迈进了一步,将两者结合起来,可以开发出真正强大的模型,从而利用概率领域的强大数学保证和深度学习模型的强大健壮功能。 判别式 k 次学习方法仍然需要大量带标签的训练数据来训练基于深度学习的特征提取器。 另一方面,贝叶斯程序学习方法利用模型中的归纳偏差和手工设计的特征,因此需要较少的标注训练数据。 在 miniImageNet 数据集(由 100 个类组成,每个类中包含 600 个图像)上,此方法可以一次学习一次和五次学习获得最先进的结果。 离统一概率模型和深度学习的领域又迈进了一步,将两者结合起来,可以开发出真正强大的模型,从而利用概率领域的强大数学保证和深度学习模型的强大健壮功能。 判别式 K 次学习方法仍然需要大量带标签的训练数据来训练基于深度学习的特征提取器。 另一方面,贝叶斯程序学习方法利用模型中的归纳偏差和手工设计的特征,因此需要较少的标注训练数据。
# 总结 # 总结
......
...@@ -18,15 +18,15 @@ ...@@ -18,15 +18,15 @@
在对象检测和语义分割领域也有一些显着贡献。 让我们讨论其中的两种方法。 在对象检测和语义分割领域也有一些显着贡献。 让我们讨论其中的两种方法。
# 少数场景中的对象检测 # 小样本领域中的对象检测
[《RepMet:用于分类和几次对象检测的基于代表的度量学习》](https://arxiv.org/abs/1806.04728)是一种几次学习对象检测方法。 在本文中,作者提出了一种用于对象区域建议的特征金字塔网络的变体,并且在其顶部,他们添加了基于度量的分类器,该分类器根据与学习的类代表的距离对建议的区域进行分类。 他们还通过在 ImageNet 数据集上建立了用于少发物体检测任务的基准,为研究界做出了贡献。 [《RepMet:用于分类和几次对象检测的基于代表的度量学习》](https://arxiv.org/abs/1806.04728)是一种小样本学习对象检测方法。 在本文中,作者提出了一种用于对象区域建议的特征金字塔网络的变体,并且在其顶部,他们添加了基于度量的分类器,该分类器根据与学习的类代表的距离对建议的区域进行分类。 他们还通过在 ImageNet 数据集上建立了用于少发物体检测任务的基准,为研究界做出了贡献。
同样,[《具有共同注意和共同激励的一次目标检测》](https://arxiv.org/abs/1911.12529)也可以在建议的区域基础上进行过滤 使用传统的视觉方法。 在这项工作中,作者假设将提供目标图像和查询图像。 例如,如果我们要检测笔架,则目标图像将是笔架,而查询图像将是桌子上的笔架。 在这种方法中,我们首先从目标图像中提取有关对象的空间信息,然后从查询图像中提取上下文对象。 上下文和空间信息在确定对象方面起着重要作用。 例如,如果有一张桌子,出现笔架的可能性就会增加。 这类似于人类使用上下文学习的方式。 该模型还通过将输入传递给注意力模型来利用上下文的帮助。 同样,[《具有共同注意和共同激励的一次目标检测》](https://arxiv.org/abs/1911.12529)也可以在建议的区域基础上进行过滤 使用传统的视觉方法。 在这项工作中,作者假设将提供目标图像和查询图像。 例如,如果我们要检测笔架,则目标图像将是笔架,而查询图像将是桌子上的笔架。 在这种方法中,我们首先从目标图像中提取有关对象的空间信息,然后从查询图像中提取上下文对象。 上下文和空间信息在确定对象方面起着重要作用。 例如,如果有一张桌子,出现笔架的可能性就会增加。 这类似于人类使用上下文学习的方式。 该模型还通过将输入传递给注意力模型来利用上下文的帮助。
# 少数镜头域中的图像分割 # 小样本领域中的图像分割
研究工作[《CANet:具有迭代细化和专注的几次学习的类不可知分割网络》](https://arxiv.org/abs/1903.02351)证明了潜在的增长 医学影像行业。 在本文中,作者提出了一个用于语义分割的两级框架:**密集比较模块****DCM**)和**迭代优化模块****IOM**)。 DCM 通过使用通用的 ResNet 架构提取特征,在训练集示例和测试集示例之间进行了密集的特征比较,而 IOM 通过残差块加 CNN 和**粗糙的空间金字塔池****ASPP**)模块。 研究工作[《CANet:具有迭代细化和专注的小样本学习的类不可知分割网络》](https://arxiv.org/abs/1903.02351)证明了潜在的增长 医学影像行业。 在本文中,作者提出了一个用于语义分割的两级框架:**密集比较模块****DCM**)和**迭代优化模块****IOM**)。 DCM 通过使用通用的 ResNet 架构提取特征,在训练集示例和测试集示例之间进行了密集的特征比较,而 IOM 通过残差块加 CNN 和**粗糙的空间金字塔池****ASPP**)模块。
同样, [《PANet:具有原型对齐功能的几次语义分割》](https://arxiv.org/abs/1908.06391)通过以下方式解决了少数镜头分割问题: 度量学习方法。 本文还提出了一种对齐网络,以更好地利用从支持集中提取的信息。 在 PANet 中,最初,网络从特定嵌入空间内的一些支持图像中学习特定于类别的表示,然后通过将每个像素与学习到的特定于类别的表示进行匹配,对查询/目标图像执行分割。 通过使用这种方法,PANet 可以利用支持集中的重要见解,并在几次分割的情况下提供更可靠的概括。 同样, [《PANet:具有原型对齐功能的几次语义分割》](https://arxiv.org/abs/1908.06391)通过以下方式解决了少数镜头分割问题: 度量学习方法。 本文还提出了一种对齐网络,以更好地利用从支持集中提取的信息。 在 PANet 中,最初,网络从特定嵌入空间内的一些支持图像中学习特定于类别的表示,然后通过将每个像素与学习到的特定于类别的表示进行匹配,对查询/目标图像执行分割。 通过使用这种方法,PANet 可以利用支持集中的重要见解,并在几次分割的情况下提供更可靠的概括。
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
获得伪标签后,我们将实标签与伪标签连接起来,将实特征与伪特征连接在一起。 连接后,我们训练了一个新模型,事实证明该模型比初始模型更准确。 我们一直这样做,直到获得最佳精度。 获得伪标签后,我们将实标签与伪标签连接起来,将实特征与伪特征连接在一起。 连接后,我们训练了一个新模型,事实证明该模型比初始模型更准确。 我们一直这样做,直到获得最佳精度。
# 学习 # 学习不平
在学习不平衡的情况下,我们有一个不平衡的数据集。 也就是说,我们从一个类别中获得的样本要多于从其他类别中获得的样本。 这也被普遍称为**偏态分布数据集**。让我们看一下处理偏斜数据集的一些流行方法: 在学习不平衡的情况下,我们有一个不平衡的数据集。 也就是说,我们从一个类别中获得的样本要多于从其他类别中获得的样本。 这也被普遍称为**偏态分布数据集**。让我们看一下处理偏斜数据集的一些流行方法:
...@@ -71,11 +71,11 @@ ...@@ -71,11 +71,11 @@
![](img/d2619e72-ed14-4933-9ca1-7d658c79f2f2.png) ![](img/d2619e72-ed14-4933-9ca1-7d658c79f2f2.png)
换句话说,在一个数据集上训练的神经网络模型可以通过对前一个网络进行微调而用于其他数据集,就像我们如何使用在不同域数据集(例如 MNIST 数据集)上训练的连体网络来提取更好的特征一样 用于签名匹配,手写匹配等。 迁移学习在深度学习领域引起了很多关注,并已被证明对于许多应用程序非常有用。 但是,由于数据限制,我们无法在制造,医药,化学等非常见领域中使用它。 换句话说,在一个数据集上训练的神经网络模型可以通过对前一个网络进行微调而用于其他数据集,就像我们如何使用在不同域数据集(例如 MNIST 数据集)上训练的连体网络来提取更好的特征一样 用于签名匹配,手写匹配等。 迁移学习在深度学习领域引起了很多关注,并已被证明对于许多应用非常有用。 但是,由于数据限制,我们无法在制造,医药,化学等非常见领域中使用它。
# 应用领域 # 应用领域
从理论上讲,一次学习有多种应用程序,但直到最近才开始在实际场景中使用。 使用一次学习已取得了最新进展,例如编写 SQL 代码,改进变形的医学图像以及运行签名验证。 还有其他几个领域仍在研究中。 OpenAI,Google,Microsoft 和 Amazon 等公司正在 AI 研究方面投入巨资。 解决一次学习将意味着创建具有人类能力的机械大脑。 这种进步可以通过多种方式挽救生命:可以为罕见病的发现铺平道路,解决全球粮食危机或优化供应链模型。 从理论上讲,一次学习有多种应用,但直到最近才开始在实际场景中使用。 使用一次学习已取得了最新进展,例如编写 SQL 代码,改进变形的医学图像以及运行签名验证。 还有其他几个领域仍在研究中。 OpenAI,Google,Microsoft 和 Amazon 等公司正在 AI 研究方面投入巨资。 解决一次学习将意味着创建具有人类能力的机械大脑。 这种进步可以通过多种方式挽救生命:可以为罕见病的发现铺平道路,解决全球粮食危机或优化供应链模型。
在本书中,我们探讨了一些一次学习的可能方法。 如果您想探索更多内容,请参阅“进一步阅读”部分。 在本书中,我们探讨了一些一次学习的可能方法。 如果您想探索更多内容,请参阅“进一步阅读”部分。
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
要进一步了解本章,请参考以下作品: 要进一步了解本章,请参考以下作品:
* [《元学习实践》](https://www.packtpub.com/big-data-and-business-intelligence/hands-meta-learning-python) * [《元学习实践》](https://www.packtpub.com/big-data-and-business-intelligence/hands-meta-learning-python)
* [《为几次学习重新研究基于局部描述符的图像到类度量》](https://arxiv.org/pdf/1903.12290.pdf) * [《为小样本学习重新研究基于局部描述符的图像到类度量》](https://arxiv.org/pdf/1903.12290.pdf)
* [《通过类别遍历查找与几项学习相关的任务相关功能》](https://arxiv.org/pdf/1905.11116.pdf) * [《通过类别遍历查找与几项学习相关的任务相关功能》](https://arxiv.org/pdf/1905.11116.pdf)
* [《RepMet:基于代表的度量学习,用于分类和几次检测》](https://arxiv.org/abs/1806.04728) * [《RepMet:基于代表的度量学习,用于分类和几次检测》](https://arxiv.org/abs/1806.04728)
* [《具有共同注意和共同激励的一次对象检测》](https://arxiv.org/pdf/1911.12529.pdf) * [《具有共同注意和共同激励的一次对象检测》](https://arxiv.org/pdf/1911.12529.pdf)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
# 这本书适合谁 # 这本书适合谁
这本 PyTorch 书籍适用于 NLP 开发人员,机器学习和深度学习开发人员,或致力于使用传统 NLP 方法和深度学习架构来构建智能语言应用程序的任何人。 如果您希望在开发项目中采用现代的 NLP 技术和模型,那么本书非常适合您。 必须具备 Python 编程的工作知识和 NLP 任务的基本工作知识。 这本 PyTorch 书籍适用于 NLP 开发人员,机器学习和深度学习开发人员,或致力于使用传统 NLP 方法和深度学习架构来构建智能语言应用的任何人。 如果您希望在开发项目中采用现代的 NLP 技术和模型,那么本书非常适合您。 必须具备 Python 编程的工作知识和 NLP 任务的基本工作知识。
# 这本书涵盖的内容 # 这本书涵盖的内容
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* 词嵌入 * 词嵌入
* 探索 CBOW * 探索 CBOW
* 探索 n 元组 * 探索 n 元组
* 代币 * 标记
* 对词性进行标记和分块 * 对词性进行标记和分块
* 特遣部队 * 特遣部队
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
在本章中,我们将研究**循环神经网络****RNN**),这是 PyTorch 中基本前馈神经网络的变体,我们在第 1 章“机器学习基础”中学习了如何构建它。 通常,RNN 可用于任何可以将数据表示为序列的任务。 其中包括使用以序列表示的历史数据的时间序列进行股票价格预测之类的事情。 我们通常在 NLP 中使用 RNN,因为可以将文本视为单个单词的序列,并可以对其进行建模。 传统的神经网络将单个向量作为模型的输入,而 RNN 可以采用整个向量序列。 如果我们将文档中的每个单词表示为向量嵌入,则可以将整个文档表示为向量序列(或 3 阶张量)。 然后,我们可以使用 RNN(以及更复杂的 RNN 形式,称为**长短期记忆****LSTM**))从我们的数据中学习。 在本章中,我们将研究**循环神经网络****RNN**),这是 PyTorch 中基本前馈神经网络的变体,我们在第 1 章“机器学习基础”中学习了如何构建它。 通常,RNN 可用于任何可以将数据表示为序列的任务。 其中包括使用以序列表示的历史数据的时间序列进行股票价格预测之类的事情。 我们通常在 NLP 中使用 RNN,因为可以将文本视为单个单词的序列,并可以对其进行建模。 传统的神经网络将单个向量作为模型的输入,而 RNN 可以采用整个向量序列。 如果我们将文档中的每个单词表示为向量嵌入,则可以将整个文档表示为向量序列(或 3 阶张量)。 然后,我们可以使用 RNN(以及更复杂的 RNN 形式,称为**长短期记忆****LSTM**))从我们的数据中学习。
在本章中,我们将介绍 RNN 的基础知识和更高级的 LSTM。 然后,我们将研究情感分析,并通过一个实际的示例来研究如何使用 PyTorch 构建 LSTM 对文档进行分类。 最后,我们将在简单的云应用程序平台 Heroku 上托管我们的简单模型,这将使​​我们能够使用我们的模型进行预测。 在本章中,我们将介绍 RNN 的基础知识和更高级的 LSTM。 然后,我们将研究情感分析,并通过一个实际的示例来研究如何使用 PyTorch 构建 LSTM 对文档进行分类。 最后,我们将在简单的云应用平台 Heroku 上托管我们的简单模型,这将使​​我们能够使用我们的模型进行预测。
本章涵盖以下主题: 本章涵盖以下主题:
* 建立 RNN * 建立 RNN
* 使用 LSTM * 使用 LSTM
* 使用 LSTM 构建情感分析器 * 使用 LSTM 构建情感分析器
* 在 Heroku 上部署应用程序 * 在 Heroku 上部署应用
# 技术要求 # 技术要求
...@@ -566,7 +566,7 @@ predict("It was not good") ...@@ -566,7 +566,7 @@ predict("It was not good")
现在,我们已经建立了一个 LSTM 模型,可以从头开始进行情感分析。 尽管我们的模型远非完美,但我们已演示了如何获取带有情感标签的评论并训练模型以能够对新评论做出预测。 接下来,我们将展示如何在 Heroku 云平台上托管我们的模型,以便其他人可以使用您的模型进行预测 现在,我们已经建立了一个 LSTM 模型,可以从头开始进行情感分析。 尽管我们的模型远非完美,但我们已演示了如何获取带有情感标签的评论并训练模型以能够对新评论做出预测。 接下来,我们将展示如何在 Heroku 云平台上托管我们的模型,以便其他人可以使用您的模型进行预测
# 在 Heroku 上部署应用程序 # 在 Heroku 上部署应用
现在,我们已经在本地计算机上训练了模型,我们可以使用它来进行预测。 但是,如果您希望其他人能够使用您的模型进行预测,则不一定有好处。 如果我们将模型托管在基于云的平台(例如 Heroku)上并创建基本的 API,其他人将能够调用该 API 以使用我们的模型进行预测。 现在,我们已经在本地计算机上训练了模型,我们可以使用它来进行预测。 但是,如果您希望其他人能够使用您的模型进行预测,则不一定有好处。 如果我们将模型托管在基于云的平台(例如 Heroku)上并创建基本的 API,其他人将能够调用该 API 以使用我们的模型进行预测。
...@@ -690,7 +690,7 @@ mkdir models ...@@ -690,7 +690,7 @@ mkdir models
return response, 200 return response, 200
``` ```
6. 随着我们的应用程序主体的完成,我们还必须添加两件额外的事情来使我们的 API 运行。首先,我们必须在`wsgi.py`文件中添加以下内容。 6. 随着我们的应用主体的完成,我们还必须添加两件额外的事情来使我们的 API 运行。首先,我们必须在`wsgi.py`文件中添加以下内容。
```py ```py
from app import app as application from app import app as application
...@@ -704,7 +704,7 @@ mkdir models ...@@ -704,7 +704,7 @@ mkdir models
web: gunicorn app:app --preload web: gunicorn app:app --preload
``` ```
这就是应用程序运行所需要的全部。 我们可以先使用以下命令在本地启动 API,以测试 API 是否运行: 这就是应用运行所需要的全部。 我们可以先使用以下命令在本地启动 API,以测试 API 是否运行:
```py ```py
gunicorn --bind 0.0.0.0:8080 wsgi:application -w 1 gunicorn --bind 0.0.0.0:8080 wsgi:application -w 1
...@@ -750,7 +750,7 @@ git push heroku master ...@@ -750,7 +750,7 @@ git push heroku master
curl -X GET https://sentiment-analysis-flask-api.herokuapp.com/predict -H "Content-Type: application/json" -d '{"input":"the film was good"}' curl -X GET https://sentiment-analysis-flask-api.herokuapp.com/predict -H "Content-Type: application/json" -d '{"input":"the film was good"}'
``` ```
您的应用程序现在将根据模型返回预测。 恭喜,您现在已经学会了如何从头训练 LSTM 模型,将其上传到云中以及使用它进行预测! 展望未来,本教程有望成为您训练自己的 LSTM 模型并将其自己部署到云的基础。 您的应用现在将根据模型返回预测。 恭喜,您现在已经学会了如何从头训练 LSTM 模型,将其上传到云中以及使用它进行预测! 展望未来,本教程有望成为您训练自己的 LSTM 模型并将其自己部署到云的基础。
# 总结 # 总结
......
...@@ -242,7 +242,7 @@ x0 + t0 = E0 ...@@ -242,7 +242,7 @@ x0 + t0 = E0
编码器-解码器注意层的工作方式与我们编码器中的多头自我注意层相同。 但是,主要区别在于它从下面的层创建查询矩阵,并从编码器的输出获取键和值矩阵。 编码器-解码器注意层的工作方式与我们编码器中的多头自我注意层相同。 但是,主要区别在于它从下面的层创建查询矩阵,并从编码器的输出获取键和值矩阵。
这些编码器和解码器部分构成了我们的转换器,构成了 BERT 的基础。 接下来,我们将研究 BERT 的某些应用程序,并研究一些在特定任务下表现出更高性能的变体。 这些编码器和解码器部分构成了我们的转换器,构成了 BERT 的基础。 接下来,我们将研究 BERT 的某些应用,并研究一些在特定任务下表现出更高性能的变体。
## BERT 的应用 ## BERT 的应用
...@@ -621,7 +621,7 @@ What day is it today? ...@@ -621,7 +621,7 @@ What day is it today?
# 总结 # 总结
在本章中,我们首先研究了几种最新的 NLP 语言模型。 尤其是 BERT,似乎已被广泛接受为行业标准的最新语言模型,并且 BERT 及其变体已被企业在其自己的 NLP 应用程序中广泛使用。 在本章中,我们首先研究了几种最新的 NLP 语言模型。 尤其是 BERT,似乎已被广泛接受为行业标准的最新语言模型,并且 BERT 及其变体已被企业在其自己的 NLP 应用中广泛使用。
接下来,我们研究了机器学习的几个重点领域。 即语义角色标签,选区解析,文本范围和机器理解。 这些领域可能会占 NLP 正在进行的当前研究的很大一部分。 接下来,我们研究了机器学习的几个重点领域。 即语义角色标签,选区解析,文本范围和机器理解。 这些领域可能会占 NLP 正在进行的当前研究的很大一部分。
......
# 第 2 部分:自然语言处理基础 # 第 2 部分:自然语言处理基础
在本节中,您将学习构建**自然语言处理****NLP**)应用程序的基础知识。 您还将在本节中学习如何在 PyTorch 中使用各种 NLP 技术,例如单词嵌入,CBOW 和标记化。 在本节中,您将学习构建**自然语言处理****NLP**)应用的基础知识。 您还将在本节中学习如何在 PyTorch 中使用各种 NLP 技术,例如单词嵌入,CBOW 和标记化。
本节包含以下章节: 本节包含以下章节:
......
# 第 3 节:使用 PyTorch 1.x 的实际 NLP 应用程序 # 第 3 节:使用 PyTorch 1.x 的实际 NLP 应用
在本节中,我们将使用 PyTorch 中可用的各种**自然语言处理****NLP**)技术来构建各种实际 -使用 PyTorch 的世界应用程序。 情感分析,文本摘要,文本分类以及使用 PyTorch 构建聊天机器人应用程序是本节将介绍的一些任务。 在本节中,我们将使用 PyTorch 中可用的各种**自然语言处理****NLP**)技术来构建各种实际 -使用 PyTorch 的世界应用。 情感分析,文本摘要,文本分类以及使用 PyTorch 构建聊天机器人应用是本节将介绍的一些任务。
本节包含以下章节: 本节包含以下章节:
......
# 前言 # 前言
**人工智能****AI**)继续流行并破坏了广泛的领域,但这是一个复杂而艰巨的话题。 在本书中,您将掌握构建深度学习应用程序的方法,以及如何使用 PyTorch 进行研究和解决实际问题。 **人工智能****AI**)继续流行并破坏了广泛的领域,但这是一个复杂而艰巨的话题。 在本书中,您将掌握构建深度学习应用的方法,以及如何使用 PyTorch 进行研究和解决实际问题。
本书从张量处理的基础开始,采用基于秘籍的方法,然后介绍了**卷积神经网络****CNN**)和 PyTorch 中的**循环神经网络****RNN**)。 熟悉这些基本网络后,您将使用深度学习来构建医学图像分类器。 接下来,您将使用 TensorBoard 进行可视化。 您还将深入研究**生成对抗网络****GAN**)和**深度强化学习****DRL**),然后最终将模型大规模部署到生产中。 您将发现针对机器学习,深度学习和强化学习中常见问题的解决方案。 您将学习如何在计算机视觉,**自然语言处理****NLP**)中实现 AI 任务并解决实际问题。 其他实际领域。 本书从张量处理的基础开始,采用基于秘籍的方法,然后介绍了**卷积神经网络****CNN**)和 PyTorch 中的**循环神经网络****RNN**)。 熟悉这些基本网络后,您将使用深度学习来构建医学图像分类器。 接下来,您将使用 TensorBoard 进行可视化。 您还将深入研究**生成对抗网络****GAN**)和**深度强化学习****DRL**),然后最终将模型大规模部署到生产中。 您将发现针对机器学习,深度学习和强化学习中常见问题的解决方案。 您将学习如何在计算机视觉,**自然语言处理****NLP**)中实现 AI 任务并解决实际问题。 其他实际领域。
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
第 7 章,“深度强化学习”可帮助您通过各种秘籍来了解深度 RL。 本章是一系列秘籍和任务,您将在其中利用所需的能力和架构来转变为深度强化学习专家。 第 7 章,“深度强化学习”可帮助您通过各种秘籍来了解深度 RL。 本章是一系列秘籍和任务,您将在其中利用所需的能力和架构来转变为深度强化学习专家。
第 8 章,“PyTorch 中的生产 AI 模型”,着眼于以两种方式生产 PyTorch 应用程序。 首先,生成已经训练过的模型,其次,对大型数据集进行分布式训练。 最后,我们将研究各种框架之间的可移植性。 第 8 章,“PyTorch 中的生产 AI 模型”,着眼于以两种方式生产 PyTorch 应用。 首先,生成已经训练过的模型,其次,对大型数据集进行分布式训练。 最后,我们将研究各种框架之间的可移植性。
# 充分利用这本书 # 充分利用这本书
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
在本章中,我们将介绍以下秘籍: 在本章中,我们将介绍以下秘籍:
* 代币 * 标记
* 创建字段 * 创建字段
* 开发数据集 * 开发数据集
* 开发迭代器 * 开发迭代器
...@@ -67,7 +67,7 @@ pip install torchtext ...@@ -67,7 +67,7 @@ pip install torchtext
至此,我们完成了本章所需的设置。 至此,我们完成了本章所需的设置。
# 代币 # 标记
在处理自然语言处理任务时,我们采用文本语料库并将其分解为较小的单元。 在本秘籍中,我们将句子分解为单个单词,其中每个单词代表一个意思,其他单词与它附近的其他单词一起表达一个句子的意图。 计算机只能理解数字,因此为这些单词分配了唯一的整数值来表示单词。 将句子分解为标记的过程称为标记化。 在本秘籍中,我们将执行单词标记化。 在处理自然语言处理任务时,我们采用文本语料库并将其分解为较小的单元。 在本秘籍中,我们将句子分解为单个单词,其中每个单词代表一个意思,其他单词与它附近的其他单词一起表达一个句子的意图。 计算机只能理解数字,因此为这些单词分配了唯一的整数值来表示单词。 将句子分解为标记的过程称为标记化。 在本秘籍中,我们将执行单词标记化。
......
...@@ -98,7 +98,7 @@ pip install flask ...@@ -98,7 +98,7 @@ pip install flask
>>from image_classifier import create_model, predict_image >>from image_classifier import create_model, predict_image
``` ```
9. 现在,我们将创建一个 Flask 应用程序和分类器模型: 9. 现在,我们将创建一个 Flask 应用和分类器模型:
```py ```py
>>app = Flask(__name__) >>app = Flask(__name__)
...@@ -125,20 +125,20 @@ pip install flask ...@@ -125,20 +125,20 @@ pip install flask
return jsonify({'object_name' : object_name}) return jsonify({'object_name' : object_name})
``` ```
2. 最后,如果运行`imageapp.py`,我们将启动 Flask 应用程序 2. 最后,如果运行`imageapp.py`,我们将启动 Flask 应用:
```py ```py
>>if __name__ == '__main__': >>if __name__ == '__main__':
app.run(debug=True) app.run(debug=True)
``` ```
3. 接下来,您需要使用以下命令运行 Flask 应用程序 3. 接下来,您需要使用以下命令运行 Flask 应用:
```py ```py
python imageapp.py python imageapp.py
``` ```
通过运行此命令,Flask 服务器将启动并运行。 您应该可以通过`http://127.0.0.1:5000/`访问应用程序的 URL 并发送`POST`请求。 通过运行此命令,Flask 服务器将启动并运行。 您应该可以通过`http://127.0.0.1:5000/`访问应用的 URL 并发送`POST`请求。
4. 使用邮差工具,您可以检查 API。 这是图像的示例响应: 4. 使用邮差工具,您可以检查 API。 这是图像的示例响应:
...@@ -156,7 +156,7 @@ python imageapp.py ...@@ -156,7 +156,7 @@ python imageapp.py
![](img/1f477c82-4311-4f6f-9b05-04ad7f50f4eb.png) ![](img/1f477c82-4311-4f6f-9b05-04ad7f50f4eb.png)
在此秘籍中,我们使用 Flask 进行了简单的应用程序部署。 在此秘籍中,我们使用 Flask 进行了简单的应用部署。
# 这个怎么运作... # 这个怎么运作...
...@@ -164,7 +164,7 @@ python imageapp.py ...@@ -164,7 +164,7 @@ python imageapp.py
在此文件中,第一个函数加载预先训练的`densenet161`模型,该模型在 ImageNet 数据集中具有 1,000 个类别的模型上进行训练; 我们将模型设置为评估模式,然后返回模型。 第二个函数将给定的输入图像转换为张量并对其进行变换。 我们使用了`PIL`中的`Image`模块来读取图像数据。 第三个功能通过将给定图像转换为张量并将其传递到模型中来进行预测。 这将返回图像中对象的名称。 在此文件中,第一个函数加载预先训练的`densenet161`模型,该模型在 ImageNet 数据集中具有 1,000 个类别的模型上进行训练; 我们将模型设置为评估模式,然后返回模型。 第二个函数将给定的输入图像转换为张量并对其进行变换。 我们使用了`PIL`中的`Image`模块来读取图像数据。 第三个功能通过将给定图像转换为张量并将其传递到模型中来进行预测。 这将返回图像中对象的名称。
然后,我们切换到`imageapp.py`文件,在这里我们使用 Flask 创建了 Web 应用程序。 在这里,我们使用`app = Flask(__name__)`创建了 Flask 应用,并使用`create_model`功能创建了模型。 此后,我们创建了一个名为`/predict`的路由,该路由使用我们创建的应用程序实例接收了一个`POST`请求。 然后,我们定义了`predicted`函数,该函数将在调用`/predict` URL 时被调用。 `request.files`在 POST 请求中保存文件。 在这里,我们检查了是否使用发布参数名称`image`上传了图像文件。 然后,我们切换到`imageapp.py`文件,在这里我们使用 Flask 创建了 Web 应用。 在这里,我们使用`app = Flask(__name__)`创建了 Flask 应用,并使用`create_model`功能创建了模型。 此后,我们创建了一个名为`/predict`的路由,该路由使用我们创建的应用实例接收了一个`POST`请求。 然后,我们定义了`predicted`函数,该函数将在调用`/predict` URL 时被调用。 `request.files`在 POST 请求中保存文件。 在这里,我们检查了是否使用发布参数名称`image`上传了图像文件。
最后,我们将此图像数据传递到我们先前定义的`predict_image`函数中。 Flask 中的`jsonify`方法可确保响应为`.json`格式。 `app.run(debug=True)`启动 Flask 服务器并处理请求。 最后,我们将此图像数据传递到我们先前定义的`predict_image`函数中。 Flask 中的`jsonify`方法可确保响应为`.json`格式。 `app.run(debug=True)`启动 Flask 服务器并处理请求。
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
## 这本书适合谁 ## 这本书适合谁
这本书是为初学者而写的,但不会让他们跳来跳去另一本书转向高级主题。 因此,我们避免尽可能多地解释算法,而是专注于在 PyTorch 中的实现,有时着眼于使用这些算法的实际应用程序的实现。 对于那些了解如何使用 Python 进行编程并了解深度学习基础知识的人来说,这本书是理想的选择。 本书适用于已经在实践传统机器学习概念的人,或者是开发人员并且希望实际探索深度学习的世界并将其实现部署到生产中的人们。 这本书是为初学者而写的,但不会让他们跳来跳去另一本书转向高级主题。 因此,我们避免尽可能多地解释算法,而是专注于在 PyTorch 中的实现,有时着眼于使用这些算法的实际应用的实现。 对于那些了解如何使用 Python 进行编程并了解深度学习基础知识的人来说,这本书是理想的选择。 本书适用于已经在实践传统机器学习概念的人,或者是开发人员并且希望实际探索深度学习的世界并将其实现部署到生产中的人们。
## 这本书涵盖的内容 ## 这本书涵盖的内容
......
...@@ -28,7 +28,7 @@ Python 在深度学习社区中的广泛接受使一些研究人员和开发人 ...@@ -28,7 +28,7 @@ Python 在深度学习社区中的广泛接受使一些研究人员和开发人
## 什么是 PyTorch? ## 什么是 PyTorch?
如前所述,PyTorch 是可以由 GPU 提供支持的张量计算库。 PyTorch 的构建具有特定目标,这使其与所有其他深度学习框架有所不同。 在本书中,您将通过不同的应用程序重新审视这些目标,并且到本书结束时,无论您打算要进行原型设计,您都应该能够开始使用 PyTorch 的各种用例。 一个想法或建立生产的超可扩展模型。 如前所述,PyTorch 是可以由 GPU 提供支持的张量计算库。 PyTorch 的构建具有特定目标,这使其与所有其他深度学习框架有所不同。 在本书中,您将通过不同的应用重新审视这些目标,并且到本书结束时,无论您打算要进行原型设计,您都应该能够开始使用 PyTorch 的各种用例。 一个想法或建立生产的超可扩展模型。
作为 **Python 优先框架**,PyTorch 大大超越了在整体 C++ 或 C 引擎上实现 Python 包装器的其他框架。 在 PyTorch 中,您可以继承 PyTorch 类并根据需要进行自定义。 内置于 PyTorch 核心的命令式编码风格仅由于 Python 优先方法才有可能。 尽管诸如 TensorFlow,MXNet 和 CNTK 的某些符号图框架提出了一种强制性方法,但由于社区的支持及其灵活性,PyTorch 仍能保持领先地位。 作为 **Python 优先框架**,PyTorch 大大超越了在整体 C++ 或 C 引擎上实现 Python 包装器的其他框架。 在 PyTorch 中,您可以继承 PyTorch 类并根据需要进行自定义。 内置于 PyTorch 核心的命令式编码风格仅由于 Python 优先方法才有可能。 尽管诸如 TensorFlow,MXNet 和 CNTK 的某些符号图框架提出了一种强制性方法,但由于社区的支持及其灵活性,PyTorch 仍能保持领先地位。
...@@ -198,7 +198,7 @@ for epoch in range(epochs): ...@@ -198,7 +198,7 @@ for epoch in range(epochs):
事实证明,对于人类来说如此明显的功能对计算机而言并不那么明显,反之亦然。 特征选择问题的实现使我们进入了深度学习的时代。 这是机器学习的子集,其中我们使用相同的数据驱动方法,但不是让计算机明确选择功能,而是让计算机决定功能应该是什么。 事实证明,对于人类来说如此明显的功能对计算机而言并不那么明显,反之亦然。 特征选择问题的实现使我们进入了深度学习的时代。 这是机器学习的子集,其中我们使用相同的数据驱动方法,但不是让计算机明确选择功能,而是让计算机决定功能应该是什么。
让我们再次考虑面部识别示例。 Google 于 2014 年发表的 FaceNet 论文在深度学习的帮助下解决了它。 FaceNet 使用两个深层网络实现了整个应用程序。 第一个网络是从面孔识别特征集,第二个网络是使用该特征集并识别面孔(从技术上讲,将面孔分类为不同的存储桶)。 本质上,第一个网络正在做我们以前做的事情,第二个网络是一个简单而传统的机器学习算法。 让我们再次考虑面部识别示例。 Google 于 2014 年发表的 FaceNet 论文在深度学习的帮助下解决了它。 FaceNet 使用两个深层网络实现了整个应用。 第一个网络是从面孔识别特征集,第二个网络是使用该特征集并识别面孔(从技术上讲,将面孔分类为不同的存储桶)。 本质上,第一个网络正在做我们以前做的事情,第二个网络是一个简单而传统的机器学习算法。
深度网络能够从数据集中识别特征,前提是我们拥有大型的标记数据集。 FaceNet 的第一个网络接受了带有相应标签的庞大人脸数据集的训练。 第一个网络经过训练,可以预测每个人脸的 128 个特征(通常来说,从我们的面孔有 128 个测量值,例如左眼和右眼之间的距离),第二个网络仅使用这 128 个特征来识别人。 深度网络能够从数据集中识别特征,前提是我们拥有大型的标记数据集。 FaceNet 的第一个网络接受了带有相应标签的庞大人脸数据集的训练。 第一个网络经过训练,可以预测每个人脸的 128 个特征(通常来说,从我们的面孔有 128 个测量值,例如左眼和右眼之间的距离),第二个网络仅使用这 128 个特征来识别人。
...@@ -214,7 +214,7 @@ for epoch in range(epochs): ...@@ -214,7 +214,7 @@ for epoch in range(epochs):
### 了解不同的架构 ### 了解不同的架构
深度学习已经存在了数十年,针对不同的用例演变出了不同的结构和架构。 其中一些基于我们对大脑的想法,而另一些则基于大脑的实际工作。 即将到来的所有章节均基于业界正在使用的的最新架构。 我们将介绍每种架构下的一个或多个应用程序,每一章都涵盖所有概念,规范和技术细节,其中显然都包含 PyTorch 代码。 深度学习已经存在了数十年,针对不同的用例演变出了不同的结构和架构。 其中一些基于我们对大脑的想法,而另一些则基于大脑的实际工作。 即将到来的所有章节均基于业界正在使用的的最新架构。 我们将介绍每种架构下的一个或多个应用,每一章都涵盖所有概念,规范和技术细节,其中显然都包含 PyTorch 代码。
#### 全连接网络 #### 全连接网络
...@@ -250,7 +250,7 @@ RNN 是最常见的深度学习算法之一,它们席卷全球。 我们现在 ...@@ -250,7 +250,7 @@ RNN 是最常见的深度学习算法之一,它们席卷全球。 我们现在
#### 循环神经网络 #### 循环神经网络
顾名思义,循环神经网络是树状网络,用于了解序列数据的层次结构。 递归网络已在**自然语言处理**应用程序中大量使用,尤其是 Salesforce 首席科学家 Richard Socher 及其团队。 顾名思义,循环神经网络是树状网络,用于了解序列数据的层次结构。 递归网络已在**自然语言处理**应用中大量使用,尤其是 Salesforce 首席科学家 Richard Socher 及其团队。
词向量,我们将在第 5 章,“序列数据处理”中很快看到,它们能够将词的含义有效地映射到向量空间中,但是涉及到含义 在整个句子中,没有像 word2vec 这样的单词适合的解决方案。 循环神经网络是此类应用最常用的算法之一。 递归网络可以创建一个解析树和组成向量,并映射其他层次关系,这反过来又帮助我们找到了结合单词和句子的规则。 **斯坦福自然语言推断**小组发现了一种著名的且使用良好的算法,称为 **SNLI**,这是递归网络使用的一个很好的例子。 词向量,我们将在第 5 章,“序列数据处理”中很快看到,它们能够将词的含义有效地映射到向量空间中,但是涉及到含义 在整个句子中,没有像 word2vec 这样的单词适合的解决方案。 循环神经网络是此类应用最常用的算法之一。 递归网络可以创建一个解析树和组成向量,并映射其他层次关系,这反过来又帮助我们找到了结合单词和句子的规则。 **斯坦福自然语言推断**小组发现了一种著名的且使用良好的算法,称为 **SNLI**,这是递归网络使用的一个很好的例子。
...@@ -306,7 +306,7 @@ Figure 1.16: GAN setup ...@@ -306,7 +306,7 @@ Figure 1.16: GAN setup
import torch import torch
``` ```
PyTorch 中的基本数据抽象是`Tensor`对象,它是 NumPy 中`ndarray`的替代方案。 您可以在 PyTorch 中以多种方式创建张量。 我们将在此处讨论一些基本方法,在构建应用程序时,您将在接下来的各章中看到所有这些方法: PyTorch 中的基本数据抽象是`Tensor`对象,它是 NumPy 中`ndarray`的替代方案。 您可以在 PyTorch 中以多种方式创建张量。 我们将在此处讨论一些基本方法,在构建应用时,您将在接下来的各章中看到所有这些方法:
```py ```py
uninitialized = torch.Tensor(3,2) uninitialized = torch.Tensor(3,2)
......
...@@ -12,7 +12,7 @@ PyTorch 最初是由 Facebook 实习生作为研究框架开始的,现已发 ...@@ -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 模型 数百万个请求,以及将模型迁移到单板计算机和移动设备。
## 构思和计划 ## 构思和计划
......
...@@ -53,14 +53,14 @@ PyTorch 为计算机视觉提供了几个便捷功能,其中包括卷积层和 ...@@ -53,14 +53,14 @@ PyTorch 为计算机视觉提供了几个便捷功能,其中包括卷积层和
除了用于计算机视觉的高层功能之外,`torchvision`还具有一些方便的实用程序功能来建立网络。 在本章中,我们将探讨其中的一些。 除了用于计算机视觉的高层功能之外,`torchvision`还具有一些方便的实用程序功能来建立网络。 在本章中,我们将探讨其中的一些。
本章使用两个神经网络应用程序说明 PyTorch: 本章使用两个神经网络应用说明 PyTorch:
* **简单 CNN**:用于对 CIFAR10 图像进行分类的简单神经网络架构 * **简单 CNN**:用于对 CIFAR10 图像进行分类的简单神经网络架构
* **语义分割**:使用来自简单 CNN 的概念进行语义分割的高级示例 * **语义分割**:使用来自简单 CNN 的概念进行语义分割的高级示例
### 简单 CNN ### 简单 CNN
我们正在开发 CNN 以执行简单的分类任务。 使用简单 CNN 的想法是为了了解 CNN 的工作原理。 弄清基础知识后,我们将转到高级网络设计,在其中使用高级 PyTorch 函数,该函数与该应用程序具有相同的功能,但效率更高。 我们正在开发 CNN 以执行简单的分类任务。 使用简单 CNN 的想法是为了了解 CNN 的工作原理。 弄清基础知识后,我们将转到高级网络设计,在其中使用高级 PyTorch 函数,该函数与该应用具有相同的功能,但效率更高。
我们将使用 CIFAR10 作为输入数据集,它由 10 类 60,000 张`32x32`彩色图像组成,每类 6,000 张图像。 `torchvision`具有更高级别的功能,可下载和处理数据集。 如我们在第 3 章,“深度学习工作流”中看到的示例一样,我们下载数据集,然后使用转换对其进行转换,并将其包装在`get_data()`函数下。 我们将使用 CIFAR10 作为输入数据集,它由 10 类 60,000 张`32x32`彩色图像组成,每类 6,000 张图像。 `torchvision`具有更高级别的功能,可下载和处理数据集。 如我们在第 3 章,“深度学习工作流”中看到的示例一样,我们下载数据集,然后使用转换对其进行转换,并将其包装在`get_data()`函数下。
...@@ -294,7 +294,7 @@ running_loss += loss.item() ...@@ -294,7 +294,7 @@ running_loss += loss.item()
### 语义分割 ### 语义分割
我们已经了解了 CNN 的工作原理。 现在,我们将进行下一步,并开发 CNN 的高级应用程序,称为语义分段。 顾名思义,该技术将图像的一部分标记为一个类别,例如,将所有树木标记为绿色,将建筑物标记为红色,将汽车标记为灰色,等等。 分割本身意味着从图像中识别结构,区域等。 我们已经了解了 CNN 的工作原理。 现在,我们将进行下一步,并开发 CNN 的高级应用,称为语义分段。 顾名思义,该技术将图像的一部分标记为一个类别,例如,将所有树木标记为绿色,将建筑物标记为红色,将汽车标记为灰色,等等。 分割本身意味着从图像中识别结构,区域等。
语义分割是智能的,在我们想要了解图像中的内容而不是仅识别结构或区域时将使用它。 语义分割正在识别和理解像素级图像中的内容。 语义分割是智能的,在我们想要了解图像中的内容而不是仅识别结构或区域时将使用它。 语义分割正在识别和理解像素级图像中的内容。
...@@ -571,7 +571,7 @@ class SegmentationModel(nn.Module): ...@@ -571,7 +571,7 @@ class SegmentationModel(nn.Module):
在过去的十年中,借助人工智能,计算机视觉领域得到了显着改善。 现在,它不仅用于诸如对象检测/识别之类的传统用例,而且还用于提高图像质量,从图像/视频进行丰富的搜索,从图像/视频生成文本,3D 建模等等。 在过去的十年中,借助人工智能,计算机视觉领域得到了显着改善。 现在,它不仅用于诸如对象检测/识别之类的传统用例,而且还用于提高图像质量,从图像/视频进行丰富的搜索,从图像/视频生成文本,3D 建模等等。
在本章中,我们已经介绍了 CNN,这是迄今为止计算机视觉取得所有成功的关键。 CNN 的许多架构变体已用于不同目的,但是所有这些实现的核心是 CNN 的基本构建块。 关于 CNN 的技术局限性,已经进行了大量研究,尤其是从人类视觉仿真的角度。 已经证明,CNN 不能完全模拟人类视觉系统的工作方式。 这使许多研究小组认为应该有替代方案。 替代 CNN 的一种最流行的方法是使用胶囊网络,这也是杰弗里·欣顿实验室的成果。 但是现在,CNN 正在作为成千上万的实时和关键计算机视觉应用程序的核心。 在本章中,我们已经介绍了 CNN,这是迄今为止计算机视觉取得所有成功的关键。 CNN 的许多架构变体已用于不同目的,但是所有这些实现的核心是 CNN 的基本构建块。 关于 CNN 的技术局限性,已经进行了大量研究,尤其是从人类视觉仿真的角度。 已经证明,CNN 不能完全模拟人类视觉系统的工作方式。 这使许多研究小组认为应该有替代方案。 替代 CNN 的一种最流行的方法是使用胶囊网络,这也是杰弗里·欣顿实验室的成果。 但是现在,CNN 正在作为成千上万的实时和关键计算机视觉应用的核心。
在下一章中,我们将研究另一种基本的网络架构:循环神经网络。 在下一章中,我们将研究另一种基本的网络架构:循环神经网络。
......
...@@ -452,7 +452,7 @@ def optimize_model(): ...@@ -452,7 +452,7 @@ def optimize_model():
在本章中,我们学习了无监督学习的一个全新领域:强化学习。 这是一个完全不同的领域,我们在本章中仅涉及了这个主题。 我们学习了如何对问题进行措辞以进行强化学习,然后我们训练了一个模型,该模型可以看到环境提供的一些测量结果,并且可以学习如何平衡赤字。 您可以应用相同的知识来教机器人走路,驾驶汽车以及玩游戏。 这是深度学习的更多物理应用之一。 在本章中,我们学习了无监督学习的一个全新领域:强化学习。 这是一个完全不同的领域,我们在本章中仅涉及了这个主题。 我们学习了如何对问题进行措辞以进行强化学习,然后我们训练了一个模型,该模型可以看到环境提供的一些测量结果,并且可以学习如何平衡赤字。 您可以应用相同的知识来教机器人走路,驾驶汽车以及玩游戏。 这是深度学习的更多物理应用之一。
在下一章和最后一章中,我们将着眼于生产我们的 PyTorch 模型,以便您可以在任何框架或语言上运行它们,并扩展您的深度学习应用程序 在下一章和最后一章中,我们将着眼于生产我们的 PyTorch 模型,以便您可以在任何框架或语言上运行它们,并扩展您的深度学习应用。
## 参考 ## 参考
......
...@@ -12,7 +12,7 @@ ONNX 很棒,并且每个人都喜欢它,但是 ONNX 的主要缺点之一是 ...@@ -12,7 +12,7 @@ ONNX 很棒,并且每个人都喜欢它,但是 ONNX 的主要缺点之一是
接下来是 TorchScript 的引入,它可以将本机 Python 模型转换为可以在高性能 Universe 中加载的序列化形式,例如 C++ 线程。 PyTorch 的后端 LibTorch 可以读取 TorchScript,这使 PyTorch 高效。 有了它,开发人员可以对模型进行原型设计,甚至可以使用 Python 本身对其进行训练。 训练后,可以将模型转换为到**中间表示****IR**)。 目前,仅开发了 C++ 后端,因此可以将 IR 作为 C++ 对象加载,然后可以从 PyTorch 的 C++ API 中读取。 TorchScript 甚至可以在 Python 程序中转换控制流,这在生产支持的情况下使其优于 ONNX 方法。 TorchScript 本身是 Python 语言中可能的操作的子集,因此不允许任何 Python 操作用 TorchScript 编写。 官方文档本身提供了非常详细的说明,并讨论了可能的情况和不可能的情况,以及许多示例[1]。 接下来是 TorchScript 的引入,它可以将本机 Python 模型转换为可以在高性能 Universe 中加载的序列化形式,例如 C++ 线程。 PyTorch 的后端 LibTorch 可以读取 TorchScript,这使 PyTorch 高效。 有了它,开发人员可以对模型进行原型设计,甚至可以使用 Python 本身对其进行训练。 训练后,可以将模型转换为到**中间表示****IR**)。 目前,仅开发了 C++ 后端,因此可以将 IR 作为 C++ 对象加载,然后可以从 PyTorch 的 C++ API 中读取。 TorchScript 甚至可以在 Python 程序中转换控制流,这在生产支持的情况下使其优于 ONNX 方法。 TorchScript 本身是 Python 语言中可能的操作的子集,因此不允许任何 Python 操作用 TorchScript 编写。 官方文档本身提供了非常详细的说明,并讨论了可能的情况和不可能的情况,以及许多示例[1]。
在本章中,我们将从使用 Flask(流行的 Python Web 框架)提供普通的 Python PyTorch 模型开始。 这样的设置通常就足够了,特别是如果您要设置示例 Web 应用程序或满足您个人需求或类似用例的东西。 然后,我们将探索 ONNX 并将 PyTorch 模型转换为 MXNet,然后可以使用 MXNet 模型服务器提供服务。 从那里,我们将转到 TorchScript,这是 PyTorch 街区的新孩子。 使用 TorchScript,我们将制作 C++ 可执行文件,然后可以在 LibTorch 的帮助下从 C++ 执行该可执行文件。 然后,可以从稳定,高性能的 C++ 服务器甚至使用 cgo 的 Go 服务器提供高效的 C++ 可执行文件。 对于所有份量,我们将使用在第 2 章,“简单神经网络”中构建的 fizzbuzz 网络。 在本章中,我们将从使用 Flask(流行的 Python Web 框架)提供普通的 Python PyTorch 模型开始。 这样的设置通常就足够了,特别是如果您要设置示例 Web 应用或满足您个人需求或类似用例的东西。 然后,我们将探索 ONNX 并将 PyTorch 模型转换为 MXNet,然后可以使用 MXNet 模型服务器提供服务。 从那里,我们将转到 TorchScript,这是 PyTorch 街区的新孩子。 使用 TorchScript,我们将制作 C++ 可执行文件,然后可以在 LibTorch 的帮助下从 C++ 执行该可执行文件。 然后,可以从稳定,高性能的 C++ 服务器甚至使用 cgo 的 Go 服务器提供高效的 C++ 可执行文件。 对于所有份量,我们将使用在第 2 章,“简单神经网络”中构建的 fizzbuzz 网络。
## 与烧瓶一起食用 ## 与烧瓶一起食用
...@@ -29,7 +29,7 @@ pip install Flask ...@@ -29,7 +29,7 @@ pip install Flask
``` ```
这将安装其他依赖项 Werkzeug(应用程序和服务器之间的 Python 接口),Jinga(作为模板引擎),其危险(用于安全签名数据)和 Click(作为 CLI 构建器)。 这将安装其他依赖项 Werkzeug(应用和服务器之间的 Python 接口),Jinga(作为模板引擎),其危险(用于安全签名数据)和 Click(作为 CLI 构建器)。
安装后,用户将可以访问 CLI,并使用`flask run`调用我们的脚本将启动服务器: 安装后,用户将可以访问 CLI,并使用`flask run`调用我们的脚本将启动服务器:
...@@ -45,9 +45,9 @@ def hello(): ...@@ -45,9 +45,9 @@ def hello():
该示例包含四个部分: 该示例包含四个部分:
* 第一行是我们导入 Flask 包的位置。 * 第一行是我们导入 Flask 包的位置。
* 我们创建一个 Flask 对象,这是我们的大型 Web 应用程序对象,Flask 服务器将使用该对象来运行我们的服务器。 * 我们创建一个 Flask 对象,这是我们的大型 Web 应用对象,Flask 服务器将使用该对象来运行我们的服务器。
* 有了应用程序对象后,我们需要存储有关对象应对其执行操作的 URL 的信息。 为此,应用程序对象带有`route`方法,该方法接受所需的 URL 并返回装饰器。 这是我们希望应用程序现在提供的 URL。 * 有了应用对象后,我们需要存储有关对象应对其执行操作的 URL 的信息。 为此,应用对象带有`route`方法,该方法接受所需的 URL 并返回装饰器。 这是我们希望应用现在提供的 URL。
* 由应用程序对象返回的装饰器对一个函数进行装饰,当 URL 命中时,将触发该函数。 我们将其命名为`hello`。 函数的名称在这里并不重要。 在前面的示例中,它只是检查输入并做出相应的响应。 但是对于我们的模型服务器,我们使此功能稍微复杂一点,以便它可以接受输入并将该输入提供给我们构建的模型。 然后,我们模型的返回值将作为 HTTP 响应推回给用户。 * 由应用对象返回的装饰器对一个函数进行装饰,当 URL 命中时,将触发该函数。 我们将其命名为`hello`。 函数的名称在这里并不重要。 在前面的示例中,它只是检查输入并做出相应的响应。 但是对于我们的模型服务器,我们使此功能稍微复杂一点,以便它可以接受输入并将该输入提供给我们构建的模型。 然后,我们模型的返回值将作为 HTTP 响应推回给用户。
我们通过建立`flask_trial`目录开始实现,并将该文件另存为`app.py`在该目录中: 我们通过建立`flask_trial`目录开始实现,并将该文件另存为`app.py`在该目录中:
...@@ -64,7 +64,7 @@ flask run ...@@ -64,7 +64,7 @@ flask run
``` ```
我们可以通过向服务器位置发出 HTTP 请求来测试简单的 Flask 应用程序。 如果一切正常,我们应该得到一个“你好,世界!” 来自服务器的消息。 我们可以通过向服务器位置发出 HTTP 请求来测试简单的 Flask 应用。 如果一切正常,我们应该得到一个“你好,世界!” 来自服务器的消息。
```py ```py
-> curl "http://127.0.0.1:5000" -> curl "http://127.0.0.1:5000"
...@@ -72,7 +72,7 @@ flask run ...@@ -72,7 +72,7 @@ flask run
``` ```
我们已经建立了简单的 Flask 应用程序。 现在,将 fizzbuzz 模型引入我们的应用程序。 以下代码片段显示了与第 2 章和“简单神经网络”相同的模型,供您参考。 该模型将从路由器功能中调用。 我们已经在第 2 章和“一个简单的神经网络”中对模型进行了训练,因此,我们将在这里加载训练后的模型,而不是再次对其进行训练: 我们已经建立了简单的 Flask 应用。 现在,将 fizzbuzz 模型引入我们的应用。 以下代码片段显示了与第 2 章和“简单神经网络”相同的模型,供您参考。 该模型将从路由器功能中调用。 我们已经在第 2 章和“一个简单的神经网络”中对模型进行了训练,因此,我们将在这里加载训练后的模型,而不是再次对其进行训练:
```py ```py
import torch.nn as nn import torch.nn as nn
...@@ -99,7 +99,7 @@ class FizBuzNet(nn.Module): ...@@ -99,7 +99,7 @@ class FizBuzNet(nn.Module):
#### 适用于 Flask 的模型 #### 适用于 Flask 的模型
下面的屏幕快照给出了我们应用程序的目录结构。 `assets`文件夹具有训练好的模型,在加载模型时,`controller.py`文件将使用该模型。 根目录中的`app.py`是 Flask 应用程序的入口。 Flask 首选`app.py`作为入口点文件的默认名称。 下面的屏幕快照给出了我们应用的目录结构。 `assets`文件夹具有训练好的模型,在加载模型时,`controller.py`文件将使用该模型。 根目录中的`app.py`是 Flask 应用的入口。 Flask 首选`app.py`作为入口点文件的默认名称。
当您执行`flask run`时,Flask 将在当前目录中查找`app.py`文件并执行该文件。 `controller.py`文件是我们从`model.py`文件加载模型的地方。 然后,加载的模型将等待用户通过 HTTP 端点输入。 `app.py`将用户输入重定向到`controller`,然后将其转换为 Torch 张量。 当您执行`flask run`时,Flask 将在当前目录中查找`app.py`文件并执行该文件。 `controller.py`文件是我们从`model.py`文件加载模型的地方。 然后,加载的模型将等待用户通过 HTTP 端点输入。 `app.py`将用户输入重定向到`controller`,然后将其转换为 Torch 张量。
...@@ -109,7 +109,7 @@ class FizBuzNet(nn.Module): ...@@ -109,7 +109,7 @@ class FizBuzNet(nn.Module):
图 8.1:当前目录 图 8.1:当前目录
目录中有四个组件用于制作 Flask 应用。 `assets`文件夹是我们保留模型的地方。 其他三个文件是代码所在的位置。 让我们研究一下每个。 我们将从入口文件`app.py`开始。 它是先前提供的简单 Flask 应用程序的扩展版本。 该文件教我们如何定义 URL 端点,以及如何将 URL 端点映射到 Python 函数。 我们的扩展`app.py`文件显示在以下代码块中: 目录中有四个组件用于制作 Flask 应用。 `assets`文件夹是我们保留模型的地方。 其他三个文件是代码所在的位置。 让我们研究一下每个。 我们将从入口文件`app.py`开始。 它是先前提供的简单 Flask 应用的扩展版本。 该文件教我们如何定义 URL 端点,以及如何将 URL 端点映射到 Python 函数。 我们的扩展`app.py`文件显示在以下代码块中:
```py ```py
import json import json
...@@ -135,13 +135,13 @@ def predict(): ...@@ -135,13 +135,13 @@ def predict():
return out return out
``` ```
Flask 为我们提供了`request`实用程序,它是一个全局变量,但对于存储有关当前请求信息的当前线程而言是局部的。 我们使用`request`对象的`get_json`函数从`request`对象获取主体`POST`参数。 然后,将通过 HTTP 传入的字符串数据转换为整数。 这个整数是我们从前端传递的数字。 我们应用程序的任务是预测下一个数字的状态。 那将是下一个数字本身还是嘶嘶声,嗡嗡声或嘶嘶声? 但是,如果您还记得,我们会训练我们的网络来预测我们通过的号码的状态。 但是,我们需要下一个号码的状态。 因此,我们将一个加到当前数上,然后将结果传递给我们的模型。 Flask 为我们提供了`request`实用程序,它是一个全局变量,但对于存储有关当前请求信息的当前线程而言是局部的。 我们使用`request`对象的`get_json`函数从`request`对象获取主体`POST`参数。 然后,将通过 HTTP 传入的字符串数据转换为整数。 这个整数是我们从前端传递的数字。 我们应用的任务是预测下一个数字的状态。 那将是下一个数字本身还是嘶嘶声,嗡嗡声或嘶嘶声? 但是,如果您还记得,我们会训练我们的网络来预测我们通过的号码的状态。 但是,我们需要下一个号码的状态。 因此,我们将一个加到当前数上,然后将结果传递给我们的模型。
我们的下一个导入是`controller`,我们在其中加载了模型文件。 我们正在调用`run`方法并将数字传递给模型。 然后,将`controller`的预测值作为字典传递回。 Flask 会将其转换为响应正文并将其发送回用户。 我们的下一个导入是`controller`,我们在其中加载了模型文件。 我们正在调用`run`方法并将数字传递给模型。 然后,将`controller`的预测值作为字典传递回。 Flask 会将其转换为响应正文并将其发送回用户。
在继续之前,我们可以从以前的简单 Flask 应用程序的扩展版本中看到两个主要差异。 一种是 URL 路由:`/predictions/fizbuz_package`。 如前所述,Flask 允许您将任何 URL 端点映射到您选择的功能。 在继续之前,我们可以从以前的简单 Flask 应用的扩展版本中看到两个主要差异。 一种是 URL 路由:`/predictions/fizbuz_package`。 如前所述,Flask 允许您将任何 URL 端点映射到您选择的功能。
其次,我们在装饰器中使用了另一个关键字参数:`methods`。 这样,我们告诉 Flask,不仅需要通过 URL 规则来调用此函数,而且还需要在对该 URL 的`POST`方法调用上进行调用。 因此,我们像以前一样使用`flask run`运行该应用程序,并使用`curl`命令对其进行测试。 其次,我们在装饰器中使用了另一个关键字参数:`methods`。 这样,我们告诉 Flask,不仅需要通过 URL 规则来调用此函数,而且还需要在对该 URL 的`POST`方法调用上进行调用。 因此,我们像以前一样使用`flask run`运行该应用,并使用`curl`命令对其进行测试。
```py ```py
-> curl -X POST http://127.0.0.1:5000/predictions/fizbuz_package \ -> curl -X POST http://127.0.0.1:5000/predictions/fizbuz_package \
...@@ -160,16 +160,16 @@ Flask 为我们提供了`request`实用程序,它是一个全局变量,但 ...@@ -160,16 +160,16 @@ Flask 为我们提供了`request`实用程序,它是一个全局变量,但
#### 准备生产的服务器 #### 准备生产的服务器
这是关于如何使用 Flask 将 PyTorch 模型部署到服务器的非常基本的演练。 但是 Flask 的内置服务器尚未投入生产,只能用于开发目的。 开发完成后,我们应该使用其他服务器软件包在生产中为 Flask 应用程序提供服务。 这是关于如何使用 Flask 将 PyTorch 模型部署到服务器的非常基本的演练。 但是 Flask 的内置服务器尚未投入生产,只能用于开发目的。 开发完成后,我们应该使用其他服务器软件包在生产中为 Flask 应用提供服务。
Gunicorn 是 Python 开发人员使用的最受欢迎的服务器软件包之一,将其与 Flask 应用程序绑定非常容易。 您可以使用`pip`安装 Gunicorn,就像我们安装 Flask 一样: Gunicorn 是 Python 开发人员使用的最受欢迎的服务器软件包之一,将其与 Flask 应用绑定非常容易。 您可以使用`pip`安装 Gunicorn,就像我们安装 Flask 一样:
```py ```py
pip install gunicorn pip install gunicorn
``` ```
Gunicorn 需要我们传递模块名称,以便它能够拾取模块并运行服务器。 但是 Gunicorn 希望应用程序对象具有名称`application`,而我们的项目则不是这样。 因此,我们需要显式传递应用程序对象名称和模块名称。 Gunicorn 的命令行工具有很多选择,但是我们正在尝试使其尽可能简单: Gunicorn 需要我们传递模块名称,以便它能够拾取模块并运行服务器。 但是 Gunicorn 希望应用对象具有名称`application`,而我们的项目则不是这样。 因此,我们需要显式传递应用对象名称和模块名称。 Gunicorn 的命令行工具有很多选择,但是我们正在尝试使其尽可能简单:
```py ```py
gunicorn app:app gunicorn app:app
...@@ -492,7 +492,7 @@ mxnet-model-server \ ...@@ -492,7 +492,7 @@ mxnet-model-server \
--models fizbuz_package.mar --models fizbuz_package.mar
``` ```
现在,我们的模型服务器已启动并在端口 8080 上运行(如果您尚未更改端口)。 我们可以尝试执行与 Flask 应用程序相同的`curl`命令(显然,我们必须更改端口号)并检查模型。 我们应该获得与 Flask 应用程序完全相同的结果,但是现在我们可以根据需要动态地动态扩展或缩减工作人员的数量。 MMS 为此提供了管理 API。 管理 API 带有几个可配置的选项,但是这里我们只关注于增加或减少工作人员的数量。 现在,我们的模型服务器已启动并在端口 8080 上运行(如果您尚未更改端口)。 我们可以尝试执行与 Flask 应用相同的`curl`命令(显然,我们必须更改端口号)并检查模型。 我们应该获得与 Flask 应用完全相同的结果,但是现在我们可以根据需要动态地动态扩展或缩减工作人员的数量。 MMS 为此提供了管理 API。 管理 API 带有几个可配置的选项,但是这里我们只关注于增加或减少工作人员的数量。
除了在端口 8080 上运行的服务器之外,还将在 8081 上运行管理 API 服务,我们可以对其进行调用和控制配置。 使用简单的`GET`请求命中该端点将为您提供服务器的状态。 但是在探究这一点之前,我们将工人数量设为 1(默认情况下为 4)。 API 端点是适当的 REST 端点; 我们在路径中指定模型名称,并传递参数`max_worker=1`以使工人数为 1。 我们也可以通过`min_worker=<number>`来增加工人数量。 官方文档[2]中详细介绍了管理 API 上可能的配置。 除了在端口 8080 上运行的服务器之外,还将在 8081 上运行管理 API 服务,我们可以对其进行调用和控制配置。 使用简单的`GET`请求命中该端点将为您提供服务器的状态。 但是在探究这一点之前,我们将工人数量设为 1(默认情况下为 4)。 API 端点是适当的 REST 端点; 我们在路径中指定模型名称,并传递参数`max_worker=1`以使工人数为 1。 我们也可以通过`min_worker=<number>`来增加工人数量。 官方文档[2]中详细介绍了管理 API 上可能的配置。
......
...@@ -453,7 +453,7 @@ Shape of mfcc: torch.Size([1383, 13]) ...@@ -453,7 +453,7 @@ Shape of mfcc: torch.Size([1383, 13])
* **VCTK**:109 位以英语为母语的母语者说的语音数据,带有各种重音([在此处详细了解](https://homepages.inf.ed.ac.uk/jyamagis/page3/page58/page58.html))。 * **VCTK**:109 位以英语为母语的母语者说的语音数据,带有各种重音([在此处详细了解](https://homepages.inf.ed.ac.uk/jyamagis/page3/page58/page58.html))。
* **Yesno**:一个人在希伯来语中说是或否的 60 张唱片; 每个记录长 8 个字([在此处了解更多](https://www.openslr.org/1/))。 * **Yesno**:一个人在希伯来语中说是或否的 60 张唱片; 每个记录长 8 个字([在此处了解更多](https://www.openslr.org/1/))。
* **Common Voice**:开源的多语言语音数据集,任何人都可以用来训练启用语音的应用程序[在此处了解更多](https://voice.mozilla.org/en/datasets))。 * **Common Voice**:开源的多语言语音数据集,任何人都可以用来训练启用语音的应用([在此处了解更多](https://voice.mozilla.org/en/datasets))。
* **LibriSpeech**:阅读英语语音的大型语料库(1000 小时)([在此处详细了解](http://www.openslr.org/12))。 * **LibriSpeech**:阅读英语语音的大型语料库(1000 小时)([在此处详细了解](http://www.openslr.org/12))。
```py ```py
......
...@@ -210,7 +210,7 @@ test_loader = torch.utils.data.DataLoader( ...@@ -210,7 +210,7 @@ test_loader = torch.utils.data.DataLoader(
## 定义网络 ## 定义网络
在本教程中,我们将使用卷积神经网络来处理原始音频数据。 通常,更高级的转换将应用于音频数据,但是 CNN 可以用于准确处理原始数据。 具体架构是根据[本文](https://arxiv.org/pdf/1610.00087.pdf)中描述的 M5 网络架构建模的。 模型处理原始音频数据的一个重要方面是其第一层过滤器的接收范围。 我们模型的第一个滤波器长度为 80,因此在处理以 8kHz 采样的音频时,接收场约为 10ms(而在 4kHz 时约为 20ms)。 此大小类似于语音处理应用程序,该应用程序通常使用 20ms 到 40ms 的接收域。 在本教程中,我们将使用卷积神经网络来处理原始音频数据。 通常,更高级的转换将应用于音频数据,但是 CNN 可以用于准确处理原始数据。 具体架构是根据[本文](https://arxiv.org/pdf/1610.00087.pdf)中描述的 M5 网络架构建模的。 模型处理原始音频数据的一个重要方面是其第一层过滤器的接收范围。 我们模型的第一个滤波器长度为 80,因此在处理以 8kHz 采样的音频时,接收场约为 10ms(而在 4kHz 时约为 20ms)。 此大小类似于语音处理应用,该应用通常使用 20ms 到 40ms 的接收域。
```py ```py
class M5(nn.Module): class M5(nn.Module):
......
...@@ -300,7 +300,7 @@ resp = requests.post("http://localhost:5000/predict", ...@@ -300,7 +300,7 @@ resp = requests.post("http://localhost:5000/predict",
## 后续步骤 ## 后续步骤
我们编写的服务器非常琐碎,可能无法完成生产应用程序所需的一切。 因此,您可以采取一些措施来改善它: 我们编写的服务器非常琐碎,可能无法完成生产应用所需的一切。 因此,您可以采取一些措施来改善它:
* 端点`/predict`假定请求中始终会有一个图像文件。 这可能并不适用于所有请求。 我们的用户可能发送带有其他参数的图像,或者根本不发送任何图像。 * 端点`/predict`假定请求中始终会有一个图像文件。 这可能并不适用于所有请求。 我们的用户可能发送带有其他参数的图像,或者根本不发送任何图像。
* 用户也可以发送非图像类型的文件。 由于我们没有处理错误,因此这将破坏我们的服务器。 添加显式的错误处理路径将引发异常,这将使我们能够更好地处理错误的输入 * 用户也可以发送非图像类型的文件。 由于我们没有处理错误,因此这将破坏我们的服务器。 添加显式的错误处理路径将引发异常,这将使我们能够更好地处理错误的输入
......
...@@ -100,9 +100,9 @@ traced_script_module.save("traced_resnet_model.pt") ...@@ -100,9 +100,9 @@ traced_script_module.save("traced_resnet_model.pt")
## 第 3 步:在 C++ 中加载脚本模块 ## 第 3 步:在 C++ 中加载脚本模块
要在 C++ 中加载序列化的 PyTorch 模型,您的应用程序必须依赖于 PyTorch C++ API –也称为 *LibTorch* 。 LibTorch 发行版包含共享库,头文件和 CMake 构建配置文件的集合。 虽然 CMake 不是依赖 LibTorch 的要求,但它是推荐的方法,将来会得到很好的支持。 对于本教程,我们将使用 CMake 和 LibTorch 构建一个最小的 C++ 应用程序,该应用程序简单地加载并执行序列化的 PyTorch 模型。 要在 C++ 中加载序列化的 PyTorch 模型,您的应用必须依赖于 PyTorch C++ API –也称为 *LibTorch* 。 LibTorch 发行版包含共享库,头文件和 CMake 构建配置文件的集合。 虽然 CMake 不是依赖 LibTorch 的要求,但它是推荐的方法,将来会得到很好的支持。 对于本教程,我们将使用 CMake 和 LibTorch 构建一个最小的 C++ 应用,该应用简单地加载并执行序列化的 PyTorch 模型。
### 最小的 C++ 应用程序 ### 最小的 C++ 应用
让我们从讨论加载模块的代码开始。 以下将已经做: 让我们从讨论加载模块的代码开始。 以下将已经做:
...@@ -133,9 +133,9 @@ int main(int argc, const char* argv[]) { ...@@ -133,9 +133,9 @@ int main(int argc, const char* argv[]) {
``` ```
`<torch/script.h>`标头包含了运行示例所需的 LibTorch 库中的所有相关包含。 我们的应用程序接受序列化的 PyTorch `ScriptModule`的文件路径作为其唯一的命令行参数,然后继续使用`torch::jit::load()`函数对该模块进行反序列化,该函数将该文件路径作为输入。 作为回报,我们收到一个`torch::jit::script::Module`对象。 我们将稍后讨论如何执行它。 `<torch/script.h>`标头包含了运行示例所需的 LibTorch 库中的所有相关包含。 我们的应用接受序列化的 PyTorch `ScriptModule`的文件路径作为其唯一的命令行参数,然后继续使用`torch::jit::load()`函数对该模块进行反序列化,该函数将该文件路径作为输入。 作为回报,我们收到一个`torch::jit::script::Module`对象。 我们将稍后讨论如何执行它。
### 取决于 LibTorch 和构建应用程序 ### 取决于 LibTorch 和构建应用
假设我们将以上代码存储到名为`example-app.cpp`的文件中。 最小的`CMakeLists.txt`构建起来看起来很简单: 假设我们将以上代码存储到名为`example-app.cpp`的文件中。 最小的`CMakeLists.txt`构建起来看起来很简单:
...@@ -151,7 +151,7 @@ set_property(TARGET example-app PROPERTY CXX_STANDARD 14) ...@@ -151,7 +151,7 @@ set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
``` ```
建立示例应用程序的最后一件事是 LibTorch 发行版。 您可以随时从 PyTorch 网站上的[下载页面](https://pytorch.org/)获取最新的稳定版本。 如果下载并解压缩最新的归档文件,则应该收到具有以下目录结构的文件夹: 建立示例应用的最后一件事是 LibTorch 发行版。 您可以随时从 PyTorch 网站上的[下载页面](https://pytorch.org/)获取最新的稳定版本。 如果下载并解压缩最新的归档文件,则应该收到具有以下目录结构的文件夹:
```py ```py
libtorch/ libtorch/
...@@ -170,7 +170,7 @@ libtorch/ ...@@ -170,7 +170,7 @@ libtorch/
在 Windows 上,调试和发行版本不兼容 ABI。 如果计划以调试模式构建项目,请尝试使用 LibTorch 的调试版本。 另外,请确保在下面的`cmake --build .`行中指定正确的配置。 在 Windows 上,调试和发行版本不兼容 ABI。 如果计划以调试模式构建项目,请尝试使用 LibTorch 的调试版本。 另外,请确保在下面的`cmake --build .`行中指定正确的配置。
最后一步是构建应用程序。 为此,假定示例目录的布局如下: 最后一步是构建应用。 为此,假定示例目录的布局如下:
```py ```py
example-app/ example-app/
...@@ -179,7 +179,7 @@ example-app/ ...@@ -179,7 +179,7 @@ example-app/
``` ```
现在,我们可以运行以下命令从`example-app/`文件夹中构建应用程序 现在,我们可以运行以下命令从`example-app/`文件夹中构建应用:
```py ```py
mkdir build mkdir build
...@@ -239,7 +239,7 @@ ok ...@@ -239,7 +239,7 @@ ok
## 步骤 4:在 C++ 中执行脚本模块 ## 步骤 4:在 C++ 中执行脚本模块
在用 C++ 成功加载序列化的`ResNet18`之后,我们现在离执行它仅几行代码了! 让我们将这些行添加到 C++ 应用程序`main()`函数中: 在用 C++ 成功加载序列化的`ResNet18`之后,我们现在离执行它仅几行代码了! 让我们将这些行添加到 C++ 应用的`main()`函数中:
```py ```py
// Create a vector of inputs. // Create a vector of inputs.
...@@ -258,7 +258,7 @@ std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n'; ...@@ -258,7 +258,7 @@ std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';
要总体上了解有关`torch::ones`和 PyTorch C++ API 之类的功能的更多信息,请参阅[这个页面](https://pytorch.org/cppdocs)上的文档。 PyTorch C++ API 提供了与 Python API 几乎相同的功能,使您可以像在 Python 中一样进一步操纵和处理张量。 要总体上了解有关`torch::ones`和 PyTorch C++ API 之类的功能的更多信息,请参阅[这个页面](https://pytorch.org/cppdocs)上的文档。 PyTorch C++ API 提供了与 Python API 几乎相同的功能,使您可以像在 Python 中一样进一步操纵和处理张量。
在最后一行,我们打印输出的前五个条目。 由于在本教程前面的部分中,我们为 Python 中的模型提供了相同的输入,因此理想情况下,我们应该看到相同的输出。 让我们通过重新编译我们的应用程序并以相同的序列化模型运行它来进行尝试: 在最后一行,我们打印输出的前五个条目。 由于在本教程前面的部分中,我们为 Python 中的模型提供了相同的输入,因此理想情况下,我们应该看到相同的输出。 让我们通过重新编译我们的应用并以相同的序列化模型运行它来进行尝试:
```py ```py
root@4b5a67132e81:/example-app/build# make root@4b5a67132e81:/example-app/build# make
......
...@@ -24,7 +24,7 @@ PyTorch C++ 前端是 PyTorch 机器学习框架的纯 C++ 接口。 虽然 PyTo ...@@ -24,7 +24,7 @@ PyTorch C++ 前端是 PyTorch 机器学习框架的纯 C++ 接口。 虽然 PyTo
* **低延迟系统**:您可能希望在具有高每秒帧数和低延迟要求的纯 C++ 游戏引擎中进行强化学习研究。 与 Python 库相比,使用纯 C++ 库更适合这种环境。 由于 Python 解释器的缓慢性,Python 可能根本无法处理。 * **低延迟系统**:您可能希望在具有高每秒帧数和低延迟要求的纯 C++ 游戏引擎中进行强化学习研究。 与 Python 库相比,使用纯 C++ 库更适合这种环境。 由于 Python 解释器的缓慢性,Python 可能根本无法处理。
* **高度多线程环境**:由于全局解释器锁定(GIL),Python 一次不能运行多个系统线程。 多处理是一种替代方法,但可伸缩性却不如它,并且存在很多缺点。 C++ 没有这样的约束,线程易于使用和创建。 需要重型并行化的模型,例如[深度神经演化](https://eng.uber.com/deep-neuroevolution/)中使用的模型,可以从中受益。 * **高度多线程环境**:由于全局解释器锁定(GIL),Python 一次不能运行多个系统线程。 多处理是一种替代方法,但可伸缩性却不如它,并且存在很多缺点。 C++ 没有这样的约束,线程易于使用和创建。 需要重型并行化的模型,例如[深度神经演化](https://eng.uber.com/deep-neuroevolution/)中使用的模型,可以从中受益。
* **现有 C++ 代码库**:您可能是现有 C++ 应用程序的所有者,该应用程序从事从后端服务器中的网页服务到照片编辑软件中的 3D 图形渲染等所有工作,并且希望将机器学习方法集成到您的系统中。 C++ 前端使您可以继续使用 C++,并避免在 Python 和 C++ 之间来回绑定的麻烦,同时保留了传统 PyTorch(Python)体验的大部分灵活性和直观性。 * **现有 C++ 代码库**:您可能是现有 C++ 应用的所有者,该应用从事从后端服务器中的网页服务到照片编辑软件中的 3D 图形渲染等所有工作,并且希望将机器学习方法集成到您的系统中。 C++ 前端使您可以继续使用 C++,并避免在 Python 和 C++ 之间来回绑定的麻烦,同时保留了传统 PyTorch(Python)体验的大部分灵活性和直观性。
C++ 前端无意与 Python 前端竞争。 它是对它的补充。 我们知道研究人员和工程师都喜欢 PyTorch,因为它具有简单,灵活和直观的 API。 我们的目标是确保您可以在所有可能的环境(包括上述环境)中利用这些核心设计原则。 如果这些场景中的一种很好地描述了您的用例,或者您只是感兴趣或好奇,请在以下段落中继续研究 C++ 前端。 C++ 前端无意与 Python 前端竞争。 它是对它的补充。 我们知道研究人员和工程师都喜欢 PyTorch,因为它具有简单,灵活和直观的 API。 我们的目标是确保您可以在所有可能的环境(包括上述环境)中利用这些核心设计原则。 如果这些场景中的一种很好地描述了您的用例,或者您只是感兴趣或好奇,请在以下段落中继续研究 C++ 前端。
...@@ -32,9 +32,9 @@ C++ 前端无意与 Python 前端竞争。 它是对它的补充。 我们知道 ...@@ -32,9 +32,9 @@ C++ 前端无意与 Python 前端竞争。 它是对它的补充。 我们知道
C++ 前端试图提供一个与 Python 前端尽可能接近的 API。 如果您对 Python 前端有丰富的经验,并且问过自己“我如何使用 C++ 前端 X?”,请像在 Python 中那样编写代码,而且大多数情况下,相同的函数和方法也可以在 C++ 中使用 就像在 Python 中一样(只记得用双冒号替换点)。 C++ 前端试图提供一个与 Python 前端尽可能接近的 API。 如果您对 Python 前端有丰富的经验,并且问过自己“我如何使用 C++ 前端 X?”,请像在 Python 中那样编写代码,而且大多数情况下,相同的函数和方法也可以在 C++ 中使用 就像在 Python 中一样(只记得用双冒号替换点)。
## 编写基本应用程序 ## 编写基本应用
首先,编写一个最小的 C++ 应用程序,以验证我们是否在同一页面上了解我们的设置和构建环境。 首先,您需要获取 *LibTorch* 发行版的副本-我们现成的 zip 归档文件,其中打包了使用 C++ 前端所需的所有相关标头,库和 CMake 构建文件。 LibTorch 发行版可从 [PyTorch 网站](https://pytorch.org/get-started/locally/)下载,适用于 Linux,MacOS 和 Windows。 本教程的其余部分将假定基本的 Ubuntu Linux 环境,但是您也可以在 MacOS 或 Windows 上随意进行操作。 首先,编写一个最小的 C++ 应用,以验证我们是否在同一页面上了解我们的设置和构建环境。 首先,您需要获取 *LibTorch* 发行版的副本-我们现成的 zip 归档文件,其中打包了使用 C++ 前端所需的所有相关标头,库和 CMake 构建文件。 LibTorch 发行版可从 [PyTorch 网站](https://pytorch.org/get-started/locally/)下载,适用于 Linux,MacOS 和 Windows。 本教程的其余部分将假定基本的 Ubuntu Linux 环境,但是您也可以在 MacOS 或 Windows 上随意进行操作。
小费 小费
...@@ -66,7 +66,7 @@ int main() { ...@@ -66,7 +66,7 @@ int main() {
``` ```
稍后,为了构建这个小应用程序以及我们完整的训练脚本,我们将使用以下`CMakeLists.txt`文件: 稍后,为了构建这个小应用以及我们完整的训练脚本,我们将使用以下`CMakeLists.txt`文件:
```py ```py
cmake_minimum_required(VERSION 3.0 FATAL_ERROR) cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
...@@ -84,7 +84,7 @@ set_property(TARGET dcgan PROPERTY CXX_STANDARD 14) ...@@ -84,7 +84,7 @@ set_property(TARGET dcgan PROPERTY CXX_STANDARD 14)
虽然 CMake 是 LibTorch 的推荐构建系统,但这并不是硬性要求。 您还可以使用 Visual Studio 项目文件,QMake,普通 Makefile 或您认为合适的任何其他构建环境。 但是,我们不为此提供现成的支持。 虽然 CMake 是 LibTorch 的推荐构建系统,但这并不是硬性要求。 您还可以使用 Visual Studio 项目文件,QMake,普通 Makefile 或您认为合适的任何其他构建环境。 但是,我们不为此提供现成的支持。
在上面的 CMake 文件中记下第 4 行:`find_package(Torch REQUIRED)`。 这指示 CMake 查找 LibTorch 库的构建配置。 为了使 CMake 知道在哪里找到这些文件,调用`cmake`时必须设置`CMAKE_PREFIX_PATH`。 在执行此操作之前,让我们就`dcgan`应用程序的以下目录结构达成一致: 在上面的 CMake 文件中记下第 4 行:`find_package(Torch REQUIRED)`。 这指示 CMake 查找 LibTorch 库的构建配置。 为了使 CMake 知道在哪里找到这些文件,调用`cmake`时必须设置`CMAKE_PREFIX_PATH`。 在执行此操作之前,让我们就`dcgan`应用的以下目录结构达成一致:
```py ```py
dcgan/ dcgan/
...@@ -93,7 +93,7 @@ dcgan/ ...@@ -93,7 +93,7 @@ dcgan/
``` ```
此外,我将指向未压缩的 LibTorch 分布的路径称为`/path/to/libtorch`。 注意,它**必须是绝对路径**。 特别是,将`CMAKE_PREFIX_PATH`设置为`../../libtorch`之类的内容会以意想不到的方式中断。 而是写`$PWD/../../libtorch`以获取相应的绝对路径。 现在,我们准备构建我们的应用程序 此外,我将指向未压缩的 LibTorch 分布的路径称为`/path/to/libtorch`。 注意,它**必须是绝对路径**。 特别是,将`CMAKE_PREFIX_PATH`设置为`../../libtorch`之类的内容会以意想不到的方式中断。 而是写`$PWD/../../libtorch`以获取相应的绝对路径。 现在,我们准备构建我们的应用:
```py ```py
root@fa350df05ecf:/home# mkdir build root@fa350df05ecf:/home# mkdir build
......
...@@ -440,13 +440,13 @@ TorchScript 图形表示仍可能更改。 不要依靠它看起来像这样。 ...@@ -440,13 +440,13 @@ TorchScript 图形表示仍可能更改。 不要依靠它看起来像这样。
TorchScript 的一项有用功能是能够将模型序列化到磁盘文件中。 该文件可以通过有线方式发送,存储在文件系统中,或者更重要的是,可以动态反序列化和执行,而无需保留原始源代码。 这在 Python 中是可能的,但在 C++ 中也是可能的。 为此,PyTorch [提供了纯 C++ API](https://pytorch.org/cppdocs/),用于反序列化以及执行 TorchScript 模型。 如果您还没有的话,请阅读[在 C++ 中加载和运行序列化 TorchScript 模型](https://pytorch.org/tutorials/advanced/cpp_export.html)的教程,接下来的几段将基于该教程构建。 TorchScript 的一项有用功能是能够将模型序列化到磁盘文件中。 该文件可以通过有线方式发送,存储在文件系统中,或者更重要的是,可以动态反序列化和执行,而无需保留原始源代码。 这在 Python 中是可能的,但在 C++ 中也是可能的。 为此,PyTorch [提供了纯 C++ API](https://pytorch.org/cppdocs/),用于反序列化以及执行 TorchScript 模型。 如果您还没有的话,请阅读[在 C++ 中加载和运行序列化 TorchScript 模型](https://pytorch.org/tutorials/advanced/cpp_export.html)的教程,接下来的几段将基于该教程构建。
简而言之,即使从文件反序列化并以 C++ 运行,也可以像常规`torch`运算符一样执行自定义运算符。 唯一的要求是将我们先前构建的自定义运算符共享库与执行模型的 C++ 应用程序链接。 在 Python 中,只需调用`torch.ops.load_library`即可。 在 C++ 中,您需要在使用的任何构建系统中将共享库与主应用程序链接。 下面的示例将使用 CMake 展示这一点。 简而言之,即使从文件反序列化并以 C++ 运行,也可以像常规`torch`运算符一样执行自定义运算符。 唯一的要求是将我们先前构建的自定义运算符共享库与执行模型的 C++ 应用链接。 在 Python 中,只需调用`torch.ops.load_library`即可。 在 C++ 中,您需要在使用的任何构建系统中将共享库与主应用链接。 下面的示例将使用 CMake 展示这一点。
注意 注意
从技术上讲,您还可以在运行时将共享库动态加载到 C++ 应用程序中,就像在 Python 中一样。 在 Linux 上,可以使用`dlopen`来执行此操作。 在其他平台上也存在等效项。 从技术上讲,您还可以在运行时将共享库动态加载到 C++ 应用中,就像在 Python 中一样。 在 Linux 上,可以使用`dlopen`来执行此操作。 在其他平台上也存在等效项。
在上面链接的 C++ 执行教程的基础上,让我们从一个最小的 C++ 应用程序开始,在与自定义运算符不同的文件夹中的`main.cpp`文件中,该文件加载并执行序列化的 TorchScript 模型: 在上面链接的 C++ 执行教程的基础上,让我们从一个最小的 C++ 应用开始,在与自定义运算符不同的文件夹中的`main.cpp`文件中,该文件加载并执行序列化的 TorchScript 模型:
```py ```py
#include <torch/script.h> // One-stop header. #include <torch/script.h> // One-stop header.
...@@ -488,7 +488,7 @@ target_compile_features(example_app PRIVATE cxx_range_for) ...@@ -488,7 +488,7 @@ target_compile_features(example_app PRIVATE cxx_range_for)
``` ```
在这一点上,我们应该能够构建应用程序 在这一点上,我们应该能够构建应用:
并在尚未通过模型的情况下运行它: 并在尚未通过模型的情况下运行它:
...@@ -510,9 +510,9 @@ compute.save("example.pt") ...@@ -510,9 +510,9 @@ compute.save("example.pt")
``` ```
最后一行将脚本功能序列化为一个名为`example.pt`的文件。 如果我们随后将此序列化模型传递给 C++ 应用程序,则可以立即运行它: 最后一行将脚本功能序列化为一个名为`example.pt`的文件。 如果我们随后将此序列化模型传递给 C++ 应用,则可以立即运行它:
或者可能不是。 也许还没有。 当然! 我们尚未将自定义运算符库与我们的应用程序链接。 让我们立即执行此操作,并正确进行操作,让我们稍微更新一下文件组织,如下所示: 或者可能不是。 也许还没有。 当然! 我们尚未将自定义运算符库与我们的应用链接。 让我们立即执行此操作,并正确进行操作,让我们稍微更新一下文件组织,如下所示:
```py ```py
example_app/ example_app/
...@@ -541,11 +541,11 @@ target_compile_features(example_app PRIVATE cxx_range_for) ...@@ -541,11 +541,11 @@ target_compile_features(example_app PRIVATE cxx_range_for)
``` ```
基本的 CMake 配置与以前非常相似,只是我们将`warp_perspective` CMake 构建添加为子目录。 一旦其 CMake 代码运行,我们将`example_app`应用程序`warp_perspective`共享库链接。 基本的 CMake 配置与以前非常相似,只是我们将`warp_perspective` CMake 构建添加为子目录。 一旦其 CMake 代码运行,我们将`example_app`应用与`warp_perspective`共享库链接。
注意 注意
上面的示例中嵌入了一个关键细节:`warp_perspective`链接行的`-Wl,--no-as-needed`前缀。 这是必需的,因为我们实际上不会在应用程序代码中从`warp_perspective`共享库中调用任何函数。 我们只需要运行`TORCH_LIBRARY`函数。 麻烦的是,这使链接器感到困惑,并使其认为可以完全跳过与库的链接。 在 Linux 上,`-Wl,--no-as-needed`标志会强制链接发生(注意:此标志特定于 Linux!)。 还有其他解决方法。 最简单的方法是在运算符库中定义*一些函数*,您需要从主应用程序中调用该函数。 这可能就像在某个标头中声明的函数`void init();`一样简单,然后在运算符库中将其定义为`void init() { }`。 在主应用程序中调用此`init()`函数会给链接器以印象,这是一个值得链接的库。 不幸的是,这超出了我们的控制范围,我们宁愿让您知道其原因和简单的解决方法,而不是让您将一些不透明的宏放入代码中。 上面的示例中嵌入了一个关键细节:`warp_perspective`链接行的`-Wl,--no-as-needed`前缀。 这是必需的,因为我们实际上不会在应用代码中从`warp_perspective`共享库中调用任何函数。 我们只需要运行`TORCH_LIBRARY`函数。 麻烦的是,这使链接器感到困惑,并使其认为可以完全跳过与库的链接。 在 Linux 上,`-Wl,--no-as-needed`标志会强制链接发生(注意:此标志特定于 Linux!)。 还有其他解决方法。 最简单的方法是在运算符库中定义*一些函数*,您需要从主应用中调用该函数。 这可能就像在某个标头中声明的函数`void init();`一样简单,然后在运算符库中将其定义为`void init() { }`。 在主应用中调用此`init()`函数会给链接器以印象,这是一个值得链接的库。 不幸的是,这超出了我们的控制范围,我们宁愿让您知道其原因和简单的解决方法,而不是让您将一些不透明的宏放入代码中。
现在,由于我们现在在顶层找到了`Torch`软件包,因此`warp_perspective`子目录中的`CMakeLists.txt`文件可以缩短一些。 它看起来应该像这样: 现在,由于我们现在在顶层找到了`Torch`软件包,因此`warp_perspective`子目录中的`CMakeLists.txt`文件可以缩短一些。 它看起来应该像这样:
...@@ -558,7 +558,7 @@ target_link_libraries(warp_perspective PRIVATE opencv_core opencv_photo) ...@@ -558,7 +558,7 @@ target_link_libraries(warp_perspective PRIVATE opencv_core opencv_photo)
``` ```
让我们重新构建示例应用程序,该应用程序还将与自定义运算符库链接。 在顶层`example_app`目录中: 让我们重新构建示例应用,该应用还将与自定义运算符库链接。 在顶层`example_app`目录中:
```py ```py
$ mkdir build $ mkdir build
...@@ -623,7 +623,7 @@ $ ./example_app example.pt ...@@ -623,7 +623,7 @@ $ ./example_app example.pt
## 结论 ## 结论
本教程向您介绍了如何在 C++ 中实现自定义 TorchScript 运算符,如何将其构建到共享库中,如何在 Python 中使用它来定义 TorchScript 模型以及如何将其加载到 C++ 应用程序中以进行推理工作负载。 现在,您可以使用与第三方 C++ 库进行接口的 C++ 运算符扩展 TorchScript 模型,编写自定义的高性能 CUDA 内核,或实现任何其他需要 Python,TorchScript 和 C++ 之间的界线才能平稳融合的用例。 本教程向您介绍了如何在 C++ 中实现自定义 TorchScript 运算符,如何将其构建到共享库中,如何在 Python 中使用它来定义 TorchScript 模型以及如何将其加载到 C++ 应用中以进行推理工作负载。 现在,您可以使用与第三方 C++ 库进行接口的 C++ 运算符扩展 TorchScript 模型,编写自定义的高性能 CUDA 内核,或实现任何其他需要 Python,TorchScript 和 C++ 之间的界线才能平稳融合的用例。
与往常一样,如果您遇到任何问题或疑问,可以使用我们的[论坛](https://discuss.pytorch.org/)[GitHub ISSUE](https://github.com/pytorch/pytorch/issues) 进行联系。 另外,我们的[常见问题解答(FAQ)页面](https://pytorch.org/cppdocs/notes/faq.html)可能包含有用的信息。 与往常一样,如果您遇到任何问题或疑问,可以使用我们的[论坛](https://discuss.pytorch.org/)[GitHub ISSUE](https://github.com/pytorch/pytorch/issues) 进行联系。 另外,我们的[常见问题解答(FAQ)页面](https://pytorch.org/cppdocs/notes/faq.html)可能包含有用的信息。
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
**作者**[Shen Li](https://mrshenli.github.io/) **作者**[Shen Li](https://mrshenli.github.io/)
这是`torch.distributed`软件包的概述页面。 由于在不同位置添加了越来越多的文档,示例和教程,因此不清楚要针对特定​​问题咨询哪个文档或教程,或者阅读这些内容的最佳顺序是什么。 该页面的目的是通过将文档分类为不同的主题并简要描述每个主题来解决此问题。 如果这是您第一次使用 PyTorch 构建分布式训练应用程序,建议使用本文档导航至最适合您的用例的技术。 这是`torch.distributed`软件包的概述页面。 由于在不同位置添加了越来越多的文档,示例和教程,因此不清楚要针对特定​​问题咨询哪个文档或教程,或者阅读这些内容的最佳顺序是什么。 该页面的目的是通过将文档分类为不同的主题并简要描述每个主题来解决此问题。 如果这是您第一次使用 PyTorch 构建分布式训练应用,建议使用本文档导航至最适合您的用例的技术。
## 简介 ## 简介
...@@ -12,18 +12,18 @@ ...@@ -12,18 +12,18 @@
* [分布式数据并行训练](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)(DDP)是一种广泛采用的单程序多数据训练范例。 使用 DDP,可以在每个流程上复制模型,并且每个模型副本都将获得一组不同的输入数据样本。 DDP 负责梯度通信,以保持模型副本同步,并使其与梯度计算重叠,以加快训练速度。 * [分布式数据并行训练](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)(DDP)是一种广泛采用的单程序多数据训练范例。 使用 DDP,可以在每个流程上复制模型,并且每个模型副本都将获得一组不同的输入数据样本。 DDP 负责梯度通信,以保持模型副本同步,并使其与梯度计算重叠,以加快训练速度。
* [基于 RPC 的分布式训练](https://pytorch.org/docs/master/rpc.html)(RPC)开发来支持无法适应数据并行训练的常规训练结构,例如分布式管道并行性,参数服务器范式以及 DDP 与其他训练范式的组合。 它有助于管理远程对象的生命周期,并将自动微分引擎扩展到机器范围之外。 * [基于 RPC 的分布式训练](https://pytorch.org/docs/master/rpc.html)(RPC)开发来支持无法适应数据并行训练的常规训练结构,例如分布式管道并行性,参数服务器范式以及 DDP 与其他训练范式的组合。 它有助于管理远程对象的生命周期,并将自动微分引擎扩展到机器范围之外。
* [集体通信](https://pytorch.org/docs/stable/distributed.html)(c10d)库支持跨组内的进程发送张量。 它提供了集体通信 API(例如[`all_reduce`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.all_reduce)[`all_gather`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.all_gather))和 P2P 通信 API(例如[`send`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.send)[`isend`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.isend))。 从 v1.6.0 开始,DDP 和 RPC([ProcessGroup 后端](https://pytorch.org/docs/master/rpc.html#process-group-backend))建立在 c10d 上,其中前者使用集体通信,而后者使用 P2P 通信。 通常,开发人员无需直接使用此原始通信 API,因为上述 DDP 和 RPC 功能可以满足许多分布式训练方案的需求。 但是,在某些情况下,此 API 仍然很有帮助。 一个示例是分布式参数平均,其中应用程序希望在向后传递之后计算所有模型参数的平均值,而不是使用 DDP 来传递梯度。 这可以使通信与计算脱钩,并允许对通信内容进行更细粒度的控制,但另一方面,它也放弃了 DDP 提供的性能优化。 [用 PyTorch 编写分布式应用程序](https://pytorch.org/tutorials/intermediate/dist_tuto.html)显示了使用 c10d 通信 API 的示例。 * [集体通信](https://pytorch.org/docs/stable/distributed.html)(c10d)库支持跨组内的进程发送张量。 它提供了集体通信 API(例如[`all_reduce`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.all_reduce)[`all_gather`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.all_gather))和 P2P 通信 API(例如[`send`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.send)[`isend`](https://pytorch.org/docs/stable/distributed.html#torch.distributed.isend))。 从 v1.6.0 开始,DDP 和 RPC([ProcessGroup 后端](https://pytorch.org/docs/master/rpc.html#process-group-backend))建立在 c10d 上,其中前者使用集体通信,而后者使用 P2P 通信。 通常,开发人员无需直接使用此原始通信 API,因为上述 DDP 和 RPC 功能可以满足许多分布式训练方案的需求。 但是,在某些情况下,此 API 仍然很有帮助。 一个示例是分布式参数平均,其中应用希望在向后传递之后计算所有模型参数的平均值,而不是使用 DDP 来传递梯度。 这可以使通信与计算脱钩,并允许对通信内容进行更细粒度的控制,但另一方面,它也放弃了 DDP 提供的性能优化。 [用 PyTorch 编写分布式应用](https://pytorch.org/tutorials/intermediate/dist_tuto.html)显示了使用 c10d 通信 API 的示例。
现有的大多数文档都是为 DDP 或 RPC 编写的,本页面的其余部分将详细介绍这两个组件的材料。 现有的大多数文档都是为 DDP 或 RPC 编写的,本页面的其余部分将详细介绍这两个组件的材料。
## 数据并行训练 ## 数据并行训练
PyTorch 为数据并行训练提供了几种选择。 对于从简单到复杂以及从原型到生产逐渐增长的应用程序,共同的发展轨迹将是: PyTorch 为数据并行训练提供了几种选择。 对于从简单到复杂以及从原型到生产逐渐增长的应用,共同的发展轨迹将是:
1. 如果数据和模型可以放在一个 GPU 中,并且不关心训练速度,请使用单设备训练。 1. 如果数据和模型可以放在一个 GPU 中,并且不关心训练速度,请使用单设备训练。
2. 如果服务器上有多个 GPU,请使用单机多 GPU [`DataParallel`](https://pytorch.org/docs/master/generated/torch.nn.DataParallel.html),并且您希望以最少的代码更改来加快训练速度。 2. 如果服务器上有多个 GPU,请使用单机多 GPU [`DataParallel`](https://pytorch.org/docs/master/generated/torch.nn.DataParallel.html),并且您希望以最少的代码更改来加快训练速度。
3. 如果您想进一步加快训练速度并愿意编写更多代码来设置它,请使用单机多 GPU [`DistributedDataParallel`](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html) 3. 如果您想进一步加快训练速度并愿意编写更多代码来设置它,请使用单机多 GPU [`DistributedDataParallel`](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)
4. 如果应用程序需要跨计算机边界扩展,请使用多计算机[`DistributedDataParallel`](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)[启动脚本](https://github.com/pytorch/examples/blob/master/distributed/ddp/README.md) 4. 如果应用需要跨计算机边界扩展,请使用多计算机[`DistributedDataParallel`](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)[启动脚本](https://github.com/pytorch/examples/blob/master/distributed/ddp/README.md)
5. 如果预计会出现错误(例如,OOM),或者在训练过程中资源可以动态加入和离开,请使用[扭弹性](https://pytorch.org/elastic)启动分布式训练。 5. 如果预计会出现错误(例如,OOM),或者在训练过程中资源可以动态加入和离开,请使用[扭弹性](https://pytorch.org/elastic)启动分布式训练。
注意 注意
...@@ -32,7 +32,7 @@ PyTorch 为数据并行训练提供了几种选择。 对于从简单到复杂 ...@@ -32,7 +32,7 @@ PyTorch 为数据并行训练提供了几种选择。 对于从简单到复杂
### `torch.nn.DataParallel` ### `torch.nn.DataParallel`
[`DataParallel`](https://pytorch.org/docs/master/generated/torch.nn.DataParallel.html)软件包以最低的编码障碍实现了单机多 GPU 并行处理。 它只需要一行更改应用程序代码。 教程[可选:数据并行](https://pytorch.org/tutorials/beginner/blitz/data_parallel_tutorial.html)显示了一个示例。 需要注意的是,尽管`DataParallel`非常易于使用,但通常无法提供最佳性能。 这是因为`DataParallel`的实现会在每个前向传递中复制该模型,并且其单进程多线程并行性自然会遭受 GIL 争用。 为了获得更好的性能,请考虑使用[`DistributedDataParallel`](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html) [`DataParallel`](https://pytorch.org/docs/master/generated/torch.nn.DataParallel.html)软件包以最低的编码障碍实现了单机多 GPU 并行处理。 它只需要一行更改应用代码。 教程[可选:数据并行](https://pytorch.org/tutorials/beginner/blitz/data_parallel_tutorial.html)显示了一个示例。 需要注意的是,尽管`DataParallel`非常易于使用,但通常无法提供最佳性能。 这是因为`DataParallel`的实现会在每个前向传递中复制该模型,并且其单进程多线程并行性自然会遭受 GIL 争用。 为了获得更好的性能,请考虑使用[`DistributedDataParallel`](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)
### `torch.nn.parallel.DistributedDataParallel` ### `torch.nn.parallel.DistributedDataParallel`
...@@ -42,16 +42,16 @@ DDP 材料如下: ...@@ -42,16 +42,16 @@ DDP 材料如下:
1. [DDP 注释](https://pytorch.org/docs/stable/notes/ddp.html)提供了一个入门示例,并简要介绍了其设计和实现。 如果这是您第一次使用 DDP,请从本文档开始。 1. [DDP 注释](https://pytorch.org/docs/stable/notes/ddp.html)提供了一个入门示例,并简要介绍了其设计和实现。 如果这是您第一次使用 DDP,请从本文档开始。
2. [分布式数据并行入门](../intermediate/ddp_tutorial.html)解释了 DDP 训练的一些常见问题,包括不平衡的工作量,检查点和多设备模型。 请注意,DDP 可以轻松与[单机模型并行最佳实践](../intermediate/model_parallel_tutorial.html)教程中描述的单机多设备模型并行性结合。 2. [分布式数据并行入门](../intermediate/ddp_tutorial.html)解释了 DDP 训练的一些常见问题,包括不平衡的工作量,检查点和多设备模型。 请注意,DDP 可以轻松与[单机模型并行最佳实践](../intermediate/model_parallel_tutorial.html)教程中描述的单机多设备模型并行性结合。
3. [启动和配置分布式数据并行应用程序](https://github.com/pytorch/examples/blob/master/distributed/ddp/README.md)文档显示了如何使用 DDP 启动脚本。 3. [启动和配置分布式数据并行应用](https://github.com/pytorch/examples/blob/master/distributed/ddp/README.md)文档显示了如何使用 DDP 启动脚本。
4. [使用 Amazon AWS 的 PyTorch 分布式训练器](aws_distributed_training_tutorial.html)演示了如何在 AWS 上使用 DDP。 4. [使用 Amazon AWS 的 PyTorch 分布式训练器](aws_distributed_training_tutorial.html)演示了如何在 AWS 上使用 DDP。
### TorchElastic ### TorchElastic
随着应用程序复杂性和规模的增长,故障恢复成为当务之急。 有时,使用 DDP 时不可避免地会遇到 OOM 之类的错误,但是 DDP 本身无法从这些错误中恢复,基本的`try-except`块也无法工作。 这是因为 DDP 要求所有进程以紧密同步的方式运行,并且在不同进程中启动的所有`AllReduce`通信都必须匹配。 如果组中的某个进程抛出 OOM 异常,则很可能导致不同步(`AllReduce`操作不匹配),从而导致崩溃或挂起。 如果您期望在训练过程中发生故障,或者资源可能会动态离开并加入,请使用 [Torrlastic](https://pytorch.org/elastic) 启动分布式数据并行训练。 随着应用复杂性和规模的增长,故障恢复成为当务之急。 有时,使用 DDP 时不可避免地会遇到 OOM 之类的错误,但是 DDP 本身无法从这些错误中恢复,基本的`try-except`块也无法工作。 这是因为 DDP 要求所有进程以紧密同步的方式运行,并且在不同进程中启动的所有`AllReduce`通信都必须匹配。 如果组中的某个进程抛出 OOM 异常,则很可能导致不同步(`AllReduce`操作不匹配),从而导致崩溃或挂起。 如果您期望在训练过程中发生故障,或者资源可能会动态离开并加入,请使用 [Torrlastic](https://pytorch.org/elastic) 启动分布式数据并行训练。
## 通用分布式训练 ## 通用分布式训练
许多训练范式不适合数据并行性,例如参数服务器范式,分布式管道并行性,具有多个观察者或代理的强化学习应用程序等。 [`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)旨在支持一般的分布式训练方案 。 许多训练范式不适合数据并行性,例如参数服务器范式,分布式管道并行性,具有多个观察者或代理的强化学习应用等。 [`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)旨在支持一般的分布式训练方案 。
[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)程序包具有四个主要支柱: [`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)程序包具有四个主要支柱:
...@@ -63,7 +63,7 @@ DDP 材料如下: ...@@ -63,7 +63,7 @@ DDP 材料如下:
RPC 教程如下: RPC 教程如下:
1. [分布式 RPC 框架入门](../intermediate/rpc_tutorial.html)教程首先使用一个简单的强化学习(RL)示例来演示 RPC 和 RRef。 然后,它对 RNN 示例应用了基本的分布式模型并行性,以展示如何使用分布式 Autograd 和分布式优化器。 1. [分布式 RPC 框架入门](../intermediate/rpc_tutorial.html)教程首先使用一个简单的强化学习(RL)示例来演示 RPC 和 RRef。 然后,它对 RNN 示例应用了基本的分布式模型并行性,以展示如何使用分布式 Autograd 和分布式优化器。
2. [使用分布式 RPC 框架实现参数服务器](../intermediate/rpc_param_server_tutorial.html)教程借鉴了 [HogWild 的训练精神](https://people.eecs.berkeley.edu/~brecht/papers/hogwildTR.pdf),并将其应用于异步参数服务器(PS)训练应用程序 2. [使用分布式 RPC 框架实现参数服务器](../intermediate/rpc_param_server_tutorial.html)教程借鉴了 [HogWild 的训练精神](https://people.eecs.berkeley.edu/~brecht/papers/hogwildTR.pdf),并将其应用于异步参数服务器(PS)训练应用。
3. 使用 RPC 的[分布式管道并行化](../intermediate/dist_pipeline_parallel_tutorial.html)教程将单机管道并行示例(在[单机模型并行最佳实践](../intermediate/model_parallel_tutorial.html)中介绍)扩展到了分布式环境,并展示了如何使用 RPC 来实现它 。 3. 使用 RPC 的[分布式管道并行化](../intermediate/dist_pipeline_parallel_tutorial.html)教程将单机管道并行示例(在[单机模型并行最佳实践](../intermediate/model_parallel_tutorial.html)中介绍)扩展到了分布式环境,并展示了如何使用 RPC 来实现它 。
4. [使用异步执行实现批量 RPC](../intermediate/rpc_async_execution.html) 教程演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器实现 RPC 批量。这可以帮助加速推理和训练。 它使用了以上教程 1 和 2 中采用的类似 RL 和 PS 示例。 4. [使用异步执行实现批量 RPC](../intermediate/rpc_async_execution.html) 教程演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器实现 RPC 批量。这可以帮助加速推理和训练。 它使用了以上教程 1 和 2 中采用的类似 RL 和 PS 示例。
5. [将分布式`DataParallel`与分布式 RPC 框架结合](../advanced/rpc_ddp_tutorial.html)教程演示了如何将 DDP 与 RPC 结合使用分布式数据并行性和分布式模型并行性来训练模型。 5. [将分布式`DataParallel`与分布式 RPC 框架结合](../advanced/rpc_ddp_tutorial.html)教程演示了如何将 DDP 与 RPC 结合使用分布式数据并行性和分布式模型并行性来训练模型。
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* [`DistributedDataParallel` API 文档](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html) * [`DistributedDataParallel` API 文档](https://pytorch.org/docs/master/generated/torch.nn.parallel.DistributedDataParallel.html)
* [`DistributedDataParallel`注意事项](https://pytorch.org/docs/master/notes/ddp.html) * [`DistributedDataParallel`注意事项](https://pytorch.org/docs/master/notes/ddp.html)
[`DistributedDataParallel`](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel)(DDP)在模块级别实现可在多台计算机上运行的数据并行性。 使用 DDP 的应用程序应产生多个进程,并为每个进程创建一个 DDP 实例。 DDP 在[`torch.distributed`](https://pytorch.org/tutorials/intermediate/dist_tuto.html)程序包中使用集体通信来同步梯度和缓冲区。 更具体地说,DDP 为`model.parameters()`给定的每个参数注册一个 Autograd 挂钩,当在后向传递中计算相应的梯度时,挂钩将触发。 然后,DDP 使用该信号触发跨进程的梯度同步。 有关更多详细信息,请参考 [DDP 设计说明](https://pytorch.org/docs/master/notes/ddp.html) [`DistributedDataParallel`](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel)(DDP)在模块级别实现可在多台计算机上运行的数据并行性。 使用 DDP 的应用应产生多个进程,并为每个进程创建一个 DDP 实例。 DDP 在[`torch.distributed`](https://pytorch.org/tutorials/intermediate/dist_tuto.html)程序包中使用集体通信来同步梯度和缓冲区。 更具体地说,DDP 为`model.parameters()`给定的每个参数注册一个 Autograd 挂钩,当在后向传递中计算相应的梯度时,挂钩将触发。 然后,DDP 使用该信号触发跨进程的梯度同步。 有关更多详细信息,请参考 [DDP 设计说明](https://pytorch.org/docs/master/notes/ddp.html)
推荐的使用 DDP 的方法是为每个模型副本生成一个进程,其中一个模型副本可以跨越多个设备。 DDP 进程可以放在同一台计算机上,也可以在多台计算机上,但是 GPU 设备不能在多个进程之间共享。 本教程从一个基本的 DDP 用例开始,然后演示了更高级的用例,包括检查点模型以及将 DDP 与模型并行结合。 推荐的使用 DDP 的方法是为每个模型副本生成一个进程,其中一个模型副本可以跨越多个设备。 DDP 进程可以放在同一台计算机上,也可以在多台计算机上,但是 GPU 设备不能在多个进程之间共享。 本教程从一个基本的 DDP 用例开始,然后演示了更高级的用例,包括检查点模型以及将 DDP 与模型并行结合。
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
## 基本用例 ## 基本用例
要创建 DDP 模块,请首先正确设置过程组。 更多细节可以在[用 PyTorch 编写分布式应用程序](https://pytorch.org/tutorials/intermediate/dist_tuto.html)中找到。 要创建 DDP 模块,请首先正确设置过程组。 更多细节可以在[用 PyTorch 编写分布式应用](https://pytorch.org/tutorials/intermediate/dist_tuto.html)中找到。
```py ```py
import os import os
...@@ -187,7 +187,7 @@ class ToyMpModel(nn.Module): ...@@ -187,7 +187,7 @@ class ToyMpModel(nn.Module):
``` ```
将多 GPU 模型传递给 DDP 时,不得设置`device_ids``output_device`。 输入和输出数据将通过应用程序或模型`forward()`方法放置在适当的设备中。 将多 GPU 模型传递给 DDP 时,不得设置`device_ids``output_device`。 输入和输出数据将通过应用或模型`forward()`方法放置在适当的设备中。
```py ```py
def demo_model_parallel(rank, world_size): def demo_model_parallel(rank, world_size):
......
# 用 PyTorch 编写分布式应用程序 # 用 PyTorch 编写分布式应用
> 原文:<https://pytorch.org/tutorials/intermediate/dist_tuto.html> > 原文:<https://pytorch.org/tutorials/intermediate/dist_tuto.html>
......
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
本教程使用两个简单的示例来演示如何使用[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)包构建分布式训练,该包首先在 PyTorch v1.4 中作为原型功能引入。 这两个示例的源代码可以在 [PyTorch 示例](https://github.com/pytorch/examples)中找到。 本教程使用两个简单的示例来演示如何使用[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)包构建分布式训练,该包首先在 PyTorch v1.4 中作为原型功能引入。 这两个示例的源代码可以在 [PyTorch 示例](https://github.com/pytorch/examples)中找到。
先前的教程[分布式数据并行入门](ddp_tutorial.html)[使用 PyTorch](dist_tuto.html) 编写分布式应用程序,描述了[`DistributedDataParallel`](https://pytorch.org/docs/stable/_modules/torch/nn/parallel/distributed.html),该模型支持特定的训练范例,该模型可在多个过程之间复制模型 每个进程都处理输入数据的拆分。 有时,您可能会遇到需要不同训练范例的场景。 例如: 先前的教程[分布式数据并行入门](ddp_tutorial.html)[使用 PyTorch](dist_tuto.html) 编写分布式应用,描述了[`DistributedDataParallel`](https://pytorch.org/docs/stable/_modules/torch/nn/parallel/distributed.html),该模型支持特定的训练范例,该模型可在多个过程之间复制模型 每个进程都处理输入数据的拆分。 有时,您可能会遇到需要不同训练范例的场景。 例如:
1. 在强化学习中,从环境中获取训练数据可能相对昂贵,而模型本身可能很小。 在这种情况下,产生多个并行运行的观察者并共享一个代理可能会很有用。 在这种情况下,代理将在本地负责训练,但是应用程序仍将需要库在观察者和训练者之间发送和接收数据。 1. 在强化学习中,从环境中获取训练数据可能相对昂贵,而模型本身可能很小。 在这种情况下,产生多个并行运行的观察者并共享一个代理可能会很有用。 在这种情况下,代理将在本地负责训练,但是应用仍将需要库在观察者和训练者之间发送和接收数据。
2. 您的模型可能太大,无法容纳在一台计算机上的 GPU 中,因此需要一个库来帮助将模型拆分到多台计算机上。 或者,您可能正在实现[参数服务器](https://www.cs.cmu.edu/~muli/file/parameter_server_osdi14.pdf)训练框架,其中模型参数和训练器位于不同的机器上。 2. 您的模型可能太大,无法容纳在一台计算机上的 GPU 中,因此需要一个库来帮助将模型拆分到多台计算机上。 或者,您可能正在实现[参数服务器](https://www.cs.cmu.edu/~muli/file/parameter_server_osdi14.pdf)训练框架,其中模型参数和训练器位于不同的机器上。
[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)程序包可以帮助解决上述情况。 在情况 1 中, [RPC](https://pytorch.org/docs/master/rpc.html#rpc)[RRef](https://pytorch.org/docs/master/rpc.html#rref) 允许将数据从一个工作程序发送到另一个工作程序,同时轻松引用远程数据对象。 在情况 2 中,[分布式 Autograd](https://pytorch.org/docs/master/rpc.html#distributed-autograd-framework)[分布式优化器](https://pytorch.org/docs/master/rpc.html#module-torch.distributed.optim)使执行反向传递和优化器步骤就像本地训练一样。 在接下来的两节中,我们将使用强化学习示例和语言模型示例来演示[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)的 API。 请注意,本教程并非旨在构建最准确或最有效的模型来解决给定的问题,相反,此处的主要目标是演示如何使用[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)包来构建分布式训练 应用程序 [`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)程序包可以帮助解决上述情况。 在情况 1 中, [RPC](https://pytorch.org/docs/master/rpc.html#rpc)[RRef](https://pytorch.org/docs/master/rpc.html#rref) 允许将数据从一个工作程序发送到另一个工作程序,同时轻松引用远程数据对象。 在情况 2 中,[分布式 Autograd](https://pytorch.org/docs/master/rpc.html#distributed-autograd-framework)[分布式优化器](https://pytorch.org/docs/master/rpc.html#module-torch.distributed.optim)使执行反向传递和优化器步骤就像本地训练一样。 在接下来的两节中,我们将使用强化学习示例和语言模型示例来演示[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)的 API。 请注意,本教程并非旨在构建最准确或最有效的模型来解决给定的问题,相反,此处的主要目标是演示如何使用[`torch.distributed.rpc`](https://pytorch.org/docs/master/rpc.html)包来构建分布式训练 应用。
## 使用 RPC 和 RRef 进行分布式强化学习 ## 使用 RPC 和 RRef 进行分布式强化学习
...@@ -46,7 +46,7 @@ class Policy(nn.Module): ...@@ -46,7 +46,7 @@ class Policy(nn.Module):
``` ```
首先,让我们准备一个帮助程序,以在`RRef`的所有者工作程序上远程运行功能。 您将在本教程的示例中的多个地方发现该功能。 理想情况下,`torch.distributed.rpc`软件包应立即提供这些帮助程序功能。 例如,如果应用程序可以直接调用`RRef.some_func(*arg)`,然后将其转换为`RRef`所有者的 RPC,将会更容易。 在[`pytorch/pytorch#31743`](https://github.com/pytorch/pytorch/issues/31743)中跟踪了此 API 的进度。 首先,让我们准备一个帮助程序,以在`RRef`的所有者工作程序上远程运行功能。 您将在本教程的示例中的多个地方发现该功能。 理想情况下,`torch.distributed.rpc`软件包应立即提供这些帮助程序功能。 例如,如果应用可以直接调用`RRef.some_func(*arg)`,然后将其转换为`RRef`所有者的 RPC,将会更容易。 在[`pytorch/pytorch#31743`](https://github.com/pytorch/pytorch/issues/31743)中跟踪了此 API 的进度。
```py ```py
from torch.distributed.rpc import rpc_sync from torch.distributed.rpc import rpc_sync
...@@ -105,7 +105,7 @@ class Observer: ...@@ -105,7 +105,7 @@ class Observer:
``` ```
agent 的代码稍微复杂一点,我们将其分成多个部分。 在此示例中,代理既充当训练者又充当主角色,以便它向多个分布式观察者发送命令以运行情节,并且还记录本地的所有动作和奖励,这些动作和奖赏将在每个情节之后的训练阶段使用。 下面的代码显示了`Agent`构造函数,其中大多数行都在初始化各种组件。 最后的循环在其他工作者上远程初始化观察者,并在本地将`RRefs`保留给这些观察者。 代理稍后将使用那些观察者`RRefs`发送命令。 应用程序无需担心`RRefs`的寿命。 每个`RRef`的所有者维护一个参考计数图以跟踪其生命周期,并保证只要该`RRef`的任何活动用户都不会删除远程数据对象。 有关详细信息,请参考`RRef` [设计文档](https://pytorch.org/docs/master/notes/rref.html) agent 的代码稍微复杂一点,我们将其分成多个部分。 在此示例中,代理既充当训练者又充当主角色,以便它向多个分布式观察者发送命令以运行情节,并且还记录本地的所有动作和奖励,这些动作和奖赏将在每个情节之后的训练阶段使用。 下面的代码显示了`Agent`构造函数,其中大多数行都在初始化各种组件。 最后的循环在其他工作者上远程初始化观察者,并在本地将`RRefs`保留给这些观察者。 代理稍后将使用那些观察者`RRefs`发送命令。 应用无需担心`RRefs`的寿命。 每个`RRef`的所有者维护一个参考计数图以跟踪其生命周期,并保证只要该`RRef`的任何活动用户都不会删除远程数据对象。 有关详细信息,请参考`RRef` [设计文档](https://pytorch.org/docs/master/notes/rref.html)
```py ```py
import gym import gym
...@@ -360,7 +360,7 @@ class RNNModel(nn.Module): ...@@ -360,7 +360,7 @@ class RNNModel(nn.Module):
``` ```
在介绍分布式优化器之前,让我们添加一个辅助函数来生成模型参数的 RRef 列表,该列表将由分布式优化器使用。 在本地训练中,应用程序可以调用`Module.parameters()`来获取对所有参数张量的引用,并将其传递给本地优化器以进行后续更新。 但是,由于某些参数存在于远程计算机上,因此同一 API 在分布式训练方案中不起作用。 因此,分布式优化器不采用参数`Tensors`的列表,而是采用`RRefs`的列表,每个模型参数一个`RRef`用于本地和远程模型参数。 辅助函数非常简单,只需调用`Module.parameters()`并在每个参数上创建一个本地`RRef` 在介绍分布式优化器之前,让我们添加一个辅助函数来生成模型参数的 RRef 列表,该列表将由分布式优化器使用。 在本地训练中,应用可以调用`Module.parameters()`来获取对所有参数张量的引用,并将其传递给本地优化器以进行后续更新。 但是,由于某些参数存在于远程计算机上,因此同一 API 在分布式训练方案中不起作用。 因此,分布式优化器不采用参数`Tensors`的列表,而是采用`RRefs`的列表,每个模型参数一个`RRef`用于本地和远程模型参数。 辅助函数非常简单,只需调用`Module.parameters()`并在每个参数上创建一个本地`RRef`
```py ```py
def _parameter_rrefs(module): def _parameter_rrefs(module):
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* [使用分布式 RPC 框架](rpc_param_server_tutorial.html)实现参数服务器 * [使用分布式 RPC 框架](rpc_param_server_tutorial.html)实现参数服务器
* [RPC 异步执行装饰器](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) * [RPC 异步执行装饰器](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)
本教程演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器来构建批量 RPC 应用程序,该装饰器通过减少阻止的 RPC 线程数和合并被调用方上的 CUDA 操作来帮助加快训练速度。 这使用 TorchServer 的相同想法进行[批量推断](https://pytorch.org/serve/batch_inference_with_ts.html) 本教程演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器来构建批量 RPC 应用,该装饰器通过减少阻止的 RPC 线程数和合并被调用方上的 CUDA 操作来帮助加快训练速度。 这使用 TorchServer 的相同想法进行[批量推断](https://pytorch.org/serve/batch_inference_with_ts.html)
注意 注意
...@@ -19,20 +19,20 @@ ...@@ -19,20 +19,20 @@
## 基础知识 ## 基础知识
先前的教程显示了使用[`torch.distributed.rpc`](https://pytorch.org/docs/stable/rpc.html)构建分布式训练应用程序的步骤,但并未详细说明在处理 RPC 请求时被调用方发生的情况。 从 PyTorch v1.5 开始,每个 RPC 请求都会在被调用方上阻塞一个线程,以在该请求中执行该函数,直到该函数返回为止。 这适用于许多用例,但有一个警告。 如果用户功能例如通过嵌套 RPC 调用在 IO 上阻塞,或者例如在等待其他 RPC 请求解除阻塞的信号时阻塞,则被调用方上的 RPC 线程将必须空闲,直到 IO 完成或发生信令事件为止。 结果,RPC 被调用者可能使用了不必要的更多线程。 造成此问题的原因是 RPC 将用户功能视为黑盒,并且几乎不了解该功能会发生什么。 为了允许用户函数产生和释放 RPC 线程,需要向 RPC 系统提供更多提示。 先前的教程显示了使用[`torch.distributed.rpc`](https://pytorch.org/docs/stable/rpc.html)构建分布式训练应用的步骤,但并未详细说明在处理 RPC 请求时被调用方发生的情况。 从 PyTorch v1.5 开始,每个 RPC 请求都会在被调用方上阻塞一个线程,以在该请求中执行该函数,直到该函数返回为止。 这适用于许多用例,但有一个警告。 如果用户功能例如通过嵌套 RPC 调用在 IO 上阻塞,或者例如在等待其他 RPC 请求解除阻塞的信号时阻塞,则被调用方上的 RPC 线程将必须空闲,直到 IO 完成或发生信令事件为止。 结果,RPC 被调用者可能使用了不必要的更多线程。 造成此问题的原因是 RPC 将用户功能视为黑盒,并且几乎不了解该功能会发生什么。 为了允许用户函数产生和释放 RPC 线程,需要向 RPC 系统提供更多提示。
从 v1.6.0 开始,PyTorch 通过引入两个新概念来解决此问题: 从 v1.6.0 开始,PyTorch 通过引入两个新概念来解决此问题:
* [`torch.futures.Future`](https://pytorch.org/docs/master/futures.html) 类型封装了异步执行,还支持安装回调函数。 * [`torch.futures.Future`](https://pytorch.org/docs/master/futures.html) 类型封装了异步执行,还支持安装回调函数。
* 一个[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器,允许应用程序告诉被调用方目标函数将返回将来的函数,并且在执行期间可以暂停并产生多次。 * 一个[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器,允许应用告诉被调用方目标函数将返回将来的函数,并且在执行期间可以暂停并产生多次。
使用这两个工具,应用程序代码可以将用户功能分解为多个较小的功能,将它们作为`Future`对象上的回调链接在一起,然后返回包含最终结果的`Future`。 在被调用方,当获取`Future`对象时,它还将安装后续的 RPC 响应准备和通讯作为回调,这将在最终结果准备好时触发。 这样,被调用者不再需要阻塞一个线程并等待直到最终返回值准备就绪。 有关简单示例,请参考[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 的 API 文档。 使用这两个工具,应用代码可以将用户功能分解为多个较小的功能,将它们作为`Future`对象上的回调链接在一起,然后返回包含最终结果的`Future`。 在被调用方,当获取`Future`对象时,它还将安装后续的 RPC 响应准备和通讯作为回调,这将在最终结果准备好时触发。 这样,被调用者不再需要阻塞一个线程并等待直到最终返回值准备就绪。 有关简单示例,请参考[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 的 API 文档。
除了减少被调用方上的空闲线程数之外,这些工具还有助于使批量 RPC 处理更容易,更快捷。 本教程的以下两节演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器来构建分布式批更新参数服务器和批量强化学习应用程序 除了减少被调用方上的空闲线程数之外,这些工具还有助于使批量 RPC 处理更容易,更快捷。 本教程的以下两节演示了如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器来构建分布式批更新参数服务器和批量强化学习应用。
## 批量更新参数服务器 ## 批量更新参数服务器
考虑具有一个参数服务器(PS)和多个训练器的同步参数服务器训练应用程序。 在此应用程序中,PS 保留参数并等待所有训练器报告坡度。 在每次迭代中,它都会等到收到所有训练者的梯度后,再一次更新所有参数。 下面的代码显示 PS 类的实现。 `update_and_fetch_model`方法是用`@rpc.functions.async_execution`装饰的,将由训练器调用。 每次调用都会返回一个`Future`对象,该对象将填充有更新的模型。 大多数训练器发起的调用仅将梯度累积到`.grad`字段,立即返回,并在 PS 上产生 RPC 线程。 最后到达的训练器将触发优化器步骤,并消耗所有先前报告的梯度。 然后,它使用更新的模型设置`future_model`,该模型又通过`Future`对象通知其他训练器的所有先前请求,并将更新后的模型发送给所有训练器。 考虑具有一个参数服务器(PS)和多个训练器的同步参数服务器训练应用。 在此应用中,PS 保留参数并等待所有训练器报告坡度。 在每次迭代中,它都会等到收到所有训练者的梯度后,再一次更新所有参数。 下面的代码显示 PS 类的实现。 `update_and_fetch_model`方法是用`@rpc.functions.async_execution`装饰的,将由训练器调用。 每次调用都会返回一个`Future`对象,该对象将填充有更新的模型。 大多数训练器发起的调用仅将梯度累积到`.grad`字段,立即返回,并在 PS 上产生 RPC 线程。 最后到达的训练器将触发优化器步骤,并消耗所有先前报告的梯度。 然后,它使用更新的模型设置`future_model`,该模型又通过`Future`对象通知其他训练器的所有先前请求,并将更新后的模型发送给所有训练器。
```py ```py
import threading import threading
...@@ -126,7 +126,7 @@ class Trainer(object): ...@@ -126,7 +126,7 @@ class Trainer(object):
在本教程中,我们将跳过启动多个进程的代码,有关完整实现,请参考[示例](https://github.com/pytorch/examples/tree/master/distributed/rpc)回购。 请注意,可以在没有[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器的情况下实现批量。 但是,这将需要在 PS 上阻塞更多的 RPC 线程,或者使用另一轮 RPC 来获取更新的模型,后者将增加代码的复杂性和通信开销。 在本教程中,我们将跳过启动多个进程的代码,有关完整实现,请参考[示例](https://github.com/pytorch/examples/tree/master/distributed/rpc)回购。 请注意,可以在没有[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器的情况下实现批量。 但是,这将需要在 PS 上阻塞更多的 RPC 线程,或者使用另一轮 RPC 来获取更新的模型,后者将增加代码的复杂性和通信开销。
本节使用一个简单的参数服务器训练示例来说明如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器实现批量 RPC 应用程序。 在下一节中,我们将使用批量重新实现上一[分布式 RPC 框架](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html)入门指南中的强化学习示例,并演示其对训练速度的影响。 本节使用一个简单的参数服务器训练示例来说明如何使用[`@rpc.functions.async_execution`](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution)装饰器实现批量 RPC 应用。 在下一节中,我们将使用批量重新实现上一[分布式 RPC 框架](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html)入门指南中的强化学习示例,并演示其对训练速度的影响。
## 批量 CartPole 解算器 ## 批量 CartPole 解算器
......
# 前言 # 前言
**强化学习****RL**)使您可以在业务环境中开发智能,快速且自学的系统。 这是训练您的学习型代理商并解决人工智能中各种问题的有效方法,从游戏,自动驾驶汽车和机器人到企业应用程序,其范围从数据中心节能(冷却数据中心)到智能仓储解决方案。 **强化学习****RL**)使您可以在业务环境中开发智能,快速且自学的系统。 这是训练您的学习型代理商并解决人工智能中各种问题的有效方法,从游戏,自动驾驶汽车和机器人到企业应用,其范围从数据中心节能(冷却数据中心)到智能仓储解决方案。
本书涵盖了通过将深度神经网络架构与强化学习相结合而在深度强化学习中取得的主要进步和成功。 该书还向读者介绍了强化学习的概念,它的优点以及为什么它如此受欢迎。 它讨论了 MDP,蒙特卡洛树搜索,策略和值迭代,时间差异学习(例如 Q 学习)和 SARSA。 您将使用 TensorFlow 和 OpenAI Gym 来构建简单的神经网络模型,以从自己的行为中学习。 您还将看到强化学习算法如何在游戏,图像处理和 NLP 中发挥作用。 本书涵盖了通过将深度神经网络架构与强化学习相结合而在深度强化学习中取得的主要进步和成功。 该书还向读者介绍了强化学习的概念,它的优点以及为什么它如此受欢迎。 它讨论了 MDP,蒙特卡洛树搜索,策略和值迭代,时间差异学习(例如 Q 学习)和 SARSA。 您将使用 TensorFlow 和 OpenAI Gym 来构建简单的神经网络模型,以从自己的行为中学习。 您还将看到强化学习算法如何在游戏,图像处理和 NLP 中发挥作用。
......
...@@ -77,7 +77,7 @@ EIIE 通过**在线随机批量学习**(**OSBL**)进行训练,其中强化 ...@@ -77,7 +77,7 @@ EIIE 通过**在线随机批量学习**(**OSBL**)进行训练,其中强化
# 问题定义 # 问题定义
众所周知,投资组合管理是指跨多种金融产品(资产)对资金进行持续重新分配。 在这项工作中,时间分为相等长度的时间段,其中每个时间段`T = 30`分钟。 在每个时期的开始,交易代理将资金重新分配到不同的资产上。 资产的价格在一段时间内会波动,但要考虑四个重要的价格指标,它们足以表该期间资产的价格变动。 这些价格指标如下: 众所周知,投资组合管理是指跨多种金融产品(资产)对资金进行持续重新分配。 在这项工作中,时间分为相等长度的时间段,其中每个时间段`T = 30`分钟。 在每个时期的开始,交易代理将资金重新分配到不同的资产上。 资产的价格在一段时间内会波动,但要考虑四个重要的价格指标,它们足以表该期间资产的价格变动。 这些价格指标如下:
* 开盘价 * 开盘价
* 最高价 * 最高价
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
# 文字摘要 # 文字摘要
文本摘要是通过保留文档的重要信息自动生成作为输入输入的文档测试的摘要文本的过程。 文本摘要以简洁的方式压缩了大量信息; 因此,摘要在与新闻/文章,文本搜索和报告生成相关的应用程序中起着重要作用。 文本摘要是通过保留文档的重要信息自动生成作为输入输入的文档测试的摘要文本的过程。 文本摘要以简洁的方式压缩了大量信息; 因此,摘要在与新闻/文章,文本搜索和报告生成相关的应用中起着重要作用。
有两种类型的汇总算法: 有两种类型的汇总算法:
...@@ -248,6 +248,6 @@ DCN 在答案的开始位置创建概率分布,并在答案的结束位置创 ...@@ -248,6 +248,6 @@ DCN 在答案的开始位置创建概率分布,并在答案的结束位置创
# 总结 # 总结
在本章中,我们学习了强化学习如何破坏 NLP 的领域。 我们研究了在 NLP 中使用强化学习的原因。 我们涵盖了 NLP 中的两个主要应用领域,即文本摘要和问题回答,并了解了在现有模型中如何实现强化学习框架以获得最新结果的基础。 NLP 中还有其他实现了强化学习的应用程序领域,例如对话生成和机器翻译(讨论它们不在本书的范围之内)。 在本章中,我们学习了强化学习如何破坏 NLP 的领域。 我们研究了在 NLP 中使用强化学习的原因。 我们涵盖了 NLP 中的两个主要应用领域,即文本摘要和问题回答,并了解了在现有模型中如何实现强化学习框架以获得最新结果的基础。 NLP 中还有其他实现了强化学习的应用领域,例如对话生成和机器翻译(讨论它们不在本书的范围之内)。
这使我们结束了深度强化学习的惊人旅程。 我们通过了解概念开始了基础知识,然后使用 TensorFlow 和 OpenAI Gym 实现了这些概念,然后遍历了很酷的研究领域,在这些领域中正在实现核心强化学习。 我希望旅途很有趣,我们能够建立最好的基础。 这使我们结束了深度强化学习的惊人旅程。 我们通过了解概念开始了基础知识,然后使用 TensorFlow 和 OpenAI Gym 实现了这些概念,然后遍历了很酷的研究领域,在这些领域中正在实现核心强化学习。 我希望旅途很有趣,我们能够建立最好的基础。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册