diff --git a/docs/2.0/tutorials/beginner/basics/autogradqs_tutorial.md b/docs/2.0/tutorials/beginner/basics/autogradqs_tutorial.md index 4cf9a68fb..3c6f68794 100644 --- a/docs/2.0/tutorials/beginner/basics/autogradqs_tutorial.md +++ b/docs/2.0/tutorials/beginner/basics/autogradqs_tutorial.md @@ -70,8 +70,9 @@ tensor([0.3313, 0.0626, 0.2530]) ``` > 注意: -> * 我们只能从计算图中将 `require_grad` 设置为 `True` 的叶子结点获取 `grad` 属性。对于计算图中的其他节点,梯度不可获取。 -> * 在给定的计算图中,出于性能原因我们只能用 `backward` 进行一次梯度计算。如果我们想要对同一张计算图做几次 `backward` 调用,我们需要在 `backward` 调用时传递 `retain_graph=True` 参数。 +> +>* 我们只能从计算图中将 `require_grad` 设置为 `True` 的叶子结点获取 `grad` 属性。对于计算图中的其他节点,梯度不可获取。 +>* 在给定的计算图中,出于性能原因我们只能用 `backward` 进行一次梯度计算。如果我们想要对同一张计算图做几次 `backward` 调用,我们需要在 `backward` 调用时传递 `retain_graph=True` 参数。 ## 禁用梯度追踪 @@ -108,18 +109,21 @@ False ``` 你想要禁用梯度追踪的原因可能是: + - 为了把你神经网络中的某些参数标记为**冻结参数(frozen parameters)** - 为了在你只做前向传递的时候加快计算速度,因为在不追踪梯度的张量上进行的运算会更加高效。 ## 计算图的更多内容 -从概念上来说,autograd 在一个用[函数(Function)对象](https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)构成的有向无环图中保持一份数据(张量)的记录以及全部执行的操作(以及产生的新张量)。在这个有向无环图(**DAG**)中,叶子节点是输入张量,根节点是输出张量。通过从根节点到叶子节点地追踪这个图,你可以用链式法自动计算梯度。 +从概念上来说,autograd 在一个由[函数(Function)对象](https://pytorch.org/docs/stable/autograd.html#torch.autograd.Function)构成的有向无环图中保持一份数据(张量)以及全部执行的操作(以及产生的新张量)的记录。在这个有向无环图(**DAG**)中,叶子节点是输入张量,根节点是输出张量。通过从根节点到叶子节点地追踪这个图,你可以用链式法则自动计算梯度。 在前向传递中,autograd 同时做两件事: + - 运行指定的操作来计算、生成一个张量 - 维持这次运算在有向无环图中的*梯度函数* 当对有向无环图的根节点调用 `.backward()` 方法时,反向传递就开始了。然后 `autograd` 会: + - 从每个 `.grad_fn` 中计算梯度 - 在对应张量的 `.grad` 属性中累计它们 - 应用链式法则,一路传播到叶子张量。 @@ -127,9 +131,9 @@ False > 注意: > **PyTorch 中的有向无环图是动态的**: 一个重要的观察是这个图是从零重建的;每次 `.backward()` 调用之后,autograd 都会开始构建一张新图。这一点允许你在模型中使用流控制语句;如果需要的话,你可以在每次迭代中改变结构、大小和和运算。 -## 选读: 张量梯度和 Jacobian 乘积 +## 选读: 张量梯度和 Jacobian (译为:雅各布)乘积 -在许多场景中,我们有一个标量损失函数,且我们需要对某些参数计算梯度。然而,也有场景下输出函数是一个任意的张量。在这种场景下,PyTorch 允许你计算一个 Jacobian 乘积,而不是真实的梯度。 +在许多场景中,我们有一个标量损失函数,且我们需要对某些参数计算梯度。然而,也有些场景下输出函数是一个任意的张量。在这种场景下,PyTorch 允许你计算一个 Jacobian 乘积,而不是真实的梯度。 对于一个向量函数 $\vec y = f(\vec x)$, 给定 $\vec x = < x_1,...,x_n >$ 且 $\vec y = < y_1,...,y_n >$, 一个 $\vec y$ 对 $\vec x$ 的梯度可以用 Jacobian 矩阵表示为: @@ -179,10 +183,10 @@ tensor([[4., 2., 2., 2., 2.], [2., 2., 2., 4., 2.]]) ``` -请注意当我们用相同的参数第二次调用 `backward` 的时候,梯度值是不一样的。这是因为在执行 `backward` 传播的时候,PyTorch **累计了梯度**,也就是说计算的梯度被加到计算图中所有叶子节点的 `grad` 属性中。如果你想计算正确的梯度,你需要显式清零 `grad` 属性。在真实工作中训练一个*优化器*可以帮我们做到这一点。 +请注意当我们用相同的参数第二次调用 `backward` 的时候,梯度值是不一样的。这是因为在执行 `backward` 传播的时候,PyTorch **累计了梯度**,也就是说计算的梯度被加到计算图中所有叶子节点的 `grad` 属性中。如果你想计算正确的梯度,你需要显式清零 `grad` 属性。在实际的工作训练中,*优化器*可以帮我们做到这一点。 > 注意: -> 之前我们调用 `backward()` 函数的时候没有加参数。这实际上相当于调用 `backward(torch.tensor(1.0))` -- 是一个计算标量值函数(比如神经网络训练过程中的损失)的梯度的好方法。 +> 之前我们调用 `backward()` 函数的时候没有加参数。这实际上相当于调用 `backward(torch.tensor(1.0))`, 这是在标量值函数的情况下计算梯度的有效方法,比如神经网络训练中的损失。 ## 进一步阅读: diff --git a/docs/2.0/tutorials/beginner/basics/buildmodel_tutorial.md b/docs/2.0/tutorials/beginner/basics/buildmodel_tutorial.md index 6dc36e1a1..ba5fb578b 100644 --- a/docs/2.0/tutorials/beginner/basics/buildmodel_tutorial.md +++ b/docs/2.0/tutorials/beginner/basics/buildmodel_tutorial.md @@ -6,7 +6,7 @@ > > 原始地址: -神经网络由在数据上完成操作的层/模块构成。[`torch.nn`](https://pytorch.org/docs/stable/nn.html) 命名空间提供了所有你用来构建你自己的神经网络所需的的东西。PyTorch 中每个模块都是 [`nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html) 的子类。一个由其他模块(层)组成的神经网络自身也是一个模块。这种嵌套的结构让构建和管理复杂的结构更轻松。 +神经网络由在数据上进行操作的层/模块构成。[`torch.nn`](https://pytorch.org/docs/stable/nn.html) 命名空间提供了所有你用来构建你自己的神经网络所需的组件。PyTorch 中每个模块都是 [`nn.Module`](https://pytorch.org/docs/stable/generated/torch.nn.Module.html) 的子类。一个由其他模块(层)组成的神经网络自身也是一个模块。这种嵌套的结构让构建和管理复杂的结构更轻松。 在下面的章节中,我们将构建一个神经网络来给 FashionMNIST 数据集的图片分类。 @@ -84,7 +84,7 @@ NeuralNetwork( ) ``` -为了使用这个模型,我们给它传递输入数据。这将会执行模型的 `forward`,伴随着一些[幕后工作](https://github.com/pytorch/pytorch/blob/270111b7b611d174967ed204776985cefca9c144/torch/nn/modules/module.py#L866)。不要直接调用 `model.forward()` ! +为了使用这个模型,我们给它传递输入数据。这将会执行模型的 `forward` 函数,以及一些[后台操作](https://github.com/pytorch/pytorch/blob/270111b7b611d174967ed204776985cefca9c144/torch/nn/modules/module.py#L866)。请不要直接调用 `model.forward()` ! 将数据传递给模型并调用后返回一个 2 维张量(第0维对应一组 10 个代表每种类型的原始预测值,第1维对应该类型对应的原始预测值)。我们将它传递给一个 `nn.Softmax` 模块的实例来来获得预测概率。 @@ -104,7 +104,7 @@ Predicted class: tensor([7], device='cuda:0') ## 模型层 -让我们分析这个 FashionMNIST 模型层。为了说明,我们会取一个由 3 张 28x28 的图片数据组成的样例数据,并看看当我们将它传递给模型后会发生什么。 +让我们分析这个 FashionMNIST 模型的各层。为了说明,我们会取一个由 3 张 28x28 的图片数据组成的样例数据,并看看当我们将它传递给模型后会发生什么。 ```py input_image = torch.rand(3,28,28) @@ -151,7 +151,7 @@ torch.Size([3, 20]) ### nn.ReLU -非线性的激活函数创造了模型的输入值和输出值之间的复杂映射。它们在线性转换之后应用来引入*非线性*,帮助神经网络学习更广阔范围的现象。 +非线性的激活函在模型的输入和输出之间数创造了复杂的映射关系。它们在线性转换之后引入*非线性*,帮助神经网络学习更广阔范围的现象。 在这个模型中,我们在线性层之间使用 [`nn.ReLU`](https://pytorch.org/docs/stable/generated/torch.nn.ReLU.html),不过还有其他的激活函数可以用在你的模型中引入非线性。 @@ -205,7 +205,7 @@ logits = seq_modules(input_image) ### nn.Softmax -模型的最后一层返回 *logits*(介于[负无穷,正无穷]之间的原始值),然后被传递给 [`nn.Softmax`](https://pytorch.org/docs/stable/generated/torch.nn.Softmax.html) 模块。这些 logits 值被缩放到 [0,1],代表模型对与每种类型的预测概率. `dim` 参数代表沿着该维度数值应该加总为 1. +模型的最后一层返回 *logits*(介于[负无穷,正无穷]之间的原始值),然后被传递给 [`nn.Softmax`](https://pytorch.org/docs/stable/generated/torch.nn.Softmax.html) 模块。这些 logits 值被缩放到 [0,1],代表模型对每种类型的预测概率, `dim` 参数代表沿着该维度数值应该加总为 1. ```py softmax = nn.Softmax(dim=1) @@ -214,9 +214,9 @@ pred_probab = softmax(logits) ## 模型参数 -神经网络内的许多层都是参数化的,比如有可以在训练中优化的关联的权重值和偏差值。子类化 `nn.Module` 会自动追踪所有你定义在模型对象中的字段,并通过你模型的 `parameters()` 或者 `named_parameters()` 访问所有参数。 +神经网络内的许多层都是参数化的,比如可以在训练中与层相关的可优化权重和偏置。 `nn.Module` 的子类会自动追踪所有你定义在模型对象中的字段,并通过你模型的 `parameters()` 或者 `named_parameters()` 方法访问所有参数。 -在这个例子中,我们在每个参数上遍历,然后打印出它的大小(size)并预测数值。 +在这个例子中,我们在每个参数上遍历,然后打印出它的大小(size)与数值。 ```py print(f"Model structure: {model}\n\n") diff --git a/docs/2.0/tutorials/beginner/basics/data_tutorial.md b/docs/2.0/tutorials/beginner/basics/data_tutorial.md index e8b64391b..fa2425dc9 100644 --- a/docs/2.0/tutorials/beginner/basics/data_tutorial.md +++ b/docs/2.0/tutorials/beginner/basics/data_tutorial.md @@ -19,10 +19,11 @@ Fashion-MNIST是一个由 60,000 个训练实例和 10,000 个测试实例组成 每个例子包括一个28×28的灰度图像和10个类别中的一个相关标签。 我们加载 [FashionMNIST Dataset](https://pytorch.org/vision/stable/datasets.html#fashion-mnist) 参数如下: - - ``root`` 是存储训练/测试数据的路径, - - ``train`` 指定训练或测试数据集, - - ``download=True`` 如果 ``root`` 指定的目录没有数据,就自动从网上下载数据。 - - ``transform`` 和 ``target_transform`` 指定特征和标签的转换。 + +- ``root`` 是存储训练/测试数据的路径, +- ``train`` 指定训练或测试数据集, +- ``download=True`` 如果 ``root`` 指定的目录没有数据,就自动从网上下载数据。 +- ``transform`` 和 ``target_transform`` 指定特征和标签的转换。 ```py import torch @@ -164,7 +165,7 @@ def __getitem__(self, idx): ``Dataset`` 每次加载一组我们数据集的特征和标签样本。在训练一个模型时,我们通常希望以 "小批量" 的方式传递样本,在每个训练周期重新打乱数据以减少模型的过拟合,并使用 Python 的 ``multiprocessing`` 来加快数据的加载速度。 -`DataLoader` 是一个可迭代的,它用一个简单的API为我们抽象出这种复杂性。 +`DataLoader` 是一个可迭代的对象,它用一个简单的API为我们抽象出这种复杂性。 ```py from torch.utils.data import DataLoader diff --git a/docs/2.0/tutorials/beginner/basics/optimization_tutorial.md b/docs/2.0/tutorials/beginner/basics/optimization_tutorial.md index 7d2b57b3a..93bfd6245 100644 --- a/docs/2.0/tutorials/beginner/basics/optimization_tutorial.md +++ b/docs/2.0/tutorials/beginner/basics/optimization_tutorial.md @@ -7,7 +7,7 @@ > 原始地址: -既然我们已经有了模型和数据,现在应该训练、验证、测试我们的模型(基于我们的数据来优化参数)。训练一个模型也是一个遍历的过程;在每次遍历中,模型会对输出中进行一次预测,计算这个预测的错误程度(损失值),收集这些错误相对于参数的导数(像我们前面一章说的),然后通过梯度下降的方式来**优化**这些参数。关于这个过程的更详细的介绍,可以看3Blue1Brown制作的[《反向传播演算》](https://www.youtube.com/watch?v=tIeHLnjs5U8)这个视频。 +既然我们已经有了模型和数据,现在应该训练、验证、测试我们的模型(基于我们的数据来优化参数)。训练一个模型也是一个迭代的过程;在每次迭代中(又称为 epoch),模型会对输出中进行一次预测,计算这个预测的误差(损失值),收集这些误差相对于参数的导数(像我们前面一章说的),然后通过梯度下降的方式来**优化**这些参数。关于这个过程的更详细的介绍,可以看3Blue1Brown制作的[《反向传播演算》](https://www.youtube.com/watch?v=tIeHLnjs5U8)这个视频。 ## 前提代码 @@ -114,7 +114,7 @@ Extracting data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/ 我们定义以下用于训练的超参数: -- **Number of Epochs** - 遍历数据集的次数 +- **Number of Epochs** - 迭代数据集的次数 - **Batch Size** - 在参数更新之前通过网络传播的数据样本数量。 - **Learning Rate** - 学习率, 每 Batch/Epoch 次更新模型参数的幅度。较小的值会产生较慢的学习速度,较大的值可能会在训练过程中产生无法预料的行为。 @@ -126,20 +126,20 @@ epochs = 5 ## 优化循环 -设置完超参数后,接下来我们在一个优化循环中训练并优化我们的模型。优化循环的每次遍历叫做一个**Epoch(时期、纪元)**。 +设置完超参数后,接下来我们在一个优化循环中训练并优化我们的模型。优化循环的每次迭代叫做一个 **Epoch(时期、纪元)**。 -每个Epoch由两个主要部分构成: +每个 Epoch 由两个主要部分构成: - **训练循环** 在训练数据集上遍历,尝试收敛到最优的参数。 -- **验证/测试循环** 在测试数据集上遍历,来检查模型效果是否在提升。 +- **验证/测试循环** 在测试数据集上遍历,以检查模型效果是否在提升。 -让我们大致的熟悉一下一些在训练循环中使用的概念。完整的优化循环代码可以直接跳到: [完整实现](#完整实现) +让我们简单的熟悉一下在训练循环中使用的一些概念。完整的优化循环代码可以直接跳到: [完整实现](#完整实现) ## 损失函数 -拿到一些训练数据的时候,我们的模型不太可能给出正确答案。**损失函数**能测量获得的结果相对于目标值的偏离程度,我们希望在训练中能够最小化这个损失函数。我们对给定的数据样本做出预测然后和真实标签数据对比来计算损失。 +拿到一些训练数据的时候,我们的模型不太可能给出正确答案。**损失函数**能衡量获得的结果相对于目标值的偏离程度,我们希望在训练中能够最小化这个损失函数。我们对给定的数据样本做出预测然后和真实标签数据对比来计算损失。 -常见的损失函数包括给回归任务用的 `nn.MSELoss`(Mean Square Error,均方差)、给分类任务使用的 `nn.NLLLoss`(Negative Log Likelihood,负对数似然)、`nn.CrossEntropyLoss`(交叉熵损失函数)结合了 `nn.LogSoftmax` 和 `nn.NLLLoss`. +常见的损失函数包括给回归任务用的 `nn.MSELoss`(Mean Square Error, 均方误差)、给分类任务使用的 `nn.NLLLoss`(Negative Log Likelihood, 负对数似然)、`nn.CrossEntropyLoss`(交叉熵损失函数)结合了 `nn.LogSoftmax` 和 `nn.NLLLoss`. 我们把模型输出的 logits 传递给 `nn.CrossEntropyLoss`, 它会正则化 logits 并计算预测误差。 @@ -160,7 +160,7 @@ optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) 在训练循环内部, 优化在三个步骤上发生: -* 调用 `optimizer.zero_grad()` 来重置模型参数的梯度。梯度会默认累加,为了防止重复计算(梯度),我们在每次遍历中显式的清空(梯度累加值)。 +* 调用 `optimizer.zero_grad()` 来重置模型参数的梯度。梯度会默认累加,为了防止重复计算(梯度),我们在每次迭代中显式的清空(梯度累加值)。 * 调用 `loss.backward()` 来反向传播预测误差。PyTorch 对每个参数分别存储损失梯度。 * 我们获取到梯度后,调用 `optimizer.step()` 来根据反向传播中收集的梯度来调整参数。 diff --git a/docs/2.0/tutorials/beginner/basics/tensors_tutorial.md b/docs/2.0/tutorials/beginner/basics/tensors_tutorial.md index e93c8a3cf..065794b19 100644 --- a/docs/2.0/tutorials/beginner/basics/tensors_tutorial.md +++ b/docs/2.0/tutorials/beginner/basics/tensors_tutorial.md @@ -257,11 +257,13 @@ n: [2. 2. 2. 2. 2.] ```py n = np.ones(5) t = torch.from_numpy(n) +print(f"t: {t}") +print(f"n: {n}") ``` 输出: ```py -t: tensor([2., 2., 2., 2., 2.]) -n: [2. 2. 2. 2. 2.] +t: tensor([1., 1., 1., 1., 1.]) +n: [1. 1. 1. 1. 1.] ``` NumPy 数组中的更改反映到 tensor 中。 ```py