提交 ae8e9769 编写于 作者: W wizardforcel

2021-01-16 17:49:15

上级 6e57b11b
......@@ -22,7 +22,7 @@
“第 3 章”,“使用 DNN 的分类问题”,引入了要使用人工神经网络解决的现实数据问题。 探索了数据集的预处理以及定义和训练模型的过程,并通过使用误差分析提高了模型的准确率。
“第 4 章”,“卷积神经网络”,详细介绍了卷积神经网络。 使用现实生活中的数据问题,您将学习如何构建网络架构并对其进行训练,以及如何通过使用数据扩充和批处理规范化来改善结果。
“第 4 章”,“卷积神经网络”,详细介绍了卷积神经网络。 使用现实生活中的数据问题,您将学习如何构建网络架构并对其进行训练,以及如何通过使用数据扩充和批规范化来改善结果。
“第 5 章”,“样式迁移”,演示了执行样式转移任务的过程,其中将两个图像作为输入来创建新图像,并使用来自两个输入图像的元素。
......
......@@ -405,7 +405,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过
2. **目标特征**:对于受监督的模型,需要标记数据。 考虑到这一点,选择目标特征(我们希望通过构建模型来实现的目标)以评估特征是否具有许多缺失值或离群值非常重要。 此外,这有助于确定开发目标,该目标应与可用数据一致。
3. **Noisy data/outliers**: Noisy data refers to values that are visibly incorrect, for instance, a person who is 200 years old. On the other hand, outliers refer to values that, although they may be correct, are very far from the mean, for instance, a 10-year-old college student.
没有检测异常值的确切科学方法,但是有一些通常被接受的方法。 假设数据集呈正态分布,那么最受欢迎的数据集之一就是确定离平均值约 3-6 标准差的任何值。
没有检测异常值的确切科学方法,但是有一些通常被接受的方法。 假设数据集呈正态分布,那么最受欢迎的数据集之一就是确定离平均值约 3-6 标准差的任何值。
识别异常值的一种同样有效的方法是选择第 99 个百分点和第 1 个百分点的值。
......@@ -542,7 +542,7 @@ EDA 流程很有用,因为它有助于开发人员发现对于定义操作过
图 2.29:数据标准化
* **标准化**:相反,此缩放方法将转换所有值,以使其平均值为 0 且其标准差等于 1。这可使用以下公式完成:
* **标准化**:相反,此缩放方法将转换所有值,以使其平均值为 0 且其标准差等于 1。这可使用以下公式完成:
![Figure 2.30: Data standardization ](img/B15778_02_30.jpg)
......
......@@ -454,7 +454,7 @@ batch_size = 100
接下来,循环的第一个**用于遍历我们之前定义的时期数。**
请记住,**时期**是指整个数据集通过网络架构前后传递的次数。`batch_size`是指单个批量(数据集的一部分)中训练示例的数量。 最后,**迭代**是指完成一个时期所需的批处理数量。
请记住,**时期**是指整个数据集通过网络架构前后传递的次数。`batch_size`是指单个批量(数据集的一部分)中训练示例的数量。 最后,**迭代**是指完成一个时期所需的批数量。
第二个`for`循环遍历总数据集的每个批量,直到完成一个纪元为止。 在此循环中,发生以下计算:
......
......@@ -2,7 +2,7 @@
总览
本章介绍了训练**卷积神经网络****CNN**)的过程-也就是说,发生在不同层的计算通常可以在 CNN 架构中找到,其目的 训练过程。 您将学习如何通过对模型应用数据扩充和批处理规范化来改善计算机视觉模型的性能。 到本章末,您将能够使用 CNN 通过 PyTorch 解决图像分类问题。 这将是在计算机视觉领域实施其他解决方案的起点。
本章介绍了训练**卷积神经网络****CNN**)的过程-也就是说,发生在不同层的计算通常可以在 CNN 架构中找到,其目的 训练过程。 您将学习如何通过对模型应用数据扩充和批规范化来改善计算机视觉模型的性能。 到本章末,您将能够使用 CNN 通过 PyTorch 解决图像分类问题。 这将是在计算机视觉领域实施其他解决方案的起点。
# 简介
......@@ -14,7 +14,7 @@
本章将重点介绍在处理图像时 CNN 优于其他架构的原因,并更详细地说明其架构的组成部分。 它将涵盖用于构建 CNN 来解决图像分类数据问题的主要编码结构。
此外,我们将探讨数据扩充和批处理规范化的概念,这些概念将用于改善模型的性能。 本章的最终目标是比较三种不同方法的结果,以便使用 CNN 解决图像分类问题。
此外,我们将探讨数据扩充和批规范化的概念,这些概念将用于改善模型的性能。 本章的最终目标是比较三种不同方法的结果,以便使用 CNN 解决图像分类问题。
注意
......@@ -510,7 +510,7 @@ train_sampler = SubsetRandomSampler(train_idx)
dev_sampler = SubsetRandomSampler(dev_idx)
```
在前面的代码段中,PyTorch 的`SubsetRandomSampler()`函数用于通过随机采样索引将原始训练集分为训练集和验证集。 在接下来的步骤中将使用它来生成将在每次迭代中馈送到模型中的批处理
在前面的代码段中,PyTorch 的`SubsetRandomSampler()`函数用于通过随机采样索引将原始训练集分为训练集和验证集。 在接下来的步骤中将使用它来生成将在每次迭代中馈送到模型中的批
```py
batch_size = 20
......@@ -524,7 +524,7 @@ test_loader = torch.utils.data.DataLoader(test_data, \
                                          batch_size=batch_size)
