提交 01f43ff9 编写于 作者: W wizardforcel

2021-01-19 14:28:36

上级 bde7f870
......@@ -32,9 +32,9 @@ Python 在深度学习社区中的广泛接受使一些研究人员和开发人
作为 **Python 优先框架**,PyTorch 大大超越了在整体 C++ 或 C 引擎上实现 Python 包装器的其他框架。 在 PyTorch 中,您可以继承 PyTorch 类并根据需要进行自定义。 内置于 PyTorch 核心的命令式编码风格仅由于 Python 优先方法才有可能。 尽管诸如 TensorFlow,MXNet 和 CNTK 的某些符号图框架提出了一种强制性方法,但由于社区的支持及其灵活性,PyTorch 仍能保持领先地位。
基于磁带的**自动微分**系统使 PyTorch 具有**动态图**功能。 这是 PyTorch 与其他流行的符号图框架之间的主要区别之一。 基于磁带的 autograd 也支持 Chainer,autograd 和 Torch-autograd 的反向传播算法。 具有动态图功能,您的图将在 Python 解释器到达相应行时创建。 与 TensorFlow 的*定义并运行*方法不同,这称为*通过运行定义*
基于磁带的**自动微分**系统使 PyTorch 具有**动态图**功能。 这是 PyTorch 与其他流行的符号图框架之间的主要区别之一。 基于磁带的 Autograd 也支持 Chainer,Autograd 和 Torch-Autograd 的反向传播算法。 具有动态图功能,您的图将在 Python 解释器到达相应行时创建。 与 TensorFlow 的*定义并运行*方法不同,这称为*通过运行定义*
基于磁带的 autograd 使用反向模式自动微分,在前进过程中,图形将每个操作保存到磁带中,然后在磁带中向后移动以进行反向传播。 动态图和 Python 优先方法使**易于调试**,您可以在其中使用常用的 Python 调试器,例如 Pdb 或基于编辑器的调试器。
基于磁带的 Autograd 使用反向模式自动微分,在前进过程中,图形将每个操作保存到磁带中,然后在磁带中向后移动以进行反向传播。 动态图和 Python 优先方法使**易于调试**,您可以在其中使用常用的 Python 调试器,例如 Pdb 或基于编辑器的调试器。
PyTorch 核心社区不仅为 Torch 的 C 二进制文件构建了 Python 包装器,还优化了内核并对其进行了改进。 PyTorch 根据输入数据智能地选择要为定义的每个操作运行的算法。
......
......@@ -125,17 +125,17 @@ b2 = torch.zeros(1, output_size, requires_grad=True, device=device, dtype=dtype)
**注意**:自动区分,有时也称为算法区分,是通过计算机程序利用功能执行顺序的技术。 自动区分的两种主要方法是正向模式和反向模式。 在前向模式自动微分中,我们首先找到外部函数的导数,然后递归进入内部,直到我们探索所有子节点。 反向模式自动区分正好相反,并且被深度学习社区和框架使用。 它由 Seppo Linnainmaa 于 1970 年在其硕士论文中首次出版。反向模式微分的主要构建模块是存储中间变量的存储器,以及使这些变量计算导数的功能,同时从子节点移回到父节点。 节点。
正如 PyTorch 主页所说,PyTorch 中所有神经网络的中心都是 autograd 软件包。 PyTorch 借助 autograd 软件包获得了动态功能。 程序执行时,autograd 将每个操作写入磁带状数据结构并将其存储在内存中。
正如 PyTorch 主页所说,PyTorch 中所有神经网络的中心都是 Autograd 软件包。 PyTorch 借助 Autograd 软件包获得了动态功能。 程序执行时,Autograd 将每个操作写入磁带状数据结构并将其存储在内存中。
这是反向模式自动微分的关键特征之一。 这有助于 PyTorch 动态化,因为无论用户在向前传递中作为操作编写的内容都可以写入磁带,并且在反向传播开始时,autograd 可以在磁带上向后移动并随梯度一起移动,直到到达最外层 父母
这是反向模式自动微分的关键特征之一。 这有助于 PyTorch 动态化,因为无论用户在向前传递中作为操作编写的内容都可以写入磁带,并且在反向传播开始时,Autograd 可以在磁带上向后移动并随梯度一起移动,直到到达最外层 父母
磁带或内存的写操作可忽略不计,PyTorch 通过将操作写到磁带上并在向后遍历后销毁磁带来利用每次正向遍历中的行为。 尽管我会在本书中尽量避免使用尽可能多的数学方法,但是有关自动毕业如何工作的数学示例绝对可以为您提供帮助。 在下面的两个图中,说明了反向传播算法和使用链规则的 autograd 的方法。 下图中我们有一个小型网络,其中有一个乘法节点和一个加法节点。 乘法节点获取输入张量和权重张量,将其传递到加法节点以进行加法运算。
磁带或内存的写操作可忽略不计,PyTorch 通过将操作写到磁带上并在向后遍历后销毁磁带来利用每次正向遍历中的行为。 尽管我会在本书中尽量避免使用尽可能多的数学方法,但是有关自动毕业如何工作的数学示例绝对可以为您提供帮助。 在下面的两个图中,说明了反向传播算法和使用链规则的 Autograd 的方法。 下图中我们有一个小型网络,其中有一个乘法节点和一个加法节点。 乘法节点获取输入张量和权重张量,将其传递到加法节点以进行加法运算。
```py
output = X * W + B
```
由于将方程分为几步,因此我们可以根据下一阶段找到每个阶段的斜率,然后使用链式规则将其链接在一起,从而根据最终输出获得权重的误差。 第二张图显示了 autograd 如何将这些导数项中的每一个链接起来以获得最终误差。
由于将方程分为几步,因此我们可以根据下一阶段找到每个阶段的斜率,然后使用链式规则将其链接在一起,从而根据最终输出获得权重的误差。 第二张图显示了 Autograd 如何将这些导数项中的每一个链接起来以获得最终误差。
![Autograd](img/B09475_02_03.jpg)
......@@ -143,7 +143,7 @@ output = X * W + B
![Autograd](img/B09475_02_04.jpg)
图 2.4:autograd 使用的链规则
图 2.4:Autograd 使用的链规则
前面的图可以使用以下代码转换为 PyTorch 图:
......@@ -166,7 +166,7 @@ tensor([1.])
#### 张量的 Autograd 属性
当成为图形的一部分时,张量需要存储 autograd 自动区分所需的信息。 张量充当计算图中的一个节点,并通过功能模块实例连接到其他节点。 张量实例主要具有支持 autograd 的三个属性:`.grad``.data``grad_fn()`(注意字母大小写:`Function`代表 PyTorch `Function`模块,而`function`代表 Python 函数)。
当成为图形的一部分时,张量需要存储 Autograd 自动区分所需的信息。 张量充当计算图中的一个节点,并通过功能模块实例连接到其他节点。 张量实例主要具有支持 Autograd 的三个属性:`.grad``.data``grad_fn()`(注意字母大小写:`Function`代表 PyTorch `Function`模块,而`function`代表 Python 函数)。
`.grad`属性在任何时间点存储梯度,所有向后调用将当前梯度累积到`.grad`属性。 `.data`属性可访问其中包含数据的裸张量对象。
......@@ -174,7 +174,7 @@ tensor([1.])
图 2.5:`data``grad``grad_fn`
如果您想知道,前面的代码片段中的`required_grad`参数会通知张量或 autograd 引擎在进行反向传播时需要梯度。 创建张量时,可以指定是否需要该张量来承载梯度。 在我们的示例中,我们没有使用梯度更新输入张量(输入永远不会改变):我们只需要更改权重即可。 由于我们没有在迭代中更改输入,因此不需要输入张量即可计算梯度。 因此,在包装输入张量时,我们将`False`作为`required_grad`参数传递,对于权重,我们传递`True`。 检查我们之前创建的张量实例的`grad``data`属性。
如果您想知道,前面的代码片段中的`required_grad`参数会通知张量或 Autograd 引擎在进行反向传播时需要梯度。 创建张量时,可以指定是否需要该张量来承载梯度。 在我们的示例中,我们没有使用梯度更新输入张量(输入永远不会改变):我们只需要更改权重即可。 由于我们没有在迭代中更改输入,因此不需要输入张量即可计算梯度。 因此,在包装输入张量时,我们将`False`作为`required_grad`参数传递,对于权重,我们传递`True`。 检查我们之前创建的张量实例的`grad``data`属性。
`Tensor``Function`实例在图中时是相互连接的,并且一起构成了非循环计算图。 除了用户明确创建的张量以外,每个张量都连接到一个函数。 (如果用户未明确创建张量,则必须通过函数创建张量。例如,表达式`c = a + b`中的`c`由加法函数创建。 )您可以通过在张量上调用`grade_fn`来访问创建器功能。 打印`grad``.data``.grade_fn()`的值可得到以下结果:
......
......@@ -93,7 +93,7 @@ for batch in dataloader:
该社区针对视觉(`torchvision`),文本(`torchtext`)和音频(`torchaudio`)制作了三种不同的实用程序包。 它们针对不同的数据域都解决了相同的问题,并且使用户不必担心用户可能拥有的几乎所有用例中的数据处理和清理问题。 实际上,所有实用程序包都可以轻松地插入到可能理解或不理解 PyTorch 数据结构的任何类型的程序中。
#### 火炬视觉
#### TorchVision
```py
pip install torchvision
......@@ -176,7 +176,7 @@ Dataset MNIST
```
PyTorch 的 Python API 允许冻结用户决定使其不可训练的模型部分。 前面的代码中给出了一个示例。 循环访问`resnet18`的第 1 层参数的循环可访问每个参数的`requires_grad`属性,这是 autograd 在反向传播以进行梯度更新时所寻找的。 将`requires_grad`设置为`False`会屏蔽`autograd`中的特定参数,并使权重保持冻结状态。
PyTorch 的 Python API 允许冻结用户决定使其不可训练的模型部分。 前面的代码中给出了一个示例。 循环访问`resnet18`的第 1 层参数的循环可访问每个参数的`requires_grad`属性,这是 Autograd 在反向传播以进行梯度更新时所寻找的。 将`requires_grad`设置为`False`会屏蔽`autograd`中的特定参数,并使权重保持冻结状态。
`torchvision``transforms`模块是另一个主要参与者,它具有用于数据预处理和数据扩充的实用程序模块。 `transforms`模块为常用的预处理功能(例如填充,裁切,灰度缩放,仿射变换,将图像转换为 PyTorch 张量等)提供了开箱即用的实现,以及一些实现数据增强,例如翻转,随机裁剪和色彩抖动。 `Compose`实用程序将多个转换组合在一起,以形成一个管道对象。
......
......@@ -580,7 +580,7 @@ TorchScript 支持此类 Python 控制流的一个子集,唯一要做的就是
PyTorch 允许您通过两种方法制作 TorchScript IR。 最简单的是通过跟踪,就像 ONNX 一样。 您可以通过虚拟输入将模型(甚至函数)传递给`torch.jit.trace`。 PyTorch 通过模型/功能运行虚拟输入,并在运行输入时跟踪操作。
然后,可以将跟踪的函数(PyTorch 操作)转换为优化的 IR,也称为静态单分配 IR。 像 ONNX 图一样,该图中的指令也具有 TENsor 库(ATen,PyTorch 的后端)可以理解的原始运算符。
然后,可以将跟踪的函数(PyTorch 操作)转换为优化的 IR,也称为静态单分配 IR。 像 ONNX 图一样,该图中的指令也具有张量库(ATen,PyTorch 的后端)可以理解的原始运算符。
这确实很容易,但是要付出代价。 基于跟踪的推理具有 ONNX 的基本问题:它无法处理依赖于数据的模型结构更改,即`if`/`else`条件检查或循环(序列数据)。 为了处理这种情况,PyTorch 引入了脚本模式。
......
......@@ -28,7 +28,7 @@ PyTorch 是基于 Python 的科学计算软件包,可实现两个广泛的目
![../_img/autodiff.png](img/0a7a97c39d6dfc0e08d2701eb7a49231.png)
[torch.autograd 的简要介绍](blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autograd-tutorial-py)
[torch.Autograd 的简要介绍](blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autograd-tutorial-py)
![../_img/mnist1.png](img/be60e8e1f4baa0de87cf9d37c5325525.png)
......
......@@ -156,7 +156,7 @@ tensor([True, True])
注意
**DAG 在 PyTorch 中是动态的**。要注意的重要一点是,图形是从头开始重新创建的; 在每个`.backward()`调用之后,autograd 开始填充新图。 这正是允许您在模型中使用控制流语句的原因。 您可以根据需要在每次迭代中更改形状,大小和操作。
**DAG 在 PyTorch 中是动态的**。要注意的重要一点是,图形是从头开始重新创建的; 在每个`.backward()`调用之后,Autograd 开始填充新图。 这正是允许您在模型中使用控制流语句的原因。 您可以根据需要在每次迭代中更改形状,大小和操作。
### 从 DAG 中排除
......
......@@ -100,7 +100,7 @@ torch.Size([6, 1, 3, 3])
```
让我们尝试一个 32x32 随机输入。 注意:该网络的预期输入大小(LeNet)为 32x32。 要在 MNIST 数据集上使用此网络,请将图像从数据集中调整为 32x32
让我们尝试一个`32x32`随机输入。 注意:该网络的预期输入大小(LeNet)为`32x32`。 要在 MNIST 数据集上使用此网络,请将图像从数据集中调整为`32x32`
```py
input = torch.randn(1, 1, 32, 32)
......@@ -156,7 +156,7 @@ out.backward(torch.randn(1, 10))
损失函数采用一对(输出,目标)输入,并计算一个值,该值估计输出与目标之间的距离。
nn 软件包下有几种不同的[损失函数](https://pytorch.org/docs/nn.html#loss-functions)。 一个简单的损失是:`nn.MSELoss`,它计算输入和目标之间的均方误差。
`nn`软件包下有几种不同的[损失函数](https://pytorch.org/docs/nn.html#loss-functions)。 一个简单的损失是:`nn.MSELoss`,它计算输入和目标之间的均方误差。
例如:
......@@ -212,7 +212,7 @@ print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # ReLU
要反向传播错误,我们要做的只是对`loss.backward()`。 不过,您需要清除现有的梯度,否则梯度将累积到现有的梯度中。
现在,我们将其称为`loss.backward()`,然后看一下向后前后 conv1 的偏差梯度。
现在,我们将其称为`loss.backward()`,然后看一下向后前后`conv1`的偏差梯度。
```py
net.zero_grad() # zeroes the gradient buffers of all parameters
......
......@@ -8,17 +8,17 @@
## 数据呢?
通常,当您必须处理图像,文本,音频或视频数据时,可以使用将数据加载到 numpy 数组中的标准 python 包。 然后,您可以将该数组转换为`torch.*Tensor`
通常,当您必须处理图像,文本,音频或视频数据时,可以使用将数据加载到 NumPy 数组中的标准 Python 包。 然后,您可以将该数组转换为`torch.*Tensor`
* 对于图像,Pillow,OpenCV 等软件包很有用
* 对于音频,请使用 scipy 和 librosa 等软件包
* 对于音频,请使用 SciPy 和 librosa 等软件包
* 对于文本,基于 Python 或 Cython 的原始加载,或者 NLTK 和 SpaCy 很有用
专门针对视觉,我们创建了一个名为`torchvision`的程序包,其中包含用于常见数据集(例如 Imagenet,CIFAR10,MNIST 等)的数据加载器,以及用于图像(即`torchvision.datasets``torch.utils.data.DataLoader`)的数据转换器。
这提供了极大的便利,并且避免了编写样板代码。
在本教程中,我们将使用 CIFAR10 数据集。 它具有以下类别:“飞机”,“汽车”,“鸟”,“猫”,“鹿”,“狗”,“青蛙”,“马”,“船”,“卡车”。 CIFAR-10 中的图像尺寸为 3x32x32,即尺寸为 32x32 像素的 3 通道彩色图像。
在本教程中,我们将使用 CIFAR10 数据集。 它具有以下类别:“飞机”,“汽车”,“鸟”,“猫”,“鹿”,“狗”,“青蛙”,“马”,“船”,“卡车”。 CIFAR-10 中的图像尺寸为`3x32x32`,即尺寸为`32x32`像素的 3 通道彩色图像。
![cifar10](img/ae800707f2489607d51d67499071db16.png)
......@@ -45,7 +45,7 @@ import torchvision.transforms as transforms
```
火炬视觉数据集的输出是[0,1]范围的 PILImage 图像。 我们将它们转换为归一化范围[-1,1]的张量。 .. 注意:
TorchVision 数据集的输出是`[0, 1]`范围的`PILImage`图像。 我们将它们转换为归一化范围`[-1, 1]`的张量。 .. 注意:
```py
If running on Windows and you get a BrokenPipeError, try setting
......@@ -352,7 +352,7 @@ Accuracy of truck : 52 %
## 在 GPU 上进行训练
就像将 Tensor 转移到 GPU 上一样,您也将神经网络转移到 GPU 上。
就像将张量转移到 GPU 上一样,您也将神经网络转移到 GPU 上。
如果可以使用 CUDA,首先将我们的设备定义为第一个可见的 cuda 设备:
......@@ -394,7 +394,7 @@ inputs, labels = data[0].to(device), data[1].to(device)
**已实现的目标**
* 全面了解 PyTorch 的 Tensor 库和神经网络。
* 全面了解 PyTorch 的张量库和神经网络。
* 训练一个小型神经网络对图像进行分类
## 在多个 GPU 上进行训练
......@@ -410,7 +410,7 @@ inputs, labels = data[0].to(device), data[1].to(device)
* [更多示例](https://github.com/pytorch/examples)
* [更多教程](https://github.com/pytorch/tutorials)
* [在论坛上讨论 PyTorch](https://discuss.pytorch.org/)
* [在 Slack](https://pytorch.slack.com/messages/beginner/) 上与其他用户聊天
* [在 Slack 上与其他用户聊天](https://pytorch.slack.com/messages/beginner/)
**脚本的总运行时间**:(2 分钟 39.965 秒)
......
......@@ -8,7 +8,7 @@
PyTorch 的核心是提供两个主要功能:
* n 维张量,类似于 numpy,但可以在 GPU 上运行
* n 维张量,类似于 NumPy,但可以在 GPU 上运行
* 自动区分以构建和训练神经网络
我们将使用将三阶多项式拟合`y = sin(x)`的问题作为运行示例。 该网络将具有四个参数,并且将通过使网络输出与实际输出之间的欧几里德距离最小化来进行梯度下降训练,以适应随机数据。
......@@ -17,24 +17,6 @@ PyTorch 的核心是提供两个主要功能:
您可以在本页的[端浏览各个示例。](#examples-download)
目录
* [张量](#tensors)
* [热身:numpy](#warm-up-numpy)
* [PyTorch:张量](#pytorch-tensors)
* [自动微分](#autograd)
* [PyTorch:张量和自定等级](#pytorch-tensors-and-autograd)
* [PyTorch:定义新的 autograd 功能](#pytorch-defining-new-autograd-functions)
* [nn 模块](#nn-module)
* [PyTorch:nn](#pytorch-nn)
* [PyTorch:最佳](#pytorch-optim)
* [PyTorch:自定义 nn 模块](#pytorch-custom-nn-modules)
* [PyTorch:控制流+权重共享](#pytorch-control-flow-weight-sharing)
* [范例](#examples)
* [张量](#id1)
* [自动微分](#id2)
* [nn 模块](#id3)
## [张量](#id12)
### [预热:numpy](#id13)
......@@ -92,7 +74,7 @@ Numpy 是一个很棒的框架,但是它不能利用 GPU 来加速其数值计
在这里,我们介绍最基本的 PyTorch 概念:**张量**。 PyTorch 张量在概念上与 numpy 数组相同:张量是 n 维数组,PyTorch 提供了许多在这些张量上进行操作的功能。 在幕后,张量可以跟踪计算图和梯度,但它们也可用作科学计算的通用工具。
与 numpy 不同,PyTorch 张量可以利用 GPU 加速其数字计算。 要在 GPU 上运行 PyTorch Tensor,您只需要指定正确的设备即可。
与 numpy 不同,PyTorch 张量可以利用 GPU 加速其数字计算。 要在 GPU 上运行 PyTorch 张量,您只需要指定正确的设备即可。
在这里,我们使用 PyTorch 张量将三阶多项式拟合为正弦函数。 像上面的 numpy 示例一样,我们需要手动实现通过网络的正向和反向传递:
......@@ -149,11 +131,11 @@ print(f'Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3'
在上述示例中,我们必须手动实现神经网络的前向和后向传递。 对于小型的两层网络,手动实施反向传递并不是什么大问题,但是对于大型的复杂网络来说,可以很快变得非常麻烦。
幸运的是,我们可以使用[自动微分](https://en.wikipedia.org/wiki/Automatic_differentiation)来自动计算神经网络中的反向传递。 PyTorch 中的 **autograd** 软件包正是提供了此功能。 使用 autograd 时,网络的正向传播将定义**计算图**; 图中的节点为张量,边为从输入张量产生输出张量的函数。 然后通过该图进行反向传播,可以轻松计算梯度。
幸运的是,我们可以使用[自动微分](https://en.wikipedia.org/wiki/Automatic_differentiation)来自动计算神经网络中的反向传递。 PyTorch 中的 **autograd** 软件包正是提供了此功能。 使用 Autograd 时,网络的正向传播将定义**计算图**; 图中的节点为张量,边为从输入张量产生输出张量的函数。 然后通过该图进行反向传播,可以轻松计算梯度。
这听起来很复杂,在实践中非常简单。 每个张量代表计算图中的一个节点。 如果`x`是具有`x.requires_grad=True`的张量,则`x.grad`是另一个张量,其保持`x`相对于某个标量值的梯度。
在这里,我们使用 PyTorch 张量和 autograd 来实现我们的正弦波与三阶多项式示例; 现在我们不再需要通过网络手动实现反向传递:
在这里,我们使用 PyTorch 张量和 Autograd 来实现我们的正弦波与三阶多项式示例; 现在我们不再需要通过网络手动实现反向传递:
```py
# -*- coding: utf-8 -*-
......@@ -216,13 +198,13 @@ print(f'Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3'
```
### [PyTorch:定义新的 autograd 函数](#id17)
### [PyTorch:定义新的 Autograd 函数](#id17)
在幕后,每个原始的 autograd 运算符实际上都是在 Tensor 上运行的两个函数。 **正向**函数从输入张量计算输出张量。 **反向**函数接收相对于某个标量值的输出张量的梯度,并计算相对于相同标量值的输入张量的梯度。
在幕后,每个原始的 Autograd 运算符实际上都是在张量上运行的两个函数。 **正向**函数从输入张量计算输出张量。 **反向**函数接收相对于某个标量值的输出张量的梯度,并计算相对于相同标量值的输入张量的梯度。
在 PyTorch 中,我们可以通过定义`torch.autograd.Function`的子类并实现`forward``backward`函数来轻松定义自己的 autograd 运算符。 然后,我们可以通过构造实例并像调用函数一样调用新的 autograd 运算符,并传递包含输入数据的张量。
在 PyTorch 中,我们可以通过定义`torch.autograd.Function`的子类并实现`forward``backward`函数来轻松定义自己的 Autograd 运算符。 然后,我们可以通过构造实例并像调用函数一样调用新的 Autograd 运算符,并传递包含输入数据的张量。
在此示例中,我们将模型定义为`y = a + b P[3](c + dx)`而不是`y = a + bx + cx ^ 2 + dx ^ 3`,其中`P[3](x) = 1/2 (5x ^ 3 - 3x)`是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)。 我们编写了自己的自定义 autograd 函数来计算`P[3]`的前进和后退,并使用它来实现我们的模型:
在此示例中,我们将模型定义为`y = a + b P[3](c + dx)`而不是`y = a + bx + cx ^ 2 + dx ^ 3`,其中`P[3](x) = 1/2 (5x ^ 3 - 3x)`是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)。 我们编写了自己的自定义 Autograd 函数来计算`P[3]`的前进和后退,并使用它来实现我们的模型:
```py
# -*- coding: utf-8 -*-
......@@ -315,7 +297,7 @@ print(f'Result: y = {a.item()} + {b.item()} * P3({c.item()} + {d.item()} x)')
### [PyTorch:nn](#id19)
计算图和 autograd 是定义复杂运算符并自动采用导数的非常强大的范例。 但是对于大型神经网络,原始的 autograd 可能会太低级。
计算图和 Autograd 是定义复杂运算符并自动采用导数的非常强大的范例。 但是对于大型神经网络,原始的 Autograd 可能会太低级。
在构建神经网络时,我们经常想到将计算安排在**层**中,其中某些层具有**可学习的参数**,这些参数会在学习期间进行优化。
......@@ -465,7 +447,7 @@ print(f'Result: y = {linear_layer.bias.item()} + {linear_layer.weight[:, 0].item
有时,您将需要指定比一系列现有模块更复杂的模型。 对于这些情况,您可以通过子类化`nn.Module`并定义一个`forward`来定义自己的模块,该模块使用其他模块或在 Tensors 上的其他自动转换操作来接收输入 Tensors 并生成输出 Tensors。
在此示例中,我们将三阶多项式实现为自定义 Module 子类:
在此示例中,我们将三阶多项式实现为自定义`Module`子类:
```py
# -*- coding: utf-8 -*-
......@@ -534,7 +516,7 @@ print(f'Result: {model.string()}')
对于此模型,我们可以使用常规的 Python 流控制来实现循环,并且可以通过在定义正向传递时简单地多次重复使用相同的参数来实现权重共享。
我们可以轻松地将此模型实现为 Module 子类:
我们可以轻松地将此模型实现为`Module`子类:
```py
# -*- coding: utf-8 -*-
......@@ -628,7 +610,7 @@ print(f'Result: {model.string()}')
![../_img/sphx_glr_polynomial_custom_function_thumb.png](img/a5c5d931ed12e34bf68476f4f157b780.png)
[PyTorch:定义新的 autograd 函数](examples_autograd/polynomial_custom_function.html#sphx-glr-beginner-examples-autograd-polynomial-custom-function-py)
[PyTorch:定义新的 Autograd 函数](examples_autograd/polynomial_custom_function.html#sphx-glr-beginner-examples-autograd-polynomial-custom-function-py)
### [nn 模块](#id26)
......
......@@ -6,9 +6,9 @@
此实现使用 PyTorch 张量手动计算正向传播,损耗和后向通过。
PyTorch Tensor 基本上与 numpy 数组相同:它对深度学习或计算图或梯度一无所知,只是用于任意数值计算的通用 n 维数组。
PyTorch张量基本上与 numpy 数组相同:它对深度学习或计算图或梯度一无所知,只是用于任意数值计算的通用 n 维数组。
numpy 数组和 PyTorch 张量之间的最大区别是 PyTorch 张量可以在 CPU 或 GPU 上运行。 要在 GPU 上运行操作,只需将 Tensor 转换为 cuda 数据类型。
numpy 数组和 PyTorch 张量之间的最大区别是 PyTorch 张量可以在 CPU 或 GPU 上运行。 要在 GPU 上运行操作,只需将张量转换为 cuda 数据类型。
```py
import torch
......
......@@ -4,7 +4,7 @@
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`
此实现使用 PyTorch 张量上的运算来计算正向传播,并使用 PyTorch autograd 来计算梯度。
此实现使用 PyTorch 张量上的运算来计算正向传播,并使用 PyTorch Autograd 来计算梯度。
PyTorch 张量表示计算图中的一个节点。 如果`x`是具有`x.requires_grad=True`的张量,则`x.grad`是另一个张量,其保持`x`相对于某个标量值的梯度。
......
# PyTorch:定义新的 autograd 函数
# PyTorch:定义新的 Autograd 函数
> 原文:<https://pytorch.org/tutorials/beginner/examples_autograd/polynomial_custom_function.html#sphx-glr-beginner-examples-autograd-polynomial-custom-function-py>
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`。 而不是将多项式写为`y = a + bx + cx ^ 2 + dx ^ 3`,我们将多项式写为`y = a + b P[3](c + dx)`其中`P[3](x) = 1/2 (5x ^ 3 - 3x)`是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)
此实现使用 PyTorch 张量上的运算来计算正向传播,并使用 PyTorch autograd 来计算梯度。
此实现使用 PyTorch 张量上的运算来计算正向传播,并使用 PyTorch Autograd 来计算梯度。
在此实现中,我们实现了自己的自定义 autograd 函数来执行`P'[3](x)`。 通过数学,`P'[3](x) = 3/2 (5x ^ 2 - 1)`
在此实现中,我们实现了自己的自定义 Autograd 函数来执行`P'[3](x)`。 通过数学,`P'[3](x) = 3/2 (5x ^ 2 - 1)`
```py
import torch
......
......@@ -4,7 +4,7 @@
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`
此实现使用来自 PyTorch 的 nn 软件包来构建网络。 PyTorch autograd 使定义计算图和获取梯度变得容易,但是原始的 autograd 对于定义复杂的神经网络来说可能太低了。 这是 nn 软件包可以提供帮助的地方。 nn 包定义了一组模块,您可以将其视为神经网络层,该神经网络层从输入产生输出并且可能具有一些可训练的权重。
此实现使用来自 PyTorch 的 nn 软件包来构建网络。 PyTorch Autograd 使定义计算图和获取梯度变得容易,但是原始的 Autograd 对于定义复杂的神经网络来说可能太低了。 这是 nn 软件包可以提供帮助的地方。 nn 包定义了一组模块,您可以将其视为神经网络层,该神经网络层从输入产生输出并且可能具有一些可训练的权重。
```py
import torch
......
......@@ -220,7 +220,7 @@ def randomTrainingExample():
与仅使用最后一个输出的分类相反,我们在每个步骤进行预测,因此在每个步骤都计算损失。
autograd 的神奇之处在于,您可以简单地在每个步骤中对这些损失进行求和,然后在末尾调用。
Autograd 的神奇之处在于,您可以简单地在每个步骤中对这些损失进行求和,然后在末尾调用。
```py
criterion = nn.NLLLoss()
......
......@@ -404,7 +404,7 @@ def tensorsFromPair(pair):
您可以观察到以教师为主导的网络的输出,这些输出阅读的是连贯的语法,但是却偏离了正确的翻译-直观地,它已经学会了代表输出语法,并且一旦老师说了最初的几个单词就可以“理解”含义,但是 首先,它还没有正确地学习如何从翻译中创建句子。
由于 PyTorch 的 autograd 具有给我们的自由,我们可以通过简单的 if 语句随意选择是否使用教师强迫。 调高`teacher_forcing_ratio`以使用更多功能。
由于 PyTorch 的 Autograd 具有给我们的自由,我们可以通过简单的 if 语句随意选择是否使用教师强迫。 调高`teacher_forcing_ratio`以使用更多功能。
```py
teacher_forcing_ratio = 0.5
......
......@@ -755,7 +755,7 @@ gates.data<scalar_t>()[n`3`state_size + row*state_size + column]
除了冗长之外,此表达式还需要跨步才能明确知道,并因此在其参数内传递给内核函数。 您会看到,在内核函数接受具有不同大小的多个张量的情况下,您将得到很长的参数列表。
对我们来说幸运的是,ATen 提供了通过动态检查 Tensor 是维度的类型和数量而创建的访问器。 然后,访问器公开一个 API,可以有效地访问 Tensor 元素,而不必转换为单个指针:
对我们来说幸运的是,ATen 提供了通过动态检查张量是维度的类型和数量而创建的访问器。 然后,访问器公开一个 API,可以有效地访问张量元素,而不必转换为单个指针:
```py
torch::Tensor foo = torch::rand({12, 12});
......
......@@ -73,7 +73,7 @@ print(example(torch.ones([])))
注意
当我们初始化一个空的期货列表时,我们需要在`futures`上添加一个显式类型注释。 在 TorchScript 中,空容器默认假定它们包含 Tensor 值,因此我们将列表构造函数#注释为`List[torch.jit.Future[torch.Tensor]]`类型
当我们初始化一个空的期货列表时,我们需要在`futures`上添加一个显式类型注释。 在 TorchScript 中,空容器默认假定它们包含张量值,因此我们将列表构造函数#注释为`List[torch.jit.Future[torch.Tensor]]`类型
本示例使用`fork()`启动函数`foo`的 100 个实例,等待 100 个任务完成,然后对结果求和,返回`-100.0`
......
......@@ -2,11 +2,11 @@
> 原文:<https://pytorch.org/tutorials/advanced/cpp_autograd.html>
`autograd`软件包对于在 PyTorch 中构建高度灵活和动态的神经网络至关重要。 PyTorch Python 前端中的大多数 autograd API 也可以在 C++ 前端中使用,从而可以轻松地将 autograd 代码从 Python 转换为 C++。
`autograd`软件包对于在 PyTorch 中构建高度灵活和动态的神经网络至关重要。 PyTorch Python 前端中的大多数 autograd API 也可以在 C++ 前端中使用,从而可以轻松地将 Autograd 代码从 Python 转换为 C++。
在本教程中,我们将看几个在 PyTorch C++ 前端中进行 autograd 的示例。 请注意,本教程假定您已经对 Python 前端中的 autograd 有基本的了解。 如果不是这种情况,请先阅读 [Autograd:自动微分](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html)
在本教程中,我们将看几个在 PyTorch C++ 前端中进行 Autograd 的示例。 请注意,本教程假定您已经对 Python 前端中的 Autograd 有基本的了解。 如果不是这种情况,请先阅读 [Autograd:自动微分](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html)
## 基本的 autograd 操作
## 基本的 Autograd 操作
(改编自[本教程](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#autograd-automatic-differentiation)
......@@ -263,7 +263,7 @@ std::cout << input.grad() << std::endl;
有关如何使用它们的更多信息,请参见`torch::autograd::backward`[链接](https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1afa9b5d4329085df4b6b3d4b4be48914b.html))和`torch::autograd::grad`[链接](https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1a1e03c42b14b40c306f9eb947ef842d9c.html))的文档。
## 在 C++ 中使用自定义 autograd 函数
## 在 C++ 中使用自定义 Autograd 函数
(改编自[本教程](https://pytorch.org/docs/stable/notes/extending.html#extending-torch-autograd)
......@@ -386,9 +386,9 @@ std::cout << x.grad() << std::endl;
有关`torch::autograd::Function`的更多信息,请参见[其文档](https://pytorch.org/cppdocs/api/structtorch_1_1autograd_1_1_function.html)
## 将 autograd 代码从 Python 转换为 C++
## 将 Autograd 代码从 Python 转换为 C++
在较高的层次上,在 C++ 中使用 autograd 的最简单方法是先在 Python 中拥有可用的 autograd 代码,然后使用下表将您的 autograd 代码从 Python 转换为 C++:
在较高的层次上,在 C++ 中使用 Autograd 的最简单方法是先在 Python 中拥有可用的 Autograd 代码,然后使用下表将您的 Autograd 代码从 Python 转换为 C++:
| Python | C++ |
| --- | --- |
......@@ -407,7 +407,7 @@ std::cout << x.grad() << std::endl;
| `torch.Tensor.output_nr` | `torch::Tensor::output_nr`[链接](https://pytorch.org/cppdocs/api/classat_1_1_tensor.html#_CPPv4NK2at6Tensor9output_nrEv)) |
| `torch.Tensor.is_leaf` | `torch::Tensor::is_leaf`[链接](https://pytorch.org/cppdocs/api/classat_1_1_tensor.html#_CPPv4NK2at6Tensor7is_leafEv)) |
翻译后,您的大多数 Python autograd 代码都应仅在 C++ 中工作。 如果不是这种情况,请在 [GitHub 问题](https://github.com/pytorch/pytorch/issues)中提交错误报告,我们将尽快对其进行修复。
翻译后,您的大多数 Python Autograd 代码都应仅在 C++ 中工作。 如果不是这种情况,请在 [GitHub 问题](https://github.com/pytorch/pytorch/issues)中提交错误报告,我们将尽快对其进行修复。
## 结论
......
......@@ -75,11 +75,11 @@ TORCH_LIBRARY_IMPL(myops, CUDA, m) {
您知道吗,您还可以为 PyTorch 中的现有核心操作员编写`TORCH_LIBRARY_IMPL`块? 这就是实现 XLA 对 PyTorch 的支持的方式:`torch_xla`库包含一个`TORCH_LIBRARY_IMPL`,该库为 XLA 调度键上的所有基本运算符提供实现。
## 添加 autograd 支持
## 添加 Autograd 支持
至此,我们有了一个同时具有 CPU 和 CUDA 实现的操作员。 我们如何为它添加 autograd 支持? 您可能会猜到,我们将注册一个 autograd 内核(类似于[自定义 autograd 函数](cpp_autograd)教程中描述的内容)! 但是,有一个变数:与 CPU 和 CUDA 内核不同,autograd 内核需要*重新分发*:它需要回调分派器才能到达最终的 CPU 和 CUDA 实现。
至此,我们有了一个同时具有 CPU 和 CUDA 实现的操作员。 我们如何为它添加 Autograd 支持? 您可能会猜到,我们将注册一个 Autograd 内核(类似于[自定义 Autograd 函数](cpp_autograd)教程中描述的内容)! 但是,有一个变数:与 CPU 和 CUDA 内核不同,Autograd 内核需要*重新分发*:它需要回调分派器才能到达最终的 CPU 和 CUDA 实现。
因此,在编写 autograd 内核之前,让我们编写一个*调度函数*,该函数调用调度程序以为您的操作员找到合适的内核。 该函数构成了供您的操作员使用的公共 C++ API,实际上,PyTorch C++ API 中的所有张量函数都在后台完全以相同的方式调用了调度程序。 调度功能如下所示:
因此,在编写 Autograd 内核之前,让我们编写一个*调度函数*,该函数调用调度程序以为您的操作员找到合适的内核。 该函数构成了供您的操作员使用的公共 C++ API,实际上,PyTorch C++ API 中的所有张量函数都在后台完全以相同的方式调用了调度程序。 调度功能如下所示:
```py
Tensor myadd(const Tensor& self, const Tensor& other) {
......@@ -99,7 +99,7 @@ Tensor myadd(const Tensor& self, const Tensor& other) {
* 在第二行中,我们只需将所有参数传递到调度函数中,就可以简单地`call`操作员句柄。 这实际上将调用调度程序,最终控制权将转移到适合此调用的任何内核。
有了分发功能,我们现在可以编写 autograd 内核:
有了分发功能,我们现在可以编写 Autograd 内核:
```py
class MyAddFunction : public torch::autograd::Function<MyAddFunction> {
......@@ -122,7 +122,7 @@ Tensor myadd_autograd(const Tensor& self, const Tensor& other) {
```
使用`torch::autograd::Function`正常编写 autograd 函数,除了代替直接在`forward()`中编写实现,我们:
使用`torch::autograd::Function`正常编写 Autograd 函数,除了代替直接在`forward()`中编写实现,我们:
1. 使用`at::AutoNonVariableTypeMode` RAII 保护器关闭自动毕业处理,然后
2. 调用调度函数`myadd`以回调调度程序。
......@@ -193,7 +193,7 @@ TORCH_LIBRARY_IMPL(myops, Autocast, m) {
如果`tensor`为 CUDA 和`float32`,则`cached_cast(kHalf, tensor)``tensor`强制转换为`float16`,否则,`tensor`保持不变(参见[资格策略](https://pytorch.org/docs/stable/amp.html#op-eligibility)对于本地自动播报的操作)。 这样可以确保网络是否在`float16``float32` CUDA 张量的任何混合形式上调用`mymatmul``mymatmul``float16`中运行。 同时,使用非 CUDA,整数类型或`float64`输入的对`mymatmul`的调用不受影响。 建议使用`cached_cast`在您自己的自动广播包装程序中遵循本机资格策略,但不是必需的。 例如,如果要对所有输入类型强制执行`float16`,则可以使用`return mymatmul(self.half(), other.half());`而不是使用`cached_cast`
请注意,就像我们的 autograd 内核一样,我们在重新分配之前从分配中排除`Autocast`键。
请注意,就像我们的 Autograd 内核一样,我们在重新分配之前从分配中排除`Autocast`键。
默认情况下,如果未提供自动广播包装器,我们将直接进入常规的操作员实现(不进行自动广播)。 (在此示例中,我们没有使用`myadd`,因为逐点加法不需要自动广播,因此应该会失败。)
......@@ -218,7 +218,7 @@ Tensor my_multiple_input_op_autocast(const Tensor& t0, const Tensor& t1) {
```
如果您的自定义操作是[已启用 autograd 的](#autograd-support),则只需编写和注册自动广播包装器,其名称与注册自动梯度包装器的名称相同。 例如,如果您想为 autograd 部分中显示的`myadd`功能使用自动广播包装,那么您所需要做的就是
如果您的自定义操作是[已启用 Autograd 的](#autograd-support),则只需编写和注册自动广播包装器,其名称与注册自动梯度包装器的名称相同。 例如,如果您想为 Autograd 部分中显示的`myadd`功能使用自动广播包装,那么您所需要做的就是
```py
Tensor myadd_autocast(const Tensor& self, const Tensor& other) {
......@@ -233,7 +233,7 @@ TORCH_LIBRARY_IMPL(myops, Autocast, m) {
```
没有单独的体操可使后向方法自动广播兼容。 但是,在自定义 autograd 函数中定义的向后方法将以与正向方法的自动广播集相同的 dtype 运行,因此您应该选择既适合于正向方法又适合于向后方法的`<desired dtype>`
没有单独的体操可使后向方法自动广播兼容。 但是,在自定义 Autograd 函数中定义的向后方法将以与正向方法的自动广播集相同的 dtype 运行,因此您应该选择既适合于正向方法又适合于向后方法的`<desired dtype>`
### 批量
......
......@@ -62,7 +62,7 @@ DDP 材料如下:
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)训练应用程序。
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 示例。
......
......@@ -12,7 +12,7 @@
* [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/stable/nn.html#torch.nn.parallel.DistributedDataParallel) (DDP)在模块级别实现可在多台计算机上运行的数据并行性。 使用 DDP 的应用程序应产生多个进程,并为每个进程创建一个 DDP 实例。 DDP 在[火炬。分布式](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 在[火炬。分布式](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 与模型并行结合。
......
......@@ -301,7 +301,7 @@ Solved! Running reward is now 475.3163778435275!
在此示例中,我们展示了如何使用 RPC 作为通信工具来跨工作人员传递数据,以及如何使用 RRef 引用远程对象。 的确,您可以直接在`ProcessGroup` `send``recv` API 之上构建整个结构,也可以使用其他通信/ RPC 库。 但是,通过使用 torch.distributed.rpc ,您可以在后台获得本机支持并不断优化性能。
接下来,我们将展示如何将 RPC 和 RRef 与分布式 autograd 和分布式优化器结合起来执行分布式模型并行训练。
接下来,我们将展示如何将 RPC 和 RRef 与分布式 Autograd 和分布式优化器结合起来执行分布式模型并行训练。
## 使用 Distributed Autograd 和 Distributed Optimizer 的分布式 RNN
......@@ -390,7 +390,7 @@ class RNNModel(nn.Module):
现在,我们准备实施训练循环。 初始化模型参数后,我们创建`RNNModel``DistributedOptimizer`。 分布式优化器将采用参数`RRefs`的列表,查找所有不同的所有者工作器,并在每个所有者工作器上创建给定的本地优化器(即,在这种情况下,您也可以使用其他本地优化器`SGD`) 使用给定的参数(即`lr=0.05`)。
在训练循环中,它首先创建一个分布式 autograd 上下文,这将帮助分布式 autograd 引擎查找梯度和涉及的 RPC 发送/接收功能。 分布式 autograd 引擎的设计详细信息可以在其[设计说明](https://pytorch.org/docs/master/notes/distributed_autograd.html)中找到。 然后,它像本地模型一样开始前向传递,并运行分布式后向传递。 对于后向分布,您只需要指定一个根列表,在这种情况下,就是损失`Tensor`。 分布式 autograd 引擎将自动遍历分布式图形并正确编写梯度。 接下来,它在分布式优化器上运行`step`功能,该功能将与所有涉及的本地优化器联系以更新模型参数。 与本地训练相比,一个较小的差异是您不需要运行`zero_grad()`,因为每个 autograd 上下文都有专用的空间来存储梯度,并且在每次迭代创建上下文时,来自不同迭代的那些梯度不会累积到 同一组`Tensors`
在训练循环中,它首先创建一个分布式 Autograd 上下文,这将帮助分布式 Autograd 引擎查找梯度和涉及的 RPC 发送/接收功能。 分布式 Autograd 引擎的设计详细信息可以在其[设计说明](https://pytorch.org/docs/master/notes/distributed_autograd.html)中找到。 然后,它像本地模型一样开始前向传递,并运行分布式后向传递。 对于后向分布,您只需要指定一个根列表,在这种情况下,就是损失`Tensor`。 分布式 Autograd 引擎将自动遍历分布式图形并正确编写梯度。 接下来,它在分布式优化器上运行`step`功能,该功能将与所有涉及的本地优化器联系以更新模型参数。 与本地训练相比,一个较小的差异是您不需要运行`zero_grad()`,因为每个 Autograd 上下文都有专用的空间来存储梯度,并且在每次迭代创建上下文时,来自不同迭代的那些梯度不会累积到 同一组`Tensors`
```py
def run_trainer():
......
......@@ -11,7 +11,7 @@
本教程介绍了一个简单的示例,该示例使用 PyTorch 的[分布式 RPC 框架](https://pytorch.org/docs/stable/rpc.html)实现参数服务器。 参数服务器框架是一种范例,其中一组服务器存储参数(例如大型嵌入表),并且多个训练人员查询参数服务器以检索最新参数。 这些训练师可以在本地运行训练循环,并偶尔与参数服务器同步以获得最新参数。 有关参数服务器方法的更多信息,请查阅[本文](https://www.cs.cmu.edu/~muli/file/parameter_server_osdi14.pdf)
使用分布式 RPC 框架,我们将构建一个示例,其中多个训练师使用 RPC 与同一个参数服务器进行通信,并使用 [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 访问远程参数服务器实例上的状态。 每位训练师将通过使用分布式 autograd 跨多个节点拼接 autograd 图,以分布式方式启动其专用的反向传递。
使用分布式 RPC 框架,我们将构建一个示例,其中多个训练师使用 RPC 与同一个参数服务器进行通信,并使用 [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 访问远程参数服务器实例上的状态。 每位训练师将通过使用分布式 Autograd 跨多个节点拼接 Autograd 图,以分布式方式启动其专用的反向传递。
**注意**:本教程介绍了分布式 RPC 框架的用法,该方法可用于将模型拆分到多台计算机上,或用于实现参数服务器训练策略,在该策略中,网络训练师可以获取托管在另一台计算机上的参数。 相反,如果您要跨多个 GPU 复制模型,请参阅[分布式数据并行教程](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html)。 还有另一个 [RPC 教程](https://pytorch.org/tutorials/intermediate/rpc_tutorial.html),涵盖了强化学习和 RNN 用例。
......@@ -132,7 +132,7 @@ class ParameterServer(nn.Module):
```
接下来,我们将定义一些其他功能,可用于训练和验证。 第一个`get_dist_gradients`将采用 Distributed Autograd 上下文 ID,并调用`dist_autograd.get_gradients` API,以检索由分布式 autograd 计算的梯度。 可以在[分布式 autograd 文档](https://pytorch.org/docs/stable/rpc.html#distributed-autograd-framework)中找到更多信息。 请注意,由于该框架当前仅支持通过 RPC 发送张量,因此我们还会迭代生成的字典并将每个张量转换为 CPU 张量。 接下来,`get_param_rrefs`将迭代我们的模型参数,并将它们包装为(本地) [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 。 训练者节点将通过 RPC 调用此方法,并将返回要优化的参数列表。 这是[分布式优化器](https://pytorch.org/docs/stable/rpc.html#module-torch.distributed.optim)的输入,它需要所有必须优化的参数作为`RRef`的列表。
接下来,我们将定义一些其他功能,可用于训练和验证。 第一个`get_dist_gradients`将采用 Distributed Autograd 上下文 ID,并调用`dist_autograd.get_gradients` API,以检索由分布式 Autograd 计算的梯度。 可以在[分布式 Autograd 文档](https://pytorch.org/docs/stable/rpc.html#distributed-autograd-framework)中找到更多信息。 请注意,由于该框架当前仅支持通过 RPC 发送张量,因此我们还会迭代生成的字典并将每个张量转换为 CPU 张量。 接下来,`get_param_rrefs`将迭代我们的模型参数,并将它们包装为(本地) [RRef](https://pytorch.org/docs/stable/rpc.html#torch.distributed.rpc.RRef) 。 训练者节点将通过 RPC 调用此方法,并将返回要优化的参数列表。 这是[分布式优化器](https://pytorch.org/docs/stable/rpc.html#module-torch.distributed.optim)的输入,它需要所有必须优化的参数作为`RRef`的列表。
```py
# Use dist autograd to retrieve gradients accumulated for this model.
......@@ -248,7 +248,7 @@ def run_training_loop(rank, num_gpus, train_loader, test_loader):
```
接下来,我们定义我们的主要训练循环。 我们遍历了 PyTorch 的 [DataLoader](https://pytorch.org/docs/stable/data.html) 提供的可迭代项。 在编写典型的前向/后向/优化器循环之前,我们首先将逻辑包装在[分布式 Autograd 上下文](https://pytorch.org/docs/stable/rpc.html#torch.distributed.autograd.context)中。 请注意,这需要记录在模型的前向传递中调用的 RPC,以便可以构造一个适当的图,其中包括在后向传递中所有参与的分布式工作者。 分布式 autograd 上下文返回`context_id`,它用作用于累积和优化与特定迭代对应的梯度的标识符。
接下来,我们定义我们的主要训练循环。 我们遍历了 PyTorch 的 [DataLoader](https://pytorch.org/docs/stable/data.html) 提供的可迭代项。 在编写典型的前向/后向/优化器循环之前,我们首先将逻辑包装在[分布式 Autograd 上下文](https://pytorch.org/docs/stable/rpc.html#torch.distributed.autograd.context)中。 请注意,这需要记录在模型的前向传递中调用的 RPC,以便可以构造一个适当的图,其中包括在后向传递中所有参与的分布式工作者。 分布式 Autograd 上下文返回`context_id`,它用作用于累积和优化与特定迭代对应的梯度的标识符。
与调用典型的`loss.backward()`会启动此本地工作程序的向后传递相反,我们调用`dist_autograd.backward()`并传递我们的 context_id 和`loss`,这是我们希望向后传递的根 开始。 另外,我们将此`context_id`传递到优化程序调用中,该调用程序必须能够在所有节点上查找由该特定向后传递计算出的相应梯度。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册