提交 006a3072 编写于 作者: W wizardforcel

2020-12-27 14:51:23

上级 a22482cf
......@@ -192,16 +192,16 @@ MIL 中涉及的步骤如下:
我们的框架包含三个组件:
* 概念生成器
* 概念别器
* 概念别器
* 元学习者
概念生成器的作用是提取数据集中每个数据点的特征表示,捕获其高级概念,概念鉴别器的作用是识别和分类由概念生成器生成的概念,而元学习者学习由概念生成器生成的概念。 先前的所有组件(即概念生成器,概念鉴别器和元学习器)都可以一起学习。 因此,我们通过将元学习与深度学习相集成来改善原始元学习。 我们的概念生成器随着新的传入数据而发展,因此我们可以将我们的框架视为终身学习系统。
概念生成器的作用是提取数据集中每个数据点的特征表示,捕获其高级概念,概念判别器的作用是识别和分类由概念生成器生成的概念,而元学习者学习由概念生成器生成的概念。 先前的所有组件(即概念生成器,概念判别器和元学习器)都可以一起学习。 因此,我们通过将元学习与深度学习相集成来改善原始元学习。 我们的概念生成器随着新的传入数据而发展,因此我们可以将我们的框架视为终身学习系统。
但是这里到底发生了什么? 看下图; 如您所见,我们对一组任务进行采样,并将其提供给概念生成器,该概念生成器将学习概念(即嵌入),然后将这些概念提供给元学习器,后者将学习这些概念并将损失回馈给概念生成器。 同时,我们还将一些外部数据集提供给概念生成器,概念生成器学习这些输入的概念并将这些概念发送给概念识别器。 概念识别器预测这些概念的标签,计算损失,然后将损失发送回概念生成器。 通过这样做,我们增强了概念生成器概括概念的能力:
![](img/ab57f770-1198-4573-a9ab-a4e9ba34bb85.png)
但是,为什么我们要这样做呢? 代替在原始数据集上执行元学习,我们在概念空间中执行元学习。 我们如何学习这些概念? 这些概念由概念生成器通过学习输入的嵌入来生成。 因此,我们在各种相关任务上训练概念生成器和元学习器; 与此相伴的是,我们通过向概念生成器提供外部数据集,从而通过概念别器改进了概念生成器,以便可以更好地学习概念。 通过联合培训过程,我们的概念生成器可以学习各种概念并在相关任务上表现更好; 我们输入外部数据集只是为了增强概念生成器的性能,当我们输入一组新的输入时,它会不断学习。 因此,这是一个终身学习系统。
但是,为什么我们要这样做呢? 代替在原始数据集上执行元学习,我们在概念空间中执行元学习。 我们如何学习这些概念? 这些概念由概念生成器通过学习输入的嵌入来生成。 因此,我们在各种相关任务上训练概念生成器和元学习器; 与此相伴的是,我们通过向概念生成器提供外部数据集,从而通过概念别器改进了概念生成器,以便可以更好地学习概念。 通过联合培训过程,我们的概念生成器可以学习各种概念并在相关任务上表现更好; 我们输入外部数据集只是为了增强概念生成器的性能,当我们输入一组新的输入时,它会不断学习。 因此,这是一个终身学习系统。
# 关键组件
......@@ -228,7 +228,7 @@ MIL 中涉及的步骤如下:
# 概念判别损失
我们从数据集`D`中采样一些数据点`(x, y)`,将它们馈送到概念生成器,该概念生成器学习概念并将其发送给概念别器,后者试图预测这些概念的类。 因此,概念鉴别符的丢失意味着我们的概念鉴别符在预测类别方面有多出色,可以表示为:
我们从数据集`D`中采样一些数据点`(x, y)`,将它们馈送到概念生成器,该概念生成器学习概念并将其发送给概念别器,后者试图预测这些概念的类。 因此,概念鉴别符的丢失意味着我们的概念鉴别符在预测类别方面有多出色,可以表示为:
![](img/8a16d682-8033-4b27-afc0-e43e06f9a95b.png)
......@@ -258,12 +258,12 @@ MIL 中涉及的步骤如下:
现在,我们将逐步了解我们的算法:
1. 假设我们有一个任务分布`p(T)`。 首先,我们随机初始化模型参数,例如概念生成器`θ[G]`,元学习器`θ[M]`和概念别器`θ[D]`的参数。
1. 假设我们有一个任务分布`p(T)`。 首先,我们随机初始化模型参数,例如概念生成器`θ[G]`,元学习器`θ[M]`和概念别器`θ[D]`的参数。
2. 我们从任务分布中抽样一批任务,并通过概念生成器学习它们的概念,对这些概念执行元学习,然后计算元学习损失:
![](img/5e6632de-b358-46b0-9154-bc2912394c1b.png)
3. 我们从外部数据集`D`中采样一些数据点`(x, y)`,将它们馈送到概念生成器以学习其概念,将这些概念馈送到概念别器中,对它们进行分类,然后计算概念辨别损失:
3. 我们从外部数据集`D`中采样一些数据点`(x, y)`,将它们馈送到概念生成器以学习其概念,将这些概念馈送到概念别器中,对它们进行分类,然后计算概念辨别损失:
![](img/76b2ce9c-02ba-48f5-ab5a-1368c500918c.png)
......
......@@ -366,7 +366,7 @@ ReLU 的限制条件之一是其输入负值的零梯度。 这可能会减慢
# 生成对抗网络
**生成对抗网络**,通常称为 **GAN** ,是通过生成器`G`学习特定概率分布的生成模型。 生成器`G`鉴别器`D`进行零和极小极大游戏,并且两者都会随着时间的流逝而逐渐达到纳什均衡。 生成器尝试生成类似于给定概率分布`P(x)`生成的样本,而鉴别器`D`尝试区分生成器生成的那些假数据样本。`G`来自原始分布的数据样本。 发生器`G`尝试通过转换样本`z`来生成与`P(x)`相似的样本。 噪声分布`P(z)`。 鉴别符`D`在假冒时学会将生成器`G`生成的样本标记为`G(z)``x`原始时属于`P(x)`。 在 minimax 游戏的平衡状态下,生成器将学习生成与原始分布`P(x)`相似的样本,因此以下是正确的:
**生成对抗网络**,通常称为 **GAN** ,是通过生成器`G`学习特定概率分布的生成模型。 生成器`G`判别器`D`进行零和极小极大游戏,并且两者都会随着时间的流逝而逐渐达到纳什均衡。 生成器尝试生成类似于给定概率分布`P(x)`生成的样本,而判别器`D`尝试区分生成器生成的那些假数据样本。`G`来自原始分布的数据样本。 发生器`G`尝试通过转换样本`z`来生成与`P(x)`相似的样本。 噪声分布`P(z)`。 鉴别符`D`在假冒时学会将生成器`G`生成的样本标记为`G(z)``x`原始时属于`P(x)`。 在 minimax 游戏的平衡状态下,生成器将学习生成与原始分布`P(x)`相似的样本,因此以下是正确的:
![](img/0bb90a7f-37ac-4079-8896-baa81ed7b81d.png)
......@@ -376,7 +376,7 @@ ReLU 的限制条件之一是其输入负值的零梯度。 这可能会减慢
Figure 1.14: GAN architecture 
别器最小化的成本函数是二进制交叉熵,用于区分生成器生成的假数据,和属于概率分布`P(x)`的真实数据点`z`
别器最小化的成本函数是二进制交叉熵,用于区分生成器生成的假数据,和属于概率分布`P(x)`的真实数据点`z`
![](img/b9cb9aa1-7eac-4174-983d-cb5be41b1eff.png)
......@@ -400,7 +400,7 @@ Figure 1.14: GAN architecture 
![](img/f5932e0c-dc8c-4041-abe9-24e33bcfc95f.png)
对于固定的生成器分配,如果满足以下条件,则`G(x)`对于别器的效用函数将最小。
对于固定的生成器分配,如果满足以下条件,则`G(x)`对于别器的效用函数将最小。
![](img/ec1949f8-e469-4633-9aaf-d857c5f0831c.png)
......
......@@ -2,7 +2,7 @@
**样式迁移**的概念是指将产品样式渲染为另一种产品的过程。 想象一下,您的一位时尚狂朋友买了一个蓝色的手袋,想买一双类似印花的鞋子。 直到 2016 年,这还是不可能实现的,除非他们与一位时装设计师成为朋友,他们必须首先设计一款鞋子,然后才能批准生产。 然而,随着生成对抗网络的最新进展,这种设计过程可以很容易地进行。
生成对抗网络是通过在生成器网络和别器网络之间进行零和游戏来学习的网络。 假设一位时装设计师想要设计一种特定结构的手袋,并且正在探索不同的印花。 设计人员可以绘制手提包的结构草图,然后将草图图像输入到生成的对抗网络中,以得出手提包的几种可能的最终印刷品。 这种样式迁移过程可以使客户自己绘制产品设计和图案,而无需征集大量设计师的意见,从而对时尚行业产生巨大影响。 通过推荐具有类似设计和风格的产品来补充客户已经拥有的产品,时装屋也可以从中受益。
生成对抗网络是通过在生成器网络和别器网络之间进行零和游戏来学习的网络。 假设一位时装设计师想要设计一种特定结构的手袋,并且正在探索不同的印花。 设计人员可以绘制手提包的结构草图,然后将草图图像输入到生成的对抗网络中,以得出手提包的几种可能的最终印刷品。 这种样式迁移过程可以使客户自己绘制产品设计和图案,而无需征集大量设计师的意见,从而对时尚行业产生巨大影响。 通过推荐具有类似设计和风格的产品来补充客户已经拥有的产品,时装屋也可以从中受益。
在这个项目中,我们将构建一个智能人工智能系统,该系统将生成与给定手提袋样式相似的鞋子,反之亦然。 我们之前讨论的原始 GAN 不足以实现这个项目。 我们需要的是 GAN 的定制版本,例如 DiscoGAN 和 CycleGAN。
......@@ -37,7 +37,7 @@
![](img/09ada4ef-4d12-45db-a6b8-19064db767e9.png)
仅使前面的损失最小化是不够的。 我们必须确保在域`B`中创建的图像`x[B]`看起来逼真。例如,如果我们将域`A`中的衣服映射到域`B`中的鞋子,我们将确保`x[B]`类似于鞋子。 如果图像不够真实,则在域`B`侧的鉴别符`D[B]`将检测为`x[B]`为假。 鞋子,因此也要考虑与此有关的损失。 通常,在训练过程中,向鉴别器提供生成的域`B`图像`x[AB] = G[AB](X[A])`,我们选择在这里用`y[B]`表示,以便它学习从假图像中对真实图像进行分类。 您可能还记得,在 GAN 中,生成器和判别器相互进行*零和最小最大值游戏*,以便不断变得更好,直到达到平衡为止。 如果伪造的图像看起来不够逼真,则鉴别器将对其进行惩罚,这意味着生成器必须学习产生更好的图像`x[AB]`,如果输入图像`x[A]`。 考虑到所有这些因素,我们可以将我们希望最小化的生成器损耗公式化为重建损耗,以及鉴别器将`x[AB]`识别为假冒的损耗。 第二种损失将试图使生成器在域`B`中生成逼真的图像。将域`A`中的图像`x[A]`映射到域`B`中的图像的生成器损失可以表示如下:
仅使前面的损失最小化是不够的。 我们必须确保在域`B`中创建的图像`x[B]`看起来逼真。例如,如果我们将域`A`中的衣服映射到域`B`中的鞋子,我们将确保`x[B]`类似于鞋子。 如果图像不够真实,则在域`B`侧的鉴别符`D[B]`将检测为`x[B]`为假。 鞋子,因此也要考虑与此有关的损失。 通常,在训练过程中,向判别器提供生成的域`B`图像`x[AB] = G[AB](X[A])`,我们选择在这里用`y[B]`表示,以便它学习从假图像中对真实图像进行分类。 您可能还记得,在 GAN 中,生成器和判别器相互进行*零和最小最大值游戏*,以便不断变得更好,直到达到平衡为止。 如果伪造的图像看起来不够逼真,则判别器将对其进行惩罚,这意味着生成器必须学习产生更好的图像`x[AB]`,如果输入图像`x[A]`。 考虑到所有这些因素,我们可以将我们希望最小化的生成器损耗公式化为重建损耗,以及判别器将`x[AB]`识别为假冒的损耗。 第二种损失将试图使生成器在域`B`中生成逼真的图像。将域`A`中的图像`x[A]`映射到域`B`中的图像的生成器损失可以表示如下:
![](img/f2cdd9c3-d4d4-4c89-a533-e5044ea37592.png)
......@@ -47,7 +47,7 @@ L2 范数下的重建损失可以表示为:
由于我们正在处理图像,因此可以假设`x[A]`是所有像素的扁平向量,以符合 L2 规范术语。 如果我们假设`x[A]`是矩阵,则最好将`||·||_2^2`称为 **Frobenius 范数**。 但是,这些只是数学术语,实质上,我们只是将原始图像和重建图像之间的像素值差的平方和求和。
让我们考虑一下生成器在使变换后的图像`x[AB]`追求时要尽量降低成本的做法。 鉴别者将尝试将图像标记为伪图像,因此生成器`G[AB]`应当在这种情况下产生`x[AB]`使其成为假图片的对数丢失的方式尽可能小。 如果域`B`中的鉴别符`D[B]`将真实图像标记为`1`,将伪图像标记为`0`,则图像真实的概率由`D[B](.)`,则发生器应使`x[AB]`别器网络下极有可能出现,从而使`D[B](x[B]) = D[B](G[AB](x[A]))`接近`1`)。 就对数损失而言,生成器应使先前概率的负对数最小化,这基本上使我们得到`C[D(AB)]`,如下所示:
让我们考虑一下生成器在使变换后的图像`x[AB]`追求时要尽量降低成本的做法。 鉴别者将尝试将图像标记为伪图像,因此生成器`G[AB]`应当在这种情况下产生`x[AB]`使其成为假图片的对数丢失的方式尽可能小。 如果域`B`中的鉴别符`D[B]`将真实图像标记为`1`,将伪图像标记为`0`,则图像真实的概率由`D[B](.)`,则发生器应使`x[AB]`别器网络下极有可能出现,从而使`D[B](x[B]) = D[B](G[AB](x[A]))`接近`1`)。 就对数损失而言,生成器应使先前概率的负对数最小化,这基本上使我们得到`C[D(AB)]`,如下所示:
![](img/549bd16c-1bd7-4f76-b4c1-6179369f92c7.png)
......@@ -71,7 +71,7 @@ L2 范数下的重建损失可以表示为:
![](img/78578465-7cc8-40c5-9662-21aa263baa81.png)
结合`(8)``(9)`的总别器成本由`C[D]`给出,如下:
结合`(8)``(9)`的总别器成本由`C[D]`给出,如下:
![](img/8907ca7c-ae87-4a4b-80e3-37c4bfb678cc.png)
......@@ -85,7 +85,7 @@ L2 范数下的重建损失可以表示为:
# CycleGAN
**CycleGAN** 从根本上类似于 DiscoGAN,但有一个小的修改。 在 CycleGAN 中,我们可以灵活地确定相对于 GAN 损失或归因于别器的损失,为重建损失分配多少权重。 该参数有助于根据眼前的问题按正确比例平衡损失,以帮助网络在训练时更快地收敛。 CycleGAN 的其余实现与 DiscoGAN 相同。
**CycleGAN** 从根本上类似于 DiscoGAN,但有一个小的修改。 在 CycleGAN 中,我们可以灵活地确定相对于 GAN 损失或归因于别器的损失,为重建损失分配多少权重。 该参数有助于根据眼前的问题按正确比例平衡损失,以帮助网络在训练时更快地收敛。 CycleGAN 的其余实现与 DiscoGAN 相同。
# 学习从草绘的轮廓生成自然手袋
......@@ -300,7 +300,7 @@ def build_generator(self,image,reuse=False,name='generator'):
# DiscoGAN 的判别器
DiscoGAN 的判别器将学会在特定域中将真实图像与假图像区分开。 我们将有两个鉴别符:一个用于域`A`,一个用于域`B`。这些鉴别器也是可以执行二进制分类的卷积网络。 与传统的基于分类的卷积网络不同,鉴别器没有任何全连接层。 使用步长为 2 的卷积对输入图像进行下采样,直到最终层(输出为`1 x 1`)为止。同样,我们使用 LReLU 作为激活函数并使用批量归一化以实现稳定和快速的收敛。 以下代码显示了 TensorFlow 中鉴别器构建函数的实现:
DiscoGAN 的判别器将学会在特定域中将真实图像与假图像区分开。 我们将有两个鉴别符:一个用于域`A`,一个用于域`B`。这些判别器也是可以执行二进制分类的卷积网络。 与传统的基于分类的卷积网络不同,判别器没有任何全连接层。 使用步长为 2 的卷积对输入图像进行下采样,直到最终层(输出为`1 x 1`)为止。同样,我们使用 LReLU 作为激活函数并使用批量归一化以实现稳定和快速的收敛。 以下代码显示了 TensorFlow 中判别器构建函数的实现:
```py
def build_discriminator(self,image,reuse=False,name='discriminator'):
......@@ -356,7 +356,7 @@ def build_discriminator(self,image,reuse=False,name='discriminator'):
return down5
```
别器网络不同层中输出特征映射的数量为`self.df`或其倍数。 对于我们的网络,我们将`self.df`设为`64`
别器网络不同层中输出特征映射的数量为`self.df`或其倍数。 对于我们的网络,我们将`self.df`设为`64`
# 建立网络并定义成本函数
......@@ -464,11 +464,11 @@ def build_network(self):
self.saver = tf.train.Saver()
```
在构建网络中,我们首先定义 L2 范数误差和二进制交叉熵误差的成本函数。 L2 范数误差将用作重建损失,而二元互熵将用作鉴别器损失。 然后,我们使用生成器函数为两个域中的图像定义占位符,并为每个域中的伪图像定义 TensorFlow 操作。 我们还通过传递特定于域的伪造和真实图像来定义鉴别器输出的操作。 除此之外,我们为两个域中的每个域中的重建图像定义 TensorFlow 操作。
在构建网络中,我们首先定义 L2 范数误差和二进制交叉熵误差的成本函数。 L2 范数误差将用作重建损失,而二元互熵将用作判别器损失。 然后,我们使用生成器函数为两个域中的图像定义占位符,并为每个域中的伪图像定义 TensorFlow 操作。 我们还通过传递特定于域的伪造和真实图像来定义判别器输出的操作。 除此之外,我们为两个域中的每个域中的重建图像定义 TensorFlow 操作。
一旦定义了操作,我们就可以使用它们来计算损失函数,同时考虑图像的重建损失和归因于别器的损失。 请注意,我们使用了相同的生成器函数来定义域`A``B`的生成器,也定义了从`B``A`的生成器。唯一不同的是为这两个网络提供了不同的名称:`generator_AB``generator_BA`。 由于变量作用域定义为`name`,所以这两个生成器都将具有不同的权重集,并以提供的名称为前缀。
一旦定义了操作,我们就可以使用它们来计算损失函数,同时考虑图像的重建损失和归因于别器的损失。 请注意,我们使用了相同的生成器函数来定义域`A``B`的生成器,也定义了从`B``A`的生成器。唯一不同的是为这两个网络提供了不同的名称:`generator_AB``generator_BA`。 由于变量作用域定义为`name`,所以这两个生成器都将具有不同的权重集,并以提供的名称为前缀。
下表显示了我们需要跟踪的不同损耗变量。 就发生器或别器的参数而言,所有这些损失都需要最小化:
下表显示了我们需要跟踪的不同损耗变量。 就发生器或别器的参数而言,所有这些损失都需要最小化:
| **不同损失的变量** | **说明** |
| --- | --- |
......@@ -476,16 +476,16 @@ def build_network(self):
| `self.D_B_loss_fake` | 在对域`B`中的伪造图像进行分类时,鉴别符`D[B]`的二进制交叉熵损失。(相对于判别器`D[B]`的参数,该损失应最小化) |
| `self.D_A_loss_real` | 在对域`A`中的真实图像进行分类时,鉴别符`D[A]`的二进制交叉熵损失。(相对于判别器`D[A]`的参数,该损失应最小化) |
| `self.D_A_loss_fake` | 在对域`A`中的伪造图像进行分类时,鉴别符`D[A]`的二进制交叉熵损失。(相对于判别器`D[A]`的参数,该损失应最小化) |
| `self.loss_GABA` | 通过两个生成器`G[AB]``G[BA]`将域`A`中的图像映射到`B`,然后再映射回`A`的重建损失,加上假图片`G[AB](x[A])`的二进制交叉熵,由域`B`中的别器标记为真实图像。(相对于生成器`G[AB]``G[BA]`的参数,该损失应最小化) |
| `self.loss_GBAB` | 通过两个生成器`G[BA]``G[AB]`将域`B`中的图像映射到`A`,然后再映射回`B`的重建损失,加上伪图片`G[BA](x[B])`的二元交叉熵,由域`A`中的别器标记为真实图像。(相对于生成器`G[AB]``G[BA]`的参数,该损失应最小化) |
| `self.loss_GABA` | 通过两个生成器`G[AB]``G[BA]`将域`A`中的图像映射到`B`,然后再映射回`A`的重建损失,加上假图片`G[AB](x[A])`的二进制交叉熵,由域`B`中的别器标记为真实图像。(相对于生成器`G[AB]``G[BA]`的参数,该损失应最小化) |
| `self.loss_GBAB` | 通过两个生成器`G[BA]``G[AB]`将域`B`中的图像映射到`A`,然后再映射回`B`的重建损失,加上伪图片`G[BA](x[B])`的二元交叉熵,由域`A`中的别器标记为真实图像。(相对于生成器`G[AB]``G[BA]`的参数,该损失应最小化) |
前四个损耗组成了鉴别器损耗,需要根据鉴别器的参数将其最小化。 ]。 最后两个损耗组成了生成器损耗,需要根据生成器的参数将其最小化。 。
前四个损耗组成了判别器损耗,需要根据判别器的参数将其最小化。 ]。 最后两个损耗组成了生成器损耗,需要根据生成器的参数将其最小化。 。
损失变量通过`tf.summary.scaler` 与 TensorBoard 绑定,以便可以在训练过程中监控这些损失,以确保以期望的​​方式减少损失。 稍后,我们将在培训进行时在 TensorBoard 中看到这些损失痕迹。
# 建立培训流程
# 建立训练流程
`train_network`函数中,我们首先为生成器和鉴别器损失函数定义优化器。 我们将 Adam 优化器用于生成器和鉴别器,因为这是随机梯度下降优化器的高级版本,在训练 GAN 方面非常有效。 亚当使用梯度的衰减平均值(非常类似于稳定梯度的动量)和平方梯度的衰减平均值,以提供有关成本函数曲率的信息。 与`tf.summary`定义的不同损失有关的变量将写入日志文件,因此可以通过 TensorBoard 进行监视。 以下是`train`功能的详细代码:
`train_network`函数中,我们首先为生成器和判别器损失函数定义优化器。 我们将 Adam 优化器用于生成器和判别器,因为这是随机梯度下降优化器的高级版本,在训练 GAN 方面非常有效。 亚当使用梯度的衰减平均值(非常类似于稳定梯度的动量)和平方梯度的衰减平均值,以提供有关成本函数曲率的信息。 与`tf.summary`定义的不同损失有关的变量将写入日志文件,因此可以通过 TensorBoard 进行监视。 以下是`train`功能的详细代码:
```py
def train_network(self):
......@@ -608,7 +608,7 @@ def save_model(self,checkpoint_dir,step):
| 批量大小 | `self.batch_size = 64` | `64`的批量大小非常适合此实现。 但是,由于资源限制,我们可能不得不选择较小的批量大小。 |
| 学习率线性下降的时期 | `epoch_step = 10` | 在`epoch_step`指定的时期数之后,学习率呈线性下降,由以下方案确定:`lr = self.l_r if epoch < self.epoch_step else self.l_r*(self.epoch-epoch)/(self.epoch-self.epoch_step)` |
# 调用培训
# 调用训练
我们前面说明的所有函数都是在`DiscoGAN()`类内创建的,并在`__init__` 函数中声明了重要的参数值,如以下代码块所示。 训练网络时仅需要传递的两个参数是`dataset_dir`和需要对其进行训练的`epochs`的数量
......@@ -683,7 +683,7 @@ Epoch: [ 0] [ 19/ 156] time: 13.7525
.......
```
# 监控生成器和鉴别器损耗
# 监控生成器和判别器损失
可以在 TensorBoard 仪表板中监控损失。 TensorBoard 仪表板可以按以下方式调用:
......@@ -702,19 +702,19 @@ Epoch: [ 0] [ 19/ 156] time: 13.7525
2. 执行完步骤 1 中的命令后,导航到 TensorBoard 的`localhost:6006`站点:
以下屏幕快照中展示了在项目中实现的 DiscoGAN 培训期间在 TensorBoard 中查看的一些生成器和别器损耗的痕迹:
以下屏幕快照中展示了在项目中实现的 DiscoGAN 培训期间在 TensorBoard 中查看的一些生成器和别器损耗的痕迹:
![](img/8c1362f9-bf37-4c56-ac05-30bb6d00a579.png)
图 4.2:Tensorboard `Scalars`部分包含不同损耗的迹线
以下屏幕截图显示了随着训练的进行,域`A`别器的损耗成分:
以下屏幕截图显示了随着训练的进行,域`A`别器的损耗成分:
![](img/a02c2ba3-678a-4f01-8f16-0addf12d379e.png)
图 4.3:域`A`中的别器丢失
图 4.3:域`A`中的别器丢失
从前面的屏幕截图中,我们可以看到不同批量中域`A`鉴别器的损失。 `da_loss``da_loss_real``da_loss_fake`损失的总和。 `da_loss_real`稳步下降,这是因为鉴别器易于学会识别域`A`中的真实图像,而虚假图像的损失则稳定在 0.69 左右,这是二进制分类器输出时您可以期望的`logloss` 具有`1/2`概率的类。 发生这种情况是因为生成器也在同时学习以使伪图像看起来逼真,因此使鉴别人员很难轻松地将生成器图像分类为伪图像。 域`B`上的鉴别器的损耗曲线看起来与域`A`的上一幅屏幕快照所示的相似。
从前面的屏幕截图中,我们可以看到不同批量中域`A`判别器的损失。 `da_loss``da_loss_real``da_loss_fake`损失的总和。 `da_loss_real`稳步下降,这是因为判别器易于学会识别域`A`中的真实图像,而虚假图像的损失则稳定在 0.69 左右,这是二进制分类器输出时您可以期望的`logloss` 具有`1/2`概率的类。 发生这种情况是因为生成器也在同时学习以使伪图像看起来逼真,因此使鉴别人员很难轻松地将生成器图像分类为伪图像。 域`B`上的判别器的损耗曲线看起来与域`A`的上一幅屏幕快照所示的相似。
现在让我们看一下生成器的损耗曲线,如下所示:
......
......@@ -89,7 +89,7 @@ o1, o2, . . . . . ot . . . oN = { "A ","man" "in" "a" "yellow" "helmet" "is" "wo
`MSVD dataset`中大约有`1,938`个视频。 我们将使用它们来训练*逐序列视频字幕系统*。 还要注意,我们将在“图 5.3”中所示的序列到序列模型上构建模型。 但是,建议读者尝试在“图 5.4”中介绍的架构上训练模型,并了解其表现。
# 处理视频图像以创建 CNN 功能
# 处理视频图像来创建 CNN 特征
从指定位置下载数据后,下一个任务是处理视频图像帧,以从预训练的卷积神经网络的最后全连接层中提取特征。 我们使用在 ImageNet 上预训练的`VGG16`卷积神经网络。 我们将激活从`VGG16`的最后一个全连接层中取出。 由于`VGG16`的最后一个全连接层具有`4096`单位,因此每个时间步`t`的特征向量`f[t]``4096`维向量,`f[t] ∈ R^4096`
......@@ -696,7 +696,7 @@ Epoch 99 is done. Saving the model ...
从前面的图表(“图 5.7”)可以看出,损耗减少在最初的几个时期中较高,然后在时期`80`处逐渐减小。 在下一节中,我们将说明该模型在为看不见的视频生成字幕时的性能。
# 用看不见的测试视频推断
# 用没见过的测试视频推断
为了进行推理,我们构建了一个生成器函数`build_generator`,该函数复制了`build_model`的逻辑以定义所有模型变量,以及所需的 TensorFlow 操作来加载模型并在同一模型上进行推理:
......@@ -783,7 +783,7 @@ Epoch 99 is done. Saving the model ...
return video, video_mask, generated_words, probs, embeds
```
# 推理功能
# 推理函数
在推理过程中,我们调用`build_generator`定义模型以及推理所需的其他 TensorFlow 操作,然后使用`tf.train.Saver.restoreutility`从训练后的模型中保存已保存的权重,以加载定义的模型。 一旦加载了模型并准备对每个测试视频进行推理,我们就从 CNN 中提取其对应的视频帧图像预处理特征并将其传递给模型进行推理:
......
......@@ -54,7 +54,7 @@
我们可以将用户个人资料矩阵作为`US^(1/2)`,然后将项目个人资料矩阵转置为 `S^(1/2) V^T`形成潜在因子模型。 当在分级矩阵中缺少与用户未分级的电影相对应的条目时,您可能会遇到有关如何执行 SVD 的问题。 常见的方法是在执行 SVD 之前,通过用户的平均评分或总体评分的平均值来估算缺失的评分。
# 深度学习以进行潜在因素协同过滤
# 用于潜在因子协同过滤的深度学习
除了使用 SVD,您还可以利用深度学习方法来导出给定尺寸的用户和商品资料向量。
......@@ -236,7 +236,7 @@ test_ratings_df[test_ratings_df['userID'] == 1].sort_values(['rating','predictio
`surprise`软件包具有 SVD++ 的良好实现。 在下一部分中,我们将在`100K movie lens`数据集上使用 SVD++ 训练模型,并查看性能指标。
# 电影镜头 100k 数据集上的 SVD++ 训练模型
# MovieLens 100k 数据集上的 SVD++ 训练模型
可以使用以下命令通过`conda`下载`surprise`软件包:
......@@ -307,7 +307,7 @@ RMSE: 0.9320
在“用于推荐的受限玻尔兹曼机”部分中,我们将介绍用于构建推荐系统的受限玻尔兹曼机。 由于该方法可以扩展到大型数据集,因此在协同过滤中获得了很大的普及。 协同过滤域中的大多数数据集都很稀疏,从而导致困难的非凸优化问题。 与其他分解方法(例如 SVD)相比,RBM 在数据集中更不容易遭受此稀疏问题的困扰。
# 推荐的受限玻尔兹曼机
# 用于推荐的受限玻尔兹曼机
受限玻尔兹曼机是一类属于无监督学习技术的神经网络。 众所周知,**受限玻尔兹曼机****RBM**)试图通过将输入数据投影到隐藏层中来学习数据的隐藏结构。
......@@ -345,7 +345,7 @@ RBM 的参数是可见层单位`i`与隐藏层单位之间的广义权重连接`
术语`E[.]`表示对隐藏和可见单位的联合概率分布的任何给定数量的期望。 另外,`h_hat`表示给定可见单位`v`的采样的隐藏层输出。 在梯度下降的每次迭代中计算联合概率分布的期望在计算上是棘手的。 我们将采用下一节中讨论的称为**对比发散**的智能方法来计算期望值。
# 对比分歧
# 对比散度
计算联合概率分布的期望值的一种方法是通过吉布斯采样从联合概率分布中生成很多样本,然后将样本的平均值作为期望值。 在吉布斯抽样中,可以以其余变量为条件对联合概率分布中的每个变量进行抽样。 由于可见单位是独立的,因此给定隐藏单位,反之亦然,因此您可以将隐藏单位采样为`h_bar <- P(h/v)`,然后将可见单位激活给定隐藏单位为`v_bar = P(v/h = h_bar)`。 然后我们可以将样本`(v_bar, h_bar)`作为从联合概率分布中抽取的样本。 这样,我们可以生成大量样本,例如`M`,并取其平均值来计算期望的期望值。 但是,在梯度下降的每个步骤中进行如此大量的采样将使训练过程变得令人无法接受的缓慢,因此,与其在梯度下降的每个步骤中计算许多样本的平均值,不如从联合概率中生成一个样本,它应当表示整个联合概率分布上的所需期望:
......@@ -568,7 +568,7 @@ TensorFlow ops `self.x_`指的是给定隐藏层激活`self.h`的可见层激活
同样,在推理过程中,我们将与所有测试文件和测试文件一起(所有代码和评分均被读入)读入预测文件 CSV(在先前代码的推理部分中为`self.train_file`,在此处)。 一旦训练了模型,便执行预测。 由于我们已经在训练后预测了收视率,因此在推断时间内我们要做的就是将收视率预测信息与测试文件的实际收视率信息相结合(后面的`train``inference`部分中有更多详细信息)。 另外,我们从用户和电影元数据文件中读取信息以供以后使用。
# 训练成果管理制
# 训练 RBM
此处说明的`_train`功能可用于训练 RBM。 在此函数中,我们首先调用`_network`函数以构建 RBM 网络结构,然后在激活的 TensorFlow 会话中针对指定时期数训练模型。 使用 TensorFlow 的`saver`函数以指定的时间间隔保存模型:
......@@ -662,7 +662,7 @@ RBM training Completed !
请注意,受限玻尔兹曼机网络已在配备 GeForce Zotac 1070 GPU 和 64 GB RAM 的 Ubuntu 机器上进行了培训。 培训时间可能会根据用于培训网络的系统而有所不同。
# 使用训练有素的 RBM 推理
# 将训练后的 RBM 用于推理
鉴于我们已经在训练过程中生成了带有所有预测的文件`pred_all_recs.csv`,因此针对 RBM 的推理非常简单。 我们要做的只是基于提供的测试文件从`pred_all_recs.csv`中提取测试记录。 另外,我们通过将`1`添加到它们的当前值来求助于原始的`userid``movieid`。 返回原始 ID 的目的是能够从`u.user``u.item`文件中添加用户和电影信息。
......
......@@ -420,7 +420,7 @@ python freeze_code.py --path /home/santanu/Downloads/Mobile_App/ --MODEL_NAME mo
39.623 s: Model Freeze
```
# 创建用于推理的单词典
# 创建用于推理的单词到标记的词典
在预处理过程中,我们训练了 Keras 标记器,用其数字单词索引替换单词,以便将处理后的电影评论输入 LSTM 模型进行训练。 我们还保留了具有最高单词频率的前`50000`个单词,并将查看序列设置为`1000`的最大长度。 尽管训练有素的 Keras 标记生成器已保存用于推断,但 Android 应用程序无法直接使用它。 我们可以还原 Keras 标记器,并将前`50000`个单词及其对应的单词索引保存在文本文件中。 可以在 Android 应用中使用此文本文件,以构建**词对索引词典**,以将评论文本的词转换为其词索引。 重要的是要注意,可以通过参考`tokenizer.word_index.`从加载的 Keras 标记生成器对象中检索单词到索引的映射,执行此活动`tokenizer_2_txt.py`的详细代码如下:
......@@ -467,7 +467,7 @@ Using TensorFlow backend.
165.235 ms: Tokenize
```
# 应用界面页面设计
# 应用界面设计
可以使用 Android Studio 设计一个简单的移动应用程序界面,并将相关代码生成为 XML 文件。 正如您在以下屏幕截图(“图 7.3”)中所看到的那样,该应用程序包含一个简单的电影评论文本框,用户可以在其中输入他们的电影评论,并在完成后按`SUBMIT`按钮。 按下`SUBMIT`按钮后,评论将传递到核心应用逻辑,该逻辑将处理电影评论文本并将其传递给 TensorFlow 优化模型进行推理。
......
......@@ -369,7 +369,7 @@ def respond_to_input(self,model,input_sent):
'_.csv',index=False)
```
# 调用培训
# 调用训练
可以通过运行带有多个参数的`chatbot.py`(请参见 GitHub 中此项目的代码)模块来调用训练,如以下命令所示:
......
# 通过强化学习的自主无人驾驶汽车
# 使用强化学习的自主无人驾驶汽车
在过去的几年中,增强学习已经真正兴起,在增强学习中,智能体通过与环境的交互来学习决策。 这是当今人工智能和机器学习中最热门的主题之一,并且这一领域的研究正在快速发展。 在**强化学习****RL**)中,智能体将他们的行动和经验转化为学习,以便将来做出更好的决策。
......@@ -45,7 +45,7 @@
图 9.2:具有三个状态的马尔可夫决策过程的图示
# 学习 Q 值功能
# 学习 Q 值函数
对于 RL 智能体做出决定,重要的是智能体学习 Q 值函数。 可以通过**贝尔曼方程**迭代地学习 Q 值函数。 当智能体开始与环境交互时,它以随机状态`s[0]`和每个状态动作对的 Q 值的随机状态开始。 智能体的动作在某种程度上也是随机的,因为它没有状态 Q 值来做出明智的决策。 对于每个采取的行动,环境将根据哪个智能体开始建立 Q 值表并随着时间的推移而改善而返回奖励。
......@@ -79,7 +79,7 @@ Q 值表也通过迭代`t`进行索引,因为智能体只能查看到目前为
深度 Q 学习网络的训练方法很简单,称为经验回放。 让 RL 智能体与环境交互并将经验以`(s, a, r, s')`的元组形式存储在回放缓冲区中。 可以从此回放缓冲区采样小批量以训练网络。 首先,回放缓冲区是随机存储的。
# 制定成本函数
# 定义成本函数
使用架构比较容易,在该架构中,可以获取网络馈给的给定状态的所有动作的 Q 值。 在图 9.3 的右侧中也进行了说明。 我们将让智能体与环境交互并收集状态和奖励,以此为基础我们将学习 Q 函数。 实际上,网络会通过将给定状态`s`的所有动作`[a[i]], i = 1 -> n`的预测 Q 值与目标 Q 值的预测 Q 值最小化来学习 Q 函数。 每个训练记录都是一个元组`s[t], a[t], r[t], s[t + 1]`
......@@ -765,7 +765,7 @@ if __name__ == '__main__':
print('Model is not saved!')
```
# 辅助功能
# 辅助函数
以下是在此强化学习框架中用于进行动作选择,存储用于训练的观察值,状态图像处理以及节省训练后模型权重的一些辅助功能:
......@@ -865,7 +865,7 @@ def model_save(path,name,agent,R):
python main.py --environment_name 'CarRacing-v0' --model_path '/home/santanu/Autonomous Car/train/' --train_mode True --test_mode False --epsilon_greedy True --render True --width 96 --height 96 --num_stack 4 --huber_loss_thresh 1 --dropout 0.2 --memory_size 10000 --batch_size 128 --max_num_episodes 500
```
# 培训结果
# 训练结果
最初,自动驾驶汽车会犯错误,但一段时间后,汽车会通过训练从错误中吸取教训,因此会变得更好。 此屏幕快照显示了在训练的最初阶段以及随后从训练的后期(当从先前的错误中获悉)后汽车的活动图像。 在以下屏幕截图中对此进行了说明(图 9.5A 和图 9.5B):
......
......@@ -24,7 +24,7 @@
[观看以下视频,查看运行中的代码](http://bit.ly/2SgwR6P)
# 通过深度学习打破验证码
# 通过深度学习破解验证码
随着**卷积神经网络****CNN**)在计算机视觉任务中的最新成功,在几分钟内打破基本的验证码是相对容易的任务。 因此,CAPTCHA 需要比过去有更多的发展。 在本章的第一部分中,我们将介绍使用具有深度学习框架的机器人自动检测到的基本验证码的漏洞。 我们将通过利用 GAN 创建更难以被机器人检测到的 CAPTCHA 进行跟进。
......@@ -62,7 +62,7 @@ plt.imshow(image)
与文本一起,`Claptcha`工具要求使用打印字体作为输入的字体。 如我们所见,它以横轴上有些扭曲的线的形式给图像增加了噪点。
# 生成数据以训练 CAPTCHA 破坏
# 生成数据来训练 CAPTCHA 破解
在本节中,我们将使用`Claptcha`工具生成多个验证码,以训练 CNN 模型。 CNN 模型将通过监督训练来学习识别 CAPTCHA 中的字符。 我们将生成用于训练 CNN 模型的训练和验证集。 除此之外,我们将生成一个单独的测试集,以评估其概括未见数据的能力。 可以对`CaptchaGenerator.py`脚本进行如下编码以生成验证码数据:
......@@ -125,9 +125,9 @@ python CaptchaGenerator.py --outdir_train '/home/santanu/Downloads/Captcha Gener
3.328 min: main_process
```
在下一节中,我们将讨论 CAPTCHA 破器的卷积神经网络架构。
在下一节中,我们将讨论 CAPTCHA 破器的卷积神经网络架构。
# 验证码破器 CNN 架构
# 验证码破器 CNN 架构
我们将使用 CNN 架构来识别 CAPTCHA 中的字符。 CNN 在密集层之前将具有两对卷积和池化。 我们将把验证码分为四个字符,然后将它们分别输入模型,而不是将整个验证码输入网络。 这要求 CNN 的最终输出层预测与`26`字母和`10`数字有关的`36`类之一。
......@@ -159,11 +159,11 @@ def _model_(n_classes):
```
可以如下图所示图示 CAPTCHA 破器 CNN 模型(“图 10.3”):
可以如下图所示图示 CAPTCHA 破器 CNN 模型(“图 10.3”):
![](img/608c6914-e403-4e73-80a5-15da7deb8b53.png)
图 10.3:CAPTCHA 破器 CNN 架构
图 10.3:CAPTCHA 破器 CNN 架构
# 预处理 CAPTCHA 图像
......@@ -266,9 +266,9 @@ class DataGenerator(keras.utils.Sequence):
return X,y
```
# 训练 CAPTCHA 破
# 训练 CAPTCHA 破
可以通过调用`train`功能来训练 CAPTCHA 破器模型,如下所示:
可以通过调用`train`功能来训练 CAPTCHA 破器模型,如下所示:
```py
def train(dest_train,dest_val,outdir,batch_size,n_classes,dim,shuffle,epochs,lr):
......@@ -392,33 +392,33 @@ SVHN 是一个现实世界的数据集,由于它在对象识别算法中的使
通过这个**生成对抗网络****GAN**),我们将根据随机噪声生成房屋编号图像,并且生成的图像将与 SVHN 数据集中的图像非常相似。
回顾一下,在 GAN 中,我们有一个生成器(`G`)和一个鉴别器(`D`),它们针对损失函数彼此玩零和极小极大游戏。 随着时间的流逝,生成器和鉴别器的工作都会越来越好,直到我们到达一个固定点为止,两者都无法进一步改善。 该固定点是相对于损失函数的鞍点。 对于我们的应用,发生器`G`会将给定分布`P(z)`的噪声`z`转换​​为门牌号图像`x`,以使`x = G(z)`
回顾一下,在 GAN 中,我们有一个生成器(`G`)和一个判别器(`D`),它们针对损失函数彼此玩零和极小极大游戏。 随着时间的流逝,生成器和判别器的工作都会越来越好,直到我们到达一个固定点为止,两者都无法进一步改善。 该固定点是相对于损失函数的鞍点。 对于我们的应用,发生器`G`会将给定分布`P(z)`的噪声`z`转换​​为门牌号图像`x`,以使`x = G(z)`
生成的图像通过鉴别器`D`传递,鉴别器`D`尝试检测此生成的图像`x`为伪造,并从 SVHN 数据集中检测真实的门牌号码图像为真实。 同时,生成器将尝试创建图像`x = G(z)`,以使鉴别器发现图像是真实的。 如果我们将真实图像标记为`1`,而将生成器生成的伪图像标记为`0`,则鉴别器将尝试在给定两个类别的分类器网络中最小化二进制交叉熵损失。 鉴别符`D`所导致的损耗可以写成如下:
生成的图像通过判别器`D`传递,判别器`D`尝试检测此生成的图像`x`为伪造,并从 SVHN 数据集中检测真实的门牌号码图像为真实。 同时,生成器将尝试创建图像`x = G(z)`,以使判别器发现图像是真实的。 如果我们将真实图像标记为`1`,而将生成器生成的伪图像标记为`0`,则判别器将尝试在给定两个类别的分类器网络中最小化二进制交叉熵损失。 鉴别符`D`所导致的损耗可以写成如下:
![](img/ae36b54b-0a7c-4c94-8c4b-4e5209859d44.png)
在前面的表达式中`D(.)`是鉴别函数,其输出表示将图像标记为实数的可能性。`P[z](z)`表示随机变量噪声`z`的分布,而`P[X](x)`表示真实门牌号图像的分布。`G(.)``D(.)`分别表示生成器网络功能和鉴别器网络功能。 这些参数可以通过网络的权重进行参数化,而网络的权重是我们为表示法的混乱而方便地跳过的。 如果我们用`θ`表示发生器网络权重的参数,用`φ`表示鉴别器网络的权重,则鉴别器将学会使`(1)`相对于`φ`的损失最小化,而生成器将旨在使`(1)``θ`的损失相同。 我们可以将`(1)`中优化的损耗称为效用函数,发生器和鉴别器都在参数方面进行了优化。 实用函数`U`可以根据生成器和鉴别器的参数来编写,如下所示:
在前面的表达式中`D(.)`是鉴别函数,其输出表示将图像标记为实数的可能性。`P[z](z)`表示随机变量噪声`z`的分布,而`P[X](x)`表示真实门牌号图像的分布。`G(.)``D(.)`分别表示生成器网络功能和判别器网络功能。 这些参数可以通过网络的权重进行参数化,而网络的权重是我们为表示法的混乱而方便地跳过的。 如果我们用`θ`表示发生器网络权重的参数,用`φ`表示判别器网络的权重,则判别器将学会使`(1)`相对于`φ`的损失最小化,而生成器将旨在使`(1)``θ`的损失相同。 我们可以将`(1)`中优化的损耗称为效用函数,发生器和判别器都在参数方面进行了优化。 实用函数`U`可以根据生成器和判别器的参数来编写,如下所示:
![](img/e18dcc4f-da73-459c-ae45-a767f0e05be9.png)
从博弈论的角度来看,生成器`G`别器`D`相互之间具有效用函数`U(θ, φ)`的零和最小极大值游戏,并且最小极大值游戏的优化问题可以表示为:
从博弈论的角度来看,生成器`G`别器`D`相互之间具有效用函数`U(θ, φ)`的零和最小极大值游戏,并且最小极大值游戏的优化问题可以表示为:
![](img/b7879b3d-3991-4996-9a1e-a84f53d47c9c.png)
![](img/fa0742bb-8c7c-4eb0-9813-fd83336d1417.png)
在参数空间中的某个点上,如果某个函数相对于某些参数而言是局部最大值,而对于其余参数而言是局部最小值,则该点称为**鞍点**。 因此,`(θ_hat, φ_hat)`给出的点将成为效用函数`U(θ, φ)`的鞍点。 该鞍点是极小极大零和博弈的纳什均衡,对于生成器和鉴别器正在优化的效用,`(θ_hat, φ_hat)`参数是最佳的。 就当前问题而言,生成器`G`会产生最困难的验证码,供鉴别器以`θ_hat`作为其参数进行检测。 同样,鉴别器最适合以`φ`作为参数来检测伪造的验证码。
在参数空间中的某个点上,如果某个函数相对于某些参数而言是局部最大值,而对于其余参数而言是局部最小值,则该点称为**鞍点**。 因此,`(θ_hat, φ_hat)`给出的点将成为效用函数`U(θ, φ)`的鞍点。 该鞍点是极小极大零和博弈的纳什均衡,对于生成器和判别器正在优化的效用,`(θ_hat, φ_hat)`参数是最佳的。 就当前问题而言,生成器`G`会产生最困难的验证码,供判别器以`θ_hat`作为其参数进行检测。 同样,判别器最适合以`φ`作为参数来检测伪造的验证码。
具有鞍点的最简单功能是`x^2 - y^2`,鞍点是原点:`(0,0)`
# 优化 GAN 损
# 优化 GAN 损
在上一节中,我们已经看到,生成器和别器相对于它们各自网络的参数的最佳状态由以下公式给出:
在上一节中,我们已经看到,生成器和别器相对于它们各自网络的参数的最佳状态由以下公式给出:
![](img/ddf54bf8-41b6-4210-92af-e3c4f8ac7d3f.png)
为了最大化目标函数,我们通常使用梯度上升,而为了最小化成本函数,我们使用梯度下降。 前面的优化问题可以分为两部分:生成器和鉴别器分别通过梯度上升和梯度下降依次优化效用函数。 在优化过程中的任何步骤`t`上,鉴别器都将通过使实用程序最小化来尝试移至新状态,如下所示:
为了最大化目标函数,我们通常使用梯度上升,而为了最小化成本函数,我们使用梯度下降。 前面的优化问题可以分为两部分:生成器和判别器分别通过梯度上升和梯度下降依次优化效用函数。 在优化过程中的任何步骤`t`上,判别器都将通过使实用程序最小化来尝试移至新状态,如下所示:
![](img/c113c328-2c94-47ed-80d2-1f63f3820b12.png)
......@@ -430,7 +430,7 @@ SVHN 是一个现实世界的数据集,由于它在对象识别算法中的使
![](img/d4b20efa-241b-4aca-8cf3-0c463b81b967.png)
我们已经将生成器和鉴别器优化目标都转换为最小化问题。 鉴别器和生成器的优化都是使用梯度下降进行的,直到我们达到目标函数的鞍点。
我们已经将生成器和判别器优化目标都转换为最小化问题。 判别器和生成器的优化都是使用梯度下降进行的,直到我们达到目标函数的鞍点。
# 生成器网络
......@@ -470,11 +470,11 @@ def generator(input_dim,alpha=0.2):
图 10.5:生成器组网络图
# 别器网络
# 别器网络
别器将是一个经典的二元分类卷积神经网络,可以将生成器图像分类为伪图像,将实际 SVHN 数据集图像分类为真实图像。
别器将是一个经典的二元分类卷积神经网络,可以将生成器图像分类为伪图像,将实际 SVHN 数据集图像分类为真实图像。
别器网络可以编码如下:
别器网络可以编码如下:
```py
def discriminator(img_dim,alpha=0.2):
......@@ -497,27 +497,27 @@ def discriminator(img_dim,alpha=0.2):
return model
```
在上一个代码块中定义的别器网络将伪造的生成器图像和真实的 SVHN 图像作为输入,并将它们传递到最终输出层之前的`3` 2D 卷积集。 在该网络中的卷积之后没有合并,而是通过批量规范化和`LeakyReLU`激活。
在上一个代码块中定义的别器网络将伪造的生成器图像和真实的 SVHN 图像作为输入,并将它们传递到最终输出层之前的`3` 2D 卷积集。 在该网络中的卷积之后没有合并,而是通过批量规范化和`LeakyReLU`激活。
下图显示了别器的网络架构(“图 10.6”):
下图显示了别器的网络架构(“图 10.6”):
![](img/d9f295fb-a738-4f31-9381-013e88de5d27.png)
图 10.6:别器网络图
图 10.6:别器网络图
别器的输出激活函数为 S 形。 这有助于对来自真实 SVHN 图像的伪生成图像进行二进制分类。
别器的输出激活函数为 S 形。 这有助于对来自真实 SVHN 图像的伪生成图像进行二进制分类。
# 训练 GAN
为生成对抗网络建立培训流程并非一帆风顺,因为这需要很多技术方面的考虑。 我们定义了以下三个培训网络:
* 带有参数`θ`的生成器网络`g`
* 带有参数`φ`别器网络`d`
* 权重为`θ``φ`的以`g_d`表示的组合生成器别器网络
* 带有参数`φ`别器网络`d`
* 权重为`θ``φ`的以`g_d`表示的组合生成器别器网络
生成器`g`创建`d`别器将评估的伪造图像,并尝试将其标记为伪造。
生成器`g`创建`d`别器将评估的伪造图像,并尝试将其标记为伪造。
`g_d`网络中,`g`生成器创建伪造的图像,然后尝试欺骗`d`鉴别器,使其相信它们是真实的。 鉴别器网络使用二进制交叉熵损失进行编译,并且针对鉴别器参数`φ`优化了损失,而`g_d`网络则针对`g`发生器的参数`θ`进行了编译,以便欺骗判别器。 因此,`g_d`网络损失是与鉴别器将所有伪造图像标记为真实图像有关的二进制交叉熵损失。 在每个小型批量中,基于与`g_d``d`网络相关的损耗的优化来更新生成器和鉴别器权重:
`g_d`网络中,`g`生成器创建伪造的图像,然后尝试欺骗`d`判别器,使其相信它们是真实的。 判别器网络使用二进制交叉熵损失进行编译,并且针对判别器参数`φ`优化了损失,而`g_d`网络则针对`g`发生器的参数`θ`进行了编译,以便欺骗判别器。 因此,`g_d`网络损失是与判别器将所有伪造图像标记为真实图像有关的二进制交叉熵损失。 在每个小型批量中,基于与`g_d``d`网络相关的损耗的优化来更新生成器和判别器权重:
```py
def train(dest_train,outdir,
......@@ -580,7 +580,7 @@ def train(dest_train,outdir,
d.save_weights('discriminator', True)
```
`Adam`优化器用于两个网络的优化。 要注意的一件事是,仅需要对网络`g_d`进行编译,以仅针对发生器`G`的参数来优化损耗。 因此,我们需要禁用网络`g_d`别器`D`的参数训练。
`Adam`优化器用于两个网络的优化。 要注意的一件事是,仅需要对网络`g_d`进行编译,以仅针对发生器`G`的参数来优化损耗。 因此,我们需要禁用网络`g_d`别器`D`的参数训练。
我们可以使用以下功能来禁用或启用对网络参数的学习:
......@@ -635,7 +635,7 @@ def read_data(dest,dir_flag=False):
return X
```
# 调用培训
# 调用训练
可以通过使用以下参数运行`captcha_gan.py`脚本的`train`函数来调用 GAN 的训练:
......@@ -654,15 +654,15 @@ python captcha_gan.py train --dest_train '/home/santanu/Downloads/train_32x32.ma
| `gen_lr` | `0.0001` | 生成器学习率。 |
| `gen_beta1` | `0.5` | `beta_1`是生成器的 Adam 优化器的参数。 |
| `dis_input_dim` | `(32,32,3)` | 辨别真假房屋号码图像的形状。 |
| `dis_lr` | `0.001` | 别器网络的学习率。 |
| `dis_beta1` | `0.5` | `beta_1`是用于别器的 Adam 优化器的参数。 |
| `dis_lr` | `0.001` | 别器网络的学习率。 |
| `dis_beta1` | `0.5` | `beta_1`是用于别器的 Adam 优化器的参数。 |
| `alpha` | `0.2` | 这是`LeakyReLU`激活的泄漏因子。 当`activation`功能的输入为负时,这有助于提供一个梯度(此处为`0.2`)。 它有助于解决垂死的`ReLU`问题。 如果输入小于或等于`0`,则 ReLU 函数的输出相对于其输入的梯度为`0`。 来自较后层的反向传播错误被此`0`乘以,尽管与该`ReLU.` ReLU 相关的神经元死亡,但没有错误传递至较早层。ReLU 已死亡,许多此类死亡`ReLUs`会影响训练 。 `LeakyReLU`通过甚至为负输入值提供小的梯度来克服了这个问题,从而确保训练不会由于缺乏梯度而停止。 |
| `epochs` | `100` | 这是要运行的时期数。 |
| `smooth_coef` | `0.1` | 设计该平滑系数的目的是减少真实样本对别器的损失。 例如,`0.1``smooth_coef`可以将归因于真实图像的损失减少到原始损失的 90%。 这有助于 GAN 更好地融合。 |
| `smooth_coef` | `0.1` | 设计该平滑系数的目的是减少真实样本对别器的损失。 例如,`0.1``smooth_coef`可以将归因于真实图像的损失减少到原始损失的 90%。 这有助于 GAN 更好地融合。 |
使用 GeForce GTX 1070 GPU,用这些参数训练 GAN 大约需要 3.12 小时。 建议读者使用 GPU 进行更快的培训。
# 培训期间验证码的质量
# 训练期间的验证码的质量
现在,让我们研究训练期间各个时期生成的验证码的质量。 以下是历时`5`(请参阅“图 10.7a”),历时`51`(请参阅“图 10.7b”)和历时`100`之后的 CAPTCHA 图像。 “图 10.7c”)。 我们可以看到,随着训练的进行,CAPTCHA 图像的质量有所提高。 以下屏幕快照显示了在第 5 阶段生成的示例验证码的结果:
......@@ -682,7 +682,7 @@ python captcha_gan.py train --dest_train '/home/santanu/Downloads/train_32x32.ma
图 10.7c:在时期 100 生成的示例验证码
# 使用训练有素的生成器来创建供使用的验证码
# 使用训练好的生成器来创建验证码供使用
可以在运行时加载经过训练的 GAN 网络,以生成街景房屋编号(例如 CAPTCHA)以供使用。 `generate_captcha`函数可用于生成供使用的验证码,如下所示:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册