提交 f5eb66b4 编写于 作者: W wizardforcel

2021-01-19 11:20:54

上级 a7e0c578
......@@ -117,21 +117,21 @@ tensor([True, True])
### 可选阅读-使用`autograd`的向量演算
从数学上讲,如果您具有向量值函数\(\ vec {y} = f(\ vec {x})\),则\(\ vec {y} \)相对于\(\ vec {x } \)是雅可比矩阵\(J \)
从数学上讲,如果您具有向量值函数`y = f(x)`,则`y`相对于`x`的雅可比矩阵`J`
\[\begin{split}J = \left(\begin{array}{cc} \frac{\partial \bf{y}}{\partial x_{1}} & ... & \frac{\partial \bf{y}}{\partial x_{n}} \end{array}\right) = \left(\begin{array}{ccc} \frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{1}}{\partial x_{n}}\\ \vdots & \ddots & \vdots\\ \frac{\partial y_{m}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}} \end{array}\right)\end{split}\]
一般来说,`torch.autograd`是用于计算向量雅可比积的引擎。 也就是说,给定任何向量\(\ vec {v} \),计算乘积\(J ^ {T} \ cdot \ vec {v} \)
一般来说,`torch.autograd`是用于计算向量雅可比积的引擎。 也就是说,给定任何向量`v`,计算乘积`J^T · v`
如果\(v \)恰好是标量函数的梯度
如果`v`恰好是标量函数的梯度
\[l = g\left(\vec{y}\right) = \left(\begin{array}{ccc}\frac{\partial l}{\partial y_{1}} & \cdots & \frac{\partial l}{\partial y_{m}}\end{array}\right)^{T}\]
然后根据链式规则,向量-雅可比积将是\(l \)相对于\(\ vec {x} \)的梯度:
然后根据链式规则,向量-雅可比积将是`l`相对于`x`的梯度:
\[\begin{split}J^{T}\cdot \vec{v}=\left(\begin{array}{ccc} \frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{1}}\\ \vdots & \ddots & \vdots\\ \frac{\partial y_{1}}{\partial x_{n}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}} \end{array}\right)\left(\begin{array}{c} \frac{\partial l}{\partial y_{1}}\\ \vdots\\ \frac{\partial l}{\partial y_{m}} \end{array}\right)=\left(\begin{array}{c} \frac{\partial l}{\partial x_{1}}\\ \vdots\\ \frac{\partial l}{\partial x_{n}} \end{array}\right)\end{split}\]
上面的示例中使用的是 vector-Jacobian 乘积的这一特征。 `external_grad`表示\(\ vec {v} \)
上面的示例中使用的是 vector-Jacobian 乘积的这一特征。 `external_grad`表示`v`
## 计算图
......
......@@ -11,7 +11,7 @@ PyTorch 的核心是提供两个主要功能:
* n 维张量,类似于 numpy,但可以在 GPU 上运行
* 自动区分以构建和训练神经网络
我们将使用将三阶多项式拟合\(y = \ sin(x)\)的问题作为运行示例。 该网络将具有四个参数,并且将通过使网络输出与实际输出之间的欧几里德距离最小化来进行梯度下降训练,以适应随机数据。
我们将使用将三阶多项式拟合`y = sin(x)`的问题作为运行示例。 该网络将具有四个参数,并且将通过使网络输出与实际输出之间的欧几里德距离最小化来进行梯度下降训练,以适应随机数据。
注意
......@@ -222,7 +222,7 @@ print(f'Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3'
在 PyTorch 中,我们可以通过定义`torch.autograd.Function`的子类并实现`forward``backward`函数来轻松定义自己的 autograd 运算符。 然后,我们可以通过构造实例并像调用函数一样调用新的 autograd 运算符,并传递包含输入数据的张量。
在此示例中,我们将模型定义为\(y = a + b P_3(c + dx)\)而不是\(y = a + bx + cx ^ 2 + dx ^ 3 \),其中\(P_3(x) = \ frac {1} {2} \ left(5x ^ 3-3x \ right)\)是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)。 我们编写了自己的自定义 autograd 函数来计算\(P_3 \)的前进和后退,并使用它来实现我们的模型:
在此示例中,我们将模型定义为`y = a + b P[3](c + dx)`而不是`y = a + bx + cx ^ 2 + dx ^ 3`,其中`P[3](x) = 1/2 (5x ^ 3 - 3x)`是三次的[勒让德多项式](https://en.wikipedia.org/wiki/Legendre_polynomials)。 我们编写了自己的自定义 autograd 函数来计算`P[3]`的前进和后退,并使用它来实现我们的模型:
```py
# -*- coding: utf-8 -*-
......
......@@ -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))\))),这将使损失最大化。 然后,当目标图像仍明显是“熊猫”时,目标网络将它们误分类为“长臂猿”。
从图中,\(\ 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))\))),这将使损失最大化。 然后,当目标图像仍明显是“熊猫”时,目标网络将它们误分类为“长臂猿”。
希望本教程的动机已经明确,所以让我们跳入实施过程。
......@@ -122,7 +122,7 @@ CUDA Available: True
### FGSM 攻击
现在,我们可以通过干扰原始输入来定义创建对抗示例的函数。 `fgsm_attack`函数接受三个输入,`image`是原始的干净图像(\(x \)),`epsilon`是像素级扰动量(\(\ epsilon \) ),`data_grad`是输入图像损失的梯度(\(\ nabla_ {x} J(\ mathbf {\ theta},\ mathbf {x},y)\))。 该函数然后创建扰动图像为
现在,我们可以通过干扰原始输入来定义创建对抗示例的函数。 `fgsm_attack`函数接受三个输入,`image`是原始的干净图像(`x`),`epsilon`是像素级扰动量(\(\ epsilon \) ),`data_grad`是输入图像损失的梯度(\(\ nabla_ {x} J(\ mathbf {\ theta},\ mathbf {x},y)\))。 该函数然后创建扰动图像为
\[perturbed\_image = image + epsilon*sign(data\_grad) = x + \epsilon * sign(\nabla_{x} J(\mathbf{\theta}, \mathbf{x}, y))\]
......
......@@ -14,11 +14,11 @@
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 \))生成假样本。
对于生成器的表示法,令`z`是从标准正态分布中采样的潜在空间向量。 \(G(z)\)表示将隐向量`z`映射到数据空间的生成器函数。 `G`的目标是估计训练数据来自(\(p_ {data} \))的分布,以便它可以从该估计分布(\(p_g \))生成假样本。
因此,\(D(G(z))\)是发生器\(G \)的输出是真实图像的概率(标量)。 如 [Goodfellow 的论文](https://papers.nips.cc/paper/5423-generative-adversarial-nets.pdf)中所述,\(D \)\(G \)玩一个 minimax 游戏,其中\(D \)试图最大化其正确分类实物和假物(\(logD( x)\)),并且\(G \)尝试最小化\(D \)预测其输出为假的概率(\(log(1-D(G(g(x)))\))。 从本文来看,GAN 损失函数为
因此,\(D(G(z))\)是发生器`G`的输出是真实图像的概率(标量)。 如 [Goodfellow 的论文](https://papers.nips.cc/paper/5423-generative-adversarial-nets.pdf)中所述,`D``G`玩一个 minimax 游戏,其中`D`试图最大化其正确分类实物和假物(\(logD( x)\)),并且`G`尝试最小化`D`预测其输出为假的概率(\(log(1-D(G(g(x)))\))。 从本文来看,GAN 损失函数为
\[\underset{G}{\text{min}} \underset{D}{\text{max}}V(D,G) = \mathbb{E}_{x\sim p_{data}(x)}\big[logD(x)\big] + \mathbb{E}_{z\sim p_{z}(z)}\big[log(1-D(G(z)))\big]\]
......@@ -26,7 +26,7 @@ GAN 是用于教授 DL 模型以捕获训练数据分布的框架,因此我们
### 什么是 DCGAN?
DCGAN 是上述 GAN 的直接扩展,不同之处在于,DCGAN 分别在判别器和生成器中分别使用卷积和卷积转置层。 它最早由 Radford 等人描述。 等 在论文[中使用深度卷积生成对抗网络](https://arxiv.org/pdf/1511.06434.pdf)进行无监督表示学习。 判别器由分层的[卷积](https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d)层,[批量规范](https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d)层和 [LeakyReLU](https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU) 激活组成。 输入是 3x64x64 的输入图像,输出是输入来自真实数据分布的标量概率。 生成器由[卷积转置](https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d)层,批量规范层和 [ReLU](https://pytorch.org/docs/stable/nn.html#relu) 激活组成。 输入是从标准正态分布中提取的潜向量\(z \),输出是 3x64x64 RGB 图像。 跨步的转置层使潜向量可以转换为具有与图像相同形状的体积。 在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化模型权重的提示,所有这些都将在接下来的部分中进行解释。
DCGAN 是上述 GAN 的直接扩展,不同之处在于,DCGAN 分别在判别器和生成器中分别使用卷积和卷积转置层。 它最早由 Radford 等人描述。 等 在论文[中使用深度卷积生成对抗网络](https://arxiv.org/pdf/1511.06434.pdf)进行无监督表示学习。 判别器由分层的[卷积](https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d)层,[批量规范](https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d)层和 [LeakyReLU](https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU) 激活组成。 输入是 3x64x64 的输入图像,输出是输入来自真实数据分布的标量概率。 生成器由[卷积转置](https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d)层,批量规范层和 [ReLU](https://pytorch.org/docs/stable/nn.html#relu) 激活组成。 输入是从标准正态分布中提取的潜向量`z`,输出是 3x64x64 RGB 图像。 跨步的转置层使潜向量可以转换为具有与图像相同形状的体积。 在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化模型权重的提示,所有这些都将在接下来的部分中进行解释。
```py
from __future__ import print_function
......@@ -188,7 +188,7 @@ def weights_init(m):
### 生成器
生成器\(G \)用于将潜在空间向量(\(z \))映射到数据空间。 由于我们的数据是图像,因此将\(z \)转换为数据空间意味着最终创建与训练图像大小相同的 RGB 图像(即 3x64x64)。 在实践中,这是通过一系列跨步的二维卷积转置层来完成的,每个层都与 2d 批量规范层和 relu 激活配对。 生成器的输出通过 tanh 函数馈送,以使其返回到输入数据范围\([-1,1] \)。 值得注意的是,在卷积转置层之后存在批量规范函数,因为这是 DCGAN 论文的关键贡献。 这些层有助于训练过程中的梯度流动。 DCGAN 纸生成的图像如下所示。
生成器`G`用于将潜在空间向量(`z`)映射到数据空间。 由于我们的数据是图像,因此将`z`转换为数据空间意味着最终创建与训练图像大小相同的 RGB 图像(即 3x64x64)。 在实践中,这是通过一系列跨步的二维卷积转置层来完成的,每个层都与 2d 批量规范层和 relu 激活配对。 生成器的输出通过 tanh 函数馈送,以使其返回到输入数据范围\([-1,1] \)。 值得注意的是,在卷积转置层之后存在批量规范函数,因为这是 DCGAN 论文的关键贡献。 这些层有助于训练过程中的梯度流动。 DCGAN 纸生成的图像如下所示。
![dcgan_generator](img/85974d98be6202902f21ce274418953f.png)
......@@ -274,7 +274,7 @@ Generator(
### 判别器
如前所述,鉴别符\(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`的学习过程都是至关重要的。
鉴别码
......@@ -353,13 +353,13 @@ Discriminator(
### 损失函数和优化器
使用\(D \)\(G \)设置,我们可以指定它们如何通过损失函数和优化器学习。 我们将使用在 PyTorch 中定义的二进制交叉熵损失( [BCELoss](https://pytorch.org/docs/stable/nn.html#torch.nn.BCELoss) )函数:
使用`D``G`设置,我们可以指定它们如何通过损失函数和优化器学习。 我们将使用在 PyTorch 中定义的二进制交叉熵损失( [BCELoss](https://pytorch.org/docs/stable/nn.html#torch.nn.BCELoss) )函数:
\[\ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - \left[ y_n \cdot \log x_n + (1 - y_n) \cdot \log (1 - x_n) \right]\]
请注意,此函数如何提供目标函数中两个对数分量的计算(即\(log(D(x(x))\)\(log(1-D(G(z)))\)))。 我们可以指定\(y \)输入使用 BCE 方程的哪一部分。 这是在即将到来的训练循环中完成的,但重要的是要了解我们如何仅通过更改\(y \)(即 GT 标签)即可选择希望计算的分量。
请注意,此函数如何提供目标函数中两个对数分量的计算(即\(log(D(x(x))\)\(log(1-D(G(z)))\)))。 我们可以指定`y`输入使用 BCE 方程的哪一部分。 这是在即将到来的训练循环中完成的,但重要的是要了解我们如何仅通过更改`y`(即 GT 标签)即可选择希望计算的分量。
接下来,我们将实际标签定义为 1,将假标签定义为 0。这些标签将在计算\(D \)\(G \)的损失时使用,这也是 GAN 原始论文中使用的惯例 。 最后,我们设置了两个单独的优化器,一个用于\(D \),另一个用于\(G \)。 如 DCGAN 论文中所指定,这两个都是学习速度为 0.0002 和 Beta1 = 0.5 的 Adam 优化器。 为了跟踪生成器的学习进度,我们将生成一批固定的潜在向量,这些向量是从高斯分布(即 fixed_noise)中提取的。 在训练循环中,我们将定期将此 fixed_noise 输入到\(G \)中,并且在迭代过程中,我们将看到图像形成于噪声之外。
接下来,我们将实际标签定义为 1,将假标签定义为 0。这些标签将在计算`D``G`的损失时使用,这也是 GAN 原始论文中使用的惯例 。 最后,我们设置了两个单独的优化器,一个用于`D`,另一个用于`G`。 如 DCGAN 论文中所指定,这两个都是学习速度为 0.0002 和 Beta1 = 0.5 的 Adam 优化器。 为了跟踪生成器的学习进度,我们将生成一批固定的潜在向量,这些向量是从高斯分布(即 fixed_noise)中提取的。 在训练循环中,我们将定期将此 fixed_noise 输入到`G`中,并且在迭代过程中,我们将看到图像形成于噪声之外。
```py
# Initialize BCELoss function
......@@ -385,7 +385,7 @@ 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 部分-训练生成器**
......
......@@ -101,7 +101,7 @@ class ReplayMemory(object):
我们的环境是确定性的,因此为简单起见,此处介绍的所有方程式也都确定性地制定。 在强化学习文献中,它们还将包含对环境中随机转变的期望。
我们的目标是制定一种策略,尝试最大化折现的累积奖励\(R_ {t_0} = \ sum_ {t = t_0} ^ {\ infty} \ gamma ^ {t-t_0} r_t \),其中\ (R_ {t_0} \)也称为*返回*。 折扣\(\ gamma \)应该是\(0 \)\(1 \)之间的常数,以确保总和收敛。 这使得来自不确定的遥远未来的回报对我们的代理商而言不如可以对其充满信心的近期回报重要。
我们的目标是制定一种策略,尝试最大化折现的累积奖励\(R_ {t_0} = \ sum_ {t = t_0} ^ {\ infty} \ gamma ^ {t-t_0} r_t \),其中\ (R_ {t_0} \)也称为*返回*。 折扣\(\ gamma \)应该是`0``1`之间的常数,以确保总和收敛。 这使得来自不确定的遥远未来的回报对我们的代理商而言不如可以对其充满信心的近期回报重要。
Q 学习的主要思想是,如果我们有一个函数\(Q ^ *:State \ times Action \ rightarrow \ mathbb {R} \),这可以告诉我们,如果我们取一个 在给定状态下采取行动,那么我们就可以轻松地制定出使我们的回报最大化的策略:
......@@ -109,7 +109,7 @@ Q 学习的主要思想是,如果我们有一个函数\(Q ^ *:State \ time
但是,我们对世界一无所知,因此无法访问\(Q ^ * \)。 但是,由于神经网络是通用函数逼近器,因此我们可以简单地创建一个并将其训练为类似于\(Q ^ * \)的函数。
对于我们的训练更新规则,我们将使用一个事实,即某些策略的每个\(Q \)函数都遵循 Bellman 方程:
对于我们的训练更新规则,我们将使用一个事实,即某些策略的每个`Q`函数都遵循 Bellman 方程:
\[Q^{\pi}(s, a) = r + \gamma Q^{\pi}(s', \pi(s'))\]
......@@ -117,13 +117,13 @@ Q 学习的主要思想是,如果我们有一个函数\(Q ^ *:State \ time
\[\delta = Q(s, a) - (r + \gamma \max_a Q(s', a))\]
为了最小化此错误,我们将使用 [Huber 损失](https://en.wikipedia.org/wiki/Huber_loss)。 当误差较小时,Huber 损耗的作用类似于均方误差,而当误差较大时,则表现为平均绝对误差-当\(Q \)的估计值非常嘈杂时,这使它对异常值的鲁棒性更高。 我们通过从重播内存中采样的一批过渡\(B \)来计算:
为了最小化此错误,我们将使用 [Huber 损失](https://en.wikipedia.org/wiki/Huber_loss)。 当误差较小时,Huber 损耗的作用类似于均方误差,而当误差较大时,则表现为平均绝对误差-当`Q`的估计值非常嘈杂时,这使它对异常值的鲁棒性更高。 我们通过从重播内存中采样的一批过渡`B`来计算:
\[\mathcal{L} = \frac{1}{|B|}\sum_{(s, a, s', r) \ \in \ B} \mathcal{L}(\delta)\] \[\begin{split}\text{where} \quad \mathcal{L}(\delta) = \begin{cases} \frac{1}{2}{\delta^2} & \text{for } |\delta| \le 1, \\ |\delta| - \frac{1}{2} & \text{otherwise.} \end{cases}\end{split}\]
### Q-network
我们的模型将是一个卷积神经网络,该卷积神经网络将吸收当前屏幕补丁和先前屏幕补丁之间的差异。 它有两个输出,分别代表\(Q(s,\ mathrm {left})\)\(Q(s,\ mathrm {right})\)(其中\(s \)是网络的输入)。 实际上,网络正在尝试预测在给定当前输入的情况下执行每个操作的*预期收益*
我们的模型将是一个卷积神经网络,该卷积神经网络将吸收当前屏幕补丁和先前屏幕补丁之间的差异。 它有两个输出,分别代表\(Q(s,\ mathrm {left})\)\(Q(s,\ mathrm {right})\)(其中`s`是网络的输入)。 实际上,网络正在尝试预测在给定当前输入的情况下执行每个操作的*预期收益*
```py
class DQN(nn.Module):
......@@ -282,7 +282,7 @@ def plot_durations():
最后,是训练模型的代码。
在这里,您可以找到执行优化步骤的`optimize_model`函数。 它首先对一批进行采样,将所有张量连接为一个张量,计算\(Q(s_t,a_t)\)\(V(s_ {t + 1})= \ max_a Q(s_ {t + 1}, a)\),并将其合并为我们的损失。 根据定义,如果\(s \)为终端状态,则设置\(V(s)= 0 \)。 我们还使用目标网络来计算\(V(s_ {t + 1})\),以提高稳定性。 目标网络的权重大部分时间保持冻结状态,但经常更新以策略网络的权重。 通常这是一组固定的步骤,但是为了简单起见,我们将使用情节。
在这里,您可以找到执行优化步骤的`optimize_model`函数。 它首先对一批进行采样,将所有张量连接为一个张量,计算\(Q(s_t,a_t)\)\(V(s_ {t + 1})= \ max_a Q(s_ {t + 1}, a)\),并将其合并为我们的损失。 根据定义,如果`s`为终端状态,则设置\(V(s)= 0 \)。 我们还使用目标网络来计算\(V(s_ {t + 1})\),以提高稳定性。 目标网络的权重大部分时间保持冻结状态,但经常更新以策略网络的权重。 通常这是一组固定的步骤,但是为了简单起见,我们将使用情节。
```py
def optimize_model():
......
......@@ -363,7 +363,7 @@ class MarioNet(nn.Module):
学习涉及两个值:
**TD 估计**-给定状态\(s \)的预测最佳\(Q ^ * \)
**TD 估计**-给定状态`s`的预测最佳\(Q ^ * \)
\[{TD}_e = Q_{online}^*(s,a)\]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册