提交 5392bfc4 编写于 作者: W wizardforcel

2021-01-22 10:43:43

上级 e394780c
......@@ -549,7 +549,7 @@ for i in range(100):
5. 定义要使用的损失函数。 在这种情况下,请使用 MSE 损失函数。
6. 定义模型的优化器。 在这种情况下,请使用 Adam 优化器,并将学习率设为`0.01`。
7. 对 100 次迭代运行优化,保存每次迭代的损失值。 每 10 次迭代打印一次损失值。
8. 绘制线图以显示每个迭代步骤的损值。
8. 绘制线图以显示每个迭代步骤的损值。
注意
......
......@@ -194,7 +194,7 @@ Rosenblatt 还介绍了权重的概念(`w1`,`w2`,...,`wn`),这些数
### 反向传播
训练过程的最后一步包括在网络架构中从右向左移动以计算损函数相对于每一层的权重和偏差的偏导数(也称为梯度),以便更新这些 参数(权重和偏差),以便在下一个迭代步骤中,损失函数较低。
训练过程的最后一步包括在网络架构中从右向左移动以计算损函数相对于每一层的权重和偏差的偏导数(也称为梯度),以便更新这些 参数(权重和偏差),以便在下一个迭代步骤中,损失函数较低。
优化算法的最终目标是找到损失函数达到最小可能值的全局最小值,如下图所示:
......@@ -206,7 +206,7 @@ Rosenblatt 还介绍了权重的概念(`w1`,`w2`,...,`wn`),这些数
图 2.16:二维空间中迭代步骤的损失函数优化
在此,最左边的点`A`是任何优化之前的损失函数的初始值。 曲线底部最右边的点`B`是经过多次迭代步骤后的损函数,其值已最小化。 从一个点到另一个点的过程称为**步骤**
在此,最左边的点`A`是任何优化之前的损失函数的初始值。 曲线底部最右边的点`B`是经过多次迭代步骤后的损函数,其值已最小化。 从一个点到另一个点的过程称为**步骤**
但是,重要的是要提到损失函数并不总是像前面的函数那样平滑,这可能会带来在优化过程中达到局部最小值的风险。
......@@ -871,9 +871,9 @@ PyTorch 的构建考虑了该领域许多开发人员的意见,其优点是可
![Figure 2.32: Loss value for different iteration steps ](img/B15778_02_32.jpg)
图 2.32:不同迭代步骤的损
图 2.32:不同迭代步骤的损
可以看出,损值随时间连续减小。
可以看出,损值随时间连续减小。
7. 为了测试模型,对测试集的第一个实例进行预测,并与地面真相(目标值)进行比较。
......@@ -932,7 +932,7 @@ Ground truth: 1995.0 Prediction: 1998.0279541015625
神经网络最广为人知的形式是由一系列感知器创建的神经网络,这些感知器分层堆叠在一起,其中一列感知器(层)的输出是下一个感知器的输入。
解释了神经网络的典型学习过程。 在此,需要考虑三个主要过程:前向传播,损函数的计算和反向传播。
解释了神经网络的典型学习过程。 在此,需要考虑三个主要过程:前向传播,损函数的计算和反向传播。
该过程的最终目标是通过更新网络每个神经元中每个输入值所伴随的权重和偏差来最小化损失函数。 这可以通过迭代过程来实现,该过程可能要花费几分钟,几小时甚至几周的时间,具体取决于数据问题的性质。
......
......@@ -290,7 +290,7 @@ final_data.to_csv("dccc_prepared.csv", index=False)
## 构建模型
一旦确定了问题并且已经探究和准备了手头的数据,就可以定义模型了。 网络架构的定义,层的类型,损函数等应在前面的分析之后处理。 这主要是因为在机器学习中没有“千篇一律”的方法,而在深度学习中则没有。
一旦确定了问题并且已经探究和准备了手头的数据,就可以定义模型了。 网络架构的定义,层的类型,损函数等应在前面的分析之后处理。 这主要是因为在机器学习中没有“千篇一律”的方法,而在深度学习中则没有。
与聚类,计算机视觉和机器翻译一样,回归任务需要与分类任务不同的方法。 在以下部分中,您将找到构建用于解决分类任务的模型的关键特征,并说明如何实现“良好”架构,以及如何以及何时使用 PyTorch 中的自定义模块。 。
......
......@@ -501,7 +501,7 @@ style_features = features_extractor(style_img, model, \
分配给内容损失的权重通常称为`alpha`,而赋予样式损失的权重称为`beta`
计算总损的最终公式如下:
计算总损的最终公式如下:
![Figure 5.8: Total loss calculation ](img/B15778_05_08.jpg)
......@@ -680,6 +680,6 @@ style_features = features_extractor(style_img, model, \
最后,是时候对该迭代过程进行编码了,以用于创建具有所需功能的目标图像。 为此,计算了三种不同的损失。 有一个用于比较内容图像和目标图像之间的内容差异(内容损失),另一个用于比较样式图像和目标图像之间的风格差异(样式损失), 通过计算克矩阵实现。 最后,有一个结合了内容损失和样式损失(总损失)。
通过最小化总损的值来创建目标图像,这可以通过更新与目标图像有关的参数来完成。 尽管可以使用预先训练的网络,但获得理想目标图像的过程可能需要进行数千次迭代和相当多的时间。
通过最小化总损的值来创建目标图像,这可以通过更新与目标图像有关的参数来完成。 尽管可以使用预先训练的网络,但获得理想目标图像的过程可能需要进行数千次迭代和相当多的时间。
在下一章中,将说明不同的网络架构,以便使用文本数据序列解决数据问题。 RNN 是保存内存的神经网络架构,允许它们处理序列数据。 它们通常用于解决与人类语言理解有关的问题。
\ No newline at end of file
......@@ -284,7 +284,7 @@ for i in range(1, epochs+1):
例如,以著名的诗人埃德加·艾伦·坡(Edgar Alan Poe)所写的诗《乌鸦》(The Raven)为例,诗长超过 1000 个字。 试图使用传统的 RNN 来处理它,以创建相似的相关诗歌为目标,将导致该模型在前几段中遗漏了关键信息。 反过来,这可能导致输出与诗歌的初始主题无关。 例如,它可以忽略事件是在晚上发生的,因此使新诗不是很吓人。
之所以无法保持长期记忆,是因为传统的 RNN 遭受称为梯度消失的问题。 当用于更新网络参数以最小化损函数的梯度变得非常小,从而不再对网络的学习过程有所帮助时,就会发生这种情况。 这通常发生在网络的前几层,使网络忘记了一段时间。
之所以无法保持长期记忆,是因为传统的 RNN 遭受称为梯度消失的问题。 当用于更新网络参数以最小化损函数的梯度变得非常小,从而不再对网络的学习过程有所帮助时,就会发生这种情况。 这通常发生在网络的前几层,使网络忘记了一段时间。
因此,开发了 **LSTM** 网络。 LSTM 网络可以像存储计算机一样存储内部存储器,因此可以长时间记住信息。 也就是说,它们根据需要读取,写入和删除信息,这是通过使用门来实现的。
......
......@@ -1425,7 +1425,7 @@
target_img = content_img.clone().requires_grad_(True).to(device)
```
9. 设置不同样式层的权重,以及内容和样式损的权重。
9. 设置不同样式层的权重,以及内容和样式损的权重。
```py
style_weights = {'conv1_1': 1., 'conv2_1': 0.8, \
......
......@@ -109,7 +109,7 @@
在该等式中, `D[w] = √((f(X1) - f(X2))²)``f(X)`代表连体神经网络,`m`代表裕度。
让我们进一步求解损方程。 以`Y = 1`表示相似的货币对:
让我们进一步求解损方程。 以`Y = 1`表示相似的货币对:
![](img/029593cf-8b9d-4162-8c8f-4b58a97c679d.png)
......@@ -1058,7 +1058,7 @@ plot_loss(train_loss,val_loss)
![](img/97d99dae-968d-45c3-9d2f-13cf0b663c2b.png)
在本节中,我们探索了使用 MNIST 数据集的连体网络的实现以及使用 Omniglot 数据集的匹配网络架构。 在连体网络编码练习中,我们创建了一个小的卷积层,并由一个全连接层姐妹架构进行了扩展。 训练模型后,我们还绘制了模型获得的二维嵌入图,并观察了某些数字如何聚类在一起。 同样,在匹配网络编码练习中,我们为匹配网络的每个模块实现了小型架构,例如嵌入提取器,注意力模型和完全上下文嵌入。 我们还观察到,仅用 100 个时期,我们就可以达到约 86% 的精度,并绘制了匹配网络架构的精度和损图。
在本节中,我们探索了使用 MNIST 数据集的连体网络的实现以及使用 Omniglot 数据集的匹配网络架构。 在连体网络编码练习中,我们创建了一个小的卷积层,并由一个全连接层姐妹架构进行了扩展。 训练模型后,我们还绘制了模型获得的二维嵌入图,并观察了某些数字如何聚类在一起。 同样,在匹配网络编码练习中,我们为匹配网络的每个模块实现了小型架构,例如嵌入提取器,注意力模型和完全上下文嵌入。 我们还观察到,仅用 100 个时期,我们就可以达到约 86% 的精度,并绘制了匹配网络架构的精度和损图。
您可能还观察到某些模型是从头开始训练的-我们可能已经使用了迁移学习架构,或者增加了 LSTM 架构的隐藏大小,或者也许被认为是加权的交叉熵损失函数。 总是有实验和改进的空间。 如果您想进一步尝试使用该模型,建议您访问本书的 GitHub 页面。
......
......@@ -136,7 +136,7 @@ MANN 的读取操作与 NTM 的读取操作非常相似,唯一的区别是此
* <sub>![](img/24de8133-5c89-4516-aee1-7d67169fb126.png)</sub> :嵌入函数的快速权重,( <sub>* ![](img/23c3a7fe-0fcf-4d10-956d-5bd9810c0232.png) *</sub> )。
* <sub>![](img/85f7976d-7eba-4739-b527-e798652eabeb.png)</sub> :基本学习器模型的快速权重( <sub>* ![](img/52001f20-110a-4f6c-a3da-8418744cb716.png) *</sub> )。
* <sub>*![](img/86d121fb-e454-4b03-bb18-1224e2c5db40.png) *</sub> :一种 LSTM 架构,用于学习嵌入函数的快速权重 <sub>![](img/45de2f89-d9d7-48df-807e-474abf54ba2c.png)</sub> (( <sub>![](img/e2604082-7c04-461c-a490-d861af786a6d.png)</sub> )的慢速网络。
* <sub>*![](img/73662f56-4d4a-4173-8fda-cbc27fcddb1e.png) *</sub> :通过`v`学习快速权重 <sub>![](img/1473324d-1977-4883-a009-fd5653b452c9.png)</sub> 参数化的神经网络,用于基础学习器 <sub>![](img/5bbeac7c-31a0-4f2d-aeb2-f2d2eec0fe92.png)</sub> ,来自其损梯度。
* <sub>*![](img/73662f56-4d4a-4173-8fda-cbc27fcddb1e.png) *</sub> :通过`v`学习快速权重 <sub>![](img/1473324d-1977-4883-a009-fd5653b452c9.png)</sub> 参数化的神经网络,用于基础学习器 <sub>![](img/5bbeac7c-31a0-4f2d-aeb2-f2d2eec0fe92.png)</sub> ,来自其损梯度。
下图说明了元网络架构:
......
......@@ -70,7 +70,7 @@ MAML 的目的是为模型的参数提供良好的初始化,从而以较少的
结束`for`循环。
5. 通过使用模型`f[θ'[i]]`上的采样测试数据点`D'[i]`计算损及其梯度来更新`θ`
5. 通过使用模型`f[θ'[i]]`上的采样测试数据点`D'[i]`计算损及其梯度来更新`θ`
![](img/00a98b32-110e-44d8-9a49-e36078be0d57.png)
......@@ -109,7 +109,7 @@ LSTM 在各种门的帮助下存储信息历史记录,如上图所示。 我
![](img/5a9a4fca-cdb7-4c9d-9aba-27c879fc4481.png)
此处, <sub>![](img/483507cb-4cb0-4598-aa76-71fcabdafe41.png)</sub> 是时间步长`t`的参数, <sub>![](img/cb291113-cc4b-4419-be0f-ab628e911b69.png)</sub>`t`时的损梯度,并且 <sub>![](img/e58b0d63-1733-40c2-9ea3-c28b9571e685.png)</sub> 是时间`t`时的学习率。
此处, <sub>![](img/483507cb-4cb0-4598-aa76-71fcabdafe41.png)</sub> 是时间步长`t`的参数, <sub>![](img/cb291113-cc4b-4419-be0f-ab628e911b69.png)</sub>`t`时的损梯度,并且 <sub>![](img/e58b0d63-1733-40c2-9ea3-c28b9571e685.png)</sub> 是时间`t`时的学习率。
另一方面,LSTM 单元的单元更新方程看起来像这样:
......@@ -123,15 +123,15 @@ LSTM 在各种门的帮助下存储信息历史记录,如上图所示。 我
![](img/da2cd6b1-bca0-456b-8064-23bdb90ef26c.png)
本质上,`i[t]`被定义为具有当前梯度,当前损和先前学习率 <sub>![](img/991684d7-83b0-429c-91ef-5d41500f2726.png)</sub> 的组合的 Sigmoid 函数。
本质上,`i[t]`被定义为具有当前梯度,当前损和先前学习率 <sub>![](img/991684d7-83b0-429c-91ef-5d41500f2726.png)</sub> 的组合的 Sigmoid 函数。
对于 <sub>![](img/f76a02ea-f996-4c81-a08f-8bf2e6bd97c1.png)</sub> ,应为 1,但为避免梯度缩小的问题,其定义如下:
![](img/1d551c2d-de09-4a7b-8657-0c310ee85bbb.png)
本质上,`f[t]`被定义为具有当前梯度,当前损和遗忘门的 Sigmoid 函数。
本质上,`f[t]`被定义为具有当前梯度,当前损和遗忘门的 Sigmoid 函数。
您可能想知道为什么他们使用 LSTM 单元的这种特定选择? 如果仔细观察,会根据当前梯度和当前损选择`i[t]``f[t]`。 故意这样做是为了使元学习器能够*控制学习率*,以便在更少的时间内训练基础学习器。
您可能想知道为什么他们使用 LSTM 单元的这种特定选择? 如果仔细观察,会根据当前梯度和当前损选择`i[t]``f[t]`。 故意这样做是为了使元学习器能够*控制学习率*,以便在更少的时间内训练基础学习器。
# 数据预处理
......
......@@ -73,7 +73,7 @@
代码块设置如下:
进口火炬
导入火炬
当我们希望引起您对代码块特定部分的注意时,相关行或项目以粗体显示:
......
......@@ -186,14 +186,14 @@ ReLU 是非常简单的非线性函数,当`x <= 0`,返回`y = 0`;当`x > 0
使用神经网络从数据中学习的行为比使用基本回归学习时的行为稍微复杂一些。 尽管我们仍然像以前一样使用梯度下降,但是我们需要区分的实际损失函数变得更加复杂。 在没有激活函数的单层神经网络中,我们很容易计算损失函数的导数,因为很容易看到随着我们改变每个参数损失函数如何变化。 但是,在具有激活函数的多层神经网络中,这更加复杂。
我们必须首先执行**正向传播**,即,其中,使用模型的当前状态,我们计算`y`的预测值,并根据`y`的真实值来评估它,以便获得损失的度量。 利用这一损耗,我们可以在网络中向后移动,计算网络中每个参数的梯度。 这使我们可以知道向哪个方向更新参数,以便使可以更接近损耗最小的点。 这被称为**反向传播**。 我们可以使用**链式规则**计算相对于每个参数的损失函数的导数:
我们必须首先执行**正向传播**,即,其中,使用模型的当前状态,我们计算`y`的预测值,并根据`y`的真实值来评估它,以便获得损失的度量。 利用这一损失,我们可以在网络中向后移动,计算网络中每个参数的梯度。 这使我们可以知道向哪个方向更新参数,以便使可以更接近损失最小的点。 这被称为**反向传播**。 我们可以使用**链式规则**计算相对于每个参数的损失函数的导数:
![](img/Formula_01_032.png)
此处,![](img/Formula_01_033.png)是网络内每个给定节点的输出。 因此,总而言之,在神经网络上执行梯度下降时我们采取的四个主要步骤如下:
1. 使用您的数据执行正向传播,计算网络的总损
2. 使用反向传播,计算每个参数相对于网络中每个节点损的梯度。
1. 使用您的数据执行正向传播,计算网络的总损
2. 使用反向传播,计算每个参数相对于网络中每个节点损的梯度。
3. 更新这些参数的值,朝着使损失最小化的方向发展。
4. 重复直到收敛。
......@@ -205,7 +205,7 @@ ReLU 是非常简单的非线性函数,当`x <= 0`,返回`y = 0`;当`x > 0
图 1.14 –测试和训练时期
在这里,我们可以看到随着我们继续训练网络,随着我们向总损耗最小化的方向靠近,训练损耗会随着时间的推移而减小。 虽然这可以很好地推广到测试数据集,但一段时间后,由于我们的函数过度适合训练集中的数据,测试数据集上的总损失开始增加。 一种解决方案是**提前停止**。 因为我们希望我们的模型对之前从未见过的数据做出良好的预测,所以我们可以在测试损失最小的时候停止训练我们的模型。 经过全面训练的 NLP 模型可能能够轻松地对以前见过的句子进行分类,但是,对真正了解到某些东西的模型的衡量标准是能够对看不见的数据进行预测。
在这里,我们可以看到随着我们继续训练网络,随着我们向总损失最小化的方向靠近,训练损失会随着时间的推移而减小。 虽然这可以很好地推广到测试数据集,但一段时间后,由于我们的函数过度适合训练集中的数据,测试数据集上的总损失开始增加。 一种解决方案是**提前停止**。 因为我们希望我们的模型对之前从未见过的数据做出良好的预测,所以我们可以在测试损失最小的时候停止训练我们的模型。 经过全面训练的 NLP 模型可能能够轻松地对以前见过的句子进行分类,但是,对真正了解到某些东西的模型的衡量标准是能够对看不见的数据进行预测。
# 用于机器学习的 NLP
......
......@@ -289,9 +289,9 @@ Loss(y) = -log(y)
图 2.13 –我们网络的损失表示
然后将其汇总到数据集中所有正确的类中,以计算总损失。 请注意,我们在构建分类器时定义了对数 softmax,因为它已经应用了 softmax 函数(将预测输出限制在 0 到 1 之间)并获取了日志。 这意味着`log(y)`已经被计算出来,因此我们要计算网络上的总损所需要做的就是计算输出的负和。
然后将其汇总到数据集中所有正确的类中,以计算总损失。 请注意,我们在构建分类器时定义了对数 softmax,因为它已经应用了 softmax 函数(将预测输出限制在 0 到 1 之间)并获取了日志。 这意味着`log(y)`已经被计算出来,因此我们要计算网络上的总损所需要做的就是计算输出的负和。
我们还将优化器定义为 Adam 优化器。 优化器控制模型中的**学习率**。 模型的学习率定义了每次训练期间参数更新的大小。 学习速率的大小越大,梯度下降期间参数更新的大小越大。 优化器动态控制该学习速率,以便在初始化模型时,参数更新很大。 但是,随着模型的学习和向损最小化点的靠近,优化器将控制学习率,因此参数更新变得更小,可以更精确地定位局部最小值。
我们还将优化器定义为 Adam 优化器。 优化器控制模型中的**学习率**。 模型的学习率定义了每次训练期间参数更新的大小。 学习速率的大小越大,梯度下降期间参数更新的大小越大。 优化器动态控制该学习速率,以便在初始化模型时,参数更新很大。 但是,随着模型的学习和向损最小化点的靠近,优化器将控制学习率,因此参数更新变得更小,可以更精确地定位局部最小值。
## 训练我们的网络
......
......@@ -37,7 +37,7 @@ RNN 由循环层组成。 尽管它们在许多方面类似于标准前馈神经
![](img/Formula_05_001.png)
然后在输入序列中的每个时间步重复此操作,此层的最终输出是我们的最后一个隐藏状态`h[n]`。 当我们的网络学习时,我们像以前一样通过网络进行正向传播,以计算最终分类。 然后,我们根据此预测来计算损,并像以前一样通过网络反向传播,并随即计算梯度。 反向传播过程在循环层的所有步骤中进行,每个输入步骤和隐藏状态之间的参数都将被学习。
然后在输入序列中的每个时间步重复此操作,此层的最终输出是我们的最后一个隐藏状态`h[n]`。 当我们的网络学习时,我们像以前一样通过网络进行正向传播,以计算最终分类。 然后,我们根据此预测来计算损,并像以前一样通过网络反向传播,并随即计算梯度。 反向传播过程在循环层的所有步骤中进行,每个输入步骤和隐藏状态之间的参数都将被学习。
稍后我们将看到,我们实际上可以在每个时间步长都采用隐藏状态,而不是使用最终的隐藏状态,这对于 NLP 中的序列到序列翻译任务很有用。 但是,暂时来说,我们只是将隐藏层作为对网络其余部分的输出。
......@@ -53,7 +53,7 @@ RNN 由循环层组成。 尽管它们在许多方面类似于标准前馈神经
## 梯度爆炸和收缩
RNN 中我们经常面临的一个问题是**梯度爆炸或收缩**。 我们可以将递归层视为一个非常深的网络。 在计算梯度时,我们在隐藏状态的每次迭代中都这样做。 如果在给定位置的损相对于权重的梯度变得很大,则在递归层的所有迭代中前馈时,这将产生乘法效果。 这会导致梯度爆炸,因为它们会很快变得非常大。 如果我们的梯度较大,则可能导致网络不稳定。 另一方面,如果隐藏状态下的梯度非常小,这将再次产生乘法效果,并且梯度将接近 0。这意味着梯度可能变得太小而无法通过梯度下降准确地更新参数, 表示我们的模型无法学习。
RNN 中我们经常面临的一个问题是**梯度爆炸或收缩**。 我们可以将递归层视为一个非常深的网络。 在计算梯度时,我们在隐藏状态的每次迭代中都这样做。 如果在给定位置的损相对于权重的梯度变得很大,则在递归层的所有迭代中前馈时,这将产生乘法效果。 这会导致梯度爆炸,因为它们会很快变得非常大。 如果我们的梯度较大,则可能导致网络不稳定。 另一方面,如果隐藏状态下的梯度非常小,这将再次产生乘法效果,并且梯度将接近 0。这意味着梯度可能变得太小而无法通过梯度下降准确地更新参数, 表示我们的模型无法学习。
我们可以用来防止的梯度爆炸的一种技术是使用**梯度剪切**。 此技术限制了我们的梯度,以防止它们变得太大。 我们只需选择一个超参数`C`,就可以计算出裁剪的梯度,如下所示:
......@@ -135,7 +135,7 @@ LSTM 与 RNN 的结构非常相似。 虽然 LSTM 的各个步骤之间存在一
输出门计算 LSTM 单元的最终输出-单元状态和隐藏状态,并继续进行下一步。 单元状态`c[t]`与前两个步骤相同,是遗忘门和输入门的乘积。 通过获取串联的先前隐藏状态`h[t-1]`和当前时间步输入`x[t]`,可以计算出最终隐藏状态`h[t]`,并通过具有一些学习参数的 Sigmoid 函数来获得输出门输出`o[t]`。 最终单元状态`c[t]`通过 tanh 函数并乘以输出门输出`o[t]`,以计算最终隐藏状态`h[t]`。 这意味着在输出门上学习到的参数可以有效地控制将先前隐藏状态和当前输出中的哪些元素与最终单元状态进行组合,以作为新的隐藏状态延续到下一个时间步长。
在我们的前向遍历中,我们简单地遍历模型,初始化我们的隐藏状态和单元状态,并在每个时间步使用 LSTM 单元对其进行更新,直到剩下最终的隐藏状态为止,该状态将输出到神经元的下一层 网络。 通过在 LSTM 的所有层中进行反向传播,我们可以计算相对于网络损的梯度,因此我们知道通过梯度下降来更新参数的方向。 我们得到几种矩阵或参数-一种用于输入门,一种用于输出门,以及一种用于遗忘门。
在我们的前向遍历中,我们简单地遍历模型,初始化我们的隐藏状态和单元状态,并在每个时间步使用 LSTM 单元对其进行更新,直到剩下最终的隐藏状态为止,该状态将输出到神经元的下一层 网络。 通过在 LSTM 的所有层中进行反向传播,我们可以计算相对于网络损的梯度,因此我们知道通过梯度下降来更新参数的方向。 我们得到几种矩阵或参数-一种用于输入门,一种用于输出门,以及一种用于遗忘门。
因为我们获得的参数要比简单的 RNN 多,并且我们的计算图更加复杂,所以与简单的 RNN 相比,通过网络反向传播和更新权重的过程可能会花费更长的时间。 但是,尽管训练时间更长,但是我们已经证明,与传统的 RNN 相比,LSTM 具有显着的优势,因为输出门,输入门和遗忘门都结合在一起,使模型能够确定应使用输入的哪些元素。 更新隐藏状态,并且以后应该忘记隐藏状态的哪些元素,这意味着该模型能够更好地形成长期依存关系并保留先前序列步骤中的信息。
......
......@@ -394,7 +394,7 @@ def multi_accuracy(preds, y):
在这里,对于我们的预测,我们的模型使用`torch.max`函数对所有预测返回具有最高预测值的索引。 对于这些预测中的每一个,如果此预测索引与标签的索引相同,则将其视为正确的预测。 然后,我们对所有这些正确的预测进行计数,然后将它们除以预测的总数,以得出多类准确率的度量。 我们可以在训练循环中使用此功能来测量每个时期的准确率。
接下来,我们定义训练功能。 最初,我们将时间段的损失和准确率设置为`0`,我们将其称为`model.train()`以允许我们在训练模型时更新模型中的参数 模型:
接下来,我们定义训练函数。 最初,我们将时间段的损失和准确率设置为`0`,我们将其称为`model.train()`以允许我们在训练模型时更新模型中的参数 模型:
```py
def train(model, iterator, optimizer, criterion):
......@@ -436,7 +436,7 @@ for batch in iterator:
return total_epoch_loss, total_epoch_accuracy
```
同样,我们可以定义一个称为`eval`的函数,该函数将在验证数据上调用,以根据尚未训练模型的一组数据来计算训练后的模型性能。 尽管此功能与我们之前定义的训练功能几乎相同,但是我们必须做两个关键的补充:
同样,我们可以定义一个称为`eval`的函数,该函数将在验证数据上调用,以根据尚未训练模型的一组数据来计算训练后的模型性能。 尽管此功能与我们之前定义的训练函数几乎相同,但是我们必须做两个关键的补充:
```py
model.eval()
......
......@@ -91,7 +91,7 @@
图 7.8 –使用教师强制
但是,通过使用**教师强制**,我们使用正确的先前目标词来训练我们的模型,以便一个错误的预测不会抑制我们的模型从正确的预测中学习的能力。 这意味着,如果我们的模型在句子中的某一点做出了错误的预测,那么它仍然可以使用后续单词来做出正确的预测。 尽管我们的模型仍然会错误地预测单词,并且会损失损以更新梯度,但是现在,我们没有遭受梯度爆炸的困扰,并且我们的模型将更快地学习:
但是,通过使用**教师强制**,我们使用正确的先前目标词来训练我们的模型,以便一个错误的预测不会抑制我们的模型从正确的预测中学习的能力。 这意味着,如果我们的模型在句子中的某一点做出了错误的预测,那么它仍然可以使用后续单词来做出正确的预测。 尽管我们的模型仍然会错误地预测单词,并且会损失损以更新梯度,但是现在,我们没有遭受梯度爆炸的困扰,并且我们的模型将更快地学习:
![Figure 7.9 – Updating for losses ](img/B12365_07_09.jpg)
......
......@@ -899,7 +899,7 @@ print('Response:', ' '.join(output_words))
## 训练模型
当我们定义了所有必需的功能时,训练模型就成为一种情况或初始化我们的超参数并调用我们的训练功能
当我们定义了所有必需的功能时,训练模型就成为一种情况或初始化我们的超参数并调用我们的训练函数
1. 我们首先初始化我们的超参数。虽然这些只是建议的超参数,但我们的模型已经被设置为允许它们适应任何传递给它们的超参数的方式。用不同的超参数进行实验,看看哪些超参数能带来最佳的模型配置,这是一个很好的做法。在这里,你可以试验增加编码器和解码器的层数,增加或减少隐藏层的大小,或者增加批次大小。所有这些超参数都会对模型的学习效果产生影响,同时也会影响其他一些因素,例如训练模型所需的时间。
......@@ -1037,7 +1037,7 @@ print('Response:', ' '.join(output_words))
![Figure 8.16 – Average loss after 4,000 iterations ](img/B12365_08_16.jpg)
图 8.16 – 4,000 次迭代后的平均损
图 8.16 – 4,000 次迭代后的平均损
现在我们的模型已经训练完毕,我们可以开始评估过程并开始使用聊天机器人。
......
......@@ -18,7 +18,7 @@
* 实现模型训练
* 实现模型测试
* 加载数据集
* 定义 TensorBoard 作者
* 定义 TensorBoard 写入器
* 训练模型和解冻层
# 技术要求
......@@ -110,9 +110,9 @@ return model
# 操作步骤
我们将在此秘籍中实现训练功能
我们将在此秘籍中实现训练函数
1. 定义训练功能
1. 定义训练函数
```py
>>def train(model, device, train_loader, criterion, optimizer, epoch, writer):
......@@ -147,7 +147,7 @@ return model
return total_loss/len(train_loader)
```
通过此秘籍,我们完成了训练功能
通过此秘籍,我们完成了训练函数
# 工作原理
......@@ -189,7 +189,7 @@ return model
writer.add_image(img_name, inv_normalize(image_tensor), epoch)
```
3. 现在,我们将具有一个用于记录指标的功能
3. 现在,我们将具有一个用于记录指标的函数
```py
>>def test(model, device, test_loader, criterion, epoch, writer):
......@@ -563,7 +563,7 @@ Epoch | Training Loss | Test Loss | Accuracy |
# 工作原理
在此秘籍中,我们创建了模型并将其移至可用设备,并分别使用负对数损和 Adam 作为我们的标准和优化器。 `train_epochs()`方法用于在定义的时期范围内训练模型。 在每个时期结束时,我们使用`writer.flush()`方法来确保所有未决事件已写入磁盘。 最后,我们使用`writer.close()`刷新关闭编写器。 我们还在此功能中保存了最佳模型,以供日后重新加载。
在此秘籍中,我们创建了模型并将其移至可用设备,并分别使用负对数损和 Adam 作为我们的标准和优化器。 `train_epochs()`方法用于在定义的时期范围内训练模型。 在每个时期结束时,我们使用`writer.flush()`方法来确保所有未决事件已写入磁盘。 最后,我们使用`writer.close()`刷新关闭编写器。 我们还在此功能中保存了最佳模型,以供日后重新加载。
然后,我们从到目前为止的训练中重新加载了最佳模型,并对其进行了冻结以进行微调。 解冻后,所有模型参数均可用于训练。 我们将优化器设置为较低的学习率,对该未冻结的模型进行了更多的训练,并记录了模型的性能。 我们看到,通过微调,我们的模型表现更好。
......
......@@ -48,7 +48,7 @@ GAN 中的两个模型称为生成器和判别器,其中生成器负责创建
在此秘籍中,我们将实现 GAN 网络的生成器端:
1.我们将从进口开始:
1.我们将从导入开始:
```py
>import torch
......@@ -142,7 +142,7 @@ def forward(self, input):
在此秘籍中,我们将构建 GAN 的判别器端:
1.我们将从进口开始:
1.我们将从导入开始:
```py
>>import torch.nn.functional as F
......@@ -219,7 +219,7 @@ pip install torchsummary
在此秘籍中,我们将完成 GAN 训练:
1. 一,进口
1. 首先导入
```py
>>from torchsummary import summary
......@@ -320,14 +320,14 @@ Estimated Total Size (MB): 0.58
>>fixed_noise = torch.randn(64, z_dim, device=device)
```
7. 现在,我们将定义优化器功能
7. 现在,我们将定义优化器函数
```py
>>doptimizer = optim.Adam(discriminator.parameters())
>>goptimizer = optim.Adam(generator.parameters())
```
8. 然后,我们将为鉴别符设置标签:
8. 然后,我们将为判别器设置标签:
```py
>>real_label, fake_label = 1, 0
......@@ -437,7 +437,7 @@ doptimizer.step()
generator.zero_grad()
```
5. 然后,我们将标签从假更改为真
5. 然后,我们将标签从假更改为真:
```py
label.fill_(1)
......@@ -449,7 +449,7 @@ label.fill_(1)
d_output = discriminator(fake_images).view(-1)
```
7. 然后我们计算生成器损和梯度并更新生成器权重:
7. 然后我们计算生成器损和梯度并更新生成器权重:
```py
gerror = criterion(d_output, label)
......@@ -457,7 +457,7 @@ gerror.backward()
goptimizer.step()
```
8. 然后我们节省了损失:
8. 然后我们保存了损失:
```py
if i % 50 == 0:
......@@ -547,9 +547,9 @@ 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`。 然后,我们计算梯度并更新发生器权重。
然后,我们开始训练生成器,并且生成器应该能够欺骗判别器。 生成器必须纠正鉴别者正确预测生成的图像为假的情况。 因此,只要来自判别器的预测将生成的图像标记为伪造,就会增加生成器损`gerror`。 然后,我们计算梯度并更新发生器权重。
然后,我们定期显示模型指标,并保存固定噪声生成器生成的图像,以可视化模型在各个时期的性能。
......@@ -582,7 +582,7 @@ pip install numpy
在此秘籍中,我们将快速绘制 GAN 中的图形和图像:
1. 我们将从进口开始:
1. 我们将从导入开始:
```py
>>import matplotlib.pyplot as plt
......@@ -596,7 +596,7 @@ pip install numpy
>>plt.title("Generator and Discriminator Loss During Training")
```
3. 接下来,我们添加生成器和判别器损
3. 接下来,我们添加生成器和判别器损
```py
>>plt.plot(g_losses,label="Generator")
......@@ -642,7 +642,7 @@ pip install numpy
# 工作原理
在本秘籍中,我们使用 matplotlib 绘制图形和图像。 我们使用`figure()`和`title()`方法设置图形尺寸和标题,然后使用`plot()`方法绘制发生器和判别器损。 我们还使用`xlabel`和`ylabel`方法添加了`x`和`y`标签。 我们还使用`legend()`方法为图添加了图例,最后使用`show()`方法显示了图。
在本秘籍中,我们使用 matplotlib 绘制图形和图像。 我们使用`figure()`和`title()`方法设置图形尺寸和标题,然后使用`plot()`方法绘制发生器和判别器损。 我们还使用`xlabel`和`ylabel`方法添加了`x`和`y`标签。 我们还使用`legend()`方法为图添加了图例,最后使用`show()`方法显示了图。
我们遍历训练期间保存在`image_list`中的图像,并使用 NumPy 的`transpose()`方法以所需顺序固定图像的尺寸。 `image_list`中的图像是使用`torchvision.util.make_grid()`方法生成的,我们根据噪声向量创建了生成图像的网格。
......@@ -667,7 +667,7 @@ pip install numpy
PGGAN 的关键创新可以总结如下:
* **高分辨率层中的逐渐增长和平滑淡化**:它从低分辨率卷积变为高分辨率卷积,而不是立即跳变分辨率,而是通过参数平滑地淡化了具有更高分辨率的 nedonew 层`α`(介于 0 和 1 之间)的大小,用于控制我们使用旧的还是放大的较大输出。
* **小批量标准差**:我们计算鉴别符的统计信息,即生成器生成或来自真实数据的小批量中所有像素的标准差。 现在,判别器需要了解,如果要评估的批量中图像的标准差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗判别器。
* **小批量标准差**:我们计算判别器的统计信息,即生成器生成或来自真实数据的小批量中所有像素的标准差。 现在,判别器需要了解,如果要评估的批量中图像的标准差较低,则该图像很可能是伪造的,因为真实数据的方差更高。 因此,生成器必须增加所生成样本的方差,以欺骗判别器。
* **均衡的学习率**:所有权重(`w`)被归一化(`w'`)在某个范围内,以便`w' = w / c`的常数`c`对于每一层来说都是不同的,具体取决于重量矩阵的形状。
* **逐像素特征归一化**:对每个像素中的特征向量进行归一化,因为批量规范最适合大型微型批量,并且占用大量内存。
......@@ -681,7 +681,7 @@ Nvidia 最初执行 PGGAN 的过程要花一到两个月的时间。 但是,
在此秘籍中,我们将从火炬中心运行 PGGAN:
1. 首先,我们将设置进口
1. 首先,我们将设置导入
```py
>>import torch
......
......@@ -505,7 +505,7 @@ Rewards: 160.0
在本秘籍中,我们将完成网络模型定义。 您需要安装 OpenAI 的体育馆库。 按着这些次序:
1. 我们将从进口开始:
1. 我们将从导入开始:
```py
>>import torch.nn as nn
......@@ -604,7 +604,7 @@ agents.append(agent)
在本秘籍中,我们将编写用于评估代理,多次评估以及按给定序列评估所有代理的功能。 按着这些次序:
1. 我们将从进口开始:
1. 我们将从导入开始:
```py
>>import numpy as np
......
......@@ -31,7 +31,7 @@ pip install flask
我们将把这个秘籍分成多个文件。 请按照以下步骤操作:
1. 创建一个名为`image_classifier.py`的文件。
2. 现在,我们需要进行进口
2. 现在,我们需要进行导入
```py
>>import io
......@@ -446,7 +446,7 @@ pip install onnx
在本秘籍中,我们将 CIFAR-1o 模型导出为 ONNX 格式,并使用`onnxruntime`运行它。 请按照以下步骤操作:
1. 我们将从进口开始:
1. 我们将从导入开始:
```py
>>import onnx
......
......@@ -257,11 +257,11 @@ print(a2.grad, a2.grad_fn, a2)
![Backpropagation](img/B09475_02_07.jpg)
图 2.7:反向传播和减少损的例子
图 2.7:反向传播和减少损的例子
考虑损失函数的图形,其中`Y`轴是误差(我们的模型有多糟糕)。 最初,模型的预测将是随机的,并且对于整个数据集而言确实是不利的,也就是说,`Y`轴上的误差确实很高。 我们需要像爬山一样将其向下移动:我们要爬下山并找到山谷中能提供接近准确结果的最低点。
反向传播通过找到每个参数应移动的方向来实现这一点,从而使损值的整体运动爬下山。 我们为此寻求微积分的帮助。 任何函数相对于最终误差的导数都可以告诉我们上图中该函数的斜率是多少。 因此,反向传播通过获取关于最终损失的每个神经元(通常每个神经元通常是非线性函数)的导数并告诉我们必须移动的方向来帮助我们。
反向传播通过找到每个参数应移动的方向来实现这一点,从而使损值的整体运动爬下山。 我们为此寻求微积分的帮助。 任何函数相对于最终误差的导数都可以告诉我们上图中该函数的斜率是多少。 因此,反向传播通过获取关于最终损失的每个神经元(通常每个神经元通常是非线性函数)的导数并告诉我们必须移动的方向来帮助我们。
在拥有框架之前,这不是一个容易的过程。 实际上,找到每个参数的导数并进行更新是一项繁琐且容易出错的任务。 在 PyTorch 中,您要做的就是在最后一个节点上调用`backward`,它将反向传播并更新它。 具有梯度的`grad`属性。
......@@ -533,7 +533,7 @@ output = loss(hyp, y_)
output.backward()
```
`nn`模块的损失比我们在以后的章节中看到的要复杂得多,但是对于我们当前的用例,我们将使用`MSELoss`。 我们用`nn.MSELoss()`创建的损耗节点等效于我们在第一个示例中定义的损耗
`nn`模块的损失比我们在以后的章节中看到的要复杂得多,但是对于我们当前的用例,我们将使用`MSELoss`。 我们用`nn.MSELoss()`创建的损失节点等效于我们在第一个示例中定义的损失
```py
error = hyp - y_
......
......@@ -477,7 +477,7 @@ trainer = Engine(training_loop)
这很聪明,但这并没有节省用户大量时间,也没有兑现承诺,例如删除样板。 它所做的只是删除两个`for`循环并添加`Engine`对象创建的另一行。 这并不是 Ignite 的真正目的。 Ignite 尝试同时使编码变得有趣且灵活,从而有助于避免重复样板。
Ignite 提供了一些常用功能,例如有监督的训练或有监督的评估,并且还使用户可以灵活地定义自己的训练功能,例如训练 GAN,**强化学习****RL**)算法,依此类推。
Ignite 提供了一些常用功能,例如有监督的训练或有监督的评估,并且还使用户可以灵活地定义自己的训练函数,例如训练 GAN,**强化学习****RL**)算法,依此类推。
```py
from ignite.engine import create_supervised_trainer, create_supervised_evaluator
......@@ -582,7 +582,7 @@ def attach(self, engine, name):
通过`Engine`设置事件处理程序后,事件发生时将自动调用它们。 `EPOCH_STARTED`事件通过调用`reset()`方法来清理指标,并使存储对于当前周期指标集合保持干净。
`ITERATION_COMPLETED`触发器将调用相应指标的`update()`方法并进行指标更新。 例如,如果度量等于损失,则它会在创建`Engine`时调用我们作为参数传递给`Loss`类的损失函数来计算当前损失。 然后将计算出的损保存到对象变量中,以备将来使用。
`ITERATION_COMPLETED`触发器将调用相应指标的`update()`方法并进行指标更新。 例如,如果度量等于损失,则它会在创建`Engine`时调用我们作为参数传递给`Loss`类的损失函数来计算当前损失。 然后将计算出的损保存到对象变量中,以备将来使用。
`EPOCH_COMPLETED`事件将是最终事件,它将使用`ITERATION_COMPLETED`中更新的内容来计算最终指标得分。 一旦将`metrics`字典作为参数传递给`Engine`创建,所有这些都将作为流在用户不知道的情况下发生。 以下代码段显示了用户如何在运行`evaluator``EPOCH_COMPLETED`触发器上取回此信息:
......
......@@ -10,7 +10,7 @@
CNN 是具有数十年历史的机器学习算法,直到 Geoffrey Hinton 和他的实验室提出 AlexNet 时,才证明其功能强大。 从那时起,CNN 经历了多次迭代。 现在,我们在 CNN 之上构建了一些不同的架构,这些架构为世界各地的所有计算机视觉实现提供了动力。
CNN 是一种基本上由小型网络组成的网络架构,几乎类似于第 2 章,“简单神经网络”中引入的简单前馈网络,但用于解决图像作为输入的问题。 CNN 由神经元组成,这些神经元具有非线性,权重参数,偏差并吐出一个损值,基于该值,可以使用反向传播对整个网络进行重新排列。
CNN 是一种基本上由小型网络组成的网络架构,几乎类似于第 2 章,“简单神经网络”中引入的简单前馈网络,但用于解决图像作为输入的问题。 CNN 由神经元组成,这些神经元具有非线性,权重参数,偏差并吐出一个损值,基于该值,可以使用反向传播对整个网络进行重新排列。
如果这听起来像简单的全连接网络,那么 CNN 为何特别适合处理图像? CNN 让开发人员做出适用于图像的某些假设,例如像素值的空间关系。
......
......@@ -547,7 +547,7 @@ CycleGAN 学习每种分布的模式,并尝试将图像从一种分布映射
在 CycleGAN 中,我们不是从分布中随机采样的数据开始,而是使用来自集合 A(在本例中为一组马)的真实图像。 委托生成器 A 到 B(我们称为 A2B)将同一匹马转换为斑马,但没有将成对的马匹转换为斑马的配对图像。 训练开始时,A2B 会生成无意义的图像。 判别器 B 从 A2B 生成的图像或从集合 B(斑马的集合)中获取真实图像。 与其他任何判别器一样,它负责预测图像是生成的还是真实的。 这个过程是正常的 GAN,它永远不能保证同一匹马转换为斑马。 而是将马的图像转换为斑马的任何图像,因为损失只是为了确保图像看起来像集合 B 的分布; 它不需要与集合 A 相关。为了强加这种相关性,CycleGAN 引入了循环。
然后,从 A2B 生成的图像会通过另一个生成器 B2A,以获得`Cyclic_A`。 施加到`Cyclic_A`的损是 CycleGAN 的关键部分。 在这里,我们尝试减小`Cyclic_A``Input_A`之间的距离。 第二个损失背后的想法是,第二个生成器必须能够生成马,因为我们开始时的分布是马。 如果 A2B 知道如何将马匹映射到斑马而不改变图片中的任何其他内容,并且如果 B2A 知道如何将斑马线映射到匹马而不改变图片中的其他任何东西,那么我们对损失所做的假设应该是正确的。
然后,从 A2B 生成的图像会通过另一个生成器 B2A,以获得`Cyclic_A`。 施加到`Cyclic_A`的损是 CycleGAN 的关键部分。 在这里,我们尝试减小`Cyclic_A``Input_A`之间的距离。 第二个损失背后的想法是,第二个生成器必须能够生成马,因为我们开始时的分布是马。 如果 A2B 知道如何将马匹映射到斑马而不改变图片中的任何其他内容,并且如果 B2A 知道如何将斑马线映射到匹马而不改变图片中的其他任何东西,那么我们对损失所做的假设应该是正确的。
![CycleGAN](img/B09475_06_20.jpg)
......
......@@ -424,7 +424,7 @@ def optimize_model():
optimizer.step()
```
然后是主要部分:优化器步骤。 这是我们使用`RMSProp`找出损和反向传播的地方。 我们从存储库中提取了一些经验。 然后,我们将所有状态,动作和奖励转换为批量。 我们通过`policy_net`传递状态并获得相应的值。
然后是主要部分:优化器步骤。 这是我们使用`RMSProp`找出损和反向传播的地方。 我们从存储库中提取了一些经验。 然后,我们将所有状态,动作和奖励转换为批量。 我们通过`policy_net`传递状态并获得相应的值。
![Gym](img/B09475_07_07.jpg)
......
......@@ -2,7 +2,7 @@
> 原文:<https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py>
就是这个。 您已经了解了如何定义神经网络,计算损并更新网络的权重。
就是这个。 您已经了解了如何定义神经网络,计算损并更新网络的权重。
现在您可能在想,
......
......@@ -4,7 +4,7 @@
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`
此实现使用 numpy 手动计算正向传播,损和后向通过。
此实现使用 numpy 手动计算正向传播,损和后向通过。
numpy 数组是通用的 n 维数组; 它对深度学习,梯度或计算图一无所知,而只是执行通用数值计算的一种方法。
......
......@@ -4,7 +4,7 @@
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`
此实现使用 PyTorch 张量手动计算正向传播,损和后向通过。
此实现使用 PyTorch 张量手动计算正向传播,损和后向通过。
PyTorch 张量基本上与 numpy 数组相同:它对深度学习或计算图或梯度一无所知,只是用于任意数值计算的通用 n 维数组。
......
......@@ -22,7 +22,7 @@
![fgsm_panda_image](img/d74012096c3134b776b5e9f70e8178f3.png)
从图中,`x`是正确分类为“Pandas”的原始输入图像,`y``x`的输出,`θ`表示模型参数,而`J(θ, x, y)`是用于训练网络的损。 攻击会将梯度反向传播回输入数据,以计算`ᐁ[x] J(θ, x, y)`。 然后,它会沿方向(即`ᐁ[x] J(θ)`)沿一小步(图片中的`ε``0.007`)调整输入数据,`(x, y)`,这将使损失最大化。 然后,当目标图像仍明显是“Pandas”时,目标网络将它们误分类为“长臂猿”。
从图中,`x`是正确分类为“Pandas”的原始输入图像,`y``x`的输出,`θ`表示模型参数,而`J(θ, x, y)`是用于训练网络的损。 攻击会将梯度反向传播回输入数据,以计算`ᐁ[x] J(θ, x, y)`。 然后,它会沿方向(即`ᐁ[x] J(θ)`)沿一小步(图片中的`ε``0.007`)调整输入数据,`(x, y)`,这将使损失最大化。 然后,当目标图像仍明显是“Pandas”时,目标网络将它们误分类为“长臂猿”。
希望本教程的动机已经明确,所以让我们跳入实现过程。
......@@ -144,7 +144,7 @@ def fgsm_attack(image, epsilon, data_grad):
### 测试函数
最后,本教程的主要结果来自`test`函数。 每次调用此测试功能都会在 MNIST 测试集上执行完整的测试步骤,并报告最终精度。 但是,请注意,此功能还需要`epsilon`输入。 这是因为`test`函数报告实力为`ε`的来自对手的攻击模型的准确率。 更具体地说,对于测试集中的每个样本,函数都会计算输入数据`data_grad`的损梯度,并使用`fgsm_attack`创建一个扰动图像`perturbed_data`,然后检查受干扰的示例是否具有对抗性。 除了测试模型的准确率外,该功能还保存并返回了一些成功的对抗示例,以供以后可视化。
最后,本教程的主要结果来自`test`函数。 每次调用此测试功能都会在 MNIST 测试集上执行完整的测试步骤,并报告最终精度。 但是,请注意,此功能还需要`epsilon`输入。 这是因为`test`函数报告实力为`ε`的来自对手的攻击模型的准确率。 更具体地说,对于测试集中的每个样本,函数都会计算输入数据`data_grad`的损梯度,并使用`fgsm_attack`创建一个扰动图像`perturbed_data`,然后检查受干扰的示例是否具有对抗性。 除了测试模型的准确率外,该功能还保存并返回了一些成功的对抗示例,以供以后可视化。
```py
def test( model, device, test_loader, epsilon ):
......
......@@ -14,7 +14,7 @@
GAN 是用于教授 DL 模型以捕获训练数据分布的框架,因此我们可以从同一分布中生成新数据。 GAN 由 Ian Goodfellow 于 2014 年发明,并在论文[《生成对抗网络》](https://papers.nips.cc/paper/5423-generative-adversarial-nets.pdf)中首次进行了描述。 它们由两个不同的模型组成:*生成器**判别器*。 生成器的工作是生成看起来像训练图像的“假”图像。 判别器的工作是查看图像并从生成器输出它是真实的训练图像还是伪图像。 在训练过程中,生成器不断尝试通过生成越来越好的伪造品而使判别器的性能超过智者,而判别器正在努力成为更好的侦探并正确地对真实和伪造图像进行分类。 博弈的平衡点是当生成器生成的伪造品看起来像直接来自训练数据时,而判别器则总是猜测生成器输出是真实还是伪造品的 50% 置信度。
现在,让我们从鉴别符开始定义一些在整个教程中使用的符号。 令`x`为代表图像的数据。 `D(x)`是判别器网络,其输出`x`来自训练数据而不是生成器的(标量)概率。 在这里,由于我们要处理图像,因此`D(x)`的输入是 CHW 大小为`3x64x64`的图像。 直观地,当`x`来自训练数据时,`D(x)`应该为高,而当`x`来自发生器时,它应该为低。 `D(x)`也可以被认为是传统的二分类器。
现在,让我们从判别器开始定义一些在整个教程中使用的符号。 令`x`为代表图像的数据。 `D(x)`是判别器网络,其输出`x`来自训练数据而不是生成器的(标量)概率。 在这里,由于我们要处理图像,因此`D(x)`的输入是 CHW 大小为`3x64x64`的图像。 直观地,当`x`来自训练数据时,`D(x)`应该为高,而当`x`来自发生器时,它应该为低。 `D(x)`也可以被认为是传统的二分类器。
对于生成器的表示法,令`z`是从标准正态分布中采样的潜在空间向量。 `G(z)`表示将隐向量`z`映射到数据空间的生成器函数。 `G`的目标是估计训练数据来自`p_data`的分布,以便它可以从该估计分布(`p_g`)生成假样本。
......@@ -274,7 +274,7 @@ Generator(
### 判别器
如前所述,鉴别符`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`的学习过程都是至关重要的。
鉴别码
......@@ -394,7 +394,7 @@ optimizerG = optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))
最后,我们将进行一些统计报告,并在每个时期结束时,将我们的`fixed_noise`批量推送到生成器中,以直观地跟踪`G`的训练进度。 报告的训练统计数据是:
* `Loss_D`-判别器损失,计算为所有真实批量和所有假批量的损失总和(`log D(x) + log D(G(z))`)。
* `Loss_G`-生成器损计算为`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。 想想这是为什么。
......
......@@ -302,7 +302,7 @@ def train(model, epoch, log_interval):
```
现在我们有了训练功能,我们需要制作一个用于测试网络准确率的功能。 我们将模型设置为`eval()`模式,然后对测试数据集进行推断。 调用`eval()`将网络中所有模块中的训练变量设置为`false`。 某些层(例如批量归一化层和丢弃层)在训练期间的行为会有所不同,因此此步骤对于获取正确的结果至关重要。
现在我们有了训练函数,我们需要制作一个用于测试网络准确率的功能。 我们将模型设置为`eval()`模式,然后对测试数据集进行推断。 调用`eval()`将网络中所有模块中的训练变量设置为`false`。 某些层(例如批量归一化层和丢弃层)在训练期间的行为会有所不同,因此此步骤对于获取正确的结果至关重要。
```py
def number_of_correct(pred, target):
......
......@@ -487,7 +487,7 @@ def timeSince(since, percent):
* 启动计时器
* 初始化优化器和标准
* 创建一组训练对
* 启动空损阵列进行绘图
* 启动空损阵列进行绘图
然后,我们多次调用`train`,并偶尔打印进度(示例的百分比,到目前为止的时间,估计的时间)和平均损失。
......
......@@ -117,7 +117,7 @@ Q 学习的主要思想是,如果我们有一个函数`Q*:State x Action =>
![](img/tex34-3.gif)
为了最小化此错误,我们将使用 [Huber 损失](https://en.wikipedia.org/wiki/Huber_loss)。 当误差较小时,Huber 损的作用类似于均方误差,而当误差较大时,则表现为平均绝对误差-当`Q`的估计值非常嘈杂时,这使它对异常值的鲁棒性更高。 我们通过从重播内存中采样的一批过渡`B`来计算:
为了最小化此错误,我们将使用 [Huber 损失](https://en.wikipedia.org/wiki/Huber_loss)。 当误差较小时,Huber 损的作用类似于均方误差,而当误差较大时,则表现为平均绝对误差-当`Q`的估计值非常嘈杂时,这使它对异常值的鲁棒性更高。 我们通过从重播内存中采样的一批过渡`B`来计算:
![](img/tex34-4.gif)
......
......@@ -402,7 +402,7 @@ class Mario(Mario):
#### 更新模型
当马里奥从其重播缓冲区中采样输入时,我们计算`TD_t``TD_e`并反向传播该损`Q_online`以更新其参数`θ_online`\ \ alpha \)是传递给`optimizer`的学习率`lr`
当马里奥从其重播缓冲区中采样输入时,我们计算`TD_t``TD_e`并反向传播该损`Q_online`以更新其参数`θ_online`\ \ alpha \)是传递给`optimizer`的学习率`lr`
![](img/tex34-8.gif)
......
......@@ -728,7 +728,7 @@ for (int64_t epoch = 1; epoch <= kNumberOfEpochs; ++epoch) {
我们选择均匀分布在 0.8 到 1.0 之间的随机值,而不是各处的 1.0,以使判别器训练更可靠。 此技巧称为*标签平滑*
在评估判别器之前,我们将其参数的梯度归零。 计算完损耗后,我们通过调用`d_loss.backward()`来计算新的梯度,从而在网络中反向传播。 我们对虚假图像重复此步骤。 我们不使用数据集中的图像,而是让生成器通过为它提供一批随机噪声来为此创建伪造图像。 然后,我们将这些伪造图像转发给判别器。 这次,我们希望判别器发出低概率,最好是全零。 一旦计算了一批真实图像和一批伪造图像的判别器损耗,我们就可以一步一步地进行判别器的优化程序,以更新其参数。
在评估判别器之前,我们将其参数的梯度归零。 计算完损失后,我们通过调用`d_loss.backward()`来计算新的梯度,从而在网络中反向传播。 我们对虚假图像重复此步骤。 我们不使用数据集中的图像,而是让生成器通过为它提供一批随机噪声来为此创建伪造图像。 然后,我们将这些伪造图像转发给判别器。 这次,我们希望判别器发出低概率,最好是全零。 一旦计算了一批真实图像和一批伪造图像的判别器损失,我们就可以一步一步地进行判别器的优化程序,以更新其参数。
为了训练生成器,我们再次首先将其梯度归零,然后在伪图像上重新评估判别器。 但是,这一次,我们希望判别器将概率分配为非常接近的概率,这将表明生成器可以生成使判别器认为它们实际上是真实的图像(来自数据集)。 为此,我们用全部填充`fake_labels`张量。 最后,我们逐步使用生成器的优化器来更新其参数。
......
......@@ -173,7 +173,7 @@ std::vector<at::Tensor> lltm_forward(
#### 反向传播
C++ 扩展 API 当前不提供为我们自动生成向后函数的方法。 因此,我们还必须实现 LLTM 的后向传递,它计算相对于正向传播的每个输入的损导数。 最终,我们将前进和后退功能放入`torch.autograd.Function`中,以创建一个不错的 Python 绑定。 向后函数的作用稍大一些,因此我们将不深入研究代码(如果您有兴趣,请阅读 [Alex Graves 的论文](https://www.cs.toronto.edu/~graves/phd.pdf),以获取有关此方面的更多信息):
C++ 扩展 API 当前不提供为我们自动生成向后函数的方法。 因此,我们还必须实现 LLTM 的后向传递,它计算相对于正向传播的每个输入的损导数。 最终,我们将前进和后退功能放入`torch.autograd.Function`中,以创建一个不错的 Python 绑定。 向后函数的作用稍大一些,因此我们将不深入研究代码(如果您有兴趣,请阅读 [Alex Graves 的论文](https://www.cs.toronto.edu/~graves/phd.pdf),以获取有关此方面的更多信息):
```py
// tanh'(z) = 1 - tanh^2(z)
......
......@@ -41,7 +41,7 @@ from ray.tune.schedulers import ASHAScheduler
```
建立 PyTorch 模型需要大多数进口产品。 Ray Tune 仅最后三个进口
建立 PyTorch 模型需要大多数导入产品。 Ray Tune 仅最后三个导入
## 数据加载器
......
......@@ -486,7 +486,7 @@ Xavier 初始化是神经网络中权重的初始化,是遵循高斯分布的
![](img/93dd25ec-59c7-4c71-82b3-ce6a8f7fe21d.png)
一旦完成计算直到最后一个时间步,我们的前向传播任务就完成了。 下一个任务是通过反向传播来训练我们的循环神经网络,以使总损失最小化。 一个这样的序列的总损耗是所有时间步长上损耗的总和,也就是说,如果给定的`X`值序列及其对应的`Y`值输出序列,则损耗 是(谁)给的:
一旦完成计算直到最后一个时间步,我们的前向传播任务就完成了。 下一个任务是通过反向传播来训练我们的循环神经网络,以使总损失最小化。 一个这样的序列的总损失是所有时间步长上损失的总和,也就是说,如果给定的`X`值序列及其对应的`Y`值输出序列,则损失 是(谁)给的:
![](img/db611e16-6507-40be-a626-26d9096b2a64.png)
......
......@@ -412,7 +412,7 @@ HFFG
input_state = [0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0]
```
通过添加更多隐藏层和不同激活函数的选择,Q 网络绝对比 Q 表具有许多优势。 与 Q 表不同,在 Q 网络中,通过最小化反向传播的损来更新 Q 值。 损失函数由下式给出:
通过添加更多隐藏层和不同激活函数的选择,Q 网络绝对比 Q 表具有许多优势。 与 Q 表不同,在 Q 网络中,通过最小化反向传播的损来更新 Q 值。 损失函数由下式给出:
![](img/2aa82c3f-b95f-402e-998d-529bfbadff7d.png)
......
......@@ -513,7 +513,7 @@ def __init__(self,learning_rate,gamma,n_features,n_actions,epsilon,parameter_cha
* `ReLU`:信号从输入到隐藏层的激活函数
* `w2`:与隐藏层关联的权重矩阵
* `b2`:与输入层关联的偏置向量
* 计算主网络输出的 Q 值与目标网络输出的 Q 值之间的损
* 计算主网络输出的 Q 值与目标网络输出的 Q 值之间的损
* 使用 **adam** 优化器将损失降到最低
我们将使用以下代码定义`build_networks(self)`函数:
......@@ -1052,7 +1052,7 @@ def conv(self,inputs,w):
该功能还有助于:
* 计算主网络输出的 Q 值与目标网络输出的 Q 值之间的损
* 计算主网络输出的 Q 值与目标网络输出的 Q 值之间的损
我们可以使用亚当优化器将这种损失降到最低。
......
......@@ -152,7 +152,7 @@ repeat until :
# 异步 N 步 Q 学习
异步 N 步 Q 学习的架构在某种程度上类似于异步单步 Q 学习的架构。 区别在于,使用探索策略最多选择![](img/934eccea-ab73-4d16-8dd9-6ae2bef78aa9.png)步骤或直到达到终端状态,才能选择学习代理动作,以便计算策略网络参数的单个更新。 此过程列出了自上次更新以来![](img/55e36559-5c3e-4598-b8a3-954b2a844161.png)来自环境的奖励。 然后,对于每个时间步长,将损失计算为该时间步长的折现未来奖励与估计 Q 值之间的差。 对于每个时间步长,此损相对于特定于线程的网络参数的梯度将被计算和累积。 有多个这样的学习代理并行运行和累积梯度。 这些累积的梯度用于执行策略网络参数的异步更新。
异步 N 步 Q 学习的架构在某种程度上类似于异步单步 Q 学习的架构。 区别在于,使用探索策略最多选择![](img/934eccea-ab73-4d16-8dd9-6ae2bef78aa9.png)步骤或直到达到终端状态,才能选择学习代理动作,以便计算策略网络参数的单个更新。 此过程列出了自上次更新以来![](img/55e36559-5c3e-4598-b8a3-954b2a844161.png)来自环境的奖励。 然后,对于每个时间步长,将损失计算为该时间步长的折现未来奖励与估计 Q 值之间的差。 对于每个时间步长,此损相对于特定于线程的网络参数的梯度将被计算和累积。 有多个这样的学习代理并行运行和累积梯度。 这些累积的梯度用于执行策略网络参数的异步更新。
异步 N 步 Q 学习的伪代码如下所示。 这里,以下是全局参数:
......
......@@ -121,7 +121,7 @@ Brett Sperry 首先使用术语**实时策略**(**RTS**)作为宣传其游
![](img/2402276b-314f-4e45-bbd0-bfc839297449.png)
训练深度的自编码器后,无需解码器网络。 因此,我们的目标是训练网络,使解码器网络的输出与编码器网络的输入之间的损最小。 结果,中间层学会了创建更好的输入表示形式。 因此,我们可以为输入特征向量检索特征向量的更好,紧凑和低维的表示形式。
训练深度的自编码器后,无需解码器网络。 因此,我们的目标是训练网络,使解码器网络的输出与编码器网络的输入之间的损最小。 结果,中间层学会了创建更好的输入表示形式。 因此,我们可以为输入特征向量检索特征向量的更好,紧凑和低维的表示形式。
# 强化学习如何更好?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册