提交 0bd36462 编写于 作者: W wizardforcel

2021-01-19 11:26:50

上级 d7d0001a
......@@ -2,7 +2,7 @@
> 原文:<https://pytorch.org/tutorials/beginner/examples_autograd/polynomial_custom_function.html#sphx-glr-beginner-examples-autograd-polynomial-custom-function-py>
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`。 而不是将多项式写为\(y = a + bx + cx ^ 2 + dx ^ 3 \),我们将多项式写为\(y = a + b P_3(c + dx)\)其中\(P_3(x )= rac {1} {2} \ left(5x ^ 3-3x ight)\)是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)
经过训练的三阶多项式,可以通过最小化平方的欧几里得距离来预测`y = sin(x)``-pi``pi`。 而不是将多项式写为`y = a + bx + cx ^ 2 + dx ^ 3`,我们将多项式写为\(y = a + b P_3(c + dx)\)其中\(P_3(x )= rac {1} {2} \ left(5x ^ 3-3x ight)\)是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)
此实现使用 PyTorch 张量上的运算来计算正向传播,并使用 PyTorch autograd 来计算梯度。
......
......@@ -22,7 +22,7 @@
![fgsm_panda_image](img/d74012096c3134b776b5e9f70e8178f3.png)
从图中,\(\ mathbf {x} \)是正确分类为“熊猫”的原始输入图像,`y`\(\ mathbf {x} \)\(\ mathbf {\ theta} \)表示模型参数,而\(J(\ mathbf {\ theta},\ mathbf {x},y)\)是用于训练网络的损耗。 攻击会将梯度反向传播回输入数据,以计算\(\ nabla_ {x} J(\ mathbf {\ theta},\ mathbf {x},y)\)。 然后,它会沿方向(即\(sign(\ nabla_ {x} J(\ mathbf {\ theta}})沿一小步(图片中的\(\ epsilon \)\(0.007 \))调整输入数据 ,\ mathbf {x},y))\))),这将使损失最大化。 然后,当目标图像仍明显是“熊猫”时,目标网络将它们误分类为“长臂猿”。
从图中,`x`是正确分类为“熊猫”的原始输入图像,`y``x`的输出,`θ`表示模型参数,而\(J(\ mathbf {\ theta},\ mathbf {x},y)\)是用于训练网络的损耗。 攻击会将梯度反向传播回输入数据,以计算\(\ nabla_ {x} J(\ mathbf {\ theta},\ mathbf {x},y)\)。 然后,它会沿方向(即\(sign(\ nabla_ {x} J(\ mathbf {\ theta}})沿一小步(图片中的\(\ epsilon \)\(0.007 \))调整输入数据 ,\ mathbf {x},y))\))),这将使损失最大化。 然后,当目标图像仍明显是“熊猫”时,目标网络将它们误分类为“长臂猿”。
希望本教程的动机已经明确,所以让我们跳入实施过程。
......@@ -46,7 +46,7 @@ import matplotlib.pyplot as plt
本教程只有三个输入,定义如下:
* `epsilons`-用于运行的 epsilon 值列表。 在列表中保留 0 很重要,因为它表示原始测试集上的模型性能。 同样,从直觉上讲,我们期望ε越大,扰动越明显,但是从降低模型准确率的角度来看,攻击越有效。 由于此处的数据范围为\([0,1] \),因此 epsilon 值不得超过 1。
* `epsilons`-用于运行的`ε`值列表。 在列表中保留 0 很重要,因为它表示原始测试集上的模型性能。 同样,从直觉上讲,我们期望`ε`越大,扰动越明显,但是从降低模型准确率的角度来看,攻击越有效。 由于此处的数据范围为\([0,1] \),因此`ε`值不得超过 1。
* `pretrained_model`-到使用 [pytorch / examples / mnist](https://github.com/pytorch/examples/tree/master/mnist) 训练的 MNIST 模型的路径。 为简单起见,请在此处下载预训练模型[](https://drive.google.com/drive/folders/1fn83DF14tWmit0RTKWRhPq5uVXt73e0h?usp=sharing)
* `use_cuda`-布尔标志,如果需要和可用,则使用 CUDA。 请注意,具有 CUDA 的 GPU 在本教程中并不重要,因为 CPU 不会花费很多时间。
......@@ -144,7 +144,7 @@ def fgsm_attack(image, epsilon, data_grad):
### 测试功能
最后,本教程的主要结果来自`test`函数。 每次调用此测试功能都会在 MNIST 测试集上执行完整的测试步骤,并报告最终精度。 但是,请注意,此功能还需要`epsilon`输入。 这是因为`test`函数报告实力为\(\ epsilon \)的来自对手的攻击模型的准确率。 更具体地说,对于测试集中的每个样本,函数都会计算输入数据(\(data \ _grad \))的损耗梯度,并使用`fgsm_attack`创建一个扰动图像(\(perturbed \ _data \)) ,然后检查受干扰的示例是否具有对抗性。 除了测试模型的准确率外,该功能还保存并返回了一些成功的对抗示例,以供以后可视化。
最后,本教程的主要结果来自`test`函数。 每次调用此测试功能都会在 MNIST 测试集上执行完整的测试步骤,并报告最终精度。 但是,请注意,此功能还需要`epsilon`输入。 这是因为`test`函数报告实力为`ε`的来自对手的攻击模型的准确率。 更具体地说,对于测试集中的每个样本,函数都会计算输入数据(\(data \ _grad \))的损耗梯度,并使用`fgsm_attack`创建一个扰动图像(\(perturbed \ _data \)) ,然后检查受干扰的示例是否具有对抗性。 除了测试模型的准确率外,该功能还保存并返回了一些成功的对抗示例,以供以后可视化。
```py
def test( model, device, test_loader, epsilon ):
......@@ -213,7 +213,7 @@ def test( model, device, test_loader, epsilon ):
### 运行攻击
实现的最后一部分是实际运行攻击。 在这里,我们为`epsilon`输入中的每个 epsilon 值运行完整的测试步骤。 对于每个 epsilon,我们还保存最终精度,并在接下来的部分中绘制一些成功的对抗示例。 请注意,随着ε值的增加,打印的精度如何降低。 另外,请注意\(\ epsilon = 0 \)表示原始测试准确率,没有受到攻击。
实现的最后一部分是实际运行攻击。 在这里,我们为`epsilon`输入中的每个 epsilon 值运行完整的测试步骤。 对于每个 epsilon,我们还保存最终精度,并在接下来的部分中绘制一些成功的对抗示例。 请注意,随着ε值的增加,打印的精度如何降低。 另外,请注意`ε = 0`表示原始测试准确率,没有受到攻击。
```py
accuracies = []
......@@ -244,7 +244,7 @@ Epsilon: 0.3 Test Accuracy = 869 / 10000 = 0.0869
### 准确率与 Epsilon
第一个结果是精度与ε曲线的关系。 如前所述,随着ε的增加,我们预计测试精度会降低。 这是因为更大的ε意味着我们朝着将损失最大化的方向迈出了更大的一步。 请注意,即使 epsilon 值是线性间隔的,曲线中的趋势也不是线性的。 例如,`ε = 0.05`处的精度仅比\(\ epsilon = 0 \)低约 4%,但`ε = 0.2`处的精度比`ε = 0.15`。 另外,请注意,模型的准确率在`ε = 0.25`和`ε = 0.3`之间达到 10 类分类器的随机准确率。
第一个结果是精度与ε曲线的关系。 如前所述,随着ε的增加,我们预计测试精度会降低。 这是因为更大的ε意味着我们朝着将损失最大化的方向迈出了更大的一步。 请注意,即使 epsilon 值是线性间隔的,曲线中的趋势也不是线性的。 例如,`ε = 0.05`处的精度仅比`ε = 0`低约 4%,但`ε = 0.2`处的精度比`ε = 0.15`。 另外,请注意,模型的准确率在`ε = 0.25`和`ε = 0.3`之间达到 10 类分类器的随机准确率。
```py
plt.figure(figsize=(5,5))
......@@ -262,7 +262,7 @@ plt.show()
### 对抗示例样本
还记得没有免费午餐的想法吗? 在这种情况下,随着ε的增加,测试精度降低,但扰动变得更容易察觉。 实际上,在攻击者必须考虑的准确率下降和可感知性之间要进行权衡。 在这里,我们展示了每个 epsilon 值下成功对抗示例的一些示例。 绘图的每一行显示不同的ε值。 第一行是\(\ epsilon = 0 \)示例,这些示例表示没有干扰的原始“干净”图像。 每张图片的标题均显示“原始分类->对抗分类”。 注意,扰动在`ε = 0.15`处开始变得明显,而在`ε = 0.3`处则非常明显。 但是,在所有情况下,尽管增加了噪音,人类仍然能够识别正确的类别。
还记得没有免费午餐的想法吗? 在这种情况下,随着ε的增加,测试精度降低,但扰动变得更容易察觉。 实际上,在攻击者必须考虑的准确率下降和可感知性之间要进行权衡。 在这里,我们展示了每个`ε`值下成功对抗示例的一些示例。 绘图的每一行显示不同的ε值。 第一行是`ε = 0`示例,这些示例表示没有干扰的原始“干净”图像。 每张图片的标题均显示“原始分类->对抗分类”。 注意,扰动在`ε = 0.15`处开始变得明显,而在`ε = 0.3`处则非常明显。 但是,在所有情况下,尽管增加了噪音,人类仍然能够识别正确的类别。
```py
# Plot several examples of adversarial samples at each epsilon
......
......@@ -313,7 +313,7 @@ class Mario(Mario): # subclassing for continuity
Mario 在后台使用 [DDQN 算法](https://arxiv.org/pdf/1509.06461)。 DDQN 使用两个 ConvNet-\(Q_ {online} \)\(Q_ {target} \)-独立地逼近最佳作用值函数。
在我们的实现中,我们在\(Q_ {online} \)\(Q_ {target} \)之间共享特征生成器`features`,但是为每个特征维护单独的 FC 分类器。 \(\ theta_ {target} \)\(Q_ {target} \)的参数)被冻结,以防止反向传播进行更新。 而是定期与\(\ theta_ {online} \)同步(稍后会对此进行详细介绍)。
在我们的实现中,我们在\(Q_ {online} \)\(Q_ {target} \)之间共享特征生成器`features`,但是为每个特征维护单独的 FC 分类器。 `θ_target`\(Q_ {target} \)的参数)被冻结,以防止反向传播进行更新。 而是定期与`θ_online`同步(稍后会对此进行详细介绍)。
#### 神经网络
......@@ -367,13 +367,13 @@ class MarioNet(nn.Module):
\[{TD}_e = Q_{online}^*(s,a)\]
**TD 目标**-当前奖励和下一状态\(s'\)中的估计\(Q ^ * \)的汇总
**TD 目标**-当前奖励和下一状态`s'`中的估计\(Q ^ * \)的汇总
\[a' = argmax_{a} Q_{online}(s', a)\] \[{TD}_t = r + \gamma Q_{target}^*(s',a')\]
由于我们不知道下一个动作\(a'\)是什么,因此我们在下一个状态\(s'\)中使用动作\(a'\)最大化\(Q_ {online} \)
由于我们不知道下一个动作`a'`是什么,因此我们在下一个状态`s'`中使用动作`a'`最大化\(Q_ {online} \)
请注意,我们在`td_target()`上使用了 [@ torch.no_grad()](https://pytorch.org/docs/stable/generated/torch.no_grad.html#no-grad)装饰器来禁用梯度计算(因为我们无需在\(\ theta_ {target} \)上进行反向传播。)
请注意,我们在`td_target()`上使用了 [@ torch.no_grad()](https://pytorch.org/docs/stable/generated/torch.no_grad.html#no-grad)装饰器来禁用梯度计算(因为我们无需在`θ_target`上进行反向传播。)
```py
class Mario(Mario):
......@@ -400,11 +400,11 @@ class Mario(Mario):
#### 更新模型
当 Mario 从其重播缓冲区中采样输入时,我们计算`TD_t``TD_e`并反向传播该损耗\(Q_ {online} \)以更新其参数\(\ theta_ {online} \)\ \ alpha \)是传递给`optimizer`的学习率`lr`
当 Mario 从其重播缓冲区中采样输入时,我们计算`TD_t``TD_e`并反向传播该损耗\(Q_ {online} \)以更新其参数`θ_online`\ \ alpha \)是传递给`optimizer`的学习率`lr`
\[\theta_{online} \leftarrow \theta_{online} + \alpha \nabla(TD_e - TD_t)\]
\(\ theta_ {target} \)不会通过反向传播进行更新。 相反,我们会定期将\(\ theta_ {online} \)复制到\(\ theta_ {target} \)
`θ_target`不会通过反向传播进行更新。 相反,我们会定期将`θ_online`复制到`θ_target`
\[\theta_{target} \leftarrow \theta_{online}\]
......
......@@ -145,7 +145,7 @@ def run(rank, size):
* `dist.broadcast(tensor, src, group)`:将`tensor``src`复制到所有其他进程。
* `dist.reduce(tensor, dst, op, group)`:将`op`应用于所有`tensor`,并将结果存储在`dst`中。
* `dist.all_reduce(tensor, op, group)`:与 reduce 相同,但是结果存储在所有进程中。
* `dist.scatter(tensor, src, scatter_list, group)`:将\(i ^ {\ text {th}} \)张量`scatter_list[i]`复制到\(i ^ {\ text {th}} \)过程。
* `dist.scatter(tensor, src, scatter_list, group)`:将`i`个张量`scatter_list[i]`复制到第`i`过程。
* `dist.gather(tensor, dst, gather_list, group)`:从`dst`中的所有进程复制`tensor`
* `dist.all_gather(tensor_list, tensor, group)`:将所有进程中的`tensor`从所有进程复制到`tensor_list`
* `dist.barrier(group)`:阻止组中的所有进程,直到每个进程都进入此功能。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册