提交 a083ad67 编写于 作者: W wizardforcel

2021-01-16 12:21:38

上级 d4bb5c29
......@@ -226,7 +226,7 @@ Rosenblatt 还介绍了权重的概念(`w`1,`w`2,…,`w`n),这些数
此处,`α`是指学习率,`dw / db`表示给定神经元中权重或偏差的梯度。 从权重或偏差的原始值中减去两个值的乘积,以惩罚较高的值,这有助于计算较大的损失函数。
梯度下降算法的一种改进版本称为随机梯度下降,它基本上遵循相同的过程,区别在于它以随机批而不是一个块的形式获取输入数据,从而缩短了训练时间,同时达到了出色的性能。 此外,此方法允许使用较大的数据集,因为通过将小批数据集用作输入,我们不再受计算资源的限制。
梯度下降算法的一种改进版本称为随机梯度下降,它基本上遵循相同的过程,区别在于它以随机批而不是一个块的形式获取输入数据,从而缩短了训练时间,同时达到了出色的性能。 此外,此方法允许使用较大的数据集,因为通过将小批数据集用作输入,我们不再受计算资源的限制。
## 优缺点
......
......@@ -454,9 +454,9 @@ batch_size = 100
接下来,循环的第一个**用于遍历我们之前定义的时期数。**
请记住,**时期**是指整个数据集通过网络体系结构前后传递的次数。`batch_size`是指单个批(数据集的一部分)中训练示例的数量。 最后,**迭代**是指完成一个时期所需的批处理数量。
请记住,**时期**是指整个数据集通过网络体系结构前后传递的次数。`batch_size`是指单个批(数据集的一部分)中训练示例的数量。 最后,**迭代**是指完成一个时期所需的批处理数量。
第二个`for`循环遍历总数据集的每个批,直到完成一个纪元为止。 在此循环中,发生以下计算:
第二个`for`循环遍历总数据集的每个批,直到完成一个纪元为止。 在此循环中,发生以下计算:
1. 在一批训练集上训练模型。 在此获得预测。
2. 通过比较上一步的预测值和训练集的标签(真实情况)来计算损失。
......@@ -470,7 +470,7 @@ batch_size = 100
使用 scikit-learn 的“度量”部分,计算准确性,精确度或查全率。 您还可以探索其他性能指标。
将所有批的训练数据输入模型后,将关闭梯度计算,以通过验证数据验证当前模型的性能,如下所示:
将所有批的训练数据输入模型后,将关闭梯度计算,以通过验证数据验证当前模型的性能,如下所示:
1. 该模型对验证集中的数据执行预测。
2. 通过将先前的预测与验证集中的标签进行比较来计算损失函数。
......
......@@ -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`)将分别包含功能部件和目标的值。
注意
......@@ -548,7 +548,7 @@ test_loader = torch.utils.data.DataLoader(test_data, \
2. 设置要对数据执行的转换,这将是数据到张量的转换以及像素值的归一化。
3. 设置批量为 100 张图像,并从 **CIFAR10** 数据集下载训练和测试数据。
4. 使用 20% 的验证大小,定义将用于将数据集分为这两组的训练和验证采样器。
5. 使用`DataLoader()`函数定义用于每组数据的批
5. 使用`DataLoader()`函数定义用于每组数据的批
6. Define the architecture of your network. Use the following information to do so:
Conv1:卷积层,将彩色图像作为输入,并将其通过大小为 3 的 10 个滤镜。应将 padding 和 stride 都设置为 1。
......@@ -719,7 +719,7 @@ test_data = datasets.CIFAR10('data', train=False, download=True, \
我们不应该主要依靠批量归一化来处理过度拟合。
如前几节所述,通过减去批次平均值并除以批次标准偏差,可以对隐藏层的输出进行归一化。
如前几节所述,通过减去批量平均值并除以批量标准偏差,可以对隐藏层的输出进行归一化。
此外,通常在卷积层以及 FC 层(不包括输出层)上执行批归一化。
......
......@@ -244,7 +244,7 @@ for i in range(1, epochs+1):
对于每个时期,隐藏状态都初始化为`None`。 这是因为,在每个时期,网络都会尝试将输入映射到目标(给定一组参数时)。 该映射应该与数据集中之前的运行没有任何偏差(隐藏状态)地发生。
接下来,`for`循环遍历不同批的数据。 在此循环内,将进行预测并保存隐藏状态,该状态将用作下一批的输入。
接下来,`for`循环遍历不同批的数据。 在此循环内,将进行预测并保存隐藏状态,该状态将用作下一批的输入。
最后,计算损失函数,该函数用于更新网络参数。 然后,该过程再次开始,直到达到所需的时期数。
......@@ -388,9 +388,9 @@ for c in text:
代码的第二行创建一个包含文本字母(即文本序列中的字母和字符)的列表。 接下来,使用每个字母或字符作为键并使用与其关联的数字表示作为值来创建字典。 最后,通过对文本执行`for`循环,可以将每个字母或字符替换为其数字表示形式,从而将文本转换为数字矩阵。
### 生成批
### 生成批
对于 RNN,使用两个变量创建批次:每个批次的序列数和每个序列的长度。 这些值用于将数据划分为矩阵,这将有助于加快计算速度。
对于 RNN,使用两个变量创建批量:每个批量的序列数和每个序列的长度。 这些值用于将数据划分为矩阵,这将有助于加快计算速度。
使用 24 个整数的数据集,每批的序列数设置为 2,序列长度等于 4,除法如下:
......@@ -398,11 +398,11 @@ for c in text:
图 6.20:RNN 的批量生成
如上图所示,创建了三个批次–每个批次包含两个长度为 4 的序列。
如上图所示,创建了三个批量–每个批量包含两个长度为 4 的序列。
对于`x``y`,应完成此批生成过程,其中前者是网络的输入,后者是目标。 据此,网络的思想是找到一种方法来映射`x``y`之间的关系,考虑到`y`将领先一步。`x`
`x`的批次是按照上图中说明的方法创建的。 然后,将创建`y`的批次,以使其与`x`的长度相同。 这是因为`y`的第一个元素将是`x`的第二个元素,依此类推,直到`y`的最后一个元素(将是第一个元素)`x`的数量):
`x`的批量是按照上图中说明的方法创建的。 然后,将创建`y`的批量,以使其与`x`的长度相同。 这是因为`y`的第一个元素将是`x`的第二个元素,依此类推,直到`y`的最后一个元素(将是第一个元素)`x`的数量):
注意
......@@ -410,7 +410,7 @@ for c in text:
![Figure 6.21: A representation of the batches for x and y ](img/B15778_06_21.jpg)
图 6.21:x 和 y 批的表示
图 6.21:x 和 y 批的表示
批处理的生成可以通过以下代码片段实现:
......@@ -425,11 +425,11 @@ for b in range(0, x.shape[1], 5):
注意
尽管生成批被视为预处理数据的一部分,但通常会在训练过程的`for`循环内部对其进行编程。
尽管生成批被视为预处理数据的一部分,但通常会在训练过程的`for`循环内部对其进行编程。
## 一键编码
将所有字符转换为数字不足以将其输入模型。 这是因为这种近似会给您的模型带来一些偏差,因为转换为更高数值的字符将被视为更重要。 为避免这种情况,优良作法是将不同批编码为一热矩阵。 这包括创建一个具有零和一的三维矩阵,其中零表示不存在事件,而一个表示存在事件。 矩阵的最终形状应为`one hot = [number of sequences, sequence length, number of characters]`
将所有字符转换为数字不足以将其输入模型。 这是因为这种近似会给您的模型带来一些偏差,因为转换为更高数值的字符将被视为更重要。 为避免这种情况,优良作法是将不同批编码为一热矩阵。 这包括创建一个具有零和一的三维矩阵,其中零表示不存在事件,而一个表示存在事件。 矩阵的最终形状应为`one hot = [number of sequences, sequence length, number of characters]`
这意味着,对于批处理中的每个元素,它将创建一个长度等于整个文本中字符总数的值序列。 对于每个字符,它将放置一个零,但该位置存在一个零(它将放置一个)。
......@@ -450,7 +450,7 @@ onehot = onehot_flat.reshape((batch.shape[0],\
                              batch.shape[1], -1))
```
首先,将二维批展平。 接下来,创建一个矩阵,并用零填充。 当我们需要在给定位置表示正确的字符时,用零代替零。 最后,展平的尺寸再次扩大。
首先,将二维批展平。 接下来,创建一个矩阵,并用零填充。 当我们需要在给定位置表示正确的字符时,用零代替零。 最后,展平的尺寸再次扩大。
## 练习 6.02:预处理输入数据并创建一倍热矩阵
......@@ -686,7 +686,7 @@ while starter[-1] != "." and counter < 50:
4. 将数据集中的每个字母编码为成对的整数。 打印数据集的前 50 个编码字符和编码版本的总长度。
5. 创建一个接受批处理并将其编码为单热点矩阵的函数。
6. 创建一个定义网络体系结构的类。 该类应包含一个用于初始化 LSTM 层状态的附加函数。
7. 请确定要从数据集中创建的批次数量,请记住每个批次应包含 100 个序列,每个批次的长度应为 50。接下来,将编码数据拆分为 100 个序列。
7. 请确定要从数据集中创建的批量数量,请记住每个批量应包含 100 个序列,每个批量的长度应为 50。接下来,将编码数据拆分为 100 个序列。
8. 使用 256 作为隐藏单位数(总共两个循环层)实例化模型。
9. Define the loss function and the optimization algorithms. Use the Adam optimizer and the cross-entropy loss. Train the network for 20 epochs.
......@@ -698,7 +698,7 @@ while starter[-1] != "." and counter < 50:
注意
为输入和目标创建了批 ,其中后者是前者的副本,但领先一步。
为输入和目标创建了批 ,其中后者是前者的副本,但领先一步。
11. 绘制随时间推移的损失进度。
12. Feed the following sentence starter into the trained model and complete the sentence: "So she was considering in her own mind ".
......@@ -805,7 +805,7 @@ class LSTM(nn.Module):
## 训练模型
最后,在定义了损失函数和优化算法之后,训练模型的过程与任何其他神经网络相同。 根据研究的需要和目的,可以将数据分为不同的组。 接下来,您必须设置时期数和将数据分成批的方法。 通常在处理每批数据时保留网络内存,但随后在每个时期将其初始化为零。 通过对一批数据调用模型来获得网络的输出。 然后,计算损失函数,并优化参数。
最后,在定义了损失函数和优化算法之后,训练模型的过程与任何其他神经网络相同。 根据研究的需要和目的,可以将数据分为不同的组。 接下来,您必须设置时期数和将数据分成批的方法。 通常在处理每批数据时保留网络内存,但随后在每个时期将其初始化为零。 通过对一批数据调用模型来获得网络的输出。 然后,计算损失函数,并优化参数。
## 活动 6.03:用于情感分析的 Performin g NLP
......
......@@ -1057,7 +1057,7 @@
batch_size =批量大小)
PyTorch 的`DataLoader`函数用于创建批次,这些批次将在开发过程的训练,验证和测试阶段馈送到模型中。
PyTorch 的`DataLoader`函数用于创建批量,这些批量将在开发过程的训练,验证和测试阶段馈送到模型中。
6. Define the architecture of your network. Use the following information to do so:
......@@ -1155,7 +1155,7 @@
"""
For 遍历批(使用创建
For 遍历批(使用创建
火车装载者)
......@@ -1275,7 +1275,7 @@
"""
循环遍历批
循环遍历批
(使用火车装载程序创建)
......@@ -2089,7 +2089,7 @@
注意
考虑到没有批次用于遍历数据集,`hidden`量实际上并未在批次之间传递(而是在处理序列的每个元素时使用隐藏状态),但是 为了清楚起见,它留在这里。
考虑到没有批量用于遍历数据集,`hidden`量实际上并未在批量之间传递(而是在处理序列的每个元素时使用隐藏状态),但是 为了清楚起见,它留在这里。
损失= []
......@@ -2249,7 +2249,7 @@
5. Create a function that takes in a batch and encodes it as a one-hot matrix:
def index2onehot(批):
def index2onehot(批):
batch_flatten = batch.flatten()
......
此差异已折叠。
此差异已折叠。
......@@ -8,7 +8,7 @@
* 梯度下降概述
* 了解模型不可知的元学习
* 了解 LSTM 元学习
* 了解 LSTM 元学习
* 编码练习
# 技术要求
......@@ -76,7 +76,7 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的
结束`repeat`循环。
对于 Omniglot 和 mini-ImageNet 数据集,MAML 能够实现比暹罗网络,匹配网络和内存增强神经网络更好的性能。 由于事实证明 MAML 的性能更好,因此还有许多其他任务可以使用 MAML。 让我们来看一个这样的变体-**域自适应元学习****DAML**)。
对于 Omniglot 和 mini-ImageNet 数据集,MAML 能够实现比连体网络,匹配网络和内存增强神经网络更好的性能。 由于事实证明 MAML 的性能更好,因此还有许多其他任务可以使用 MAML。 让我们来看一个这样的变体-**域自适应元学习****DAML**)。
# MAML 应用程序–领域自适应元学习
......@@ -86,16 +86,16 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的
由于无法使用模仿学习损失函数来训练机器人,因此 DAML 提出了行为克隆目标**暂时损失**,该目标也充当日志空间中的正则化项。 众所周知,在任何情况下都要进行强正则化对于避免过度拟合非常重要,尤其是在单次学习的情况下。
# 了解 LSTM 元学习
# 了解 LSTM 元学习
LSTM 元学习器是一种元学习。 LSTM 元学习器分为两个阶段:
* **元学习**:在此阶段,模型着重于学习跨各种任务的常识。
* **基础学习者**:在基础学习者中,模型尝试优化以学习任务特定目标的参数。
* **元学习**:在此阶段,模型着重于学习跨各种任务的常识。
* **基础学习器**:在基础学习器中,模型尝试优化以学习任务特定目标的参数。
LSTM 元学习器的关键思想是训练 LSTM 单元以*学习我们原始任务的更新规则*。 用元学习框架的术语来说, **LSTM 细胞**将用作元学习者,而*特定于任务的* *目标*(例如狗的品种分类)将被使用 成为*基础学习者*
LSTM 元学习器的关键思想是训练 LSTM 单元以*学习我们原始任务的更新规则*。 用元学习框架的术语来说, **LSTM 细胞**将用作元学习器,而*特定于任务的* *目标*(例如狗的品种分类)将被使用 成为*基础学习器*
现在,问题来了,为什么我们要使用 LSTM 电池? LSTM 元学习器的作者做出了一个关键的观察,即 LSTM 中的单元状态更新与反向传播中的基于梯度的更新相似,可用于学习基本学习目标的更新规则:
现在,问题来了,为什么我们要使用 LSTM 电池? LSTM 元学习器的作者做出了一个关键的观察,即 LSTM 中的单元状态更新与反向传播中的基于梯度的更新相似,可用于学习基本学习目标的更新规则:
![](img/7f93507c-8eba-4a42-a6f5-8eb229b65be1.png)
......@@ -131,21 +131,21 @@ LSTM 在各种门的帮助下存储信息历史记录,如上图所示。 我
本质上, *f <sub>t</sub>* 被定义为具有电流梯度,电流损耗和遗忘门的 S 型函数。
您可能想知道为什么他们使用 LSTM 电池的这种特定选择? 如果仔细观察,会根据电流梯度和电流损耗选择 *i <sub>t</sub>**f <sub>t</sub>* 。 故意这样做是为了使元学习者能够*控制学习率*,以便在更少的时间内训练基础学习者
您可能想知道为什么他们使用 LSTM 电池的这种特定选择? 如果仔细观察,会根据电流梯度和电流损耗选择 *i <sub>t</sub>**f <sub>t</sub>* 。 故意这样做是为了使元学习器能够*控制学习率*,以便在更少的时间内训练基础学习器
# 数据预处理
在一般的深度学习设置中,要在给定数据集`D`上训练模型,我们将数据集分为三个部分:训练,验证和测试集。 但是在元学习设置中,我们首先将数据集划分为特定于任务的集(例如,猫品种分类和狗品种分类),称为**元集**,例如 <sub>![](img/3dd71e02-585b-4faf-97b1-18515169a0a1.png)</sub> 。 对于每个 D <sub>![](img/599bcf1b-32c6-4ae9-9722-c9ced775b04f.png)</sub><sub>![](img/ecebee63-c8fc-4914-9c04-a57eb42709a7.png)</sub><sub>![](img/cef2edc3-0b4e-4301-9716-12701269e95a.png)</sub> 组成,因此对于`K`镜头学习,每个 <sub>![](img/34a3cb7f-a7ac-48d2-a9ea-3e5259206ebc.png)</sub>*K * N* 个示例组成,其中`N`是类数。
此后, <sub>![](img/69c38655-6d44-4aa8-825a-a3edd9e03780.png)</sub> 进一步分为三个部分:![](img/224d8b14-1e25-4552-8310-74fe1d90f03b.png)。 在这里,目标是使用 <sub>![](img/d25156e7-7e5a-4f00-a665-249a333e60c6.png)</sub> 训练*学习算法*,该算法可以将任何特定于任务的集合作为训练集 <sub>![](img/0d2fad60-1123-4702-825d-4107499b703b.png)</sub> 并产生 更好的分类器(学习)。
此后, <sub>![](img/69c38655-6d44-4aa8-825a-a3edd9e03780.png)</sub> 进一步分为三个部分:![](img/224d8b14-1e25-4552-8310-74fe1d90f03b.png)。 在这里,目标是使用 <sub>![](img/d25156e7-7e5a-4f00-a665-249a333e60c6.png)</sub> 训练*学习算法*,该算法可以将任何特定于任务的集合作为训练集 <sub>![](img/0d2fad60-1123-4702-825d-4107499b703b.png)</sub> 并产生 更好的分类器(学习)。
# 算法–伪代码实现
要训​​练一个一次学习模型,您需要匹配训练条件以测试时间条件,例如,像在匹配网络中一样,在较少的数据上进行训练,但要进行多个批。 LSTM 元学习器也遵循与匹配网络相同的概念,并已被证明在特定任务目标上确实表现出色。
要训​​练一个一次学习模型,您需要匹配训练条件以测试时间条件,例如,像在匹配网络中一样,在较少的数据上进行训练,但要进行多个批。 LSTM 元学习器也遵循与匹配网络相同的概念,并已被证明在特定任务目标上确实表现出色。
要开始理解 LSTM 元学习器,首先,我们需要了解某些术语:
* **基础学习**`M`):具有特定任务的主要目标,带有参数 <sub>![](img/3a869193-6666-428a-9b6a-c61e430a0a72.png)</sub> -例如,用于识别猫的分类器
* **基础学习**`M`):具有特定任务的主要目标,带有参数 <sub>![](img/3a869193-6666-428a-9b6a-c61e430a0a72.png)</sub> -例如,用于识别猫的分类器
* **元学习器**`R`):LSTM 单元,带有参数,![](img/b72b74c6-cdc3-4fc1-bd73-fa86f86f29ad.png)
* **数据点****X,Y**):从 <sub>![](img/413e3fb6-3c9b-41de-942d-df2693286095.png)</sub> 采样的数据点
* **损失**`L`):用于调整主要任务特定目标的损失函数,例如,二进制交叉熵损失
......@@ -156,17 +156,17 @@ LSTM 在各种门的帮助下存储信息历史记录,如上图所示。 我
2. 对于 D = 1 至`n`步骤,请执行以下操作:
*<sub>![](img/413e3fb6-3c9b-41de-942d-df2693286095.png)</sub> 中随机抽取 <sub>![](img/1be8b605-c639-4b2f-9ae5-946c9ee8db6a.png)</sub>
* 随机初始化基础学习(分类模型)的初始参数( <sub>![](img/f1056b08-996c-4b72-93b8-de37060e4271.png)</sub> )。
* 随机初始化基础学习(分类模型)的初始参数( <sub>![](img/f1056b08-996c-4b72-93b8-de37060e4271.png)</sub> )。
* 对于 t = 1 至`T`步骤,重复以下步骤:
*<sub>![](img/77764a57-316f-4a17-8712-0499a6523669.png)</sub> 中随机采样输入输出对 <sub>![](img/71e25973-354f-4d95-b3b0-56383cd261af.png)</sub>
* 使用 <sub>![](img/307d9408-f535-4291-88fb-e187378dc7fa.png)</sub> 计算基础学习(分类模型)的损失。
* 使用单元格的基本学习的损失( <sub>![](img/d1aa0375-2232-46e1-840f-f213a4df4301.png)</sub> )及其梯度( <sub>![](img/a74a946f-2e63-419e-a071-52a6583c1b03.png)</sub> ),更新单元格状态( <sub>![](img/4aeee18a-9066-46f8-aec9-3db61801cbf1.png)</sub> ) 状态方程。
* 使用 <sub>![](img/307d9408-f535-4291-88fb-e187378dc7fa.png)</sub> 计算基础学习(分类模型)的损失。
* 使用单元格的基本学习的损失( <sub>![](img/d1aa0375-2232-46e1-840f-f213a4df4301.png)</sub> )及其梯度( <sub>![](img/a74a946f-2e63-419e-a071-52a6583c1b03.png)</sub> ),更新单元格状态( <sub>![](img/4aeee18a-9066-46f8-aec9-3db61801cbf1.png)</sub> ) 状态方程。
* 将基本学习器(分类模型)参数更新为![](img/f4cec93e-d6dd-4b3e-a207-339dcb81365c.png)(请参阅 LSTM 元学习器的*体系结构*部分)。
结束 *T-* 步骤循环。
* 现在,从 <sub>![](img/282a821c-7838-44d3-8f27-6f005e6ce9a3.png)</sub> 中随机采样输入输出对 <sub>![](img/1f1b9829-2e28-4cd8-a7c1-c8d3f4e68943.png)</sub>
* 使用 <sub>![](img/71c38e54-fe54-4ff4-965a-2dfc17c028ce.png)</sub> 计算基础学习(分类模型)的损失。
* 使用 <sub>![](img/71c38e54-fe54-4ff4-965a-2dfc17c028ce.png)</sub> 计算基础学习(分类模型)的损失。
* 使用 <sub>![](img/1c0b9014-4f36-4cb4-81df-076efdf752ea.png)</sub> (请参阅 LSTM 元学习器*体系结构*部分)更新元学习器(LSTM 单元)参数( <sub>![](img/0a9e3c82-d840-4d57-85fd-8d421048a655.png)</sub> )。
结束 *n-* 步骤循环。
......@@ -541,7 +541,7 @@ plt.savefig('daml-sine.png')
要求解任何方程,通常我们可以使用很多方法。 同样,为了进行优化(学习神经网络的参数),许多研究人员也公开了许多方法,但是事实证明梯度下降是一种适用于每种情况的通用方法。 如果我们希望处理特定类型的神经网络问题,那么最好探索可能适合我们任务的不同优化技术。
在这一章中,我们研究了两种最著名的一次学习优化方法:MAML 和 LSTM 元学习器。 我们了解了 MAML 如何通过优化我们的初始参数设置来解决一次学习问题,从而在几个数据点上进行一个或几个梯度下降步骤可以导致更好的概括。 我们还探讨了 LSTM 元学习者对如何训练 LSTM 细胞作为元学习者以预测基础学习者体重更新的见解。
在这一章中,我们研究了两种最著名的一次学习优化方法:MAML 和 LSTM 元学习器。 我们了解了 MAML 如何通过优化我们的初始参数设置来解决一次学习问题,从而在几个数据点上进行一个或几个梯度下降步骤可以导致更好的概括。 我们还探讨了 LSTM 元学习器对如何训练 LSTM 细胞作为元学习器以预测基础学习器体重更新的见解。
在下一章中,我们将探讨一种著名的 ML 方法贝叶斯学习。 我们将通过用概率模型表示对象类别来观察几个贝叶斯学习框架的发展。 我们将对判别式`K`-镜头学习和贝叶斯程序学习及其在现实世界中的应用进行恰当的解释。
......
......@@ -220,7 +220,7 @@ k 镜头测试时间 <sub>![](img/c3734ba9-5a51-47ff-84f2-54c038662868.png)</sub
在本章中,我们学习了在贝叶斯框架内开发概率模型的方法,该模型可以极大地减少数据需求并达到人类水平的性能。 从前面讨论的手写字符的示例中,我们还观察到概率模型不仅可以学习如何对字符进行分类,还可以学习基本概念,即以新的方式应用获得的知识,例如生成相似的字符并生成全新的 集合中只有几个字符的字符,以及将字符解析为部分和关系。
但是,人类学习需要从具有丰富重叠结构的许多经验中获得的广泛的先前经验来完成新的学习任务。 为了模仿人类学习,图形结构需要具有更多的依赖性,并且需要在模型中内置丰富的归纳偏差。 还应注意,人类在很小的时候就对物体的物理特性(形状,运动和其他力学)有很好的认识。 学习模型不会隐式地捕获对象的直观物理特性,也不会显式地将其嵌入对象中。 直观物理(类似于游戏引擎中嵌入的物理)与概率模型和深度学习的集成,是朝着更健壮的单发学习迈出的重要一步。 最后,由于先验知识以强先验和图形结构的形式嵌入到概率模型中,因此与必须从头学习任务的深度学习模型相比,它们的数据消耗更少。 但这是以在概率模型中进行有效推理的计算挑战为代价的。 在推论时,这些模型必须搜索巨大的概率空间,这对于现代计算机而言是不实际的。 相反,深度学习模型具有精确且计算上便宜的推断。 最近的工作通过使用前馈映射对*摊销*概率推理计算来解决图形模型中的这一推理挑战,可以使用成对的生成/识别网络来学习。 这提供了另一条有希望的研究领域,使深度学习和概率模型更加接近。
但是,人类学习需要从具有丰富重叠结构的许多经验中获得的广泛的先前经验来完成新的学习任务。 为了模仿人类学习,图形结构需要具有更多的依赖性,并且需要在模型中内置丰富的归纳偏差。 还应注意,人类在很小的时候就对物体的物理特性(形状,运动和其他力学)有很好的认识。 学习模型不会隐式地捕获对象的直观物理特性,也不会显式地将其嵌入对象中。 直观物理(类似于游戏引擎中嵌入的物理)与概率模型和深度学习的集成,是朝着更健壮的单发学习迈出的重要一步。 最后,由于先验知识以强先验和图形结构的形式嵌入到概率模型中,因此与必须从头学习任务的深度学习模型相比,它们的数据消耗更少。 但这是以在概率模型中进行有效推理的计算挑战为代价的。 在推论时,这些模型必须搜索巨大的概率空间,这对于现代计算机而言是不实际的。 相反,深度学习模型具有精确且计算上便宜的推断。 最近的工作通过使用前馈映射对*摊销*概率推理计算来解决图形模型中的这一推理挑战,可以使用成对的生成/识别网络来学习。 这提供了另一条有希望的研究领域,使深度学习和概率模型更加接近。
# 进一步阅读
......
......@@ -14,7 +14,7 @@
基于度量的学习是进行单次学习的较旧方法之一。 尽管该区域较旧,但仍在探索许多方面。 一个很好的例子是关于[《为短时学习重新研究基于局部描述符的图像到类度量》](https://arxiv.org/abs/1903.12290)主题的研究工作。 在本文中,作者提出了一种卷积神经网络体系结构,称为 **D4N****深最近邻神经网络**),该体系结构可提取图像级特征。 它与其他神经网络体系结构的主要区别是用基于局部描述符的图像到类度量替代了最后一层。
[《通过类别遍历查找与几次任务学习相关的任务相关特征》](https://arxiv.org/abs/1905.11116)也为改进度量学习方法做出了贡献,方法是引入 一个插件框架。 在本文中,作者讨论了众所周知的度量学习方法(例如暹罗网络和匹配网络)如何一次只关注一个任务,而不是整个学习所有任务。 **类别遍历模块****CTM**)插件组件通过完成所有支持任务来学习重要的尺寸特征。 CTM 在集中器和投影仪单元的帮助下,为相似类别提取通用特征嵌入,并在不同类别中提取唯一特征。 使用 CTM 的输出,我们可以在元学习器之前添加一个强大的功能,这可以使我们更快更好地进行优化。 通过使用此框架,他们显示了基于度量的学习方法的显着改进。
[《通过类别遍历查找与几次任务学习相关的任务相关特征》](https://arxiv.org/abs/1905.11116)也为改进度量学习方法做出了贡献,方法是引入 一个插件框架。 在本文中,作者讨论了众所周知的度量学习方法(例如连体网络和匹配网络)如何一次只关注一个任务,而不是整个学习所有任务。 **类别遍历模块****CTM**)插件组件通过完成所有支持任务来学习重要的尺寸特征。 CTM 在集中器和投影仪单元的帮助下,为相似类别提取通用特征嵌入,并在不同类别中提取唯一特征。 使用 CTM 的输出,我们可以在元学习器之前添加一个强大的功能,这可以使我们更快更好地进行优化。 通过使用此框架,他们显示了基于度量的学习方法的显着改进。
在对象检测和语义分割领域也有一些显着贡献。 让我们讨论其中的两种方法。
......@@ -71,7 +71,7 @@
![](img/d2619e72-ed14-4933-9ca1-7d658c79f2f2.png)
换句话说,在一个数据集上训练的神经网络模型可以通过对前一个网络进行微调而用于其他数据集,就像我们如何使用在不同域数据集(例如 MNIST 数据集)上训练的暹罗网络来提取更好的特征一样 用于签名匹配,手写匹配等。 迁移学习在深度学习领域引起了很多关注,并已被证明对于许多应用程序非常有用。 但是,由于数据限制,我们无法在制造,医药,化学等非常见领域中使用它。
换句话说,在一个数据集上训练的神经网络模型可以通过对前一个网络进行微调而用于其他数据集,就像我们如何使用在不同域数据集(例如 MNIST 数据集)上训练的连体网络来提取更好的特征一样 用于签名匹配,手写匹配等。 迁移学习在深度学习领域引起了很多关注,并已被证明对于许多应用程序非常有用。 但是,由于数据限制,我们无法在制造,医药,化学等非常见领域中使用它。
# 应用领域
......
......@@ -102,13 +102,13 @@ PyTorch 的主要优点之一是它能够通过使用**图形处理单元**(**
GPU 最初是为了有效地渲染图形而创建的,但是由于深度学习在的普及中得到了发展,因此 GPU 被广泛用于同时执行多种计算的能力。 传统的 CPU 可能包含大约四个或八个内核,而 GPU 则包含数百个较小的内核。 由于可以同时在所有这些内核上执行计算,因此 GPU 可以快速减少执行深度学习任务所需的时间。
考虑神经网络内的一次通过。 我们可能会采集少量数据,将其通过我们的网络以获得损失,然后反向传播,根据梯度调整参数。 如果在传统的 CPU 上要处理大量数据,则必须等到批次 1 完成后才能计算批次 2:
考虑神经网络内的一次通过。 我们可能会采集少量数据,将其通过我们的网络以获得损失,然后反向传播,根据梯度调整参数。 如果在传统的 CPU 上要处理大量数据,则必须等到批量 1 完成后才能计算批量 2:
![Figure 2.7 – One pass in a neural network ](img/B12365_02_7.jpg)
图 2.7 –神经网络中的一遍
但是,在 GPU 上,我们可以同时执行所有这些步骤,这意味着不需要批处理即可在批处理 2 开始之前完成。 我们可以同时计算所有批的参数更新,然后一次执行所有参数更新(因为结果彼此独立)。 并行方法可以极大地加快机器学习过程:
但是,在 GPU 上,我们可以同时执行所有这些步骤,这意味着不需要批处理即可在批处理 2 开始之前完成。 我们可以同时计算所有批的参数更新,然后一次执行所有参数更新(因为结果彼此独立)。 并行方法可以极大地加快机器学习过程:
![Figure 2.8 – Parallel approach to perform passes ](img/B12365_02_8.jpg)
......
......@@ -229,7 +229,7 @@ Questions.vocab.vectors
图 6.14 –张量内容
接下来,我们创建数据迭代器。 我们为训练和验证数据创建单独的迭代器。 我们首先指定一种设备,以便能够使用支持 CUDA 的 GPU 更快地训练模型。 在迭代器中,我们还指定了要由迭代器返回的批处理的大小,在这种情况下为`64`。 您可能希望对模型使用不同批大小的进行试验,因为这可能会影响训练速度以及模型收敛到其全局最优速度的速度:
接下来,我们创建数据迭代器。 我们为训练和验证数据创建单独的迭代器。 我们首先指定一种设备,以便能够使用支持 CUDA 的 GPU 更快地训练模型。 在迭代器中,我们还指定了要由迭代器返回的批处理的大小,在这种情况下为`64`。 您可能希望对模型使用不同批大小的进行试验,因为这可能会影响训练速度以及模型收敛到其全局最优速度的速度:
device = torch.device(如果 torch.cuda.is_available()则为“ cuda”,否则为“ cpu”)
......@@ -401,7 +401,7 @@ epoch_acc = 0
model.train()
接下来,我们遍历迭代器中的每批数据并执行训练步骤。 我们首先将梯度归零,以防止从上一批中计算出累积梯度。 然后,我们使用模型的当前状态根据当前批次中的句子进行预测,然后将其与标签进行比较以计算损失。 使用我们在上一节中定义的精度函数,我们可以计算给定批次的精度。 然后,我们反向传播损失,通过梯度下降更新权重并逐步通过优化器:
接下来,我们遍历迭代器中的每批数据并执行训练步骤。 我们首先将梯度归零,以防止从上一批中计算出累积梯度。 然后,我们使用模型的当前状态根据当前批量中的句子进行预测,然后将其与标签进行比较以计算损失。 使用我们在上一节中定义的精度函数,我们可以计算给定批量的精度。 然后,我们反向传播损失,通过梯度下降更新权重并逐步通过优化器:
对于迭代器中的批处理:
......@@ -417,7 +417,7 @@ loss.backward()
Optimizer.step()
最后,我们将这一批次的损失和准确性加到整个时期的总损失和准确性中。 在循环遍历该时期内的所有批次之后,我们计算该时期的总损失和准确性并返回:
最后,我们将这一批量的损失和准确性加到整个时期的总损失和准确性中。 在循环遍历该时期内的所有批量之后,我们计算该时期的总损失和准确性并返回:
epoch_loss + = loss.item()
......
......@@ -507,7 +507,7 @@ corpus_name = "movie_corpus"
batchs = batch2Train(voc,[范围内的 _ \的 random.choice(pairs)对(test_batch_size)])
input_variable,长度,target_variable,掩码,max_target_len =批
input_variable,长度,target_variable,掩码,max_target_len =批
在这里,我们可以验证输入张量是否已正确创建。 注意句子如何以填充(0 个标记)结尾,其中句子长度小于张量的最大长度(在本例中为 9)。 张量的宽度也对应于批量大小(在这种情况下为 5):
......
......@@ -73,7 +73,7 @@ pip install torchvision
>>batch_size = 64
```
4.接下来,我们将从`torchvision`中提取数据集并应用转换并创建批。 为此,我们将首先创建一个训练数据集:
4.接下来,我们将从`torchvision`中提取数据集并应用转换并创建批。 为此,我们将首先创建一个训练数据集:
```py
>>trainset = datasets.FashionMNIST('~/.pytorch/F_MNIST_data/', download=True, train=True, transform=transform)
......@@ -136,7 +136,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 的`datasets`模块附带了许多受欢迎的数据集; 如果机器上没有它,它将为您下载,传递转换并将数据转换为所需的格式以供模型训练。 在我们的案例中,数据集带有训练和测试集,并相应地加载它们。 我们使用`torch.utils.data.DataLoader`将处理后的数据分批加载,并进行其他操作,例如改组和加载到正确的设备(CPU 或 GPU)。
......@@ -461,9 +461,9 @@ Training loss: 0.2596
在本食谱中,我们首先使用`Adam`优化器定义优化器,然后为优化器设置学习率,并查看默认参数。 我们设置一个时期`10`,并为每个时期开始迭代,在每次迭代中将`running_loss`设置为 0,并在该时期内对每个图像进行迭代(模型看到数据集的次数)。 我们首先使用`.zero_grad()`方法清除梯度。 PyTorch 在每次向后传递时都会累积梯度,这在某些情况下很有用,因此将其导入以将梯度归零,以正确更新模型参数。
接下来,我们通过将每批 64 幅图像(每幅图像由 28 x 28 像素组成)展平到 784 来重塑图像,从而将张量形状从 64 x 28 x 28 更改为 64 x 784,因为我们的模型期望这种形状 输入。 接下来,我们将此输入发送到模型,并从模型中获得该批的输出预测,然后将其传递给损失函数,也称为`criterion`; 在那里,它评估了预测班级与实际班级之间的差异。
接下来,我们通过将每批 64 幅图像(每幅图像由 28 x 28 像素组成)展平到 784 来重塑图像,从而将张量形状从 64 x 28 x 28 更改为 64 x 784,因为我们的模型期望这种形状 输入。 接下来,我们将此输入发送到模型,并从模型中获得该批的输出预测,然后将其传递给损失函数,也称为`criterion`; 在那里,它评估了预测班级与实际班级之间的差异。
`loss.backward()`函数计算了梯度(即,误差相对于权重的偏导数),我们调用了`optimizer.step()`函数来更新模型的权重,以适应评估的误差。 `.item()`方法从单个元素张量中拉出标量,因此使用`loss.item()`从批次中获得`error`的标量值,将其累加到所有批次的损失中,最后将损失打印在 时代的结束。
`loss.backward()`函数计算了梯度(即,误差相对于权重的偏导数),我们调用了`optimizer.step()`函数来更新模型的权重,以适应评估的误差。 `.item()`方法从单个元素张量中拉出标量,因此使用`loss.item()`从批量中获得`error`的标量值,将其累加到所有批量的损失中,最后将损失打印在 时代的结束。
# 还有更多...
......
......@@ -561,7 +561,7 @@ pip install torchvision==0.x.x
>>validation_sample = SubsetRandomSampler(validation_indices)
```
16. 接下来,我们将数据集分成多个批。 我们将批量大小设置为 16:
16. 接下来,我们将数据集分成多个批。 我们将批量大小设置为 16:
```py
>>batch_size = 16
......@@ -573,7 +573,7 @@ pip install torchvision==0.x.x
>>from torch.utils.data.dataloader import DataLoader
```
18. 然后,我们将创建训练,验证和测试数据集批
18. 然后,我们将创建训练,验证和测试数据集批
```py
>>train_loader = DataLoader(train_data, batch_size=batch_size, sampler=training_sample)
......@@ -793,7 +793,7 @@ train_loss += loss.item()*data.size(0)
model.eval()
```
15.然后,我们遍历验证集批
15.然后,我们遍历验证集批
```py
for batch_idx, (data, target) in enumerate(valid_loader):
......@@ -863,13 +863,13 @@ valid_loss = valid_loss/len(valid_loader.sampler)
在此配方中,我们找到并训练了我们的模型。 为此,我们进行了导入,首先要确定模型并将模型分配给我们在计算机上拥有的适当设备。 我们使用`model.to(device)`方法移动模型,这比使用`model.cuda()``model.cpu()`更为优雅。
然后,我们定义了损失函数,也称为`criterion`。 由于这是一个分类问题,因此我们使用了交叉熵损失。 然后,我们选择 SGD 优化器在反向传播时更新模型权重,学习速率为 0.01,并使用`model.parameters()`传入模型参数。 然后,我们将模型运行了 30 个纪元,尽管我们可以选择任何合理的数目来执行此操作。 在循环中,我们将训练和验证损失重置为 0,并将模型设置为训练模式,然后遍历训练数据集中的每个批次。 我们首先将批次移至设备,这样,如果我们的 GPU 内存有限,则并非所有数据都不会完全加载到 GPU 内存中。 然后,我们将输入张量传递到模型中,并获取输出,并将其传递到损失函数中,以评估预测标签和真实标签之间的差异。
然后,我们定义了损失函数,也称为`criterion`。 由于这是一个分类问题,因此我们使用了交叉熵损失。 然后,我们选择 SGD 优化器在反向传播时更新模型权重,学习速率为 0.01,并使用`model.parameters()`传入模型参数。 然后,我们将模型运行了 30 个纪元,尽管我们可以选择任何合理的数目来执行此操作。 在循环中,我们将训练和验证损失重置为 0,并将模型设置为训练模式,然后遍历训练数据集中的每个批量。 我们首先将批量移至设备,这样,如果我们的 GPU 内存有限,则并非所有数据都不会完全加载到 GPU 内存中。 然后,我们将输入张量传递到模型中,并获取输出,并将其传递到损失函数中,以评估预测标签和真实标签之间的差异。
此后,我们使用`loss.backward()`进行了反向传播,并使用`optimizer.step()`步骤更新了模型权重。 然后,我们使用总历时损失来汇总批次中的损失。 然后,我们使用`model.eval()`将模型转换为评估模型,因为该模型的性能需要在验证集上进行评估,并且该模型在此阶段中不会学习,因此我们也需要关闭退出项。 遍历验证批次,我们获得了模型输出,并在整个时期累积了验证批次之间的损失。 此后,我们格式化了模型性能,以查看每个时期模型的变化。 我们注意到,模型训练和验证损失随时间的推移而减少,这表明模型正在学习。
此后,我们使用`loss.backward()`进行了反向传播,并使用`optimizer.step()`步骤更新了模型权重。 然后,我们使用总历时损失来汇总批量中的损失。 然后,我们使用`model.eval()`将模型转换为评估模型,因为该模型的性能需要在验证集上进行评估,并且该模型在此阶段中不会学习,因此我们也需要关闭退出项。 遍历验证批量,我们获得了模型输出,并在整个时期累积了验证批量之间的损失。 此后,我们格式化了模型性能,以查看每个时期模型的变化。 我们注意到,模型训练和验证损失随时间的推移而减少,这表明模型正在学习。
# 还有更多...
我们已经运行了训练有素的模型,我们需要根据保持数据或测试数据(即该模型尚未看到的数据)评估模型。 通过这样做,我们可以评估模型的真实性能。 为此,您将必须进入模型测试批次,并且对于每个批次,必须执行`_, prediction = torch.max(output, 1)`将 softmax 概率转换为实际预测,并使用`prediction.eq(target.data.view_as(prediction))`将预测与真实输出标签进行比较,其中 我们确保预测张量和输出张量的尺寸相同。 这将返回一个张量,其中匹配的张量为 1,不匹配的张量为 0。 我们可以使用它来计算每个批次中模型的准确性,并将其汇总到整个测试数据集中。
我们已经运行了训练有素的模型,我们需要根据保持数据或测试数据(即该模型尚未看到的数据)评估模型。 通过这样做,我们可以评估模型的真实性能。 为此,您将必须进入模型测试批量,并且对于每个批量,必须执行`_, prediction = torch.max(output, 1)`将 softmax 概率转换为实际预测,并使用`prediction.eq(target.data.view_as(prediction))`将预测与真实输出标签进行比较,其中 我们确保预测张量和输出张量的尺寸相同。 这将返回一个张量,其中匹配的张量为 1,不匹配的张量为 0。 我们可以使用它来计算每个批量中模型的准确性,并将其汇总到整个测试数据集中。
# 也可以看看
......
......@@ -156,7 +156,7 @@ pip install torchtext
>>SequenceField = Field(tokenize=tokenizer, init_token='<sos>', eos_token='<eos>', unk_token='<unk>')
```
7. 我们可以将批维度设置为第一维度:
7. 我们可以将批维度设置为第一维度:
```py
>>SequenceField = Field(tokenize=tokenizer, init_token='<sos>', eos_token='<eos>', unk_token='<unk>', batch_first=True)
......@@ -273,7 +273,7 @@ pip install torchtext
# 怎么做...
在此配方中,我们将数据集转换为迭代器,以便在每个纪元准备好要迭代的适当批
在此配方中,我们将数据集转换为迭代器,以便在每个纪元准备好要迭代的适当批
1. 我们将从导入开始:
......
......@@ -547,7 +547,7 @@ Epoch : | 005 / 050 |
我们还创建了固定噪声,用于可视化 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`。 然后,我们计算梯度并更新发生器权重。
......@@ -667,7 +667,7 @@ pip install numpy
PGGAN 的关键创新可以总结如下:
* **在高分辨率层中逐渐增长并逐渐淡入淡出**:它从低分辨率卷积变为高分辨率卷积,而不是立即跳变分辨率,而是通过参数平滑地淡化了具有更高分辨率的 nedonew 层 alpha(α)(介于 0 和 1 之间)的大小,用于控制我们使用旧的还是放大的较大输出。
* **迷你批处理标准偏差**:我们计算鉴别符的统计信息,即生成器生成或来自真实数据的迷你批处理中所有像素的标准偏差。 现在,判别器需要了解,如果要评估的批中图像的标准偏差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗鉴别器。
* **迷你批处理标准偏差**:我们计算鉴别符的统计信息,即生成器生成或来自真实数据的迷你批处理中所有像素的标准偏差。 现在,判别器需要了解,如果要评估的批中图像的标准偏差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗鉴别器。
* **均衡的学习率**:所有权重(`w`)被归一化( *w'*)在某个范围内,以便 *w'* =`w`/`c`的常数`c`对于每一层来说都是不同的,具体取决于重量矩阵的形状。
* **逐像素特征归一化**:对每个像素中的特征向量进行归一化,因为批处理规范最适合大型微型批处理,并且占用大量内存。
......
......@@ -575,7 +575,7 @@ CNN(
然后,我们使用了一个随机变量,其形状与输入张量的形状相同,在本例中为三通道 32 x 32 像素图像。 我们将此随机输入传递到模型中并获得输出。 然后,我们使用输出将其与模型的 ONNX 版本中的模型进行比较。
在 PyTorch 中使用跟踪或脚本导出模型。 在本食谱中,我们在`torch.onnx.export()`的帮助下使用了跟踪。 跟踪跟踪用于获取输出的操作。 这就是为什么我们提供`x`的原因-因此可以进行跟踪。 `x`必须具有正确的类型和大小。 输入尺寸在导出的 ONNX 图形中固定为所有输入尺寸,我们必须指定所有动态轴。 在此配方中,我们使用第一维的输入导出模型,将批大小设置为 1,并在`torch.onnx.export()``dynamic_axes`参数中将第一维指定为动态。
在 PyTorch 中使用跟踪或脚本导出模型。 在本食谱中,我们在`torch.onnx.export()`的帮助下使用了跟踪。 跟踪跟踪用于获取输出的操作。 这就是为什么我们提供`x`的原因-因此可以进行跟踪。 `x`必须具有正确的类型和大小。 输入尺寸在导出的 ONNX 图形中固定为所有输入尺寸,我们必须指定所有动态轴。 在此配方中,我们使用第一维的输入导出模型,将批大小设置为 1,并在`torch.onnx.export()``dynamic_axes`参数中将第一维指定为动态。
第一个参数是 PyTorch 模型,第二个参数是随机变量。 然后,我们有了`onnx`格式的路径; `export_params`用于将训练后的参数权重存储在模型文件中; `opset_version``onnx`导出版本; `do_constant_folding`用于执行常量折叠以进行优化; `input_names`是模型的输入名称,`output_names`是模型的输出名称。 然后,我们加载了导出的`onnx`模型,并检查了模型结构并使用`onnx.checker.check_model(onnx_model)`验证了架构。 通过检查模型版本,图形的结构,节点及其输入和输出来验证 ONNX 图形。
......
......@@ -460,7 +460,7 @@ tensor([[0.5594, 0.8875, 0.9234, 1.1294],
`squeeze`功能有时可以节省您的时间。 在某些情况下,您将具有一个或多个尺寸为 1 的张量。有时,您的张量中不需要那些多余的尺寸。 这就是`squeeze`将为您提供帮助的地方。 `squeeze`删除值为 1 的维。例如,如果您正在处理句子,并且有 10 个句子的批处理,每个句子包含 5 个单词,则将其映射到张量对象时,将得到 10 x 的张量 5.然后,您意识到必须将其转换为一热向量,以便神经网络进行处理。
您可以使用大小为 100 的单热点编码矢量为张量添加另一个维度(因为词汇量为 100 个单词)。 现在,您有了一个尺寸为 10 x 5 x 100 的张量对象,并且每个批和每个句子一次传递一个单词。
您可以使用大小为 100 的单热点编码矢量为张量添加另一个维度(因为词汇量为 100 个单词)。 现在,您有了一个尺寸为 10 x 5 x 100 的张量对象,并且每个批和每个句子一次传递一个单词。
现在,您必须对句子进行拆分和切分,最有可能的结果是,张量的大小为 10 x 1 x 100(每 10 个单词中的一个单词带有 100 维向量)。 您可以使用 10 x 100 的张量处理它,这使您的生活更加轻松。 继续使用`squeeze`从 10 x 1 x 100 张量得到 10 x 100 张量。
......
......@@ -294,9 +294,9 @@ SGD 的主要缺点是效率低下。 例如,考虑我们的 *FizzBu​​zz*
使用完整数据集的梯度下降的变种称为批梯度下降。 它并不比 SGD 更好。 批量梯度下降实际上提高了效率,但降低了网络的泛化能力。 SGD 必须逐个通过噪声,因此它将具有很高的抖动率,这会导致网络移出局部最小值,而分批梯度下降避免了陷入局部最小值的机会。
批量梯度下降的另一个主要缺点是其内存消耗。 由于整个批都在一起处理,因此应将庞大的数据集加载到 RAM 或 GPU 内存中,这在大多数情况下我们尝试训练数百万个样本时不切实际。 下一个变体是前面两种方法的混合,称为“小批量梯度下降”(尽管顾名思义是“小批量梯度下降”,但人们通常会使用 SGD 来指代)。
批量梯度下降的另一个主要缺点是其内存消耗。 由于整个批都在一起处理,因此应将庞大的数据集加载到 RAM 或 GPU 内存中,这在大多数情况下我们尝试训练数百万个样本时不切实际。 下一个变体是前面两种方法的混合,称为“小批量梯度下降”(尽管顾名思义是“小批量梯度下降”,但人们通常会使用 SGD 来指代)。
除了我们刚才介绍的新超参数,学习率和批量大小以外,其他所有内容均保持不变。 我们用学习率乘以`.grad`属性来更新`.data`属性,并针对每次迭代进行此操作。 选择批处理大小几乎总是取决于内存的可用性。 我们尝试使迷你批处理尽可能大,以便可以将其放置在 GPU 内存中。 将整个批划分为小批量,以确保每次梯度更新都会产生足够的抽动,从而在使用 GPU 提供的全部功能的同时,将模型从局部最小值中剔除。
除了我们刚才介绍的新超参数,学习率和批量大小以外,其他所有内容均保持不变。 我们用学习率乘以`.grad`属性来更新`.data`属性,并针对每次迭代进行此操作。 选择批处理大小几乎总是取决于内存的可用性。 我们尝试使迷你批处理尽可能大,以便可以将其放置在 GPU 内存中。 将整个批划分为小批量,以确保每次梯度更新都会产生足够的抽动,从而在使用 GPU 提供的全部功能的同时,将模型从局部最小值中剔除。
我们已经到达了模型构建旅程的最后一部分。 到目前为止,所有操作都很直观,简单,但是最后一部分有点令人困惑。 `zero_grad`做什么? 还记得关于重量`w1.grad`的第一份印刷声明吗? 它是空的,现在具有当前反向传递的渐变。 因此,我们需要在下一次向后传递之前清空渐变,因为渐变会累积而不是被重写。 参数更新后,我们在每个迭代的每个张量上调用`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 的多个内核完成的。
......@@ -272,7 +272,7 @@ train, val, test = data.TabularDataset.splits(
由于`sequential``TEXT``True`,因此我们开发的标记化函数设置为`tokenizer`。 该选项默认为 Python 的`str.split`,但是我们需要更智能的令牌化功能,而 spaCy 的令牌化功能可以为我们提供帮助。
常规 NLP 管道所做的另一个重要修改是将所有数据转换为相同的情况。 将`lower`设置为`True`会发生这种情况,但是默认情况下是`False`。 除了示例中给出的三个参数外,`Field`类还接受许多其他参数,其中包括`fix_length`以固定序列的长度; `pad_token`,默认为`<pad>`,用于填充序列以匹配`fixed_length`或批中最长序列的长度; 和`unk_token`(默认为`<unk>`),用于替换没有词汇向量的标记。
常规 NLP 管道所做的另一个重要修改是将所有数据转换为相同的情况。 将`lower`设置为`True`会发生这种情况,但是默认情况下是`False`。 除了示例中给出的三个参数外,`Field`类还接受许多其他参数,其中包括`fix_length`以固定序列的长度; `pad_token`,默认为`<pad>`,用于填充序列以匹配`fixed_length`或批中最长序列的长度; 和`unk_token`(默认为`<unk>`),用于替换没有词汇向量的标记。
`Field`的官方文档详细介绍了所有参数。 因为我们只有一个单词作为标签,所以`LABEL`字段的`sequential`设置为`False`。 这对于不同的实例非常方便,尤其是在语言翻译(输入和输出均为序列)的情况下。
......@@ -304,11 +304,11 @@ 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`还可以在每个时期对批进行混洗,并在数据集中保持足够的随机性,从而使网络无法从数据集中的顺序中学习,这实际上并没有在教授任何现实世界的信息。
如果`Iterator`类需要更巧妙地处理事情怎么办? 如果数据集用于语言建模,并且我们需要一个数据集来进行**在整个时间****BPTT**)中的反向传播,那该怎么办? `torchtext`也为这些模块抽象了模块,这些模块继承自我们刚刚使用的`Iterator`类。 `BucketIterator`模块将序列进行更智能的分组,以便将具有相同长度的序列归为一组,并且此减少了将噪声引入数据集的不必要填充的长度。 `BucketIterator`还可以在每个时期对批进行混洗,并在数据集中保持足够的随机性,从而使网络无法从数据集中的顺序中学习,这实际上并没有在教授任何现实世界的信息。
`BPTTIterator`是从`Iterator`类继承的另一个模块,可帮助语言建模数据集,并且需要为`t`的每个输入从 *t + 1* 获取标签。`t`是时间。 `BPTTIterator`接受输入数据的连续流和输出数据的连续流(在翻译网络的情况下,输入流和输出流可以不同,在语言建模网络的情况下,输入流和输出流可以相同)进行转换 它遵循前面描述的时间序列规则的迭代器。
......@@ -476,7 +476,7 @@ Ignite 是一种神经网络训练工具,可将某些样板代码抽象出来
#### 引擎
`Engine`接受一个训练器函数,该函数实质上是用于训练神经网络算法的典型循环。 它包括循环遍历,循环遍历,将现有梯度值归零,使用批调用模型,计算损失以及更新梯度。 以下示例显示了这一点,该示例取自第 2 章和*简单神经网络*
`Engine`接受一个训练器函数,该函数实质上是用于训练神经网络算法的典型循环。 它包括循环遍历,循环遍历,将现有梯度值归零,使用批调用模型,计算损失以及更新梯度。 以下示例显示了这一点,该示例取自第 2 章和*简单神经网络*
```py
for epoch in range(epochs):
......
......@@ -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):
......
......@@ -407,7 +407,7 @@ class Encoder(nn.Module):
##### LSTMCell 和 GRUCell
`LSTMCell``GRUCell`的功能性 API 绝对相似,这也正是定制`RNNCell`的方式。 它们接受输入大小和初始化程序的隐藏大小。 `forward`调用接受具有输入大小的微型输入批,并为该实例创建单元状态和隐藏状态,然后将其传递给下一个执行输入。 在静态图框架中实现这种的实现非常困难,因为该图在整个执行期间都是预先编译的并且是静态的。 循环语句也应作为图节点作为图的一部分。 这需要用户学习那些额外的 op 节点或其他在内部处理循环的功能性 API。
`LSTMCell``GRUCell`的功能性 API 绝对相似,这也正是定制`RNNCell`的方式。 它们接受输入大小和初始化程序的隐藏大小。 `forward`调用接受具有输入大小的微型输入批,并为该实例创建单元状态和隐藏状态,然后将其传递给下一个执行输入。 在静态图框架中实现这种的实现非常困难,因为该图在整个执行期间都是预先编译的并且是静态的。 循环语句也应作为图节点作为图的一部分。 这需要用户学习那些额外的 op 节点或其他在内部处理循环的功能性 API。
#### LSTM 和 GRU
......
......@@ -598,9 +598,9 @@ PyTorch 为用户提供了进入网络并进行操作的完全灵活性。 其
反射填充涉及填充输入的边界,跳过批处理尺寸和通道尺寸。 填充之后是典型的卷积模块布置,即二维卷积。
实例归一化分别对每个输出批次进行归一化,而不是像“批次归一化”中那样对整个集合进行归一化。 二维实例归一化确实在 4D 输入上实例化归一化,且批次尺寸和通道尺寸为第一维和第二维。 PyTorch 通过传递`affine=True`允许实例规范化层可训练。 参数`track_running_stats`决定是否存储训练循环的运行平均值和方差,以用于评估模式(例如归一化)。 默认情况下,它设置为`False`; 也就是说,它在训练和评估模式下都使用从输入中收集的统计信息。
实例归一化分别对每个输出批量进行归一化,而不是像“批量归一化”中那样对整个集合进行归一化。 二维实例归一化确实在 4D 输入上实例化归一化,且批量尺寸和通道尺寸为第一维和第二维。 PyTorch 通过传递`affine=True`允许实例规范化层可训练。 参数`track_running_stats`决定是否存储训练循环的运行平均值和方差,以用于评估模式(例如归一化)。 默认情况下,它设置为`False`; 也就是说,它在训练和评估模式下都使用从输入中收集的统计信息。
下图给出了批处理规范化和实例规范化的直观比较。 在图像中,数据表示为三维张量,其中 C 是通道,N 是批处理,D 是其他维,为简单起见,在一个维中表示。 如图中所示,批次归一化对整个批次中的数据进行归一化,而实例归一化则在两个维度上对一个数据实例进行归一化,从而使批次之间的差异保持完整。
下图给出了批处理规范化和实例规范化的直观比较。 在图像中,数据表示为三维张量,其中 C 是通道,N 是批处理,D 是其他维,为简单起见,在一个维中表示。 如图中所示,批量归一化对整个批量中的数据进行归一化,而实例归一化则在两个维度上对一个数据实例进行归一化,从而使批量之间的差异保持完整。
![CycleGAN](img/B09475_06_21.jpg)
......
......@@ -14,7 +14,7 @@
这些现实问题似乎非常复杂。 我们将需要对所有这些事情进行数学公式化,以便计算机可以解决它们。 为此,我们需要简化环境和决策过程以实现特定目标。
在强化学习的整个范式中,我们仅关注从交互中学习,而学习或决策者则被视为代理。 在自动驾驶汽车中,代理人是汽车,而在乒乓球中,代理人是球拍。 当代理最初进入世界时,它将对世界一无所知。 代理将必须观察其环境并根据其做出决策或采取行动。 它从环境中返回的响应称为奖励,可以是肯定的也可以是否定的。 最初,代理将随机采取行动,直到获得正面奖励为止,并告诉他们这些决定可能对其有利。
在强化学习的整个范式中,我们仅关注从交互中学习,而学习或决策者则被视为代理。 在自动驾驶汽车中,代理人是汽车,而在乒乓球中,代理人是球拍。 当代理最初进入世界时,它将对世界一无所知。 代理将必须观察其环境并根据其做出决策或采取行动。 它从环境中返回的响应称为奖励,可以是肯定的也可以是否定的。 最初,代理将随机采取行动,直到获得正面奖励为止,并告诉他们这些决定可能对其有利。
这似乎很简单,因为代理程序要做的就是考虑环境的当前状态进行决策,但是我们还想要更多。 通常,座席的目标是在其一生中最大化其累积奖励,重点是“累积”一词。 代理不仅关心在下一步中获得的报酬,而且还关心将来可能获得的报酬。 这需要有远见,并将使代理学习得更好。
......@@ -424,7 +424,7 @@ def optimize_model():
optimizer.step()
```
然后是主要部分:优化器步骤。 这是我们使用`RMSProp`找出损耗和反向传播的地方。 我们从存储库中提取了一些经验。 然后,我们将所有状态,动作和奖励转换为批。 我们通过`policy_net`传递状态并获得相应的值。
然后是主要部分:优化器步骤。 这是我们使用`RMSProp`找出损耗和反向传播的地方。 我们从存储库中提取了一些经验。 然后,我们将所有状态,动作和奖励转换为批。 我们通过`policy_net`传递状态并获得相应的值。
![Gym](img/B09475_07_07.jpg)
......
......@@ -131,7 +131,7 @@ out.backward(torch.randn(1, 10))
例如,`nn.Conv2d`将采用`nSamples x nChannels x Height x Width`的 4D 张量。
如果您只有一个样品,只需使用`input.unsqueeze(0)`添加一个假批尺寸。
如果您只有一个样品,只需使用`input.unsqueeze(0)`添加一个假批尺寸。
在继续之前,让我们回顾一下到目前为止所看到的所有课程。
......
......@@ -554,7 +554,7 @@ tensor(0.0819, grad_fn=<NllLossBackward>)
## 使用 DataLoader 重构](docs / modern-java-zh /
Pytorch 的`DataLoader`负责批管理。 您可以从任何`Dataset`创建一个`DataLoader``DataLoader`使迭代迭代变得更加容易。 不必使用`train_ds[i*bs : i*bs+bs]`,DataLoader 会自动为我们提供每个小批量。
Pytorch 的`DataLoader`负责批管理。 您可以从任何`Dataset`创建一个`DataLoader``DataLoader`使迭代迭代变得更加容易。 不必使用`train_ds[i*bs : i*bs+bs]`,DataLoader 会自动为我们提供每个小批量。
```py
from torch.utils.data import DataLoader
......@@ -610,9 +610,9 @@ tensor(0.0821, grad_fn=<NllLossBackward>)
在第 1 节中,我们只是试图建立一个合理的训练循环以用于我们的训练数据。 实际上,您**始终**也应该具有[验证集](https://www.fast.ai/2017/11/13/validation-sets/),以便识别您是否过度拟合。
对训练数据进行改组对于[很重要,](https://www.quora.com/Does-the-order-of-training-data-matter-when-training-neural-networks)对于防止批与过度拟合之间的相关性很重要。 另一方面,无论我们是否改组验证集,验证损失都是相同的。 由于改组需要花费更多时间,因此改组验证数据没有任何意义。
对训练数据进行改组对于[很重要,](https://www.quora.com/Does-the-order-of-training-data-matter-when-training-neural-networks)对于防止批与过度拟合之间的相关性很重要。 另一方面,无论我们是否改组验证集,验证损失都是相同的。 由于改组需要花费更多时间,因此改组验证数据没有任何意义。
我们将验证集的批大小设为训练集的两倍。 这是因为验证集不需要反向传播,因此占用的内存更少(不需要存储渐变)。 我们利用这一优势来使用更大的批量,并更快地计算损失。
我们将验证集的批大小设为训练集的两倍。 这是因为验证集不需要反向传播,因此占用的内存更少(不需要存储渐变)。 我们利用这一优势来使用更大的批量,并更快地计算损失。
```py
train_ds = TensorDataset(x_train, y_train)
......@@ -911,7 +911,7 @@ dev = torch.device(
```
让我们更新`preprocess`,将批移至 GPU:
让我们更新`preprocess`,将批移至 GPU:
```py
def preprocess(x, y):
......
......@@ -251,7 +251,7 @@ def plot_classes_preds(net, images, labels):
最后,让我们使用与之前教程相同的模型训练代码来训练模型,但是每 1000 批将结果写入 TensorBoard,而不是打印到控制台。 这是通过 [add_scalar](https://pytorch.org/docs/stable/tensorboard.html#torch.utils.tensorboard.writer.SummaryWriter.add_scalar) 函数完成的。
此外,在训练过程中,我们将生成一幅图像,显示该批中包含的四幅图像的模型预测与实际结果。
此外,在训练过程中,我们将生成一幅图像,显示该批中包含的四幅图像的模型预测与实际结果。
```py
running_loss = 0.0
......@@ -293,7 +293,7 @@ print('Finished Training')
![intermediate/../../_static/img/tensorboard_scalar_runs.png](img/afda8238ecd1f547d61be4d155844f68.png)
此外,我们可以查看整个学习过程中模型在任意批上所做的预测。 查看“图像”选项卡,然后在“预测与实际”可视化条件下向下滚动以查看此内容; 这表明,例如,仅经过 3000 次训练迭代,该模型就已经能够区分出视觉上截然不同的类,例如衬衫,运动鞋和外套,尽管它并没有像后来的训练那样有信心:
此外,我们可以查看整个学习过程中模型在任意批上所做的预测。 查看“图像”选项卡,然后在“预测与实际”可视化条件下向下滚动以查看此内容; 这表明,例如,仅经过 3000 次训练迭代,该模型就已经能够区分出视觉上截然不同的类,例如衬衫,运动鞋和外套,尽管它并没有像后来的训练那样有信心:
![intermediate/../../_static/img/tensorboard_images.png](img/d5ab1f07cb4a9d9200c2a2d3b238340d.png)
......
......@@ -34,7 +34,7 @@
关于`labels`的注释。 该模型将`0`类作为背景。 如果您的数据集不包含背景类,则`labels`中不应包含`0`。 例如,假设您只有*猫**狗*两类,则可以定义`1`(不是`0`)来表示*猫*和[HTG6 代表*狗*。 因此,例如,如果其中一个图像同时具有两个类,则您的`labels`张量应类似于`[1,2]`
此外,如果要在训练过程中使用宽高比分组(以便每个批仅包含具有相似长宽比的图像),则建议您还实施`get_height_and_width`方法,该方法返回图像的高度和宽度。 如果未提供此方法,我们将通过`__getitem__`查询数据集的所有元素,这会将图像加载到内存中,并且比提供自定义方法慢。
此外,如果要在训练过程中使用宽高比分组(以便每个批仅包含具有相似长宽比的图像),则建议您还实施`get_height_and_width`方法,该方法返回图像的高度和宽度。 如果未提供此方法,我们将通过`__getitem__`查询数据集的所有元素,这会将图像加载到内存中,并且比提供自定义方法慢。
### 为 PennFudan 编写自定义数据集](docs / modern-java-zh /
......
......@@ -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** -潜矢量的长度
......@@ -385,18 +385,18 @@ optimizerG = optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))
**第 1 部分-训练鉴别器**
回想一下,训练鉴别器的目的是最大程度地提高将给定输入正确分类为真实或伪造的可能性。 就古德费罗而言,我们希望“通过提高其随机梯度来更新鉴别器”。 实际上,我们要最大化\(log(D(x))+ log(1-D(G(z)))\)。 由于 ganhacks 提出了单独的小批量建议,因此我们将分两步进行计算。 首先,我们将从训练集中构造一批真实样本,向前通过\(D \),计算损失(\(log(D(x(x))\))),然后在向后通过中计算梯度。 其次,我们将使用电流生成器构造一批假样本,将这批伪造通过\(D \),计算损失(\(log(1-D(G(z())))\)),然后*向后累积*梯度。 现在,利用全批次和全批次的累积梯度,我们称之为鉴别器优化程序的一个步骤。
回想一下,训练鉴别器的目的是最大程度地提高将给定输入正确分类为真实或伪造的可能性。 就古德费罗而言,我们希望“通过提高其随机梯度来更新鉴别器”。 实际上,我们要最大化\(log(D(x))+ log(1-D(G(z)))\)。 由于 ganhacks 提出了单独的小批量建议,因此我们将分两步进行计算。 首先,我们将从训练集中构造一批真实样本,向前通过\(D \),计算损失(\(log(D(x(x))\))),然后在向后通过中计算梯度。 其次,我们将使用电流生成器构造一批假样本,将这批伪造通过\(D \),计算损失(\(log(1-D(G(z())))\)),然后*向后累积*梯度。 现在,利用全批量和全批量的累积梯度,我们称之为鉴别器优化程序的一个步骤。
**第 2 部分-训练发电机**
如原始论文所述,我们希望通过最小化\(log(1-D(G(z)))\)来训练 Generator,以产生更好的假货。 如前所述,Goodfellow 证明这不能提供足够的梯度,尤其是在学习过程的早期。 作为解决方法,我们希望最大化\(log(D(G(z())))\)。 在代码中,我们通过以下步骤来实现此目的:将第 1 部分的 Generator 输出与 Discriminator 进行分类,使用实数标签 GT 计算 G 的损耗*,反向计算 G 的梯度,最后使用优化器更新 G 的参数 步。 将真实标签用作损失函数的 GT 标签似乎是违反直觉的,但这使我们可以使用 BCELoss 的\(log(x)\)部分(而不是\(log(1-x) \)部分),这正是我们想要的。*
最后,我们将进行一些统计报告,并在每个时期结束时,将我们的 fixed_noise 批推送到生成器中,以直观地跟踪 G 的训练进度。 报告的训练统计数据是:
最后,我们将进行一些统计报告,并在每个时期结束时,将我们的 fixed_noise 批推送到生成器中,以直观地跟踪 G 的训练进度。 报告的训练统计数据是:
* **Loss_D** -鉴别器损失,计算为所有真实批次和所有假批次的损失总和(\(log(D(x))+ log(D(G(z)))\))。
* **Loss_D** -鉴别器损失,计算为所有真实批量和所有假批量的损失总和(\(log(D(x))+ log(D(G(z)))\))。
* **Loss_G** -发电机损耗计算为\(log(D(G(z())))\)
* **D(x)**-所有真实批次的鉴别器的平均输出(整个批次)。 这应该从接近 1 开始,然后在 G 变得更好时理论上收敛到 0.5。 想想这是为什么。
* **D(G(z))**-所有假批的平均鉴别器输出。 第一个数字在 D 更新之前,第二个数字在 D 更新之后。 这些数字应从 0 开始,并随着 G 的提高收敛到 0.5。 想想这是为什么。
* **D(x)**-所有真实批量的鉴别器的平均输出(整个批量)。 这应该从接近 1 开始,然后在 G 变得更好时理论上收敛到 0.5。 想想这是为什么。
* **D(G(z))**-所有假批的平均鉴别器输出。 第一个数字在 D 更新之前,第二个数字在 D 更新之后。 这些数字应从 0 开始,并随着 G 的提高收敛到 0.5。 想想这是为什么。
**注意:**此步骤可能需要一段时间,具体取决于您运行了多少个纪元以及是否从数据集中删除了一些数据。
......@@ -654,7 +654,7 @@ Starting Training Loop...
## 结果](docs / modern-java-zh /
最后,让我们看看我们是如何做到的。 在这里,我们将看三个不同的结果。 首先,我们将了解 D 和 G 的损失在训练过程中如何变化。 其次,我们将在每个时期将 G 的输出显示为 fixed_noise 批。 第三,我们将查看一批真实数据以及来自 G 的一批伪数据。
最后,让我们看看我们是如何做到的。 在这里,我们将看三个不同的结果。 首先,我们将了解 D 和 G 的损失在训练过程中如何变化。 其次,我们将在每个时期将 G 的输出显示为 fixed_noise 批。 第三,我们将查看一批真实数据以及来自 G 的一批伪数据。
**损失与训练迭代**
......@@ -676,7 +676,7 @@ plt.show()
**可视化 G 的进度**
请记住,在每次训练之后,我们如何将生成器的输出保存为 fixed_noise 批。 现在,我们可以用动画形象化 G 的训练进度。 按下播放按钮开始动画。
请记住,在每次训练之后,我们如何将生成器的输出保存为 fixed_noise 批。 现在,我们可以用动画形象化 G 的训练进度。 按下播放按钮开始动画。
```py
#%%capture
......
......@@ -78,7 +78,7 @@ class PositionalEncoding(nn.Module):
## 加载和批处理数据](docs / modern-java-zh /
本教程使用`torchtext`生成 Wikitext-2 数据集。 vocab 对象是基于训练数据集构建的,用于将标记数字化为张量。 从顺序数据开始,`batchify()`函数将数据集排列为列,以修剪掉数据分成大小为`batch_size`的批后剩余的所有令牌。 例如,以字母为序列(总长度为 26)并且批大小为 4,我们将字母分为 4 个长度为 6 的序列:
本教程使用`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}\]
......@@ -132,7 +132,7 @@ test_data = batchify(test_data, eval_batch_size)
![../_img/transformer_input_target.png](img/20ef8681366b44461cf49d1ab98ab8f2.png)
应该注意的是,这些块沿着维度 0,与 Transformer 模型中的`S`维度一致。 批尺寸`N`沿尺寸 1。
应该注意的是,这些块沿着维度 0,与 Transformer 模型中的`S`维度一致。 批尺寸`N`沿尺寸 1。
```py
bptt = 35
......
......@@ -67,7 +67,7 @@ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
为此,我们将需要两个类:
* `Transition`-表示我们环境中单个过渡的命名元组。 它本质上将(状态,动作)对映射到其(next_state,奖励)结果,该状态是屏幕差异图像,如下所述。
* `ReplayMemory`-有界大小的循环缓冲区,用于保存最近观察到的转换。 它还实现了`.sample()`方法,用于选择随机的过渡批进行训练。
* `ReplayMemory`-有界大小的循环缓冲区,用于保存最近观察到的转换。 它还实现了`.sample()`方法,用于选择随机的过渡批进行训练。
```py
Transition = namedtuple('Transition',
......
......@@ -307,7 +307,7 @@ resp = requests.post("http://localhost:5000/predict",
* 即使模型可以识别大量类别的图像,也可能无法识别所有图像。 增强实现以处理模型无法识别图像中的任何情况的情况。
* 我们在开发模式下运行 Flask 服务器,该服务器不适合在生产中进行部署。 您可以查看本教程的[,以在生产环境中部署 Flask 服务器。](https://flask.palletsprojects.com/en/1.1.x/tutorial/deploy/)
* 您还可以通过创建一个带有表单的页面来添加 UI,该表单可以拍摄图像并显示预测。 查看类似项目的[演示](https://pytorch-imagenet.herokuapp.com/)及其[源代码](https://github.com/avinassh/pytorch-flask-api-heroku)
* 在本教程中,我们仅展示了如何构建可以一次返回单个图像预测的服务。 我们可以修改服务以能够一次返回多个图像的预测。 此外,[服务流媒体](https://github.com/ShannonAI/service-streamer)库自动将对服务的请求排队,并将请求采样到微型批次中,这些微型批次可输入模型中。 您可以查看[本教程](https://github.com/ShannonAI/service-streamer/wiki/Vision-Recognition-Service-with-Flask-and-service-streamer)
* 在本教程中,我们仅展示了如何构建可以一次返回单个图像预测的服务。 我们可以修改服务以能够一次返回多个图像的预测。 此外,[服务流媒体](https://github.com/ShannonAI/service-streamer)库自动将对服务的请求排队,并将请求采样到微型批量中,这些微型批量可输入模型中。 您可以查看[本教程](https://github.com/ShannonAI/service-streamer/wiki/Vision-Recognition-Service-with-Flask-and-service-streamer)
* 最后,我们鼓励您在页面顶部查看链接到的其他 PyTorch 模型部署教程。
**脚本的总运行时间:**(0 分钟 1.232 秒)
......
......@@ -260,7 +260,7 @@ Error when attempting to broadcast dims ['N', 'C', 'H', 'W'] and dims ['N']: dim
```
如果没有`names`,则`per_batch_scale`张量与`imgs`的最后一个尺寸对齐,这不是我们想要的。 我们确实想通过将`per_batch_scale``imgs`的批尺寸对齐来执行操作。 有关如何按名称对齐张量的信息,请参见新的“按名称显式广播”功能,如下所述。
如果没有`names`,则`per_batch_scale`张量与`imgs`的最后一个尺寸对齐,这不是我们想要的。 我们确实想通过将`per_batch_scale``imgs`的批尺寸对齐来执行操作。 有关如何按名称对齐张量的信息,请参见新的“按名称显式广播”功能,如下所述。
#### 矩阵乘法](docs / modern-java-zh /
......@@ -577,7 +577,7 @@ print(output.names)
```
以上工作正常。 此外,请注意,在代码中我们根本没有提到批处理维度的名称。 实际上,我们的`MultiHeadAttention`模块与批尺寸的存在无关。
以上工作正常。 此外,请注意,在代码中我们根本没有提到批处理维度的名称。 实际上,我们的`MultiHeadAttention`模块与批尺寸的存在无关。
```py
query = torch.randn(t, d, names=('T', 'D'))
......
......@@ -742,7 +742,7 @@ __global__ void lltm_cuda_forward_kernel(
但是,这是以易于使用和可读性为代价的,尤其是对于高维数据。 在我们的示例中,例如,我们知道连续的`gates`张量具有 3 个维度:
1.`batch_size`的大小和`3*state_size`的步幅
1.`batch_size`的大小和`3*state_size`的步幅
2. `3`的行,大小和`state_size`的步幅
3. 指数,`state_size`的大小和`1`的步幅
......
......@@ -172,11 +172,11 @@ plot([mp_mean, rn_mean],
![](img/7f2d776cf49fcf3fd44fd84a238a3cc6.png)
结果表明,模型并行实现的执行时间比现有的单 GPU 实现长`4.02/3.75-1=7%`。 因此,我们可以得出结论,在 GPU 之间来回复制张量大约有 7% 的开销。 有待改进的地方,因为我们知道两个 GPU 之一在整个执行过程中处于空闲状态。 一种选择是将每个批进一步划分为拆分流水线,以便当一个拆分到达第二子网时,可以将下一个拆分馈入第一子网。 这样,两个连续的拆分可以在两个 GPU 上同时运行。
结果表明,模型并行实现的执行时间比现有的单 GPU 实现长`4.02/3.75-1=7%`。 因此,我们可以得出结论,在 GPU 之间来回复制张量大约有 7% 的开销。 有待改进的地方,因为我们知道两个 GPU 之一在整个执行过程中处于空闲状态。 一种选择是将每个批进一步划分为拆分流水线,以便当一个拆分到达第二子网时,可以将下一个拆分馈入第一子网。 这样,两个连续的拆分可以在两个 GPU 上同时运行。
## 通过流水线输入加快速度] [docs / modern-java-zh /
在以下实验中,我们将每个 120 图像批进一步分为 20 图像分割。 当 PyTorch 异步启动 CUDA 操作时,该实现无需生成多个线程即可实现并发。
在以下实验中,我们将每个 120 图像批进一步分为 20 图像分割。 当 PyTorch 异步启动 CUDA 操作时,该实现无需生成多个线程即可实现并发。
```py
class PipelineParallelResNet50(ModelParallelResNet50):
......
......@@ -152,7 +152,7 @@ def run(rank, size):
现在我们了解了分布式模块的工作原理,让我们用它编写一些有用的东西。 我们的目标是复制 [DistributedDataParallel](https://pytorch.org/docs/stable/nn.html#torch.nn.parallel.DistributedDataParallel) 的功能。 当然,这将是一个教学示例,在现实世界中,您应该使用上面链接的经过官方测试,优化的最佳版本。
很简单,我们想要实现随机梯度下降的分布式版本。 我们的脚本将允许所有进程在其数据批上计算其模型的梯度,然后平均其梯度。 为了在更改进程数时确保相似的收敛结果,我们首先必须对数据集进行分区。 (您也可以使用 [tnt.dataset.SplitDataset](https://github.com/pytorch/tnt/blob/master/torchnet/dataset/splitdataset.py#L4) 代替下面的代码段。)
很简单,我们想要实现随机梯度下降的分布式版本。 我们的脚本将允许所有进程在其数据批上计算其模型的梯度,然后平均其梯度。 为了在更改进程数时确保相似的收敛结果,我们首先必须对数据集进行分区。 (您也可以使用 [tnt.dataset.SplitDataset](https://github.com/pytorch/tnt/blob/master/torchnet/dataset/splitdataset.py#L4) 代替下面的代码段。)
```py
""" Dataset partitioning helper """
......
......@@ -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):
......@@ -183,7 +183,7 @@ class DistResNet50(nn.Module):
## 步骤 3:定义训练循环](docs / modern-java-zh /
定义模型后,让我们实施训练循环。 我们使用专门的“主”工作人员来准备随机输入和标签,并控制分布式反向传递和分布式优化器步骤。 它首先创建`DistResNet50`模块的实例。 它指定每个批的微批数量,并提供两个 RPC 工作程序的名称(即“ worker1”和“ worker2”)。 然后,它定义损失函数,并使用`parameter_rrefs()`帮助器创建`DistributedOptimizer`以获取参数`RRefs`的列表。 然后,主训练循环与常规本地训练非常相似,除了它使用`dist_autograd`向后启动并为反向和优化器`step()`提供`context_id`之外。
定义模型后,让我们实施训练循环。 我们使用专门的“主”工作人员来准备随机输入和标签,并控制分布式反向传递和分布式优化器步骤。 它首先创建`DistResNet50`模块的实例。 它指定每个批的微批数量,并提供两个 RPC 工作程序的名称(即“ worker1”和“ worker2”)。 然后,它定义损失函数,并使用`parameter_rrefs()`帮助器创建`DistributedOptimizer`以获取参数`RRefs`的列表。 然后,主训练循环与常规本地训练非常相似,除了它使用`dist_autograd`向后启动并为反向和优化器`step()`提供`context_id`之外。
```py
import torch.distributed.autograd as dist_autograd
......
......@@ -184,7 +184,7 @@ def _run_trainer(emb_rref, rank):
```
现在,我们准备介绍在每个训练师上运行的主要训练循环。 `get_next_batch`只是一个辅助函数,用于生成随机输入和训练目标。 我们针对多个时期和每个批运行训练循环:
现在,我们准备介绍在每个训练师上运行的主要训练循环。 `get_next_batch`只是一个辅助函数,用于生成随机输入和训练目标。 我们针对多个时期和每个批运行训练循环:
1. 为分布式 Autograd 设置[分布式 Autograd 上下文](https://pytorch.org/docs/master/rpc.html#torch.distributed.autograd.context)
2. 运行模型的正向传递并检索其输出。
......
......@@ -258,7 +258,7 @@ Logistic 回归是一种分类器算法。 在这里,我们尝试预测输出
* 如果![](img/d0db0ac6-9742-4fbc-905f-dddbc30cbf2e.png),即![](img/4da2a48a-9385-4c47-afe2-4989350a9732.png) =-![](img/9c44051a-1dba-4450-856c-e8e5b3ef4385.png)。 因此,为了使![](img/d827463c-5d29-4a30-aa46-211a7414eced.png)最小化,![](img/3dfc404a-2201-48a1-87e6-c1caffdbd0ba.png)应该较小,即接近于 0。
损失函数适用于单个示例,而成本函数适用于整个训练批。 因此,这种情况下的成本函数为:
损失函数适用于单个示例,而成本函数适用于整个训练批。 因此,这种情况下的成本函数为:
![](img/e07efd45-fd71-41ac-9589-0b916252baf6.png)
......
......@@ -15,11 +15,11 @@
2014 年,Google 以高达 5 亿美元的价格收购了伦敦一家名为 DeepMind 的创业公司。 在新闻中,我们了解到他们创建了一个 AI 代理来击败任何 Atari 游戏,但是 Google 付出如此高的价格收购它的主要原因是因为这一突破向**通用人工智能**靠近了一步。 通用人工智能被称为 AI 代理。 它能够完成各种任务并像人类一样泛化。 当它超过这一点时,该点称为人工超级智能。 目前,AI 社区所做的工作就是我们所说的人工智能,即人工智能,其中 AI 代理能够执行多个任务,但不能概括各种任务。
DeepMind 在研究期刊 **Nature** 上发表了他们的论文[《通过深度强化学习进行人类水平控制》](http://www.davidqiu.com:8888/research/nature14236.pdf),这表明,他们的深度强化学习算法可成功应用于 50 种不同的 Atari 游戏,并在其中 30 种游戏中达到高于人类水平的性能。 他们的 AI 代理称为 **Deep-Q 学习**。 在详细深入学习强化学习之前,让我们回顾一下强化学习的基础知识。
DeepMind 在研究期刊 **Nature** 上发表了他们的论文[《通过深度强化学习进行人类水平控制》](http://www.davidqiu.com:8888/research/nature14236.pdf),这表明,他们的深度强化学习算法可成功应用于 50 种不同的 Atari 游戏,并在其中 30 种游戏中达到高于人类水平的性能。 他们的 AI 代理称为 **Deep-Q 学习**。 在详细深入学习强化学习之前,让我们回顾一下强化学习的基础知识。
有监督和无监督的学习是 AI 应用社区众所周知的。 **监督学习**处理包含输入特征和目标标签(连续或离散)的标记数据集,并创建将这些输入特征映射到目标标签的模型。 另一方面,**无监督学习**处理仅包含输入特征但不包含目标标签的未标记数据集,其目的是发现基础模式,以将数据分类到不同集群中,并分别定义其效用。 不同集群中特定类型的数据。
因此,使用有监督和无监督的学习,我们可以创建数据分类器/回归器或数据生成器,通过一次学习就可以通过一批数据进行学习。 为了随着时间的推移增强学习,该批需要合并越来越多的数据,从而导致有监督和无监督的学习变得缓慢且难以推广。 让我们考虑一种情况,您希望 AI 代理为您玩特定的视频/虚拟游戏,但要注意的是,随着时间的流逝,该算法应该变得智能。
因此,使用有监督和无监督的学习,我们可以创建数据分类器/回归器或数据生成器,通过一次学习就可以通过一批数据进行学习。 为了随着时间的推移增强学习,该批需要合并越来越多的数据,从而导致有监督和无监督的学习变得缓慢且难以推广。 让我们考虑一种情况,您希望 AI 代理为您玩特定的视频/虚拟游戏,但要注意的是,随着时间的流逝,该算法应该变得智能。
那么,如何解决这个问题呢?
......@@ -356,9 +356,9 @@ DeepMind 在其 DQN 网络中使用了三个卷积层和两个全连接层,从
# 使用经验重播
添加到深度 Q 网络的另一个重要功能是**体验重播**。 该功能背后的想法是,代理可以存储其过去的经验,并分批使用它们来训练深度神经网络。 通过存储经验,代理可以随机抽取批,并帮助网络从各种数据中学习,而不仅仅是对即时经验的决策正式化。 这些经历中的每一个都以包括**状态,动作,奖励,****下一个状态**的四维向量的形式存储。
添加到深度 Q 网络的另一个重要功能是**体验重播**。 该功能背后的想法是,代理可以存储其过去的经验,并分批使用它们来训练深度神经网络。 通过存储经验,代理可以随机抽取批,并帮助网络从各种数据中学习,而不仅仅是对即时经验的决策正式化。 这些经历中的每一个都以包括**状态,动作,奖励,****下一个状态**的四维向量的形式存储。
为了避免存储问题,体验重放的缓冲区是固定的,并且随着新体验的存储,旧体验将被删除。 为了训练神经网络,从缓冲区中提取均匀批的随机经验。
为了避免存储问题,体验重放的缓冲区是固定的,并且随着新体验的存储,旧体验将被删除。 为了训练神经网络,从缓冲区中提取均匀批的随机经验。
# 分离目标网络以计算目标 Q 值
......@@ -1134,7 +1134,7 @@ def store_experience(self,obs,a,r,obs_):
self.experience_counter+=1
```
现在,我们将定义`fit(self)`函数,以通过从经验缓冲区中选择一个批来训练网络,计算`q_target`的张量值,然后最小化`qeval`之间的损失(即主数据库的输出) 网络)和`q_target`(即使用目标网络计算的 Q 值):
现在,我们将定义`fit(self)`函数,以通过从经验缓冲区中选择一个批来训练网络,计算`q_target`的张量值,然后最小化`qeval`之间的损失(即主数据库的输出) 网络)和`q_target`(即使用目标网络计算的 Q 值):
```py
def fit(self):
......
......@@ -34,11 +34,11 @@ Google DeepMind 和 MILA 的联合团队于 2016 年 6 月发布了用于深度
深度强化学习中异步方法的高级示意图
在异步方法中,为每个线程分配了一个进程,该进程包含一个学习器,该学习器表示与自己的环境副本进行交互的代理网络。 因此,这些多个学习并行运行以探索他们自己的环境版本。 这种并行方法允许代理在任何给定的时间步长同时经历各种不同的状态,并涵盖了非策略学习和策略学习学习算法的基础。
在异步方法中,为每个线程分配了一个进程,该进程包含一个学习器,该学习器表示与自己的环境副本进行交互的代理网络。 因此,这些多个学习并行运行以探索他们自己的环境版本。 这种并行方法允许代理在任何给定的时间步长同时经历各种不同的状态,并涵盖了非策略学习和策略学习学习算法的基础。
如上所述,异步方法能够在多核 CPU(而不是 GPU)中显示出良好的效果。 因此,异步方法非常快,因此成为最新的强化学习算法,因为到目前为止,深度强化学习算法的实现依赖于 GPU 驱动的机器和分布式体系结构,以见证所实现算法的更快收敛。
这些并行运行的多个学习者使用不同的探索策略,从而最大限度地提高了多样性。 不同学习者的不同探索策略会更改参数,并且这些更新与时间相关的机会最少。 因此,不需要经验回放记忆,并且我们依靠使用不同探索策略的并行学习来执行先前在 DQN 中使用的经验回放的角色。
这些并行运行的多个学习器使用不同的探索策略,从而最大限度地提高了多样性。 不同学习器的不同探索策略会更改参数,并且这些更新与时间相关的机会最少。 因此,不需要经验回放记忆,并且我们依靠使用不同探索策略的并行学习来执行先前在 DQN 中使用的经验回放的角色。
使用并行学习器的好处如下:
......@@ -58,7 +58,7 @@ Google DeepMind 和 MILA 的联合团队于 2016 年 6 月发布了用于深度
异步单步 Q 学习的体系结构与 DQN 非常相似。 DQN 中的代理由一组主要网络和目标网络表示,其中一步损失的计算方法是主要网络预测的当前状态 s 的状态作用值与目标状态- 目标网络计算的当前状态的动作值。 相对于策略网络的参数来计算损失的梯度,然后使用梯度下降优化器将损失最小化,从而导致主网络的参数更新。
异步单步 Q 学习中的区别在于,有多个此类学习代理,例如,学习者并行运行并计算此损失。 因此,梯度计算也并行发生在不同的线程中,其中每个学习代理都与自己的环境副本进行交互。 这些梯度在多个时间步长上在不同线程中的累积用于在固定时间步长后或情节结束后更新策略网络参数。 梯度的累积优于策略网络参数更新,因为这样可以避免覆盖每个学习者代理执行的更改。
异步单步 Q 学习中的区别在于,有多个此类学习代理,例如,学习器并行运行并计算此损失。 因此,梯度计算也并行发生在不同的线程中,其中每个学习代理都与自己的环境副本进行交互。 这些梯度在多个时间步长上在不同线程中的累积用于在固定时间步长后或情节结束后更新策略网络参数。 梯度的累积优于策略网络参数更新,因为这样可以避免覆盖每个学习器代理执行的更改。
此外,将不同的探索策略添加到不同的线程可以使学习变得多样化且稳定。 由于更好的探索,因此提高了性能,因为不同线程中的每个学习代理都受到不同的探索策略。 尽管有许多方法可以执行此操作,但一种简单的方法是在使用![](img/396240a6-a09a-4588-b405-54fef7a9be74.png) -greedy 的同时为不同的线程使用不同的 epsilon ![](img/3594b237-6432-4150-bbcb-35b868d50025.png)示例。
......@@ -208,7 +208,7 @@ repeat until :
# 异步优势演员评论家
在异步优势参与者批评者的体系结构中,每个学习代理都包含一个参与者批评者,该学习结合了基于价值和基于策略的方法的优点。 参与者网络将状态作为输入,并预测该状态的最佳动作,而评论家网络将状态和动作作为输入,并输出动作分数以量化该状态的动作效果。 参与者网络使用策略梯度更新其权重参数,而评论者网络使用 *TD(0)*来更新其权重参数,换言之,两个时间步长之间的值估计之差,如[中所述 ]第 4 章](../Text/04.html)*政策梯度*
在异步优势参与者批评者的体系结构中,每个学习代理都包含一个参与者批评者,该学习结合了基于价值和基于策略的方法的优点。 参与者网络将状态作为输入,并预测该状态的最佳动作,而评论家网络将状态和动作作为输入,并输出动作分数以量化该状态的动作效果。 参与者网络使用策略梯度更新其权重参数,而评论者网络使用 *TD(0)*来更新其权重参数,换言之,两个时间步长之间的值估计之差,如[中所述 ]第 4 章](../Text/04.html)*政策梯度*
在第 4 章和*策略梯度*中,我们研究了如何通过从策略梯度的预期未来收益中减去基线函数来更新策略梯度,从而在不影响预期收益的情况下减少方差的情况。 梯度。 预期的未来奖励和基线函数之间的差称为**优势函数**; 它不仅告诉我们状态的好坏,而且还告诉我们该动作的预期好坏。
......@@ -493,6 +493,6 @@ if __name__ == "__main__":
# 概要
我们看到,使用并行学习更新共享模型可以大大改善学习过程。 我们了解了在深度学习中使用异步方法的原因及其不同的变体,包括异步单步 Q 学习,异步单步 SARSA,异步 n 步 Q 学习和异步优势参与者。 我们还学习了实现 A3C 算法的方法,在该方法中,我们使代理学习了 Breakout and Doom 游戏。
我们看到,使用并行学习更新共享模型可以大大改善学习过程。 我们了解了在深度学习中使用异步方法的原因及其不同的变体,包括异步单步 Q 学习,异步单步 SARSA,异步 n 步 Q 学习和异步优势参与者。 我们还学习了实现 A3C 算法的方法,在该方法中,我们使代理学习了 Breakout and Doom 游戏。
在接下来的章节中,我们将重点介绍不同的领域,以及如何以及可以应用深度强化学习。
\ No newline at end of file
......@@ -222,7 +222,7 @@ 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 帮助在线使用实时输入数据
# 进一步的改进
......
......@@ -33,7 +33,7 @@
# 强化学习的演变
在本书中,我们涵盖了从基础到高级的强化学习领域中的大多数算法。 因此,这些章节是理解机器人领域中不同算法所面临的应用和挑战的前提。 早期强化学习算法通过首先获取状态动作值,然后从中得出策略来处理获取最佳策略的问题。 然后,策略迭代方法出现了,直接用于输出优化的策略。 勘探开发技术有助于完善现有政策,探索新措施并更新现有政策。 强化学习方法,例如 MDP(在第 3 章,*马尔可夫决策过程*中),其中需要采用过渡模型的值迭代方法称为基于**模型的学习者**。 另一方面,诸如 Q 学习(在第 5 章, *Q-Learning 和深度 Q 网络*中)的算法不需要这种过渡模型,因此也不需要任何预定义的策略。 ,他们被称为**模型免费土地脱离政策学习者**
在本书中,我们涵盖了从基础到高级的强化学习领域中的大多数算法。 因此,这些章节是理解机器人领域中不同算法所面临的应用和挑战的前提。 早期强化学习算法通过首先获取状态动作值,然后从中得出策略来处理获取最佳策略的问题。 然后,策略迭代方法出现了,直接用于输出优化的策略。 勘探开发技术有助于完善现有政策,探索新措施并更新现有政策。 强化学习方法,例如 MDP(在第 3 章,*马尔可夫决策过程*中),其中需要采用过渡模型的值迭代方法称为基于**模型的学习器**。 另一方面,诸如 Q 学习(在第 5 章, *Q-Learning 和深度 Q 网络*中)的算法不需要这种过渡模型,因此也不需要任何预定义的策略。 ,他们被称为**模型免费土地脱离政策学习器**
在深度强化学习领域,行动价值函数逼近器和策略函数逼近器在制定最先进的学习算法集方面发挥着关键作用。 策略搜索算法(例如策略梯度)旨在通过最大化期望的奖励总和来找到最佳策略,而使用行动值函数近似器(例如深度 Q 网络)的算法旨在通过最大化期望的总和来找到给定状态的行动值 奖励。 但是,在处理由高维和连续状态动作空间构成的环境时,性能上的差异在于,这最能描述机器人在其中运行的真实环境。 在这种情况下,策略搜索算法的性能会更好,因为它们在连续状态操作空间域中可以更好地工作:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册