```
`DataLoader()`函数用于为每组数据批量加载图像。 首先,将包含集合的变量作为参数传递,然后定义批处理大小。 最后,我们在上一步中创建的采样器用于确保随机创建每次迭代中使用的批量,这有助于提高模型的性能。 此函数的结果变量(`train_loader``dev_loader``test_loader`)将分别包含功能部件和目标的值。
`DataLoader()`函数用于为每组数据批量加载图像。 首先,将包含集合的变量作为参数传递,然后定义批大小。 最后,我们在上一步中创建的采样器用于确保随机创建每次迭代中使用的批量,这有助于提高模型的性能。 此函数的结果变量(`train_loader``dev_loader``test_loader`)将分别包含功能部件和目标的值。
注意
......@@ -719,7 +719,7 @@ test_data = datasets.CIFAR10('data', train=False, download=True, \
我们不应该主要依靠批量归一化来处理过拟合。
如前几节所述,通过减去批量平均值并除以批量标准差,可以对隐藏层的输出进行归一化。
如前几节所述,通过减去批量平均值并除以批量标准差,可以对隐藏层的输出进行归一化。
此外,通常在卷积层以及 FC 层(不包括输出层)上执行批归一化。
......@@ -750,7 +750,7 @@ class CNN(nn.Module):
        return x
```
如我们所见,批处理规范化层的初始定义与`__init__`方法内的其他任何层类似。 接下来,在`forward`方法内的激活函数之后,将每个批处理归一化层应用于其对应层的输出。
如我们所见,批量规范化层的初始定义与`__init__`方法内的其他任何层类似。 接下来,在`forward`方法内的激活函数之后,将每个批量归一化层应用于其对应层的输出。
## 活动 4.03:实现批量标准化
......@@ -792,6 +792,6 @@ class CNN(nn.Module):
通过实施数据扩充,本章的第二个活动旨在解决相同的图像分类问题,目的是比较结果。
最后,本章介绍了批处理规范化的概念。 这包括标准化每个隐藏层的输出,以加快学习速度。 在解释了在 PyTorch 中应用批量归一化的过程之后,本章的最后一个活动旨在使用批量归一化解决相同的图像分类问题。
最后,本章介绍了批规范化的概念。 这包括标准化每个隐藏层的输出,以加快学习速度。 在解释了在 PyTorch 中应用批量归一化的过程之后,本章的最后一个活动旨在使用批量归一化解决相同的图像分类问题。
既然 CNN 的概念已经很清楚并且已经应用​​于解决计算机视觉问题,那么在下一章中,我们将探索 CNN 更加复杂的应用来创建图像,而不仅仅是对其进行分类。
\ No newline at end of file
......@@ -111,7 +111,7 @@ transforms.Compose([transforms.Normalize((-0.5/0.25, \
首先,张量被克隆,附加维被删除。 接下来,定义转换。
要了解恢复归一化的过程,请考虑使用所有尺寸的均值 0.5 和标准差 0.25 进行归一化的图像。 恢复标准化的方法是使用平均值的负值除以标准差作为平均值(-0.5 除以 0.25)。 新的标准偏差应等于一除以标准偏差(1 除以 0.25)。 定义用于加载和显示图像的功能可以帮助节省时间,并确保对内容图像和样式图像执行相同的过程。 在下面的练习中将扩展此过程。
要了解恢复归一化的过程,请考虑使用所有尺寸的均值 0.5 和标准差 0.25 进行归一化的图像。 恢复标准化的方法是使用平均值的负值除以标准差作为平均值(-0.5 除以 0.25)。 新的标准差应等于一除以标准差(1 除以 0.25)。 定义用于加载和显示图像的功能可以帮助节省时间,并确保对内容图像和样式图像执行相同的过程。 在下面的练习中将扩展此过程。
注意
......@@ -160,7 +160,7 @@ transforms.Compose([transforms.Normalize((-0.5/0.25, \
注意
使用规范化图像训练 VGG 网络,其中每个通道的平均值分别为 0.485、0.456 和 0.406,标准差分别为 0.229、0.224 和 0.225。
使用规范化图像训练 VGG 网络,其中每个通道的平均值分别为 0.485、0.456 和 0.406,标准差分别为 0.229、0.224 和 0.225。
3. Define a function that will receive the image path as input and use **PIL** to open the image. Next, it should apply the transformations to the image:
......
......@@ -412,7 +412,7 @@ for c in text:
图 6.21:x 和 y 批量的表示
处理的生成可以通过以下代码片段实现:
的生成可以通过以下代码片段实现:
```py
x = np.array(indexed_data).reshape((2,-1))
......@@ -421,7 +421,7 @@ for b in range(0, x.shape[1], 5):
    print(batch)
```
首先,将数字矩阵划分为多个序列(根据需要)。 接下来,通过`for`循环,可以将已排序的数据划分为指定长度的批处理。 通过打印`batch`变量,可以观察到结果。
首先,将数字矩阵划分为多个序列(根据需要)。 接下来,通过`for`循环,可以将已排序的数据划分为指定长度的批。 通过打印`batch`变量,可以观察到结果。
注意
......@@ -431,7 +431,7 @@ for b in range(0, x.shape[1], 5):
将所有字符转换为数字不足以将其输入模型。 这是因为这种近似会给您的模型带来一些偏差,因为转换为更高数值的字符将被视为更重要。 为避免这种情况,优良作法是将不同批量编码为一热矩阵。 这包括创建一个具有零和一的三维矩阵,其中零表示不存在事件,而一个表示存在事件。 矩阵的最终形状应为`one hot = [number of sequences, sequence length, number of characters]`
这意味着,对于批处理中的每个元素,它将创建一个长度等于整个文本中字符总数的值序列。 对于每个字符,它将放置一个零,但该位置存在一个零(它将放置一个)。
这意味着,对于批中的每个元素,它将创建一个长度等于整个文本中字符总数的值序列。 对于每个字符,它将放置一个零,但该位置存在一个零(它将放置一个)。
注意
......@@ -684,7 +684,7 @@ while starter[-1] != "." and counter < 50:
2. 打开并将*爱丽丝梦游仙境*中的文本读到笔记本中。 打印前 50 个字符和文本文件总长度的摘录。
3. 创建一个变量,该变量包含数据集中未重复字符的列表。 然后,创建一个字典,将每个字符映射到一个整数,其中字符将是键,而整数将是值。
4. 将数据集中的每个字母编码为成对的整数。 打印数据集的前 50 个编码字符和编码版本的总长度。
5. 创建一个接受批处理并将其编码为单热点矩阵的函数。
5. 创建一个接受批并将其编码为单热点矩阵的函数。
6. 创建一个定义网络架构的类。 该类应包含一个用于初始化 LSTM 层状态的附加函数。
7. 请确定要从数据集中创建的批量数量,请记住每个批量应包含 100 个序列,每个批量的长度应为 50。接下来,将编码数据拆分为 100 个序列。
8. 使用 256 作为隐藏单位数(总共两个循环层)实例化模型。
......
......@@ -645,7 +645,7 @@
返回
接下来,定义训练过程的不同参数。 这包括损失函数,优化算法,批处理大小和时期数,如以下代码所示:
接下来,定义训练过程的不同参数。 这包括损失函数,优化算法,批大小和时期数,如以下代码所示:
模型=分类器(X_train.shape [1])
......@@ -2265,7 +2265,7 @@
归还
此函数采用二维矩阵并将其展平。 接下来,它创建一个平坦矩阵的形状和包含字母的字典长度的零填充矩阵(在“步骤 3”中创建)。 接下来,它用一个字符填充对应于批处理中每个字符的字母。 最后,它对矩阵进行整形以使其为三维。
此函数采用二维矩阵并将其展平。 接下来,它创建一个平坦矩阵的形状和包含字母的字典长度的零填充矩阵(在“步骤 3”中创建)。 接下来,它用一个字符填充对应于批中每个字符的字母。 最后,它对矩阵进行整形以使其为三维。
6. Create a class that defines the architecture of the network. This class should contain an additional function that initializes the states of the LSTM layers:
......
......@@ -187,9 +187,9 @@ Logistic 回归是**判别式分类器**的一种形式,在判别式分类器
# 训练程序
在训练架构方面,匹配网络遵循某种技术:它们尝试在训练阶段复制测试条件。 简而言之,正如我们在上一节中所了解的那样,匹配网络从训练数据中采样标签集,然后它们从同一标签集生成支持集和批量集。 数据预处理之后,匹配网络通过训练模型以将支持集作为训练集,并将批处理集作为测试集来最小化错误,从而学习其参数。 通过将支持集作为训练集,将批处理集作为测试集的训练过程,可使匹配的网络复制测试条件。
在训练架构方面,匹配网络遵循某种技术:它们尝试在训练阶段复制测试条件。 简而言之,正如我们在上一节中所了解的那样,匹配网络从训练数据中采样标签集,然后它们从同一标签集生成支持集和批量集。 数据预处理之后,匹配网络通过训练模型以将支持集作为训练集,并将批量集作为测试集来最小化错误,从而学习其参数。 通过将支持集作为训练集,将批量集作为测试集的训练过程,可使匹配的网络复制测试条件。
在下一部分中,我们将介绍匹配网络的架构和算法,并学习如何在模型的训练阶段使用批处理集(即测试集)。
在下一部分中,我们将介绍匹配网络的架构和算法,并学习如何在模型的训练阶段使用批集(即测试集)。
# 建模级别–匹配的网络架构
......@@ -653,7 +653,7 @@ for i in range(0,20):
我们将执行以下步骤:
1. 首先,创建一个可以提供支持集和目标集的批处理
1. 首先,创建一个可以提供支持集和目标集的批
```py
def sample_batch(data):
......
......@@ -108,7 +108,7 @@ GPU 最初是为了有效地渲染图形而创建的,但是由于深度学习
图 2.7 –神经网络中的一遍
但是,在 GPU 上,我们可以同时执行所有这些步骤,这意味着不需要批处理即可在批处理 2 开始之前完成。 我们可以同时计算所有批量的参数更新,然后一次执行所有参数更新(因为结果彼此独立)。 并行方法可以极大地加快机器学习过程:
但是,在 GPU 上,我们可以同时执行所有这些步骤,这意味着不需要批量即可在批量 2 开始之前完成。 我们可以同时计算所有批量的参数更新,然后一次执行所有参数更新(因为结果彼此独立)。 并行方法可以极大地加快机器学习过程:
![Figure 2.8 – Parallel approach to perform passes ](img/B12365_02_8.jpg)
......
......@@ -465,7 +465,7 @@ nn.utils.clip_grad_norm(net.parameters(),剪辑)
Optimizer.step()
在这里,我们只训练了多个时期的模型,对于每个时期,我们首先使用批处理大小参数初始化隐藏层。 在这种情况下,我们设置`batch_size = 1`,因为我们一次只训练我们的模型一个句子。 对于火车装载机中的每批输入语句和标签,我们首先将梯度归零(以防止它们累积),并使用模型的当前状态使用数据的正向传递来计算模型输出。 然后使用此输出,使用模型的预测输出和正确的标签来计算损失。 然后,我们通过网络对该损失进行反向传递,以计算每个阶段的梯度。 接下来,我们使用`grad_clip_norm()`函数裁剪渐变,因为这将阻止渐变爆炸,如本章前面所述。 我们定义了`clip = 5`,这意味着任何给定节点的最大梯度为`5`。 最后,我们通过调用`optimizer.step()`,使用在向后传递中计算出的梯度来更新权重。
在这里,我们只训练了多个时期的模型,对于每个时期,我们首先使用批大小参数初始化隐藏层。 在这种情况下,我们设置`batch_size = 1`,因为我们一次只训练我们的模型一个句子。 对于火车装载机中的每批输入语句和标签,我们首先将梯度归零(以防止它们累积),并使用模型的当前状态使用数据的正向传递来计算模型输出。 然后使用此输出,使用模型的预测输出和正确的标签来计算损失。 然后,我们通过网络对该损失进行反向传递,以计算每个阶段的梯度。 接下来,我们使用`grad_clip_norm()`函数裁剪渐变,因为这将阻止渐变爆炸,如本章前面所述。 我们定义了`clip = 5`,这意味着任何给定节点的最大梯度为`5`。 最后,我们通过调用`optimizer.step()`,使用在向后传递中计算出的梯度来更新权重。
如果我们自己运行此循环,我们将训练我们的模型。 但是,我们想在每个时期之后评估模型的性能,以便根据验证数据集确定模型的性能。 我们这样做如下:
......
......@@ -229,7 +229,7 @@ Questions.vocab.vectors
图 6.14 –张量内容
接下来,我们创建数据迭代器。 我们为训练和验证数据创建单独的迭代器。 我们首先指定一种设备,以便能够使用支持 CUDA 的 GPU 更快地训练模型。 在迭代器中,我们还指定了要由迭代器返回的批处理的大小,在这种情况下为`64`。 您可能希望对模型使用不同批量大小的进行试验,因为这可能会影响训练速度以及模型收敛到其全局最优速度的速度:
接下来,我们创建数据迭代器。 我们为训练和验证数据创建单独的迭代器。 我们首先指定一种设备,以便能够使用支持 CUDA 的 GPU 更快地训练模型。 在迭代器中,我们还指定了要由迭代器返回的批的大小,在这种情况下为`64`。 您可能希望对模型使用不同批量大小的进行试验,因为这可能会影响训练速度以及模型收敛到其全局最优速度的速度:
device = torch.device(如果 torch.cuda.is_available()则为“ cuda”,否则为“ cpu”)
......@@ -403,7 +403,7 @@ model.train()
接下来,我们遍历迭代器中的每批数据并执行训练步骤。 我们首先将梯度归零,以防止从上一批中计算出累积梯度。 然后,我们使用模型的当前状态根据当前批量中的句子进行预测,然后将其与标签进行比较以计算损失。 使用我们在上一节中定义的精度函数,我们可以计算给定批量的精度。 然后,我们反向传播损失,通过梯度下降更新权重并逐步通过优化器:
对于迭代器中的批处理
对于迭代器中的批
Optimizer.zero_grad()
......
......@@ -448,7 +448,7 @@ pred = self.fc_out(output.squeeze(0))
4. We then loop through each batch within our training iterator and extract the sentence to be translated (**src**) and the correct translation of this sentence (**trg**). We then zero our gradients (to prevent gradient accumulation) and calculate the output of our model by passing our model function our inputs and outputs:
对于我,在枚举(迭代器)中进行批处理
对于我,在枚举(迭代器)中进行批
src = batch.src
......
......@@ -407,7 +407,7 @@ corpus_name = "movie_corpus"
## 将句子对转换为张量
我们知道我们的模型不会将原始文本作为输入,而是将句子的张量表示作为输入。 我们也不会一一处理句子,而是分批处理。 为此,我们需要将输入和输出语句都转换为张量,其中张量的宽度表示我们希望在其上训练的批处理的大小:
我们知道我们的模型不会将原始文本作为输入,而是将句子的张量表示作为输入。 我们也不会一一处理句子,而是分批量。 为此,我们需要将输入和输出语句都转换为张量,其中张量的宽度表示我们希望在其上训练的批量的大小:
1. We start by creating several helper functions, which we can use to transform our pairs into tensors. We first create a **indexFromSentence** function, which grabs the index of each word in the sentence from the vocabulary and appends an EOS token to the end:
......@@ -495,7 +495,7 @@ corpus_name = "movie_corpus"
output_batch = []
对于批处理 p:
对于批 p:
input_batch.append(p [0])
......@@ -503,7 +503,7 @@ corpus_name = "movie_corpus"
inp,长度= inputVar(input_batch,voc)
输出,掩码,max_target_len = outputVar(输出批处理,voc)
输出,掩码,max_target_len = outputVar(输出批,voc)
返回 inp,长度,输出,掩码,max_target_len
......
......@@ -134,7 +134,7 @@ pip install torchvision
# 这个怎么运作...
在本食谱中,我们开始使用`torchvision``torchvision`中有实用程序来支持与视觉有关的任务。 有一个名为`transforms`的模块可以帮助完成许多图像预处理任务。 对于我们正在处理的特殊情况,一个由 28 x 28 灰度像素组成的图像,我们首先需要从图像中读取并使用`transforms.ToTensor()`变换将其转换为张量。 然后,我们分别将像素值的平均值和标准差设为 0.5 和 0.5,以便模型更易于训练; 为此,我们使用`transforms.Normalize((0.5,),(0.5,))`。 我们将所有转换与`transform.Compose()`结合在一起。
在本食谱中,我们开始使用`torchvision``torchvision`中有实用程序来支持与视觉有关的任务。 有一个名为`transforms`的模块可以帮助完成许多图像预处理任务。 对于我们正在处理的特殊情况,一个由 28 x 28 灰度像素组成的图像,我们首先需要从图像中读取并使用`transforms.ToTensor()`变换将其转换为张量。 然后,我们分别将像素值的平均值和标准差设为 0.5 和 0.5,以便模型更易于训练; 为此,我们使用`transforms.Normalize((0.5,),(0.5,))`。 我们将所有转换与`transform.Compose()`结合在一起。
准备好转换后,我们定义了合适的批量大小。 较高的批量大小意味着该模型具有较少的训练步骤并且学习速度更快,而较高的批量大小会导致对内存的高要求。
......
......@@ -680,7 +680,7 @@ CNN(
对于第一个全连接层,我们有 1,024 个输入(通过将最大池后的`64 x 4 x 4`张量展平而获得)和 512 个输出。 对于最后一个全连接层,我们有 512 个输入和 10 个输出,代表输出类别的数量。 我们还为全连接层定义了一个辍学层,概率为 0.3。
接下来,我们定义`forward()`方法,将`__init__()`方法中定义的组件连接在一起。 因此,输入批处理的 16 个张量(每个张量为 32 x 32 x 3)经过第一个卷积层,然后经过 ReLU,然后是最大合并层,以形成尺寸为 16 x 16 的输出张量。 x 16,然后通过第二个卷积层,然后是 ReLU 和最大池层,输出的尺寸为 8 x 8 x 32,然后是第三个卷积层,然后是 ReLU 和最大池 层,尺寸为 4 x 4 x64。此后,我们将图像展平为 1,024 个元素的向量,并将其通过辍学层传递到第一个全连接层,提供 512 个输出,然后是 ReLU 和 在最后一个全连接层中删除,以提供所需的输出数量,本例中为 10。
接下来,我们定义`forward()`方法,将`__init__()`方法中定义的组件连接在一起。 因此,输入批的 16 个张量(每个张量为 32 x 32 x 3)经过第一个卷积层,然后经过 ReLU,然后是最大合并层,以形成尺寸为 16 x 16 的输出张量。 x 16,然后通过第二个卷积层,然后是 ReLU 和最大池层,输出的尺寸为 8 x 8 x 32,然后是第三个卷积层,然后是 ReLU 和最大池 层,尺寸为 4 x 4 x64。此后,我们将图像展平为 1,024 个元素的向量,并将其通过辍学层传递到第一个全连接层,提供 512 个输出,然后是 ReLU 和 在最后一个全连接层中删除,以提供所需的输出数量,本例中为 10。
然后,我们从 CNN 类实例化该模型并打印该模型。
......@@ -787,7 +787,7 @@ optimizer.step()
train_loss += loss.item()*data.size(0)
```
14.然后,我们将模型切换到评估模式,退出训练批处理循环:
14.然后,我们将模型切换到评估模式,退出训练批循环:
```py
model.eval()
......
......@@ -170,7 +170,7 @@ pip install torchtext
对于数字字段,我们将`use_vocab`设置为`False`,这是我们为审阅标签所做的,因为我们假设标签的负数值为`0`,正数的值为`1`。 我们从标记化部分传递了`tokenizer`函数作为`tokenize`参数; 我们甚至可以通过设置`tokenize="spacy"`使用 spacy 的标记器。 对于某些任务,例如,使用`Sequence`对模型进行排序,我们可能需要特殊的标记来指示序列的开始和结束。 可以通过设置`init_token``eos_token`参数轻松完成。 这对于序列到序列的模型是正确的,并且如果在模型评估期间用于训练模型的词汇表中不存在令牌(词汇表外),则可以使用自定义令牌来替换这些令牌, 设置`unk_token`参数。
然后,将`batch_first`设置为`True`,以使输出张量的第一维为批处理维,如果`fix_length`参数设置为整​​数值,则将对输入设置固定长度 使用此字段。
然后,将`batch_first`设置为`True`,以使输出张量的第一维为批维,如果`fix_length`参数设置为整​​数值,则将对输入设置固定长度 使用此字段。
# 还有更多...
......@@ -309,9 +309,9 @@ pip install torchtext
# 这个怎么运作...
我们使用迭代器来构建训练,测试和验证批处理,并将数据集移动到适当的 CPU 或 GPU 设备中。 `Iterators`使执行这些任务变得非常优雅。 我们使用了称为`BucketIterator`的专门迭代器类,该类将输入序列分组为相似长度的序列,并自动对其进行随机排序。 我们定义了批量大小,并找到了机器上可用的设备。
我们使用迭代器来构建训练,测试和验证批,并将数据集移动到适当的 CPU 或 GPU 设备中。 `Iterators`使执行这些任务变得非常优雅。 我们使用了称为`BucketIterator`的专门迭代器类,该类将输入序列分组为相似长度的序列,并自动对其进行随机排序。 我们定义了批量大小,并找到了机器上可用的设备。
然后,我们使用`BucketIterator``splits`方法创建训练,测试和验证迭代器。 我们将`sort_within_batch`参数设置为`False`,如果使用`pack_padded_sequence`则将其设置为`True`,这将阻止 LSTM 看到输入序列的填充部分。 当`True`使用`sort_key`参数时,它将按降序对批处理中的序列进行排序。
然后,我们使用`BucketIterator``splits`方法创建训练,测试和验证迭代器。 我们将`sort_within_batch`参数设置为`False`,如果使用`pack_padded_sequence`则将其设置为`True`,这将阻止 LSTM 看到输入序列的填充部分。 当`True`使用`sort_key`参数时,它将按降序对批中的序列进行排序。
# 还有更多...
......
......@@ -288,7 +288,7 @@ return model
}
```
2. 然后,我们将定义图像路径,批处理大小,日志路径和保存模型的路径:
2. 然后,我们将定义图像路径,批大小,日志路径和保存模型的路径:
```py
>>datadir = '../input/chest-xray-pneumonia/chest_xray/chest_xray/'
......@@ -333,7 +333,7 @@ return model
# 这个怎么运作...
在此配方中,我们定义了训练,验证和测试数据集中图像所需的转换。 根据数据集选择变换,并且归一化变换中的值来自 ImageNet 统计信息。 然后,我们定义了数据集路径,模型名称,批处理大小和日志目录。 然后,我们使用`datasets.ImageFolder()`方法根据文件夹名称加载数据,并为每个数据集创建一个迭代器。
在此配方中,我们定义了训练,验证和测试数据集中图像所需的转换。 根据数据集选择变换,并且归一化变换中的值来自 ImageNet 统计信息。 然后,我们定义了数据集路径,模型名称,批大小和日志目录。 然后,我们使用`datasets.ImageFolder()`方法根据文件夹名称加载数据,并为每个数据集创建一个迭代器。
请注意,我们翻转了验证数据集和测试数据集目录。 这是因为给定数据集的验证数据集确实很小,因此我们将测试数据集用于验证数据集。
......
# 探索生成对抗网络
**生成对抗网络****GAN**)是一种机器学习技术,其中同时训练两种模型:一种专门用于创建伪造数据,另一种专门用于区分伪造数据和伪造数据。 真实数据。 术语*生成的*反映了以下事实:这些神经网络用于创建新数据,而术语*对抗性*来自以下事实:两个模型相互竞争,从而提高了质量 生成的数据。
**生成对抗网络****GAN**)是一种机器学习技术,其中同时训练两种模型:一种专门用于创建伪造数据,另一种专门用于区分伪造数据和伪造数据。 真实数据。 术语*生成*反映了以下事实:这些神经网络用于创建新数据,而术语*对抗*来自以下事实:两个模型相互竞争,从而提高了质量 生成的数据。
GAN 中的两个模型称为生成器和鉴别器,其中生成器负责创建数据,鉴别器接收数据并将其分类为真实数据或由生成器生成。 生成器的目标是创建与训练集中的真实数据没有区别的数据样本。
......@@ -16,7 +16,7 @@ GAN 中的两个模型称为生成器和鉴别器,其中生成器负责创建
![](img/13480561-764e-43be-b39a-07d7656540db.png)
在此图中,有一个数据源,其中包含训练图像`x`,生成器必须捕获其属性并重新创建。 生成器接收随机向量`z`,该向量充当生成器创建伪图像的种子。 生成器获取种子并生成 *x <sup>*</sup>* 图像,鉴别器从真实和虚假图像中获取图像,并输出给定​​输入为真实的概率(假设 图像用 1 表示,伪图像用 0 表示)。 然后,我们获得分类误差,并使用它来迭代训练鉴别器和生成器。 鉴别器的目的是使分类误差最小,而发生器的目的是使分类误差最大化。
在此图中,有一个数据源,其中包含训练图像`x`,生成器必须捕获其属性并重新创建。 生成器接收随机向量`z`,该向量充当生成器创建伪图像的种子。 生成器获取种子并生成`x*`图像,鉴别器从真实和虚假图像中获取图像,并输出给定​​输入为真实的概率(假设 图像用 1 表示,伪图像用 0 表示)。 然后,我们获得分类误差,并使用它来迭代训练鉴别器和生成器。 鉴别器的目的是使分类误差最小,而发生器的目的是使分类误差最大化。
从理论上讲,生成器和判别器达到平衡,其中生成器已捕获了生成的伪图像中真实图像的所有特征,而从进一步的训练中没有任何收获。 类似地,鉴别者只能以 50% 的概率猜测图像是伪造的还是真实的,因为这两个图像就其性质而言完全无法区分。 在那个状态下,GAN 已经收敛。 然而,实际上,这种状态很难实现。 在本章中,我们将探讨 GAN 的概念以及 PyTorch 中各种 GAN 的实现。
......@@ -34,7 +34,7 @@ GAN 中的两个模型称为生成器和鉴别器,其中生成器负责创建
# 创建一个 DCGAN 生成器
在本食谱及其后续食谱中,我们将实现 DCGAN。 DCGAN 代表“深度卷积 GAN”; 与香草 GAN 相比,它们有很大的改进。 在 DCGAN 中,我们使用卷积神经网络,而不是香草 GAN 中的全连接网络。 在第 3 章,“用于计算机视觉的卷积神经网络”中,我们看到了第 2 章*的全连接分类器如何处理神经网络* ,是该领域的一项改进; DCGAN 与香草 GAN 的情况相同。 在 DCGAN 中,我们将使用批量归一化,这是一种技术,它可以将作为输入输入到下一层的层的输出归一化。 批量归一化允许网络的每一层独立于其他层进行学习,从而减少了协变量偏移。
在本食谱及其后续食谱中,我们将实现 DCGAN。 DCGAN 代表“深度卷积 GAN”; 与香草 GAN 相比,它们有很大的改进。 在 DCGAN 中,我们使用卷积神经网络,而不是香草 GAN 中的全连接网络。 在第 3 章,“用于计算机视觉的卷积神经网络”中,我们看到了第 2 章“处理神经网络”中全连接分类器是什么样,是该领域的一项改进; DCGAN 与香草 GAN 的情况相同。 在 DCGAN 中,我们将使用批量归一化,这是一种技术,它可以将作为输入输入到下一层的层的输出归一化。 批量归一化允许网络的每一层独立于其他层进行学习,从而减少了协变量偏移。
批量归一化是通过缩放来实现的,以使平均值为 0,方差为 1。在此配方中,我们将生成类似于 MNIST 数据集的手写数字,其中包含来自噪声向量的数据。 我们将扩展此噪声向量,将其转换为 2D 矩阵,最后将其转换为 28 x 28 黑白图像。 为了增加高度和宽度,我们必须执行与卷积操作相反的操作,这称为反卷积。 我们将在使用卷积执行分类任务时执行此操作。 在执行反卷积时,我们将增加高度和宽度,同时减少通道数。
......@@ -42,7 +42,7 @@ GAN 中的两个模型称为生成器和鉴别器,其中生成器负责创建
![](img/89189246-b3a7-49dc-acc5-78bc00c5f9b7.png)
请注意,我们将使用第 3 章,“用于计算机视觉的卷积神经网络” *和*中的概念,因此再次阅读这些食谱将非常有用。
请注意,我们将使用第 3 章,“用于计算机视觉的卷积神经网络”中的概念,因此再次阅读这些食谱将非常有用。
# 怎么做...
......@@ -116,7 +116,7 @@ def forward(self, input):
在此食谱中,我们进行了变换以将图像转换为张量并对其进行归一化,就像在第 3 章,“用于计算机视觉的卷积神经网络”中所做的一样。 然后,我们确定了机器上的设备:CPU 或 GPU。 然后,我们定义了从`nn.Module`类继承的`Generator_model`类,就像在所有以前的架构中所做的一样。
在构造函数中,我们传递了`z_dim`参数,这是我们的噪声向量大小。 然后,我们定义了一个全连接单元`self.fc`,我们将噪声向量传递给该单元,并为其提供了`256 * 7 * 7`输出。 然后,我们定义了一个称为`self.gen``nn.Sequential`单元,其中包含用于定义生成器的关键组件。 我们使用 PyTorch 中提供的`nn.ConvTranspose2d``nn.BatchNorm2d``nn.LeakyReLU`使用一组反卷积,批处理规范化和激活层。 `ConvTranspose2d`接受输入通道,输出通道,内核大小,步幅和填充等参数。 `BatchNorm2d`接受上一层的要素/通道数作为其参数,而 LeakyReLU 接受负斜率的角度。
在构造函数中,我们传递了`z_dim`参数,这是我们的噪声向量大小。 然后,我们定义了一个全连接单元`self.fc`,我们将噪声向量传递给该单元,并为其提供了`256 * 7 * 7`输出。 然后,我们定义了一个称为`self.gen``nn.Sequential`单元,其中包含用于定义生成器的关键组件。 我们使用 PyTorch 中提供的`nn.ConvTranspose2d``nn.BatchNorm2d``nn.LeakyReLU`使用一组反卷积,批规范化和激活层。 `ConvTranspose2d`接受输入通道,输出通道,内核大小,步幅和填充等参数。 `BatchNorm2d`接受上一层的要素/通道数作为其参数,而 LeakyReLU 接受负斜率的角度。
与 ReLU 不同,LeakyReLU 允许传递小的梯度信号以获取负值。 它使来自鉴别器的梯度流入发生器。 我们在输出层中使用了 tanh 激活,但是从 DCGAN 论文中我们观察到,使用有界激活可以使模型学会快速饱和并覆盖训练分布的色彩空间。 tanh 的对称性在这里可能是一个优势,因为网络应该以对称方式处理较深的颜色和较浅的颜色。
......@@ -195,7 +195,7 @@ def forward(self, input):
# 这个怎么运作...
在本食谱中,我们定义了一个分类器; 使用`nn.Sequential()`定义卷积,激活和批处理规范化单元的数组; 并且还定义了最后一个全连接层,该层采用平坦的张量并给出通过 S 形层的单个输出。 由于只有两个类,因此我们最后使用了 S 形层。 输入是尺寸为`1 x 28 x 28`的图像张量,并经过第一卷积单元以给出尺寸为`32 x 14 x 14`的输出张量。 第二个卷积层使它成为`64 x 7 x 7`张量,然后从那里变成`128 x 4 x 4`。 之后,我们将拉平并使张量穿过全连接层。
在本食谱中,我们定义了一个分类器; 使用`nn.Sequential()`定义卷积,激活和批规范化单元的数组; 并且还定义了最后一个全连接层,该层采用平坦的张量并给出通过 S 形层的单个输出。 由于只有两个类,因此我们最后使用了 S 形层。 输入是尺寸为`1 x 28 x 28`的图像张量,并经过第一卷积单元以给出尺寸为`32 x 14 x 14`的输出张量。 第二个卷积层使它成为`64 x 7 x 7`张量,然后从那里变成`128 x 4 x 4`。 之后,我们将拉平并使张量穿过全连接层。
# 也可以看看
......@@ -203,7 +203,7 @@ def forward(self, input):
# 训练 DCGAN 模型
我们在前两个配方中定义了生成器,即*创建 DCGan 生成器**创建 DCGAN 鉴别器*。 在本食谱中,我们将继续训练 GAN 模型。 请记住,生成器的目标是创建与数据集尽可能相似的图像,而鉴别器的目标是区分真实图像和生成的图像。 从理论上讲,生成器将捕获数据集中图像的所有特征,并且无法学习更多信息,而鉴别器只能猜测图像是真实的还是生成的。 在本食谱中,我们将通过整合到目前为止已经创建的生成器和鉴别器来完成 DCGANs 模型的训练。
我们在前两个配方中定义了生成器,即“创建 DCGan 生成器”和“创建 DCGAN 鉴别器”。 在本食谱中,我们将继续训练 GAN 模型。 请记住,生成器的目标是创建与数据集尽可能相似的图像,而鉴别器的目标是区分真实图像和生成的图像。 从理论上讲,生成器将捕获数据集中图像的所有特征,并且无法学习更多信息,而鉴别器只能猜测图像是真实的还是生成的。 在本食谱中,我们将通过整合到目前为止已经创建的生成器和鉴别器来完成 DCGANs 模型的训练。
# 准备好
......@@ -541,13 +541,13 @@ Epoch : | 005 / 050 |
# 这个怎么运作...
我们从`weights_init`函数开始,该函数用于从均值 0 和标准差 0.02 的正态分布中随机初始化所有权重。 初始化模型后,函数将模型作为输入,并重新初始化所有卷积,卷积转置和批归一化层。
我们从`weights_init`函数开始,该函数用于从均值 0 和标准差 0.02 的正态分布中随机初始化所有权重。 初始化模型后,函数将模型作为输入,并重新初始化所有卷积,卷积转置和批归一化层。
然后,我们使用`torchsummary`库打印模型的摘要; 为此,我们将模型与输入维一起传递。 方便地查看我们所有的输出尺寸是否正确,并检查每一层中参数的数量和大小。 接下来,我们定义损失函数,并使用二进制交叉熵损失,因为只有一个输出具有两个可能的状态,分别表示图像是真实的 1 还是伪造的 0。
我们还创建了固定噪声,用于可视化 GAN 模型在迭代过程中的改进。 我们使用 ADAM 优化器分别更新了生成器和鉴别器`goptimizer`和`doptimizer`的权重。 然后,我们进行了准备以存储一些模型指标,以查看模型在迭代过程中的变化,然后开始训练循环。
我们遍历了每个迷你批量并开始训练鉴别器。 我们仅从 MNIST 数据集中获取图像,然后使用`real_images = data[0].to(device)`将其移动到设备中; 由于图像全部来自 MNIST 数据集,因此我们知道它们是真实的,因此我们创建了与小批量相同大小的标签向量,并用真实图像标签 1 进行填充。然后,将这些真实图像传递到 预测的鉴别符,然后使用此预测从准则中得出误差`derror_real`并计算梯度。 然后,我们创建了相等数量的噪声向量,并将它们传递给生成器以生成图像,然后将这些生成的图像传递给鉴别器以获取预测,然后从准则`derror_fake`中获取误差。 然后,我们再次进行此操作以计算和累积梯度。 然后,我们从真实图像和伪图像中获得了误差之和,以得出总的鉴别器误差,并更新鉴别器的权重。
我们遍历了每个批量并开始训练鉴别器。 我们仅从 MNIST 数据集中获取图像,然后使用`real_images = data[0].to(device)`将其移动到设备中; 由于图像全部来自 MNIST 数据集,因此我们知道它们是真实的,因此我们创建了与小批量相同大小的标签向量,并用真实图像标签 1 进行填充。然后,将这些真实图像传递到 预测的鉴别符,然后使用此预测从准则中得出误差`derror_real`并计算梯度。 然后,我们创建了相等数量的噪声向量,并将它们传递给生成器以生成图像,然后将这些生成的图像传递给鉴别器以获取预测,然后从准则`derror_fake`中获取误差。 然后,我们再次进行此操作以计算和累积梯度。 然后,我们从真实图像和伪图像中获得了误差之和,以得出总的鉴别器误差,并更新鉴别器的权重。
然后,我们开始训练生成器,并且生成器应该能够欺骗鉴别器。 生成器必须纠正鉴别者正确预测生成的图像为假的情况。 因此,只要来自鉴别器的预测将生成的图像标记为伪造,就会增加生成器损耗`gerror`。 然后,我们计算梯度并更新发生器权重。
......@@ -565,7 +565,7 @@ Epoch : | 005 / 050 |
以前我们已经看到,使用 GAN,生成器和鉴别器相互竞争,并且这样做可以产生越来越好的图像。 但是,从理论上讲,它们达到了生成器已捕获真实图像的所有特征的程度,并且生成器无法学习。 同样,鉴别者只能猜测给定图像是真实的还是伪造的,成功机会为 50/50。 在这一点上,据说 GAN 已经收敛。
现在,任何方面的改善都会导致另一面的结果降低,这是**零和**状态或 **Nash 平衡**; 但是在实践中很难实现,因为生成器和鉴别器都在不断变化,因此检查 GAN 性能的最佳方法是通过图形和图表。 在本食谱中,我们将快速了解可视化。
现在,任何方面的改善都会导致另一面的结果降低,这是**零和**状态或**纳什平衡**; 但是在实践中很难实现,因为生成器和鉴别器都在不断变化,因此检查 GAN 性能的最佳方法是通过图形和图表。 在本食谱中,我们将快速了解可视化。
# 准备好
......@@ -642,7 +642,7 @@ pip install numpy
# 这个怎么运作...
在本食谱中,我们使用 matplotlib 绘制图形和图像。 我们使用`figure()`和`title()`方法设置图形尺寸和标题,然后使用`plot()`方法绘制发生器和鉴别器损耗。 我们还使用`xlabel`和`ylabel`方法添加了`x`和*和*标签。 我们还使用`legend()`方法为图添加了图例,最后使用`show()`方法显示了图。
在本食谱中,我们使用 matplotlib 绘制图形和图像。 我们使用`figure()`和`title()`方法设置图形尺寸和标题,然后使用`plot()`方法绘制发生器和鉴别器损耗。 我们还使用`xlabel`和`ylabel`方法添加了`x`和`y`标签。 我们还使用`legend()`方法为图添加了图例,最后使用`show()`方法显示了图。
我们遍历训练期间保存在`image_list`中的图像,并使用 NumPy 的`transpose()`方法以所需顺序固定图像的尺寸。 `image_list`中的图像是使用`torchvision.util.make_grid()`方法生成的,我们根据噪声向量创建了生成图像的网格。
......@@ -666,10 +666,10 @@ pip install numpy
PGGAN 的关键创新可以总结如下:
* **在高分辨率层中逐渐增长并逐渐淡入淡出**:它从低分辨率卷积变为高分辨率卷积,而不是立即跳变分辨率,而是通过参数平滑地淡化了具有更高分辨率的 nedonew 层 alpha(α)(介于 0 和 1 之间)的大小,用于控制我们使用旧的还是放大的较大输出。
* **迷你批处理标准偏差**:我们计算鉴别符的统计信息,即生成器生成或来自真实数据的迷你批处理中所有像素的标准偏差。 现在,判别器需要了解,如果要评估的批量中图像的标准偏差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗鉴别器。
* **均衡的学习率**:所有权重(`w`)被归一化( *w'*)在某个范围内,以便 *w'* =`w`/`c`的常数`c`对于每一层来说都是不同的,具体取决于重量矩阵的形状。
* **逐像素特征归一化**:对每个像素中的特征向量进行归一化,因为批处理规范最适合大型微型批处理,并且占用大量内存。
* **高分辨率层中的逐渐增长和平滑淡化**:它从低分辨率卷积变为高分辨率卷积,而不是立即跳变分辨率,而是通过参数平滑地淡化了具有更高分辨率的 nedonew 层 alpha(α)(介于 0 和 1 之间)的大小,用于控制我们使用旧的还是放大的较大输出。
* **小批量标准差**:我们计算鉴别符的统计信息,即生成器生成或来自真实数据的小批量中所有像素的标准差。 现在,判别器需要了解,如果要评估的批量中图像的标准差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗鉴别器。
* **均衡的学习率**:所有权重(`w`)被归一化(`w'`)在某个范围内,以便`w' = w / c`的常数`c`对于每一层来说都是不同的,具体取决于重量矩阵的形状。
* **逐像素特征归一化**:对每个像素中的特征向量进行归一化,因为批量规范最适合大型微型批量,并且占用大量内存。
Nvidia 最初执行 PGGAN 的过程要花一到两个月的时间。 但是,为了让我们看到 PGGAN 的性能,我们将使用 PyTorch 集线器,它是使用 PyTorch 构建的预训练模型的存储库。
......
......@@ -279,7 +279,7 @@ self.explore_limit = False
batch = random.sample(self.memory, BATCH_SIZE)
```
10. 现在,让我们使用批处理更新 q 值:
10. 现在,让我们使用批更新 q 值:
```py
for state, action, reward, next_state, terminal in batch:
......@@ -318,7 +318,7 @@ if not self.explore_limit:
`load_memory()`方法中,我们从环境中存储了状态,操作,奖励,下一个状态和终端,以用于训练网络。 我们使用的下一个方法是`predict_action`。 在此方法中,我们使用`np.random.rand()`选择了`random_number`,这为我们提供了`[0,1)`的值。 如果此`random_number`小于当前的`exploration_rate`,则我们选择一个随机动作,该动作由`exploration_rate`控制。 这就是我们合并探索的方式。 但是,如果`random_number`大于`exploration_rate`,则`target_net`会预测`q_values`并选择具有最大 q 值的动作。
最后,我们实现了`experience_replay`方法。 在这里,我们等待数据点的数量至少为`BATCH_SIZE`,然后从内存中随机抽样一批。 这使它可以从一系列不同的观察中学习,而不是从一系列紧密相关的观察中学习。 遍历批处理时,我们使用`target_net`根据 q 值更新公式更新了 q 值。 然后,我们根据新 q 值与`policy_net`预测的 q 值之间的误差训练了`policy_net`。 之后,通过将其乘以勘探衰减量逐渐降低勘探速率,直到获得最低勘探速率。 我们这样做是因为,在训练的初始阶段,我们希望代理人进行更多探索; 但是,随着训练的进行,我们希望算法能够收敛。 至此,我们已经完成了 DQN 类的所有功能。
最后,我们实现了`experience_replay`方法。 在这里,我们等待数据点的数量至少为`BATCH_SIZE`,然后从内存中随机抽样一批。 这使它可以从一系列不同的观察中学习,而不是从一系列紧密相关的观察中学习。 遍历批时,我们使用`target_net`根据 q 值更新公式更新了 q 值。 然后,我们根据新 q 值与`policy_net`预测的 q 值之间的误差训练了`policy_net`。 之后,通过将其乘以勘探衰减量逐渐降低勘探速率,直到获得最低勘探速率。 我们这样做是因为,在训练的初始阶段,我们希望代理人进行更多探索; 但是,随着训练的进行,我们希望算法能够收敛。 至此,我们已经完成了 DQN 类的所有功能。
# 还有更多...
......
......@@ -458,7 +458,7 @@ tensor([[0.5594, 0.8875, 0.9234, 1.1294],
`split``chunk`是用于拆分张量的类似操作。 `split`接受每个输出张量要的大小。 例如,如果要在第 0 个维度上拆分大小为 3 x 2 的张量,尺寸为 1,则将得到三个大小均为 1 x 2 的张量。但是,如果在第 0 个维度上使用 2 作为大小,则将 会得到 2 x 2 的张量和另一个 1 x 2 的张量。
`squeeze`功能有时可以节省您的时间。 在某些情况下,您将具有一个或多个尺寸为 1 的张量。有时,您的张量中不需要那些多余的尺寸。 这就是`squeeze`将为您提供帮助的地方。 `squeeze`删除值为 1 的维。例如,如果您正在处理句子,并且有 10 个句子的批处理,每个句子包含 5 个单词,则将其映射到张量对象时,将得到 10 x 的张量 5.然后,您意识到必须将其转换为一热向量,以便神经网络进行处理。
`squeeze`功能有时可以节省您的时间。 在某些情况下,您将具有一个或多个尺寸为 1 的张量。有时,您的张量中不需要那些多余的尺寸。 这就是`squeeze`将为您提供帮助的地方。 `squeeze`删除值为 1 的维。例如,如果您正在处理句子,并且有 10 个句子的批,每个句子包含 5 个单词,则将其映射到张量对象时,将得到 10 x 的张量 5.然后,您意识到必须将其转换为一热向量,以便神经网络进行处理。
您可以使用大小为 100 的单热点编码向量为张量添加另一个维度(因为词汇量为 100 个单词)。 现在,您有了一个尺寸为 10 x 5 x 100 的张量对象,并且每个批量和每个句子一次传递一个单词。
......
......@@ -67,7 +67,7 @@ def get_numpy_data(input_size=10, limit=1000):
* 我们将输入转换为 10 位二进制数,因此我们的第一个输入层需要 10 个神经元才能接受这 10 位数字。
* 由于我们的输出始终是大小为 4 的向量,因此我们需要有四个输出神经元。
* 看来我们要解决的问题很简单:比较深度学习在当今世界中产生的虚构冲动。 首先,我们可以有一个大小为 100 的隐藏层。
* 由于在处理之前批处理数据总是更好,为了获得良好的结果,我们将对输入的批处理添加 64 个数据点。 请查看本章末尾的*查找错误*部分,以了解批处理为什么更好。
* 由于在处理之前批量数据总是更好,为了获得良好的结果,我们将对输入的批量添加 64 个数据点。 请查看本章末尾的*查找错误*部分,以了解批量为什么更好。
让我们定义超参数并调用我们先前定义的函数以获取训练和测试数据。 我们将为各种神经网络模型定义五个典型的超参数:
......@@ -222,7 +222,7 @@ for epoch in range(epochs):
b2 -= lr * b2.grad
```
前面的代码段与在第 1 章,*深度学习演练和 PyTorch 简介*中看到的相同,其中解释了静态和动态计算图,但在这里我们来看一下 从另一个角度看代码:模型说明。 它从循环遍历每个时期的批处理开始,并使用我们正在构建的模型处理每个批处理。 与基于静态计算图的框架不同,我们尚未构建图。 我们刚刚定义了超参数,并根据我们的数据制作了张量。
前面的代码段与在第 1 章,*深度学习演练和 PyTorch 简介*中看到的相同,其中解释了静态和动态计算图,但在这里我们来看一下 从另一个角度看代码:模型说明。 它从循环遍历每个时期的批量开始,并使用我们正在构建的模型处理每个批量。 与基于静态计算图的框架不同,我们尚未构建图。 我们刚刚定义了超参数,并根据我们的数据制作了张量。
##### 建立图表
......@@ -245,7 +245,7 @@ print(a2.grad, a2.grad_fn, a2)
##### 查找错误
是时候找出了,我们的模型在 Fizz 嗡嗡声中的预测效果如何。 我们使用最基本的回归损失,称为**均方误差****MSE**)。 最初,我们发现批处理中每个元素的预测与输出之间的差异(还记得我们为每个输入数据点创建的大小为 4 的向量吗?)。 然后我们对所有差异求平方,并将所有差异求和在一起,以获得一个单一值。 如果您不熟悉损失函数,则不必担心被 2.0 除。 这样做是为了使数学在进行反向传播时保持整洁。
是时候找出了,我们的模型在 Fizz 嗡嗡声中的预测效果如何。 我们使用最基本的回归损失,称为**均方误差****MSE**)。 最初,我们发现批中每个元素的预测与输出之间的差异(还记得我们为每个输入数据点创建的大小为 4 的向量吗?)。 然后我们对所有差异求平方,并将所有差异求和在一起,以获得一个单一值。 如果您不熟悉损失函数,则不必担心被 2.0 除。 这样做是为了使数学在进行反向传播时保持整洁。
##### 反向传播
......@@ -296,7 +296,7 @@ SGD 的主要缺点是效率低下。 例如,考虑我们的 *FizzBu​​zz*
批量梯度下降的另一个主要缺点是其内存消耗。 由于整个批量都在一起处理,因此应将庞大的数据集加载到 RAM 或 GPU 内存中,这在大多数情况下我们尝试训练数百万个样本时不切实际。 下一个变体是前面两种方法的混合,称为“小批量梯度下降”(尽管顾名思义是“小批量梯度下降”,但人们通常会使用 SGD 来指代)。
除了我们刚才介绍的新超参数,学习率和批量大小以外,其他所有内容均保持不变。 我们用学习率乘以`.grad`属性来更新`.data`属性,并针对每次迭代进行此操作。 选择批处理大小几乎总是取决于内存的可用性。 我们尝试使迷你批处理尽可能大,以便可以将其放置在 GPU 内存中。 将整个批量划分为小批量,以确保每次梯度更新都会产生足够的抽动,从而在使用 GPU 提供的全部功能的同时,将模型从局部最小值中剔除。
除了我们刚才介绍的新超参数,学习率和批量大小以外,其他所有内容均保持不变。 我们用学习率乘以`.grad`属性来更新`.data`属性,并针对每次迭代进行此操作。 选择批量大小几乎总是取决于内存的可用性。 我们尝试使小批量尽可能大,以便可以将其放置在 GPU 内存中。 将整个批量划分为小批量,以确保每次梯度更新都会产生足够的抽动,从而在使用 GPU 提供的全部功能的同时,将模型从局部最小值中剔除。
我们已经到达了模型构建旅程的最后一部分。 到目前为止,所有操作都很直观,简单,但是最后一部分有点令人困惑。 `zero_grad`做什么? 还记得关于重量`w1.grad`的第一份印刷声明吗? 它是空的,现在具有当前反向传递的渐变。 因此,我们需要在下一次向后传递之前清空渐变,因为渐变会累积而不是被重写。 参数更新后,我们在每个迭代的每个张量上调用`zero_grad()`,然后继续进行下一个迭代。
......@@ -584,7 +584,7 @@ for epoch in range(epochs):
optimizer.step()
```
这是循环遍历批处理并使用输入批处理调用`net`的代码。 然后,将`net(x_)`返回的`hyp`与实际值`y_`一起传递给损失函数。 损失函数返回的错误用作叶子节点来调用`backward()`。 然后,我们调用`optimizer``step()`函数,该函数将更新参数。 更新之后,用户负责将梯度归零,这现在可以通过`optimizer.zero_grad()`实现。
这是循环遍历批量并使用输入批量调用`net`的代码。 然后,将`net(x_)`返回的`hyp`与实际值`y_`一起传递给损失函数。 损失函数返回的错误用作叶子节点来调用`backward()`。 然后,我们调用`optimizer``step()`函数,该函数将更新参数。 更新之后,用户负责将梯度归零,这现在可以通过`optimizer.zero_grad()`实现。
## 摘要
......
......@@ -83,7 +83,7 @@ for batch in dataloader:
print(batch)
```
`DataLoader`类接受从`torch.utils.data.Dataset`继承的`dataset`类。 `DataLoader`接受`dataset`并执行不重要的操作,例如迷你批处理,多线程,改组等,以从数据集中获取数据。 它接受来自用户的`dataset`实例,并使用采样器策略以迷你批量的形式采样数据。
`DataLoader`类接受从`torch.utils.data.Dataset`继承的`dataset`类。 `DataLoader`接受`dataset`并执行不重要的操作,例如小批量,多线程,改组等,以从数据集中获取数据。 它接受来自用户的`dataset`实例,并使用采样器策略以小批量的形式采样数据。
`num_worker`参数决定应该操作多少个并行线程来获取数据。 这有助于避免 CPU 瓶颈,以便 CPU 可以赶上 GPU 的并行操作。 数据加载器允许用户指定是否使用固定的 CUDA 内存,这会将数据张量复制到 CUDA 的固定的内存中,然后再返回给用户。 使用固定内存是设备之间快速数据传输的关键,因为数据是由数据加载程序本身加载到固定内存中的,而无论如何,这都是由 CPU 的多个内核完成的。
......@@ -242,7 +242,7 @@ pip install torchtext
* 将数据集分为训练集,测试集和验证集。
* 将数据集转换为神经网络可以理解的形式。 数值化,一键编码和词嵌入是常见的方法。
*处理
*
* 填充到最长序列的长度。
没有像`torchtext`这样的帮助程序类,这些平凡的任务令人沮丧且无济于事。 我们将使用`torchtext`的强大 API 来简化所有这些任务。
......@@ -304,9 +304,9 @@ print(next(iter(test_iter)))
建立词汇表后,我们可以要求`torchtext`给我们迭代器,该迭代器可以循环执行神经网络。 上面的代码片段显示了`build_vocab`如何接受参数,然后如何调用`Iterator`包的`splits`函数来为我们的训练,验证和测试数据创建三个不同的迭代器。
为了使用 CPU,将`device`参数设置为`-1`。 如果是`0`,则`Iterator`会将数据加载到默认 GPU,或者我们可以指定设备编号。 批量大小期望我们传递的每个数据集的批量大小。 在这种情况下,我们具有用于训练,验证和测试的三个数据集,因此我们传递具有三个批处理大小的元组。
为了使用 CPU,将`device`参数设置为`-1`。 如果是`0`,则`Iterator`会将数据加载到默认 GPU,或者我们可以指定设备编号。 批量大小期望我们传递的每个数据集的批量大小。 在这种情况下,我们具有用于训练,验证和测试的三个数据集,因此我们传递具有三个批大小的元组。
`sort_key`使用我们传递的`lambda`函数对数据集进行排序。 在某些情况下,对数据集进行排序会有所帮助,而在大多数情况下,随机性会帮助网络学习一般情况。 `Iterator`足够聪明,可以使用通过参数传递的批处理大小来批处理输入数据集,但是它并不止于此。 它可以动态地将所有序列填充到每批最长序列的长度。 `Iterator`的输出(如`print`语句所示)为`TEXT`数据,其大小为`16x99`,其中`99`是我们为测试数据集传递的批处理大小,而 16 是该数据集的长度。 该特定批量中最长的序列。
`sort_key`使用我们传递的`lambda`函数对数据集进行排序。 在某些情况下,对数据集进行排序会有所帮助,而在大多数情况下,随机性会帮助网络学习一般情况。 `Iterator`足够聪明,可以使用通过参数传递的批量大小来批量输入数据集,但是它并不止于此。 它可以动态地将所有序列填充到每批最长序列的长度。 `Iterator`的输出(如`print`语句所示)为`TEXT`数据,其大小为`16x99`,其中`99`是我们为测试数据集传递的批量大小,而 16 是该数据集的长度。 该特定批量中最长的序列。
如果`Iterator`类需要更巧妙地处理事情怎么办? 如果数据集用于语言建模,并且我们需要一个数据集来进行**在整个时间****BPTT**)中的反向传播,那该怎么办? `torchtext`也为这些模块抽象了模块,这些模块继承自我们刚刚使用的`Iterator`类。 `BucketIterator`模块将序列进行更智能的分组,以便将具有相同长度的序列归为一组,并且此减少了将噪声引入数据集的不必要填充的长度。 `BucketIterator`还可以在每个时期对批量进行混洗,并在数据集中保持足够的随机性,从而使网络无法从数据集中的顺序中学习,这实际上并没有在教授任何现实世界的信息。
......
......@@ -49,7 +49,7 @@ CNN 通过两种机制实现位置不变:跨步和合并。 步幅值决定了
## 使用 PyTorch 的计算机视觉
PyTorch 为计算机视觉提供了几个便捷功能,其中包括卷积层和池化层。 PyTorch 在`torch.nn`包下提供`Conv1d``Conv2d``Conv3d`。 听起来,`Conv1d`处理一维卷积,`Conv2d`处理带有图像之类输入的二维卷积,`Conv3d`处理诸如视频之类的输入上的三维卷积。 显然,这很令人困惑,因为指定的尺寸从未考虑输入的深度。 例如,`Conv2d`处理四维输入,其中第一维将是批处理大小,第二维将是图像的深度(在 RGB 通道中),最后两个维将是图像的高度和宽度。 图片。
PyTorch 为计算机视觉提供了几个便捷功能,其中包括卷积层和池化层。 PyTorch 在`torch.nn`包下提供`Conv1d``Conv2d``Conv3d`。 听起来,`Conv1d`处理一维卷积,`Conv2d`处理带有图像之类输入的二维卷积,`Conv3d`处理诸如视频之类的输入上的三维卷积。 显然,这很令人困惑,因为指定的尺寸从未考虑输入的深度。 例如,`Conv2d`处理四维输入,其中第一维将是批大小,第二维将是图像的深度(在 RGB 通道中),最后两个维将是图像的高度和宽度。 图片。
除了用于计算机视觉的高层功能之外,`torchvision`还具有一些方便的实用程序功能来建立网络。 在本章中,我们将探讨其中的一些。
......@@ -83,7 +83,7 @@ def get_data():
函数的第一部分对来自 CIFAR10 数据集的 NumPy 数组进行转换。 首先将其转换为 Torch 张量,然后进行归一化转换。 `ToTensor`不仅将 NumPy 数组转换为 Torch 张量,而且还更改了维度的顺序和值的范围。
PyTorch 的所有更高层 API 都希望通道(张量的深度)成为批量大小之后的第一维。 因此,形状(高度 x 宽度 x 通道(RGB))在[0,255]范围内的输入将转换为形状(通道(RGB)x 高度 x 宽度)在[0.0,255]之间的`torch.FloatTensor` 1.0]。 然后,将每个通道(RGB)的平均值和标准差设置为 0.5,进行标准化。 `torchvision`转换完成的规范化操作与以下 Python 函数相同:
PyTorch 的所有更高层 API 都希望通道(张量的深度)成为批量大小之后的第一维。 因此,形状(高度 x 宽度 x 通道(RGB))在[0,255]范围内的输入将转换为形状(通道(RGB)x 高度 x 宽度)在[0.0,255]之间的`torch.FloatTensor` 1.0]。 然后,将每个通道(RGB)的平均值和标准差设置为 0.5,进行标准化。 `torchvision`转换完成的规范化操作与以下 Python 函数相同:
```py
def normalize(image, mean, std):
......@@ -380,19 +380,19 @@ class ConvBlock(nn.Module):
return self.conv_block(x)
```
LinkNet 中的所有卷积都紧随其后的是批处理规范化和 ReLU 层,但是有一些例外,没有 ReLU 层。 这就是`ConvBlock`的目标。 如前所述,`ConvBlock``torch.nn.Module`的子类,可以根据正向传递中发生的任何事情进行反向传播。 `__init__`接受输入和输出尺寸,内核大小,步幅值,填充宽度,表示是否需要偏置的布尔值和表示是否需要激活(ReLU)的布尔值。
LinkNet 中的所有卷积都紧随其后的是批规范化和 ReLU 层,但是有一些例外,没有 ReLU 层。 这就是`ConvBlock`的目标。 如前所述,`ConvBlock``torch.nn.Module`的子类,可以根据正向传递中发生的任何事情进行反向传播。 `__init__`接受输入和输出尺寸,内核大小,步幅值,填充宽度,表示是否需要偏置的布尔值和表示是否需要激活(ReLU)的布尔值。
我们使用`torch.nn.Conv2d``torch.nn.BatchNorm2d``torch.nn.ReLu`来配置`ConvBlock`。 PyTorch 的 Conv2D 接受`ConvBlock``__init__`的所有参数,但表示类似激活要求的布尔值除外。 除此之外,Conv2D 还接受另外两个用于 dilation 和 group 的可选参数。 `torch.nn`的 ReLU 函数仅接受一个称为`inplace`的可选参数,默认为`False`。 如果`inplace``True`,则 ReLU 将应用于就地数据,而不是创建另一个存储位置。 在许多情况下,这可能会稍微节省内存,但会导致问题,因为我们正在破坏输入。 经验法则是:除非您迫切需要内存优化,否则请远离它。
处理规范化用于规范每个批处理中的数据,而不是一开始只进行一次。 在开始时,标准化对于获得相等比例的输入至关重要,这反过来又可以提高精度。 但是,随着数据流经网络,非线性和权重和偏差的增加可能导致内部数据规模不同。
量规范化用于规范每个批量中的数据,而不是一开始只进行一次。 在开始时,标准化对于获得相等比例的输入至关重要,这反过来又可以提高精度。 但是,随着数据流经网络,非线性和权重和偏差的增加可能导致内部数据规模不同。
标准化每一层被证明是解决此特定问题的一种方法,即使我们提高了学习速度,也可以提高准确率。 批量归一化还可以帮助网络从更稳定的输入分布中学习,从而加快了网络的收敛速度。 PyTorch 对不同尺寸的输入实现了批量归一化,就像卷积层一样。 在这里我们使用`BatchNorm2d`,因为我们有四维数据,其中一维是批处理大小,另一维是深度。
标准化每一层被证明是解决此特定问题的一种方法,即使我们提高了学习速度,也可以提高准确率。 批量归一化还可以帮助网络从更稳定的输入分布中学习,从而加快了网络的收敛速度。 PyTorch 对不同尺寸的输入实现了批量归一化,就像卷积层一样。 在这里我们使用`BatchNorm2d`,因为我们有四维数据,其中一维是批大小,另一维是深度。
`BatchNorm2d`用两个可学习的参数实现:伽玛和贝塔。 除非我们将仿射参数设置为`False`,否则 PyTorch 会在反向传播时处理这些功能的学习。 现在,`BatchNorm2d`接受特征数量,ε值,动量和仿射作为参数。
ε值将添加到平方根内的分母中以保持数值稳定性,而动量因子决定应从上一层获得多少动量以加快操作速度。
`__init__`检查是否需要激活并创建层。 这是`torch.nn.Sequential`有用的地方。 将三个不同的层(卷积,批处理规范化和 ReLU)定义为单个`ConvBlock`层的明显方法是为所有三个层创建 Python 属性,并将第一层的输出传递给第二层,然后将该输出传递给第三层 in。但是使用`nn.Sequential`,我们可以将它们链接在一起并创建一个 Python 属性。 这样做的缺点是,随着网络的增长,您将为所有小模块提供额外的`Sequential`包装器,这将使解释网络图变得困难。 存储库中的可用代码(带有`nn.Sequential`包装器)将生成类似*的图形,如图 4.10a* 一样,而没有使用`Sequential`包装器构建的层将生成类似*的图形,如图 4.10b 所示。*
`__init__`检查是否需要激活并创建层。 这是`torch.nn.Sequential`有用的地方。 将三个不同的层(卷积,批规范化和 ReLU)定义为单个`ConvBlock`层的明显方法是为所有三个层创建 Python 属性,并将第一层的输出传递给第二层,然后将该输出传递给第三层 in。但是使用`nn.Sequential`,我们可以将它们链接在一起并创建一个 Python 属性。 这样做的缺点是,随着网络的增长,您将为所有小模块提供额外的`Sequential`包装器,这将使解释网络图变得困难。 存储库中的可用代码(带有`nn.Sequential`包装器)将生成类似*的图形,如图 4.10a* 一样,而没有使用`Sequential`包装器构建的层将生成类似*的图形,如图 4.10b 所示。*
```py
class ConvBlockWithoutSequential(nn.Module):
......
......@@ -144,7 +144,7 @@ inputs.vocab.load_vectors('glove.6B.300d')
图 5.2:具有输入,隐藏状态和输出展开序列的通用 RNN 单元流程图
“图 5.2”显示了展开的同一 RNN 单元,以可视化如何处理句子中的每个单词。 由于我们为每个单词使用相同的 RNN 单元,因此大大减少了神经网络所需的参数数量,这使我们能够处理大型迷你批处理。 网络参数学习的方式是处理序列的顺序。 这是 RNN 的核心原则。
“图 5.2”显示了展开的同一 RNN 单元,以可视化如何处理句子中的每个单词。 由于我们为每个单词使用相同的 RNN 单元,因此大大减少了神经网络所需的参数数量,这使我们能够处理大型小批量。 网络参数学习的方式是处理序列的顺序。 这是 RNN 的核心原则。
![RNNCell](img/B09475_05_03.jpg)
......@@ -191,11 +191,11 @@ class RNNCell(nn.Module):
尽管如果在 PyTorch 中一个接一个地传递序列长度,我们不会遇到不同序列长度的问题,但是如果我们的框架是基于静态计算图的框架,则会遇到麻烦。 在静态计算图中,甚至序列长度也必须是静态的,这就是基于静态图的框架与基于 NLP 的任务极不兼容的原因。 但是,像 TensorFlow 这样的高度复杂的框架通过为用户提供另一个名为`dynamic_rnn`的 API 来处理此问题。
第一种方法似乎很好用,因为我们每次分别为每个句子处理一个单词。 但是,迷你批处理的输入要比一次处理一个数据输入更有效,以使我们的损失函数收敛到全局最小值。 做到这一点的明显有效的方法是填充。 用零填充输入(或输入数据集中不存在的任何预定义值)有助于我们解决此特定问题。 但是,当我们尝试手动执行操作时,它变得很繁琐,并且变得多余,因为每次处理顺序数据时都必须这样做。 PyTorch 在`torch.nn`下有一个单独的实用程序包,其中包含我们 RNN 所需的实用程序。
第一种方法似乎很好用,因为我们每次分别为每个句子处理一个单词。 但是,小批量的输入要比一次处理一个数据输入更有效,以使我们的损失函数收敛到全局最小值。 做到这一点的明显有效的方法是填充。 用零填充输入(或输入数据集中不存在的任何预定义值)有助于我们解决此特定问题。 但是,当我们尝试手动执行操作时,它变得很繁琐,并且变得多余,因为每次处理顺序数据时都必须这样做。 PyTorch 在`torch.nn`下有一个单独的实用程序包,其中包含我们 RNN 所需的实用程序。
##### 打击垫顺序
函数`pad_sequence`听起来很像:在标识批处理中最长的序列后,将序列用零填充,然后将其他所有句子填充到该长度:
函数`pad_sequence`听起来很像:在标识批中最长的序列后,将序列用零填充,然后将其他所有句子填充到该长度:
```py
>>> import torch.nn.utils.rnn as rnn_utils
......@@ -216,7 +216,7 @@ class RNNCell(nn.Module):
##### 装箱顺序
您是否看到用零填充输入并使用 RNN 处理输入的问题,特别是在我们如此关心最后一个隐藏状态的情况下? 批处理中包含一个非常大的句子的简短句子最终将填充很多零,并且在生成隐藏状态时,我们也必须遍历这些零。
您是否看到用零填充输入并使用 RNN 处理输入的问题,特别是在我们如此关心最后一个隐藏状态的情况下? 批中包含一个非常大的句子的简短句子最终将填充很多零,并且在生成隐藏状态时,我们也必须遍历这些零。
下图显示了一个包含三个句子的批量输入示例。 短句子用零填充,以使长度等于最长句子。 但是在处理它们时,我们最终也会处理零。 对于双向 RNN,问题更加复杂,因为我们必须从两端进行处理。
......@@ -291,7 +291,7 @@ class Merger(nn.Module):
```
在这里,`Merger`节点被构建为模拟 SPINN 的实际实现。 `Merger``forward`功能获得两个序列:`prem``hypo`。 我们首先通过正常减法确定两个句子之间的差异,然后通过逐元素相乘找到它们之间的乘积。 然后,我们将实际句子与差异和刚刚找到的乘积连接起来,然后将它们传递给批处理规范化层和丢弃层。
在这里,`Merger`节点被构建为模拟 SPINN 的实际实现。 `Merger``forward`功能获得两个序列:`prem``hypo`。 我们首先通过正常减法确定两个句子之间的差异,然后通过逐元素相乘找到它们之间的乘积。 然后,我们将实际句子与差异和刚刚找到的乘积连接起来,然后将它们传递给批规范化层和丢弃层。
`Merger`节点也是我们的简单 RNN 的最终分类器层的一部分,该分类器由其他几个节点组成。
......@@ -497,7 +497,7 @@ SPINN 将输入的句子编码为固定长度的向量,就像基于 RNN 的编
#### 减少
约简网络将最左边的单词,最右边的单词和句子上下文作为输入,并在`forward`调用中生成单个约简的输出。 句子上下文由另一个称为`Tracker`的深度网络给出。 `Reduce`不在乎网络中正在发生的事情; 它总是接受三个输入,并由此减少输出。 树 LSTM 是标准 LSTM 的变体,用于与`bundle``unbundle`等其他辅助功能一起批处理`Reduce`网络中发生的繁重操作。
约简网络将最左边的单词,最右边的单词和句子上下文作为输入,并在`forward`调用中生成单个约简的输出。 句子上下文由另一个称为`Tracker`的深度网络给出。 `Reduce`不在乎网络中正在发生的事情; 它总是接受三个输入,并由此减少输出。 树 LSTM 是标准 LSTM 的变体,用于与`bundle``unbundle`等其他辅助功能一起批`Reduce`网络中发生的繁重操作。
```py
class Reduce(nn.Module):
......
......@@ -100,7 +100,7 @@ net = nn.Sequential(
nn.Conv2d(fm, 256, 1))
```
前面的代码段是完整的 PixelCNN 模型,该模型包装在顺序单元中。 它由一堆`MaskedConv2d`实例组成,这些实例继承自`torch.nn.Conv2d`,并使用了`torch.nn``Conv2d`的所有`*args``**kwargs`。 每个卷积单元之后是批处理规范层和 ReLU 层,这是与卷积层成功组合的。 作者决定不在普通层上使用线性层,而是决定使用普通的二维卷积,事实证明,该方法比线性层更好。
前面的代码段是完整的 PixelCNN 模型,该模型包装在顺序单元中。 它由一堆`MaskedConv2d`实例组成,这些实例继承自`torch.nn.Conv2d`,并使用了`torch.nn``Conv2d`的所有`*args``**kwargs`。 每个卷积单元之后是批规范层和 ReLU 层,这是与卷积层成功组合的。 作者决定不在普通层上使用线性层,而是决定使用普通的二维卷积,事实证明,该方法比线性层更好。
##### 屏蔽卷积
......@@ -596,11 +596,11 @@ PyTorch 为用户提供了进入网络并进行操作的完全灵活性。 其
之前我们在 CycleGAN 中看到了发电机的图形。 与我们探讨的第一个简单 GAN 不同,A2B 和 B2A 都具有相同的内部结构,内部具有卷积。 整个生成器都包装在以`ReflectionPad2D`开头的单个序列模块中。
反射填充涉及填充输入的边界,跳过批处理尺寸和通道尺寸。 填充之后是典型的卷积模块布置,即二维卷积。
反射填充涉及填充输入的边界,跳过批尺寸和通道尺寸。 填充之后是典型的卷积模块布置,即二维卷积。
实例归一化分别对每个输出批量进行归一化,而不是像“批量归一化”中那样对整个集合进行归一化。 二维实例归一化确实在 4D 输入上实例化归一化,且批量尺寸和通道尺寸为第一维和第二维。 PyTorch 通过传递`affine=True`允许实例规范化层可训练。 参数`track_running_stats`决定是否存储训练循环的运行平均值和方差,以用于评估模式(例如归一化)。 默认情况下,它设置为`False`; 也就是说,它在训练和评估模式下都使用从输入中收集的统计信息。
下图给出了批处理规范化和实例规范化的直观比较。 在图像中,数据表示为三维张量,其中 C 是通道,N 是批处理,D 是其他维,为简单起见,在一个维中表示。 如图中所示,批量归一化对整个批量中的数据进行归一化,而实例归一化则在两个维度上对一个数据实例进行归一化,从而使批量之间的差异保持完整。
下图给出了批量规范化和实例规范化的直观比较。 在图像中,数据表示为三维张量,其中 C 是通道,N 是批量,D 是其他维,为简单起见,在一个维中表示。 如图中所示,批量归一化对整个批量中的数据进行归一化,而实例归一化则在两个维度上对一个数据实例进行归一化,从而使批量之间的差异保持完整。
![CycleGAN](img/B09475_06_21.jpg)
......
......@@ -428,7 +428,7 @@ def optimize_model():
![Gym](img/B09475_07_07.jpg)
然后,我们收集与操作批处理相对应的值。
然后,我们收集与操作批相对应的值。
![Gym](img/B09475_07_08.jpg)
......
......@@ -513,7 +513,7 @@ train_ds = TensorDataset(x_train, y_train)
```
以前,我们不得不分别遍历 x 和 y 值的迷你批处理
以前,我们不得不分别遍历 x 和 y 值的小批量
```py
xb = x_train[start_i:end_i]
......@@ -564,7 +564,7 @@ train_dl = DataLoader(train_ds, batch_size=bs)
```
以前,我们的循环遍历如下批处理(xb,yb):
以前,我们的循环遍历如下批(xb,yb):
```py
for i in range((n-1)//bs + 1):
......
......@@ -26,7 +26,7 @@ GAN 是用于教授 DL 模型以捕获训练数据分布的框架,因此我们
### 什么是 DCGAN?](docs / modern-java-zh /
DCGAN 是上述 GAN 的直接扩展,不同之处在于,DCGAN 分别在鉴别器和生成器中分别使用卷积和卷积转置层。 它最早由 Radford 等人描述。 等 在论文[中使用深度卷积生成对抗网络](https://arxiv.org/pdf/1511.06434.pdf)进行无监督表示学习。 鉴别器由分层的[卷积](https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d)层,[处理规范](https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d)层和 [LeakyReLU](https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU) 激活组成。 输入是 3x64x64 的输入图像,输出是输入来自真实数据分布的标量概率。 生成器由[卷积转置](https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d)层,批处理规范层和 [ReLU](https://pytorch.org/docs/stable/nn.html#relu) 激活组成。 输入是从标准正态分布中提取的潜向量\(z \),输出是 3x64x64 RGB 图像。 跨步的转置层使潜向量可以转换为具有与图像相同形状的体积。 在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化模型权重的提示,所有这些都将在接下来的部分中进行解释。
DCGAN 是上述 GAN 的直接扩展,不同之处在于,DCGAN 分别在鉴别器和生成器中分别使用卷积和卷积转置层。 它最早由 Radford 等人描述。 等 在论文[中使用深度卷积生成对抗网络](https://arxiv.org/pdf/1511.06434.pdf)进行无监督表示学习。 鉴别器由分层的[卷积](https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d)层,[量规范](https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d)层和 [LeakyReLU](https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU) 激活组成。 输入是 3x64x64 的输入图像,输出是输入来自真实数据分布的标量概率。 生成器由[卷积转置](https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d)层,批量规范层和 [ReLU](https://pytorch.org/docs/stable/nn.html#relu) 激活组成。 输入是从标准正态分布中提取的潜向量\(z \),输出是 3x64x64 RGB 图像。 跨步的转置层使潜向量可以转换为具有与图像相同形状的体积。 在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化模型权重的提示,所有这些都将在接下来的部分中进行解释。
```py
from __future__ import print_function
......@@ -70,7 +70,7 @@ Random Seed: 999
* **dataroot** -数据集文件夹根目录的路径。 我们将在下一节中进一步讨论数据集
* **worker** -使用 DataLoader 加载数据的工作线程数
* **batch_size** -训练中使用的批量大小。 DCGAN 纸使用的批处理大小为 128
* **batch_size** -训练中使用的批量大小。 DCGAN 纸使用的批大小为 128
* **image_size** -用于训练的图像的空间大小。 此实现默认为 64x64。 如果需要其他尺寸,则必须更改 D 和 G 的结构。 有关更多详细信息,请参见此处的[](https://github.com/pytorch/examples/issues/70)
* **nc** -输入图像中的彩色通道数。 对于彩色图像,这是 3
* **nz** -潜向量的长度
......@@ -172,7 +172,7 @@ plt.imshow(np.transpose(vutils.make_grid(real_batch[0].to(device)[:64], padding=
### 权重初始化](docs / modern-java-zh /
在 DCGAN 论文中,作者指定所有模型权重均应从均值= 0,stdev = 0.02 的正态分布中随机初始化。 `weights_init`函数采用已初始化的模型作为输入,并重新初始化所有卷积,卷积转置和批处理归一化层以满足此标准。 初始化后立即将此功能应用于模型。
在 DCGAN 论文中,作者指定所有模型权重均应从均值= 0,stdev = 0.02 的正态分布中随机初始化。 `weights_init`函数采用已初始化的模型作为输入,并重新初始化所有卷积,卷积转置和批归一化层以满足此标准。 初始化后立即将此功能应用于模型。
```py
# custom weights initialization called on netG and netD
......@@ -188,7 +188,7 @@ def weights_init(m):
### 生成器](docs / modern-java-zh /
生成器\(G \)用于将潜在空间向量(\(z \))映射到数据空间。 由于我们的数据是图像,因此将\(z \)转换为数据空间意味着最终创建与训练图像大小相同的 RGB 图像(即 3x64x64)。 在实践中,这是通过一系列跨步的二维卷积转置层来完成的,每个层都与 2d 批处理规范层和 relu 激活配对。 生成器的输出通过 tanh 函数馈送,以使其返回到输入数据范围\([-1,1] \)。 值得注意的是,在卷积转置层之后存在批处理规范函数,因为这是 DCGAN 论文的关键贡献。 这些层有助于训练过程中的梯度流动。 DCGAN 纸生成的图像如下所示。
生成器\(G \)用于将潜在空间向量(\(z \))映射到数据空间。 由于我们的数据是图像,因此将\(z \)转换为数据空间意味着最终创建与训练图像大小相同的 RGB 图像(即 3x64x64)。 在实践中,这是通过一系列跨步的二维卷积转置层来完成的,每个层都与 2d 批量规范层和 relu 激活配对。 生成器的输出通过 tanh 函数馈送,以使其返回到输入数据范围\([-1,1] \)。 值得注意的是,在卷积转置层之后存在批量规范函数,因为这是 DCGAN 论文的关键贡献。 这些层有助于训练过程中的梯度流动。 DCGAN 纸生成的图像如下所示。
![dcgan_generator](img/85974d98be6202902f21ce274418953f.png)
......@@ -274,7 +274,7 @@ Generator(
### 判别器](docs / modern-java-zh /
如前所述,鉴别符\(D \)是一个二进制分类网络,将图像作为输入并输出标量概率,即输入图像是真实的(与假的相对)。 在这里,\(D \)拍摄 3x64x64 的输入图像,通过一系列的 Conv2d,BatchNorm2d 和 LeakyReLU 层对其进行处理,然后通过 Sigmoid 激活函数输出最终概率。 如果需要解决此问题,可以用更多层扩展此架构,但是使用跨步卷积,BatchNorm 和 LeakyReLU 仍然很重要。 DCGAN 论文提到,使用跨步卷积而不是通过池化来进行下采样是一个好习惯,因为它可以让网络学习自己的池化功能。 批处理规范和泄漏 relu 函数还可以促进健康的梯度流,这对于\(G \)\(D \)的学习过程都是至关重要的。
如前所述,鉴别符\(D \)是一个二进制分类网络,将图像作为输入并输出标量概率,即输入图像是真实的(与假的相对)。 在这里,\(D \)拍摄 3x64x64 的输入图像,通过一系列的 Conv2d,BatchNorm2d 和 LeakyReLU 层对其进行处理,然后通过 Sigmoid 激活函数输出最终概率。 如果需要解决此问题,可以用更多层扩展此架构,但是使用跨步卷积,BatchNorm 和 LeakyReLU 仍然很重要。 DCGAN 论文提到,使用跨步卷积而不是通过池化来进行下采样是一个好习惯,因为它可以让网络学习自己的池化功能。 批规范和泄漏 relu 函数还可以促进健康的梯度流,这对于\(G \)\(D \)的学习过程都是至关重要的。
鉴别码
......
......@@ -73,7 +73,7 @@ Sample rate of waveform: 44100
* **FrequencyMasking**:在频域中对频谱图应用屏蔽。
* **TimeMasking**:在时域中对频谱图应用屏蔽。
每个变换都支持批处理:您可以对单个原始音频信号或频谱图或许多相同形状的信号执行变换。
每个变换都支持批:您可以对单个原始音频信号或频谱图或许多相同形状的信号执行变换。
由于所有变换都是`nn.Modules``jit.ScriptModules`,因此它们可以随时用作神经网络的一部分。
......
......@@ -302,7 +302,7 @@ def train(model, epoch, log_interval):
```
现在我们有了训练功能,我们需要制作一个用于测试网络准确率的功能。 我们将模型设置为`eval()`模式,然后对测试数据集进行推断。 调用`eval()`将网络中所有模块中的训练变量设置为 false。 某些层(例如批处理归一化层和丢弃层)在训练期间的行为会有所不同,因此此步骤对于获取正确的结果至关重要。
现在我们有了训练功能,我们需要制作一个用于测试网络准确率的功能。 我们将模型设置为`eval()`模式,然后对测试数据集进行推断。 调用`eval()`将网络中所有模块中的训练变量设置为 false。 某些层(例如批归一化层和丢弃层)在训练期间的行为会有所不同,因此此步骤对于获取正确的结果至关重要。
```py
def number_of_correct(pred, target):
......
......@@ -76,13 +76,13 @@ class PositionalEncoding(nn.Module):
```
## 加载和批处理数据](docs / modern-java-zh /
## 加载和批数据](docs / modern-java-zh /
本教程使用`torchtext`生成 Wikitext-2 数据集。 vocab 对象是基于训练数据集构建的,用于将标记数字化为张量。 从顺序数据开始,`batchify()`函数将数据集排列为列,以修剪掉数据分成大小为`batch_size`的批量后剩余的所有令牌。 例如,以字母为序列(总长度为 26)并且批大小为 4,我们将字母分为 4 个长度为 6 的序列:
\[\begin{split}\begin{bmatrix} \text{A} & \text{B} & \text{C} & \ldots & \text{X} & \text{Y} & \text{Z} \end{bmatrix} \Rightarrow \begin{bmatrix} \begin{bmatrix}\text{A} \\ \text{B} \\ \text{C} \\ \text{D} \\ \text{E} \\ \text{F}\end{bmatrix} & \begin{bmatrix}\text{G} \\ \text{H} \\ \text{I} \\ \text{J} \\ \text{K} \\ \text{L}\end{bmatrix} & \begin{bmatrix}\text{M} \\ \text{N} \\ \text{O} \\ \text{P} \\ \text{Q} \\ \text{R}\end{bmatrix} & \begin{bmatrix}\text{S} \\ \text{T} \\ \text{U} \\ \text{V} \\ \text{W} \\ \text{X}\end{bmatrix} \end{bmatrix}\end{split}\]
这些列被模型视为独立的,这意味着无法了解`G``F`的依赖性,但可以进行更有效的批处理
这些列被模型视为独立的,这意味着无法了解`G``F`的依赖性,但可以进行更有效的批
```py
import io
......
......@@ -122,7 +122,7 @@ print(category_lines['Italian'][:5])
为了制造一个单词,我们将其中的一些连接成 2D 矩阵`<line_length x 1 x n_letters>`
额外的 1 维是因为 PyTorch 假定所有内容都是成批的-在这里我们仅使用 1 的批处理大小。
额外的 1 维是因为 PyTorch 假定所有内容都是成批的-在这里我们仅使用 1 的批大小。
```py
import torch
......
......@@ -98,11 +98,11 @@ model = TextSentiment(VOCAB_SIZE, EMBED_DIM, NUN_CLASS).to(device)
```
## 用于生成批处理的函数](docs / modern-java-zh /
## 用于生成批的函数](docs / modern-java-zh /
由于文本条目的长度不同,因此使用自定义函数 generate_batch()生成数据批和偏移量。 该功能被传递到`torch.utils.data.DataLoader`中的`collate_fn``collate_fn`的输入是张量列表,其大小为 batch_size,`collate_fn`函数将它们打包成一个小批量。 请注意此处,并确保将`collate_fn`声明为顶级 def。 这样可以确保该功能在每个工作程序中均可用。
原始数据批处理输入中的文本条目打包到一个列表中,并作为单个张量级联,作为`nn.EmbeddingBag`的输入。 偏移量是定界符的张量,表示文本张量中各个序列的起始索引。 Label 是一个张量,用于保存单个文本条目的标签。
原始数据批输入中的文本条目打包到一个列表中,并作为单个张量级联,作为`nn.EmbeddingBag`的输入。 偏移量是定界符的张量,表示文本张量中各个序列的起始索引。 Label 是一个张量,用于保存单个文本条目的标签。
```py
def generate_batch(batch):
......
......@@ -73,7 +73,7 @@ test_data = data_process(test_filepaths)
## `DataLoader`](docs / modern-java-zh /
我们将使用的最后`torch`个特定功能是`DataLoader`,它易于使用,因为它将数据作为第一个参数。 具体来说,正如文档所说:`DataLoader`结合了一个数据集和一个采样器,并在给定的数据集上提供了可迭代的。 `DataLoader`支持地图样式和可迭代样式的数据集,具有单进程或多进程加载,自定义加载顺序以及可选的自动批处理(归类)和内存固定。
我们将使用的最后`torch`个特定功能是`DataLoader`,它易于使用,因为它将数据作为第一个参数。 具体来说,正如文档所说:`DataLoader`结合了一个数据集和一个采样器,并在给定的数据集上提供了可迭代的。 `DataLoader`支持地图样式和可迭代样式的数据集,具有单进程或多进程加载,自定义加载顺序以及可选的自动批(归类)和内存固定。
请注意`collate_fn`(可选),它将合并样本列表以形成张量的小批量。 在从地图样式数据集中使用批量加载时使用。
......
......@@ -62,7 +62,7 @@ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
## 重播内存](docs / modern-java-zh /
我们将使用经验重播记忆来训练我们的 DQN。 它存储代理观察到的转换,使我们以后可以重用此数据。 通过从中随机抽样,可以构建批处理的转换相关。 已经表明,这极大地稳定和改善了 DQN 训练程序。
我们将使用经验重播记忆来训练我们的 DQN。 它存储代理观察到的转换,使我们以后可以重用此数据。 通过从中随机抽样,可以构建批的转换相关。 已经表明,这极大地稳定和改善了 DQN 训练程序。
为此,我们将需要两个类:
......
......@@ -83,7 +83,7 @@ def predict():
### 准备图像](docs / modern-java-zh /
DenseNet 模型要求图像为尺寸为 224 x 224 的 3 通道 RGB 图像。我们还将使用所需的均值和标准差值对图像张量进行归一化。 您可以在上阅读有关它的更多信息。
DenseNet 模型要求图像为尺寸为 224 x 224 的 3 通道 RGB 图像。我们还将使用所需的均值和标准差值对图像张量进行归一化。 您可以在上阅读有关它的更多信息。
我们将使用`torchvision`库中的`transforms`并建立一个转换管道,该转换管道可根据需要转换图像。 您可以在上阅读有关变换[的更多信息。](https://pytorch.org/docs/stable/torchvision/transforms.html)
......
......@@ -577,7 +577,7 @@ print(output.names)
```
以上工作正常。 此外,请注意,在代码中我们根本没有提到批处理维度的名称。 实际上,我们的`MultiHeadAttention`模块与批量尺寸的存在无关。
以上工作正常。 此外,请注意,在代码中我们根本没有提到批维度的名称。 实际上,我们的`MultiHeadAttention`模块与批量尺寸的存在无关。
```py
query = torch.randn(t, d, names=('T', 'D'))
......
......@@ -16,7 +16,7 @@ Channels Last 内存格式是在保留内存尺寸的顺序中对 NCHW 张量进
![channels_last_memory_format](img/462373919a0dfe17cd816fa0d8af140c.png)
Pytorch 通过使用现有的跨步结构支持内存格式(并提供与现有模型(包括 eager,JIT 和 TorchScript)的向后兼容性)。 例如,Channels Last 格式中的 10x3x16x16 批处理的步幅等于(768、1、48、3)。
Pytorch 通过使用现有的跨步结构支持内存格式(并提供与现有模型(包括 eager,JIT 和 TorchScript)的向后兼容性)。 例如,Channels Last 格式中的 10x3x16x16 批的步幅等于(768、1、48、3)。
通道最后一个存储格式仅适用于 4D NCWH 张量。
......
......@@ -479,7 +479,7 @@ GAN 由两个不同的神经网络模型组成:*生成器*和*鉴别器*。
#### 生成器模块](docs / modern-java-zh /
我们首先定义生成器模块,该模块由一系列转置的 2D 卷积,批处理归一化和 ReLU 激活单元组成。 我们在定义自己的模块的`forward()`方法中显式地(在功能上)在模块之间传递输入:
我们首先定义生成器模块,该模块由一系列转置的 2D 卷积,批归一化和 ReLU 激活单元组成。 我们在定义自己的模块的`forward()`方法中显式地(在功能上)在模块之间传递输入:
```py
struct DCGANGeneratorImpl : nn::Module {
......@@ -630,7 +630,7 @@ for (torch::data::Example<>& batch : *data_loader) {
```
在这种情况下,数据加载器返回的类型为`torch::data::Example`。 此类型是一种简单的结构,其中的`data`字段用于数据,而`target`字段用于标签。 因为我们之前应用了`Stack`归类,所以数据加载器仅返回一个这样的示例。 如果我们未应用排序规则,则数据加载器将改为生成`std::vector<torch::data::Example<>>`,批处理中每个示例包含一个元素。
在这种情况下,数据加载器返回的类型为`torch::data::Example`。 此类型是一种简单的结构,其中的`data`字段用于数据,而`target`字段用于标签。 因为我们之前应用了`Stack`归类,所以数据加载器仅返回一个这样的示例。 如果我们未应用排序规则,则数据加载器将改为生成`std::vector<torch::data::Example<>>`,批中每个示例包含一个元素。
如果重建并运行此代码,则应看到类似以下内容的内容:
......@@ -854,7 +854,7 @@ if (batch_index % kCheckpointEvery == 0) {
```
其中`kCheckpointEvery`是设置为类似于`100`之类的整数,用于每批`100`处理检查点,而`checkpoint_counter`是每次创建检查点时都会增加的计数器。
其中`kCheckpointEvery`是设置为类似于`100`之类的整数,用于每批`100`检查点,而`checkpoint_counter`是每次创建检查点时都会增加的计数器。
要恢复训练状态,可以在创建所有模型和优化器之后但在训练循环之前添加如下代码:
......
......@@ -704,7 +704,7 @@ switch (tensor.type().scalarType()) {
请注意,我们使用普通的 ATen 执行一些操作。 这些操作仍将在 GPU 上运行,但使用 ATen 的默认实现。 这是有道理的,因为 ATen 会针对矩阵乘法(例如`addmm`)或卷积使用高度优化的例程,而这将很难实现和改善。
至于内核启动本身,我们在这里指定每个 CUDA 块将具有 1024 个线程,并且将整个 GPU 网格分为所需的`1 x 1024`线程块,以便用每个组件一个线程填充矩阵。 例如,如果我们的状态大小为 2048,批处理大小为 4,则我们将以每个 1024 个线程总共启动`4 x 2 = 8`块。 如果您以前从未听说过 CUDA 的“障碍”或“网格”,那么[简介 CUDA](https://devblogs.nvidia.com/even-easier-introduction-cuda) 可能会有所帮助。
至于内核启动本身,我们在这里指定每个 CUDA 块将具有 1024 个线程,并且将整个 GPU 网格分为所需的`1 x 1024`线程块,以便用每个组件一个线程填充矩阵。 例如,如果我们的状态大小为 2048,批大小为 4,则我们将以每个 1024 个线程总共启动`4 x 2 = 8`块。 如果您以前从未听说过 CUDA 的“障碍”或“网格”,那么[简介 CUDA](https://devblogs.nvidia.com/even-easier-introduction-cuda) 可能会有所帮助。
实际的 CUDA 内核非常简单(如果您曾经编程过 GPU):
......
......@@ -7,7 +7,7 @@
* 根据输入张量的设备,在运算符的 CPU 和 CUDA 实现之间切换。
* 在操作员的自动分级和后端实现之间切换,这取决于是否需要自动分级处理。
* 必要时应用自动广播以实现自动混合精度。
* 当操作员在`vmap`调用下运行时,应用批处理规则。
* 当操作员在`vmap`调用下运行时,应用批规则。
* 如果要跟踪导出的模型,则跟踪操作的执行。
如果在[自定义运算符代码](torch_script_custom_ops)中发现自己手动编写了 if 语句来处理这些情况,则调度程序 API 可以帮助组织代码。 (相反,如果您的自定义运算符非常简单并且仅用于 CPU 推断,则可能不需要使用调度程序,只需使用基本 API。)
......@@ -235,9 +235,9 @@ TORCH_LIBRARY_IMPL(myops, Autocast, m) {
没有单独的体操可使后向方法自动广播兼容。 但是,在自定义 autograd 函数中定义的向后方法将以与正向方法的自动广播集相同的 dtype 运行,因此您应该选择既适合于正向方法又适合于向后方法的`<desired dtype>`
### 批处理] [docs / modern-java-zh /
### 批] [docs / modern-java-zh /
处理张量允许您按示例方式编写代码,然后在`vmap`调用下运行时自动对其进行批处理。 当前正在开发用于编写批处理规则的 API,但是一旦稳定该 API,就可以通过在 Batched 调度键处注册内核来为操作员添加对`vmap`的支持。
量张量允许您按示例方式编写代码,然后在`vmap`调用下运行时自动对其进行批量。 当前正在开发用于编写批量规则的 API,但是一旦稳定该 API,就可以通过在 Batched 调度键处注册内核来为操作员添加对`vmap`的支持。
### 追踪器](docs / modern-java-zh /
......
......@@ -114,7 +114,7 @@ optimizer = optim.SGD(net.parameters(), lr=config["lr"], momentum=0.9)
```
我们还将训练数据分为训练和验证子集。 因此,我们训练了 80% 的数据,并计算了其余 20% 的验证损失。 我们遍历训练和测试集的批处理大小也是可配置的。
我们还将训练数据分为训练和验证子集。 因此,我们训练了 80% 的数据,并计算了其余 20% 的验证损失。 我们遍历训练和测试集的批大小也是可配置的。
### 通过 DataParallel 添加(多)GPU 支持](docs / modern-java-zh /
......
......@@ -696,7 +696,7 @@ Inverted Residual Block: After preparation for QAT, note fake-quantization modul
高精度训练量化模型需要在推断时对数字进行精确建模。 因此,对于量化意识训练,我们通过以下方式修改训练循环:
* 在训练快要结束时切换批处理规范以使用运行均值和方差,以更好地匹配推理数字。
* 在训练快要结束时切换批规范以使用运行均值和方差,以更好地匹配推理数字。
* 我们还冻结了量化器参数(比例和零点),并对权重进行了微调。
```py
......
......@@ -65,7 +65,7 @@ RPC 教程如下:
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 示例。
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 结合使用分布式数据并行性和分布式模型并行性来训练模型。
## PyTorch 分布式开发人员] [docs / modern-java-zh /
......
......@@ -125,7 +125,7 @@ def train(model):
```
上面的`train(model)`方法使用`nn.MSELoss`作为损失函数,并使用`optim.SGD`作为优化器。 它模拟了对`128 X 128`图像的训练,这些图像分为 3 批,每批包含 120 张图像。 然后,我们使用`timeit`来运行`train(model)`方法 10 次,并绘制带有标准差的执行时间。
上面的`train(model)`方法使用`nn.MSELoss`作为损失函数,并使用`optim.SGD`作为优化器。 它模拟了对`128 X 128`图像的训练,这些图像分为 3 批,每批包含 120 张图像。 然后,我们使用`timeit`来运行`train(model)`方法 10 次,并绘制带有标准差的执行时间。
```py
import matplotlib.pyplot as plt
......
......@@ -25,7 +25,7 @@
上一教程[分布式 RPC 框架入门](rpc_tutorial.html)显示了如何使用 [torch.distributed.rpc](https://pytorch.org/docs/master/rpc.html) 为 RNN 模型实现分布式模型并行性。 该教程使用一个 GPU 来托管`EmbeddingTable`,并且提供的代码可以正常工作。 但是,如果模型驻留在多个 GPU 上,则将需要一些额外的步骤来增加所有 GPU 的摊销利用率。 管道并行性是在这种情况下可以提供帮助的一种范例。
在本教程中,我们使用`ResNet50`作为示例模型,[单机模型并行最佳实践](model_parallel_tutorial.html)教程也使用了该模型。 类似地,`ResNet50`模型被分为两个碎片,输入批处理被划分为多个拆分,并以流水线方式馈入两个模型碎片。 区别在于,本教程将调用异步 RPC,而不是使用 CUDA 流来并行执行。 因此,本教程中介绍的解决方案也可以跨计算机边界使用。 本教程的其余部分分四个步骤介绍了实现。
在本教程中,我们使用`ResNet50`作为示例模型,[单机模型并行最佳实践](model_parallel_tutorial.html)教程也使用了该模型。 类似地,`ResNet50`模型被分为两个碎片,输入批被划分为多个拆分,并以流水线方式馈入两个模型碎片。 区别在于,本教程将调用异步 RPC,而不是使用 CUDA 流来并行执行。 因此,本教程中介绍的解决方案也可以跨计算机边界使用。 本教程的其余部分分四个步骤介绍了实现。
## 第 1 步:对 ResNet50 模型进行分区](docs / modern-java-zh /
......@@ -138,7 +138,7 @@ class ResNetShard2(ResNetBase):
## 第 2 步:将 ResNet50 模型碎片拼接到一个模块中](docs / modern-java-zh /
然后,我们创建一个`DistResNet50`模块来组装两个分片并实现流水线并行逻辑。 在构造函数中,我们使用两个`rpc.remote`调用分别将两个分片放在两个不同的 RPC 工作器上,并保持`RRef`到两个模型部分,以便可以在正向传递中引用它们。 `forward`函数将输入批量分为多个微批量,并将这些微批量以流水线方式馈送到两个模型部件。 它首先使用`rpc.remote`调用将第一个分片应用于微批处理,然后将返回的中间输出`RRef`转发到第二个模型分片。 之后,它将收集所有微输出的`Future`,并在循环后等待所有它们。 请注意,`remote()``rpc_async()`都立即返回并异步运行。 因此,整个循环是非阻塞的,并将同时启动多个 RPC。 中间输出`y_rref`保留了两个模型零件上一个微批处理的执行顺序。 微批处理的执行顺序无关紧要。 最后,正向函数将所有微批量的输出连接到一个单一的输出张量中并返回。 `parameter_rrefs`功能是简化分布式优化器构造的助手,将在以后使用。
然后,我们创建一个`DistResNet50`模块来组装两个分片并实现流水线并行逻辑。 在构造函数中,我们使用两个`rpc.remote`调用分别将两个分片放在两个不同的 RPC 工作器上,并保持`RRef`到两个模型部分,以便可以在正向传递中引用它们。 `forward`函数将输入批量分为多个微批量,并将这些微批量以流水线方式馈送到两个模型部件。 它首先使用`rpc.remote`调用将第一个分片应用于微批量,然后将返回的中间输出`RRef`转发到第二个模型分片。 之后,它将收集所有微输出的`Future`,并在循环后等待所有它们。 请注意,`remote()``rpc_async()`都立即返回并异步运行。 因此,整个循环是非阻塞的,并将同时启动多个 RPC。 中间输出`y_rref`保留了两个模型零件上一个微批量的执行顺序。 微批量的执行顺序无关紧要。 最后,正向函数将所有微批量的输出连接到一个单一的输出张量中并返回。 `parameter_rrefs`功能是简化分布式优化器构造的助手,将在以后使用。
```py
class DistResNet50(nn.Module):
......
# 使用异步执行实现批处理 RPC 处理
# 使用异步执行实现批 RPC 处理
> 原文:<https://pytorch.org/tutorials/intermediate/rpc_async_execution.html>
......@@ -11,7 +11,7 @@
* [使用分布式 RPC 框架](rpc_param_server_tutorial.html)实施参数服务器
* [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)
注意
......@@ -28,7 +28,7 @@
使用这两个工具,应用程序代码可以将用户功能分解为多个较小的功能,将它们作为`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) 装饰器来构建分布式批更新参数服务器和批量强化学习应用程序。
## 批量更新参数服务器](docs / modern-java-zh /
......@@ -124,13 +124,13 @@ 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 解算器](docs / modern-java-zh /
## 批 CartPole 解算器](docs / modern-java-zh /
本节以 [OpenAI Gym](https://gym.openai.com/) 中的 CartPole-v1 为例,说明批处理 RPC 的性能影响。 请注意,我们的目标是演示 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 的用法,而不是构建最佳的 CartPole 求解器或解决大多数不同的 RL 问题,我们使用非常简单的策略和奖励计算策略,并将重点放在 多观察者单代理批处理 RPC 实现。 我们使用与前面的教程类似的`Policy`模型,如下所示。 与上一教程相比,不同之处在于其构造函数使用了一个附加的`batch`参数来控制`F.softmax``dim`参数,因为进行批处理时,`forward`函数中的`x`参数包含来自多个观察者的状态 因此尺寸需要适当更改。 其他所有内容保持不变。
本节以 [OpenAI Gym](https://gym.openai.com/) 中的 CartPole-v1 为例,说明批量 RPC 的性能影响。 请注意,我们的目标是演示 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 的用法,而不是构建最佳的 CartPole 求解器或解决大多数不同的 RL 问题,我们使用非常简单的策略和奖励计算策略,并将重点放在 多观察者单代理批量 RPC 实现。 我们使用与前面的教程类似的`Policy`模型,如下所示。 与上一教程相比,不同之处在于其构造函数使用了一个附加的`batch`参数来控制`F.softmax``dim`参数,因为进行批量时,`forward`函数中的`x`参数包含来自多个观察者的状态 因此尺寸需要适当更改。 其他所有内容保持不变。
```py
import argparse
......@@ -165,7 +165,7 @@ class Policy(nn.Module):
```
`Observer`的构造函数也会相应地进行调整。 它还带有`batch`参数,该参数控制用于选择动作的`Agent`函数。 在批处理模式下,它将调用`Agent`上的`select_action_batch`函数,该函数将很快出现,并且该函数将以 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 装饰。
`Observer`的构造函数也会相应地进行调整。 它还带有`batch`参数,该参数控制用于选择动作的`Agent`函数。 在批模式下,它将调用`Agent`上的`select_action_batch`函数,该函数将很快出现,并且该函数将以 [@ rpc.functions.async_execution](https://pytorch.org/docs/master/rpc.html#torch.distributed.rpc.functions.async_execution) 装饰。
```py
import gym
......@@ -220,7 +220,7 @@ class Observer:
```
`Agent`的构造函数还采用`batch`参数,该参数控制如何对动作概率进行批处理。 在批处理模式下,`saved_log_probs`包含一张张量列表,其中每个张量包含一个步骤中所有观察者的动作抢夺。 如果不进行批处理,则`saved_log_probs`是字典,其中的键是观察者 ID,值是该观察者的动作概率列表。
`Agent`的构造函数还采用`batch`参数,该参数控制如何对动作概率进行批量。 在批量模式下,`saved_log_probs`包含一张张量列表,其中每个张量包含一个步骤中所有观察者的动作抢夺。 如果不进行批量,则`saved_log_probs`是字典,其中的键是观察者 ID,值是该观察者的动作概率列表。
```py
import threading
......@@ -249,7 +249,7 @@ class Agent:
```
非批处理`select_acion`只需运行状态抛出策略,保存动作概率,然后立即将动作返回给观察者。
非批`select_acion`只需运行状态抛出策略,保存动作概率,然后立即将动作返回给观察者。
```py
from torch.distributions import Categorical
......@@ -268,7 +268,7 @@ class Agent:
```
使用批处理时,状态以观察者 id 为行 ID 存储在 2D 张量`self.states`中。 然后,它通过将回调函数安装到批处理生成的`self.future_actions` `Future`对象上来链接`Future`,该对象将使用使用该观察者 ID 索引的特定行进行填充。 最后到达的观察者一口气通过策略运行所有批处理状态,并相应地设置`self.future_actions`。 发生这种情况时,将触发安装在`self.future_actions`上的所有回调函数,并使用它们的返回值来填充链接的`Future`对象,该对象进而通知`Agent`为所有先前的 RPC 请求准备和传达响应 来自其他观察者。
使用批量时,状态以观察者 id 为行 ID 存储在 2D 张量`self.states`中。 然后,它通过将回调函数安装到批量生成的`self.future_actions` `Future`对象上来链接`Future`,该对象将使用使用该观察者 ID 索引的特定行进行填充。 最后到达的观察者一口气通过策略运行所有批量状态,并相应地设置`self.future_actions`。 发生这种情况时,将触发安装在`self.future_actions`上的所有回调函数,并使用它们的返回值来填充链接的`Future`对象,该对象进而通知`Agent`为所有先前的 RPC 请求准备和传达响应 来自其他观察者。
```py
class Agent:
......@@ -381,13 +381,13 @@ if __name__ == '__main__':
```
处理 RPC 有助于将操作推断合并为较少的 CUDA 操作,从而减少了摊销的开销。 上面的`main`函数使用不同数量的观察者(从 1 到 10)在批处理和无批处理模式下运行相同的代码。下图使用默认参数值绘制了不同世界大小的执行时间。 结果证实了我们的期望,即批处理有助于加快训练速度。
量 RPC 有助于将操作推断合并为较少的 CUDA 操作,从而减少了摊销的开销。 上面的`main`函数使用不同数量的观察者(从 1 到 10)在批量和无批量模式下运行相同的代码。下图使用默认参数值绘制了不同世界大小的执行时间。 结果证实了我们的期望,即批量有助于加快训练速度。
![](img/f5504c7ed93640f2bed4d2a606c015ba.png)
## 了解更多](docs / modern-java-zh /
* [批量更新参数服务器源代码](https://github.com/pytorch/examples/blob/master/distributed/rpc/batch/parameter_server.py)
* [处理 CartPole 解算器](https://github.com/pytorch/examples/blob/master/distributed/rpc/batch/reinforce.py)
* [ CartPole 解算器](https://github.com/pytorch/examples/blob/master/distributed/rpc/batch/reinforce.py)
* [分布式 Autograd](https://pytorch.org/docs/master/rpc.html#distributed-autograd-framework)
* [分布式管道并行性](dist_pipeline_parallel_tutorial.html)
\ No newline at end of file
......@@ -809,7 +809,7 @@ array([[ 4., 4.],
接下来,我们有一些函数可以随机初始化张量。 其中,最常用的是:
* `tf.random_normal`:从指定平均值和标准差的正态分布中采样随机值
* `tf.random_normal`:从指定平均值和标准差的正态分布中采样随机值
* `tf.random_uniform()`:从指定范围的均匀分布中采样随机值
```py
......
......@@ -401,7 +401,7 @@ import cPickle as pickle #to save/load model
import gym
```
* **超参数初始化**:由于我们正在使用`RMSProp`优化器进行梯度下降,因此超参数(例如隐藏层节点的数量,批处理大小,学习率,折现系数 gamma,衰减率)。 我们将使用以下代码进行初始化:
* **超参数初始化**:由于我们正在使用`RMSProp`优化器进行梯度下降,因此超参数(例如隐藏层节点的数量,批大小,学习率,折现系数 gamma,衰减率)。 我们将使用以下代码进行初始化:
```py
#hyperparameters
......
......@@ -83,7 +83,7 @@
投资组合权重(我们将在后面讨论)实际上是由强化学习驱动的投资组合管理代理的市场行为。 将购买目标权重增加的资产,而目标权重减小的资产将被出售。 因此,最后交易期间的投资组合权重也作为 EIIE 的输入。 因此,每个期间的投资组合权重存储在**投资组合向量存储器****PVM**)中。
EIIE 通过**在线随机批处理学习****OSBL**)进行训练,其中强化学习框架的奖励函数是该时期的平均对数回报。 由于奖励功能是动态的,因此,随着训练是通过梯度上升进行的,EIIE 也在不断发展。 如前所述,EIIE 由一个神经网络组成,因此,对于当前框架,使用不同类型的神经网络测试了三种不同类型的 EIIE,即**卷积神经网络****CNN**),**循环神经网络****RNN**)和**长短期记忆 neworks****LSTM**),这是 RNN 单元。 这种类型的框架可以轻松扩展到不同的市场,而不仅限于一个。
EIIE 通过**在线随机批学习****OSBL**)进行训练,其中强化学习框架的奖励函数是该时期的平均对数回报。 由于奖励功能是动态的,因此,随着训练是通过梯度上升进行的,EIIE 也在不断发展。 如前所述,EIIE 由一个神经网络组成,因此,对于当前框架,使用不同类型的神经网络测试了三种不同类型的 EIIE,即**卷积神经网络****CNN**),**循环神经网络****RNN**)和**长短期记忆 neworks****LSTM**),这是 RNN 单元。 这种类型的框架可以轻松扩展到不同的市场,而不仅限于一个。
该提议框架的测试平台是一个名为 Poloniex 的加密货币交易市场。 实验之前,通过在一定时间间隔内的交易量排名来选择硬币。 实验在 30 分钟的交易时间内进行,并将 EIIE 的性能与前面提到的在线投资组合选择方法进行了比较。 EIIE 能够击败所有这些方法。
......@@ -218,11 +218,11 @@ EIIE 通过**在线随机批处理学习**(**OSBL**)进行训练,其中强
PVM 是按时间步长顺序(即时间顺序)收集投资组合向量的集合。 在训练纪元的每个时间步`t`,策略网络从 *t-1* 的存储位置取最后时间段的投资组合权重向量![](img/ca7f8384-0365-47e5-8367-e72df668cd15.png),并进行覆盖`t`处的内存与输出投资组合权重向量![](img/ae0ed081-d2b6-4980-bda0-ab8224c0ed3f.png)的关系。 由于策略网络参数的收敛,PVM 中的值随着训练时期的增加而收敛。
单个内存堆栈(例如 PVM)还有助于使用迷你批处理提高训练过程的并行性,从而提高训练过程的效率。
单个内存堆栈(例如 PVM)还有助于使用小批量提高训练过程的并行性,从而提高训练过程的效率。
对于有监督的学习,数据的排序以小批量为单位,但是在这里,数据需要按照训练过程中每批传递的时间步长进行排序。 现在,由于数据是按时间序列格式的,因此从不同时间段开始的小批处理是更可取的,因为它们涵盖了训练过程的独特数据。 金融市场的持续性导致不断向代理网络输入新数据,从而导致训练数据中的数据爆炸。
对于有监督的学习,数据的排序以小批量为单位,但是在这里,数据需要按照训练过程中每批传递的时间步长进行排序。 现在,由于数据是按时间序列格式的,因此从不同时间段开始的小批是更可取的,因为它们涵盖了训练过程的独特数据。 金融市场的持续性导致不断向代理网络输入新数据,从而导致训练数据中的数据爆炸。
因此,提出了 OSBL,其中在时段`t`结束时,时段的价格变动将添加到训练集中。 在完成时间段 *t + 1* 的订单后,使用从该组中随机选择的迷你批量对策略网络进行训练。 有关 OSBL 的完整详细研究超出了本书的范围,但是为了进一步探索,请阅读[上的“ *金融组合管理问题的深层强化学习框架*”中的 5.3 节。 ] https://arxiv.org/pdf/1706.10059.pdf](https://arxiv.org/pdf/1706.10059.pdf)
因此,提出了 OSBL,其中在时段`t`结束时,时段的价格变动将添加到训练集中。 在完成时间段 *t + 1* 的订单后,使用从该组中随机选择的批量对策略网络进行训练。 有关 OSBL 的完整详细研究超出了本书的范围,但是为了进一步探索,请阅读[上的“ *金融组合管理问题的深层强化学习框架*”中的 5.3 节。 ] https://arxiv.org/pdf/1706.10059.pdf](https://arxiv.org/pdf/1706.10059.pdf)
使用所有三个不同的策略网络(即 CNN,RNN 和 LSTM)在加密货币交易所 Poloniex 上对该框架进行了测试。 用于检查框架性能的投资组合的财务指标为:
......@@ -239,7 +239,7 @@ PVM 是按时间步长顺序(即时间顺序)收集投资组合向量的集
* 在此,仅使用了深度神经网络的三个变体,但也可以应用其他变体
* 随着投资组合规模的增加可线性扩展
* PVM 在使用迷你批量的训练中增加了并行性功能
* PVM 在使用批量的训练中增加了并行性功能
* OSBL 帮助在线使用实时输入数据
# 进一步的改进
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册