提交 54a0a8eb 编写于 作者: W wizardforcel

2020-12-07 21:41:21

上级 8f3cd22a
......@@ -30,9 +30,9 @@
第 1 章,“生成对抗网络”的介绍始于 GAN 的概念。 读者将学习什么是判别器,什么是生成器以及什么是博弈论。 接下来的几个主题将涵盖生成器的结构,鉴别器的结构,生成器和鉴别器的目标函数,GAN 的训练算法,Kullback-Leibler 和 Jensen-Shannon 发散,GAN 的评估矩阵,GAN 的不同问题, GAN 中梯度消失和爆炸,纳什均衡,批量归一化和正则化的问题。
第 1 章,“生成对抗网络”的介绍始于 GAN 的概念。 读者将学习什么是判别器,什么是生成器以及什么是博弈论。 接下来的几个主题将涵盖生成器的结构,判别器的结构,生成器和判别器的目标函数,GAN 的训练算法,Kullback-Leibler 和 Jensen-Shannon 散度,GAN 的评估矩阵,GAN 的不同问题, GAN 中梯度消失和爆炸,纳什均衡,批量归一化和正则化的问题。
第 2 章, *3D-GAN –使用 GAN 生成形状* 首先简要介绍 3D-GAN 和各种架构细节。 在本章中,我们将训练 3D-GAN 生成真实世界的 3D 形状。 我们编写代码来收集 3D Shapenet 数据集,对其进行清理并使其经过培训。 然后,我们将使用 Keras 深度学习库为 3D-GAN 编写代码。
第 2 章,“3D-GAN – 使用 GAN 生成形状”首先简要介绍 3D-GAN 和各种架构细节。 在本章中,我们将训练 3D-GAN 生成真实世界的 3D 形状。 我们编写代码来收集 3D Shapenet 数据集,对其进行清理并使其经过培训。 然后,我们将使用 Keras 深度学习库为 3D-GAN 编写代码。
第 3 章,“使用条件 GAN 进行人脸老化”,向读者介绍了条件生成对抗网络(cGAN)和 Age-cGAN。 我们将学习数据准备中的不同步骤,例如下载,清理和格式化数据。 我们将使用 IMDb Wiki 图像数据集。 我们将使用 Keras 框架为 Age-cGAN 编写代码。 接下来,我们将在 IMDb Wiki 图像数据集上训练网络。 最后,我们将使用年龄作为条件参数的训练模型来生成图像,而训练后的模型将针对不同年龄的人的脸部生成图像。
......@@ -42,7 +42,7 @@
第 6 章, “StackGAN – 逼真的文本到图像合成”,本章将首先介绍 StackGAN。 数据收集和数据准备是重要的步骤,我们将学习收集数据集,清理数据集并格式化以进行培训的过程。 我们将在 Jupyter 笔记本内的 Keras 中为 StackGAN 编写代码。 接下来,我们将在 CUB 数据集上训练网络。 最后,在完成模型训练后,我们将从文本描述中生成逼真的图像。 我们将讨论 StackGAN 的不同行业应用以及如何在生产中部署它们。
第 7 章, “CycleGAN – 将绘画变成照片”,介绍了如何训练 CycleGAN 将画作变成照片。 我们将首先介绍 CycleGAN,并研究它们的不同应用。 我们将介绍不同的数据收集,数据清理和数据格式化技术。 接下来,我们将编写 CycleGAN 的 Keras 实现,并在 Jupyter 笔记本中获得有关代码的详细说明。 我们将在准备好的数据集上训练 CycleGAN。 我们将测试我们训练有素的模型,以将绘画转换为照片。 最后,我们看一下 CycleGAN 的实际应用。
第 7 章, “CycleGAN – 将绘画变成照片”,介绍了如何训练 CycleGAN 将画作变成照片。 我们将首先介绍 CycleGAN,并研究它们的不同应用。 我们将介绍不同的数据收集,数据清理和数据格式化技术。 接下来,我们将编写 CycleGAN 的 Keras 实现,并在 Jupyter 笔记本中获得有关代码的详细说明。 我们将在准备好的数据集上训练 CycleGAN。 我们将测试我们训练有素的模型,以将绘画转换为照片。 最后,我们看一下 CycleGAN 的实际应用。
第 8 章,“条件 GAN – 使用条件对抗网络进行图像到图像的翻译”,介绍了如何训练条件 GAN 进行图像到图像的翻译。 我们将首先介绍条件 GAN 和不同的数据准备技术,例如数据收集,数据清理和数据格式化。 接下来,我们将在 Jupyter 笔记本的 Keras 中编写条件 GAN 的代码。 接下来,我们学习如何在已经准备好的数据集上训练条件 GAN。 我们将探索不同的超参数进行训练。 最后,我们将测试条件 GAN,并讨论实际应用中图像到图像转换的不同用例。
......@@ -77,9 +77,9 @@
下载文件后,请确保使用以下最新版本解压缩或解压缩文件夹:
* Windows 的 WinRAR / 7-Zip
* Mac 版 Zipeg / iZip / UnRarX
* 适用于 Linux 的 7-Zip / PeaZip
* Windows 的 WinRAR/7-Zip
* Mac 的 Zipeg/iZip/UnRarX
* Linux 的 7-Zip/PeaZip
本书的代码包也托管在 [GitHub](https://github.com/PacktPublishing/Generative-Adversarial-Networks-Projects) 上。 如果代码有更新,它将在现有的 GitHub 存储库中进行更新。
......
此差异已折叠。
......@@ -4,7 +4,7 @@
3D-GAN 是用于 3D 形状生成的 GAN 体系结构。 由于处理 3D 图像涉及复杂性,因此 3D 形状生成通常是一个复杂的问题。 3D-GAN 是一种可以生成逼真的,变化的 3D 形状的解决方案,由吴嘉俊,张成凯,薛天凡等人在题为*的论文中介绍,该文章通过 3D 生成专家模型学习对象形状的概率潜在空间 建模*可以在[这个页面](http://3dgan.csail.mit.edu/papers/3dgan_nips.pdf)上找到该论文。 在本章中,我们将使用 Keras 框架实现 3D-GAN。
3D-GAN 是用于 3D 形状生成的 GAN 体系结构。 由于处理 3D 图像涉及复杂性,因此 3D 形状生成通常是一个复杂的问题。 3D-GAN 是一种可以生成逼真的,变化的 3D 形状的解决方案,由吴嘉俊,张成凯,薛天凡等人在题为《通过 3D 生成对抗建模学习对象形状的概率潜在空间》的论文中介绍,可以在[这个页面](http://3dgan.csail.mit.edu/papers/3dgan_nips.pdf)上找到该论文。 在本章中,我们将使用 Keras 框架实现 3D-GAN。
我们将涵盖以下主题:
......@@ -24,7 +24,7 @@
**3D 生成对抗网络****3D-GAN**)是 GAN 的变体,就像 StackGAN,CycleGAN 和`S`**上层分辨率一样 生成对抗网络****SRGAN**)。 与香草 GAN 相似,它具有生成器和鉴别器模型。 这两个网络都使用 3D 卷积层,而不是使用 2D 卷积。 如果提供足够的数据,它可以学习生成具有良好视觉质量的 3D 形状。
**3D 生成对抗网络****3D-GAN**)是 GAN 的变体,就像 StackGAN,CycleGAN 和`S`**上层分辨率一样 生成对抗网络****SRGAN**)。 与朴素 GAN 相似,它具有生成器和判别器模型。 这两个网络都使用 3D 卷积层,而不是使用 2D 卷积。 如果提供足够的数据,它可以学习生成具有良好视觉质量的 3D 形状。
在仔细查看 3D-GAN 网络之前,让我们了解 3D 卷积。
......@@ -50,9 +50,9 @@
3D-GAN 中的两个网络都是深度卷积神经网络。 发电机网络通常是一个上采样网络。 它对噪声向量(来自概率潜在空间的向量)进行上采样,以生成形状为的 3D 图像,该形状的长度,宽度,高度和通道与输入图像相似。 别器网络是下采样网络。 使用一系列 3D 卷积运算和密集层,它可以识别提供给它的输入数据是真实的还是伪造的。
3D-GAN 中的两个网络都是深度卷积神经网络。 发电机网络通常是一个上采样网络。 它对噪声向量(来自概率潜在空间的向量)进行上采样,以生成形状为的 3D 图像,该形状的长度,宽度,高度和通道与输入图像相似。 别器网络是下采样网络。 使用一系列 3D 卷积运算和密集层,它可以识别提供给它的输入数据是真实的还是伪造的。
在接下来的两节中,我们将介绍生成器和别器网络的体系结构。
在接下来的两节中,我们将介绍生成器和别器网络的体系结构。
......@@ -90,11 +90,11 @@ A fully convolutional network is a network without fully connected dense layers
# 别器网络的架构
# 别器网络的架构
别器网络包含五个具有以下配置的体积卷积层:
别器网络包含五个具有以下配置的体积卷积层:
* **3D 卷积层**:5
* **通道**:64、128、256、512、1
......@@ -110,11 +110,11 @@ A fully convolutional network is a network without fully connected dense layers
* **输入**:形状为(64,64,64)的 3D 图像
* **输出**:输入数据属于真实或假类的概率
下图显示了鉴别器网络中每一层的张量流以及张量的输入和输出形状。 这将使您对鉴别器网络有更好的了解:
下图显示了判别器网络中每一层的张量流以及张量的输入和输出形状。 这将使您对判别器网络有更好的了解:
![](img/7fc08303-569e-499f-bc91-e2ae9684f947.png)
别器网络主要镜像生成器网络。 一个重要的区别是它使用中的 LeakyReLU 代替了 ReLU 作为激活功能。 而且,网络末端的 S 形层用于二进制分类,并预测所提供的图像是真实的还是伪造的。 最后一层没有规范化层,但是其他层使用批处理规范化输入。
别器网络主要镜像生成器网络。 一个重要的区别是它使用中的 LeakyReLU 代替了 ReLU 作为激活功能。 而且,网络末端的 S 形层用于二进制分类,并预测所提供的图像是真实的还是伪造的。 最后一层没有规范化层,但是其他层使用批处理规范化输入。
......@@ -128,7 +128,7 @@ A fully convolutional network is a network without fully connected dense layers
![](img/e8c1a187-a93a-40e6-92a9-3c823a391fd9.png)
在这里, *log(D(x))*是二进制交叉熵损失或分类损失, *log(1-D(G(z)))*是对抗损失,`z`是来自概率空间 *p(z)*的潜向量, *D(x)*别器网络的输出, *G(z)* 是发电机网络的输出。
在这里, *log(D(x))*是二进制交叉熵损失或分类损失, *log(1-D(G(z)))*是对抗损失,`z`是来自概率空间 *p(z)*的潜向量, *D(x)*别器网络的输出, *G(z)* 是发电机网络的输出。
......@@ -138,12 +138,12 @@ A fully convolutional network is a network without fully connected dense layers
训练 3D-GAN 类似于训练香草 GAN。 训练 3D-GAN 涉及的步骤如下:
训练 3D-GAN 类似于训练朴素 GAN。 训练 3D-GAN 涉及的步骤如下:
1. 从高斯(正态)分布中采样 200 维噪声向量。
2. 使用生成器模型生成伪图像。
3. 在真实图像(从真实数据中采样)和生成器网络生成的伪图像上训练生成器网络。
4. 使用对抗模型训练生成器模型。 不要训练别器模型。
4. 使用对抗模型训练生成器模型。 不要训练别器模型。
5. 对指定的时期数重复这些步骤。
我们将在后面的部分中详细探讨这些步骤。 让我们继续建立一个项目。
......@@ -341,7 +341,7 @@ plt.show() plt.savefig(file_path)
在本节中,我们将在 Keras 框架中实现生成器网络和别器网络。 我们需要创建两个 Keras 模型。 这两个网络都有各自独立的权重值。 让我们从发电机网络开始。
在本节中,我们将在 Keras 框架中实现生成器网络和别器网络。 我们需要创建两个 Keras 模型。 这两个网络都有各自独立的权重值。 让我们从发电机网络开始。
......@@ -432,7 +432,7 @@ def build_generator():
return gen_model
```
我们已经成功地为发电机网络创建了 Keras 模型。 接下来,为别器网络创建 Keras 模型。
我们已经成功地为发电机网络创建了 Keras 模型。 接下来,为别器网络创建 Keras 模型。
......@@ -442,7 +442,7 @@ def build_generator():
同样,要实现区分器网络,我们需要创建 Keras 模型并向其中添加神经网络层。 实施别器网络所需的步骤如下:
同样,要实现区分器网络,我们需要创建 Keras 模型并向其中添加神经网络层。 实施别器网络所需的步骤如下:
1. 首先为不同的超参数指定值:
......@@ -457,7 +457,7 @@ dis_activations = ['leaky_relu', 'leaky_relu', 'leaky_relu', 'leaky_relu', 'sigm
dis_convolutional_blocks = 5
```
2. 接下来,创建一个输入层,以允许网络进行输入。 别器网络的输入是形状为 `64x64x64x1`的 3D 图像:
2. 接下来,创建一个输入层,以允许网络进行输入。 别器网络的输入是形状为 `64x64x64x1`的 3D 图像:
```py
dis_input_layer = Input(shape=dis_input_shape)
......@@ -489,13 +489,13 @@ a = LeakyReLU(alphas[0])(a)
a = Activation(activation='sigmoid')(a)
```
5. 接下来,创建一个 Keras 模型,并为别器网络指定输入和输出:
5. 接下来,创建一个 Keras 模型,并为别器网络指定输入和输出:
```py
dis_model = Model(inputs=dis_input_layer, outputs=a)
```
6.别器网络的完整代码包装在一个函数中,如下所示:
6.别器网络的完整代码包装在一个函数中,如下所示:
```py
def build_discriminator():
......@@ -536,7 +536,7 @@ def build_discriminator():
return dis_model
```
在本节中,我们为别器网络创建了 Keras 模型。 我们现在准备训练 3D-GAN。
在本节中,我们为别器网络创建了 Keras 模型。 我们现在准备训练 3D-GAN。
......@@ -546,7 +546,7 @@ def build_discriminator():
训练 3D-GAN 类似于训练香草 GAN。 我们首先在生成的图像和真实图像上训练鉴别器网络,但是冻结生成器网络。 然后,我们训练生成器网络,但冻结区分器网络。 我们对指定的时期数重复此过程。 在一次迭代中,我们按顺序训练两个网络。 训练 3D-GAN 是一个端到端的训练过程。 让我们一步一步地进行这些步骤。
训练 3D-GAN 类似于训练朴素 GAN。 我们首先在生成的图像和真实图像上训练判别器网络,但是冻结生成器网络。 然后,我们训练生成器网络,但冻结区分器网络。 我们对指定的时期数重复此过程。 在一次迭代中,我们按顺序训练两个网络。 训练 3D-GAN 是一个端到端的训练过程。 让我们一步一步地进行这些步骤。
......@@ -657,7 +657,7 @@ volumes_batch = volumes[index * batch_size:(index + 1) * batch_size,
gen_volumes = generator.predict(z_sample,verbose=3)
```
10. 接下来,在由生成器生成的伪图像和一组真实图像中的一批真实图像上训练鉴别器网络。 另外,使鉴别器易于训练:
10. 接下来,在由生成器生成的伪图像和一组真实图像中的一批真实图像上训练判别器网络。 另外,使判别器易于训练:
```py
# Make the discriminator network trainable discriminator.trainable = True
......@@ -676,7 +676,7 @@ loss_fake = discriminator.train_on_batch(gen_volumes,
d_loss = 0.5 * (loss_real + loss_fake)
```
前面的代码训练了鉴别器网络并计算了总的鉴别器损耗。
前面的代码训练了判别器网络并计算了总的判别器损耗。
11. 训练同时包含`generator``discriminator`网络的对抗模型:
......@@ -722,7 +722,7 @@ My advice is to train it for 100 epochs to find the problems in the code. Once y
训练完成后,通过添加以下代码来保存生成器和别器模型的学习权重:
训练完成后,通过添加以下代码来保存生成器和别器模型的学习权重:
```py
""" Save models """ generator.save_weights(os.path.join(generated_volumes_dir, "generator_weights.h5"))
......@@ -803,7 +803,7 @@ TensorBoard 的 GRAPHS 部分包含两个网络的图形 。 如果网络性能
* **批次大小**:尝试使用 8、16、32、54 或 128 的批次大小值。
* **时期数**:尝试 100 个时期,并将其逐渐增加到 1,000-5,000。
* **学习率**:这是最重要的超参数。 用 0.1、0.001、0.0001 和其他较小的学习率进行实验。
* **发生器和别器网络**的不同层中的激活功能:使用 S 型,tanh,ReLU,LeakyReLU,ELU,SeLU 和其他激活功能进行实验。
* **发生器和别器网络**的不同层中的激活功能:使用 S 型,tanh,ReLU,LeakyReLU,ELU,SeLU 和其他激活功能进行实验。
* **优化算法**:尝试使用 Adam,SGD,Adadelta,RMSProp 和 Keras 框架中可用的其他优化器。
* **损失函数**:二进制交叉熵是最适合 3D-GAN 的损失函数。
* **两个网络中的层数**:根据可用的训练数据量,在网络中尝试不同的层数。 如果您有足够的可用数据来进行训练,则可以使网络更深。
......@@ -834,7 +834,7 @@ TensorBoard 的 GRAPHS 部分包含两个网络的图形 。 如果网络性能
在本章中,我们探讨了 3D-GAN。 我们首先介绍了 3D-GAN,并介绍了架构以及生成器和别器的配置。 然后,我们经历了建立项目所需的不同步骤。 我们还研究了如何准备数据集。 最后,我们在 Keras 框架中实现了 3D-GAN,并在我们的数据集中对其进行了训练。 我们还探讨了不同的超参数选项。 我们通过探索 3D-GAN 的实际应用来结束本章。
在本章中,我们探讨了 3D-GAN。 我们首先介绍了 3D-GAN,并介绍了架构以及生成器和别器的配置。 然后,我们经历了建立项目所需的不同步骤。 我们还研究了如何准备数据集。 最后,我们在 Keras 框架中实现了 3D-GAN,并在我们的数据集中对其进行了训练。 我们还探讨了不同的超参数选项。 我们通过探索 3D-GAN 的实际应用来结束本章。
在下一章中,我们将学习如何使用**条件生成对抗网络(** cGAN **)执行面部老化。**
......
......@@ -4,11 +4,11 @@
**条件 GAN****cGAN**)是 GAN 模型的扩展。 它们允许生成具有特定条件或属性的图像,因此被证明比香草 GAN 更好。 在本章中,我们将实现一个 cGAN,该 cGAN 一旦经过培训,就可以执行自动面部老化。 Grigory Antipov,Moez Baccouche 和 Jean-Luc Dugelay 在其名为 *有条件生成对抗网络* 的人脸衰老的论文中,首先介绍了我们将要实现的 cGAN 网络。 [可以在以下链接中找到](https://arxiv.org/pdf/1702.01983.pdf)
**条件 GAN****cGAN**)是 GAN 模型的扩展。 它们允许生成具有特定条件或属性的图像,因此被证明比朴素 GAN 更好。 在本章中,我们将实现一个 cGAN,该 cGAN 一旦经过培训,就可以执行自动面部老化。 Grigory Antipov,Moez Baccouche 和 Jean-Luc Dugelay 在其名为 *有条件生成对抗网络* 的人脸衰老的论文中,首先介绍了我们将要实现的 cGAN 网络。 [可以在以下链接中找到](https://arxiv.org/pdf/1702.01983.pdf)
在本章中,我们将介绍以下主题:
* 介绍用于面部衰老的 cGAN
* 介绍用于面部老化的 cGAN
* 设置项目
* 准备数据
* cGAN 的 Keras 实现
......@@ -20,11 +20,11 @@
# 介绍用于面部衰老的 cGAN
# 介绍用于面部老化的 cGAN
到目前为止,我们已经针对不同的用例实现了不同的 GAN 网络。 条件 GAN 扩展了普通 GAN 的概念,并允许我们控制发电机网络的输出。 面部衰老就是在不更改身份的情况下更改一个人的面部年龄。 在大多数其他模型(包括 GAN)中,由于不考虑面部表情和面部配件(例如太阳镜或胡须),因此会使人的外观或身份损失 50%。 Age-cGAN 会考虑所有这些属性。 在本节中,我们将探索用于面部衰老的 cGAN。
到目前为止,我们已经针对不同的用例实现了不同的 GAN 网络。 条件 GAN 扩展了普通 GAN 的概念,并允许我们控制发电机网络的输出。 面部老化就是在不更改身份的情况下更改一个人的面部年龄。 在大多数其他模型(包括 GAN)中,由于不考虑面部表情和面部配件(例如太阳镜或胡须),因此会使人的外观或身份损失 50%。 Age-cGAN 会考虑所有这些属性。 在本节中,我们将探索用于面部老化的 cGAN。
......@@ -34,7 +34,7 @@
cGAN 是 GAN 的一种,它取决于一些额外的信息。 我们将额外的`y`信息作为额外的输入层提供给生成器。 在香草 GAN 中,无法控制所生成图像的类别。 当我们向生成器添加条件`y`时,我们可以使用`y`生成特定类别的图像,该图像可以是任何类型的数据,例如类标签或整数数据 。 Vanilla GAN 只能学习一个类别,而为多个类别构造 GAN 则非常困难。 但是,可以使用 cGAN 生成针对不同类别具有不同条件的多模式模型。
cGAN 是 GAN 的一种,它取决于一些额外的信息。 我们将额外的`y`信息作为额外的输入层提供给生成器。 在朴素 GAN 中,无法控制所生成图像的类别。 当我们向生成器添加条件`y`时,我们可以使用`y`生成特定类别的图像,该图像可以是任何类型的数据,例如类标签或整数数据 。 Vanilla GAN 只能学习一个类别,而为多个类别构造 GAN 则非常困难。 但是,可以使用 cGAN 生成针对不同类别具有不同条件的多模式模型。
下图显示了 cGAN 的体系结构:
......@@ -44,7 +44,7 @@ cGAN 的训练目标函数可以表示为:
![](img/115b5d5f-6623-46dc-bed1-e99a6aa5910c.png)
此处,`G`是生成器网络,`D`鉴别器网络。 鉴别器 的损失为![](img/78a30b0f-14dc-4d20-ac13-5f3a30bc78d7.png), 发生器的损失为![](img/e81d7c4b-bd30-4887-9e84-303e9cea0a89.png)。 我们可以说 *G(z | y)*在给定 * z **和*。 在此,`z`是从正态分布得出的尺寸为 100 的先验噪声分布。
此处,`G`是生成器网络,`D`判别器网络。 判别器 的损失为![](img/78a30b0f-14dc-4d20-ac13-5f3a30bc78d7.png), 发生器的损失为![](img/e81d7c4b-bd30-4887-9e84-303e9cea0a89.png)。 我们可以说 *G(z | y)*在给定 * z **和*。 在此,`z`是从正态分布得出的尺寸为 100 的先验噪声分布。
......@@ -54,7 +54,7 @@ cGAN 的训练目标函数可以表示为:
用于面部老化的 cGAN 的架构稍微复杂一些。 Age- cGan 由四个网络组成:编码器,FaceNet,生成器网络和鉴别器网络。 使用编码器,我们可以利用潜在的向量![](img/577645cb-a80b-4a10-98e8-5cf21f336b77.png)来学习输入面部图像和年龄条件的逆映射。 FaceNet 是面部识别网络,用于学习输入图像`x`与重构的图像![](img/a77a78e0-3ea2-4ce3-8f96-deca552c9b9f.png)之间的差异。 我们有一个生成器网络,该网络使用由人脸图像和条件向量组成的隐藏表示并生成图像。 鉴别器网络将区分真实图像和伪图像。
用于面部老化的 cGAN 的架构稍微复杂一些。 Age- cGan 由四个网络组成:编码器,FaceNet,生成器网络和判别器网络。 使用编码器,我们可以利用潜在的向量![](img/577645cb-a80b-4a10-98e8-5cf21f336b77.png)来学习输入面部图像和年龄条件的逆映射。 FaceNet 是面部识别网络,用于学习输入图像`x`与重构的图像![](img/a77a78e0-3ea2-4ce3-8f96-deca552c9b9f.png)之间的差异。 我们有一个生成器网络,该网络使用由人脸图像和条件向量组成的隐藏表示并生成图像。 判别器网络将区分真实图像和伪图像。
cGAN 的问题在于它们无法学习将属性`y`的 输入图像`x`逆映射到潜向量*的任务 ] z* *。* 解决此问题的方法是使用编码器网络。 我们可以训练一个编码器网络来近似输入图像`x`的逆映射。 在本节中,我们将探讨 Age-cGAN 涉及的网络。
......@@ -86,7 +86,7 @@ cGAN 的问题在于它们无法学习将属性`y`的 输入图像`x`逆映射
鉴别器网络的主要目标是识别所提供的图像是伪造的还是真实的。 它通过使图像经过一系列下采样层和一些分类层来实现。 换句话说,它可以预测图像是真实的还是伪造的。 像其他网络一样,鉴别器网络是另一个深度卷积网络。 它包含几个卷积块。 每个卷积块都包含一个卷积层,一个批处理归一化层和一个激活函数,除了第一个卷积块之外,它没有批处理归一化层。 区分网络的配置将在 Age-cGAN 部分的 *Keras 实现中进行介绍。*
判别器网络的主要目标是识别所提供的图像是伪造的还是真实的。 它通过使图像经过一系列下采样层和一些分类层来实现。 换句话说,它可以预测图像是真实的还是伪造的。 像其他网络一样,判别器网络是另一个深度卷积网络。 它包含几个卷积块。 每个卷积块都包含一个卷积层,一个批处理归一化层和一个激活函数,除了第一个卷积块之外,它没有批处理归一化层。 区分网络的配置将在 Age-cGAN 部分的 *Keras 实现中进行介绍。*
......@@ -108,7 +108,7 @@ cGAN 的问题在于它们无法学习将属性`y`的 输入图像`x`逆映射
Age-cGAN 具有多个培训阶段。 如上一节所述,Age-cGAN 具有四个网络,并经过三个阶段的培训。 Age-cGAN 的训练包括三个阶段:
1. **有条件的 GAN 训练:**在此阶段,我们训练生成器网络和别器网络。
1. **有条件的 GAN 训练:**在此阶段,我们训练生成器网络和别器网络。
2. **初始潜在向量逼近:**在此阶段,我们训练编码器网络。
3. **潜向量优化:**在此阶段,我们同时优化编码器和发电机网络。
......@@ -128,7 +128,7 @@ Stages in the Age-cGANSource: Face Aging with Conditional Generative Adversarial
在这个阶段,我们训练生成器网络和鉴别器网络。 经过训练后,生成器网络可以生成面部的模糊图像。 此阶段类似于训练香草 GAN,其中我们同时训练两个网络。
在这个阶段,我们训练生成器网络和判别器网络。 经过训练后,生成器网络可以生成面部的模糊图像。 此阶段类似于训练朴素 GAN,其中我们同时训练两个网络。
......@@ -142,7 +142,7 @@ Stages in the Age-cGANSource: Face Aging with Conditional Generative Adversarial
![](img/0e7b1187-382e-4584-9c8b-b39c1db1fd91.png)
训练 cGAN 网络涉及优化, 功能, ![](img/e08d1823-e871-40dc-b01f-d924c155a813.png)。 训练 cGAN 可以看作是 minimax 游戏,其中同时对生成器和鉴别器进行训练。 在上式中, ![](img/7ce6d943-ee01-4777-b805-c300627ec0ec.png)代表发电机网络的参数,![](img/2e9c2935-f734-48ee-afae-ee24ccfa0b0a.png) 代表`G``D`的 参数 , ![](img/6923fbb8-a6ef-4c14-ab83-c8586f272630.png)是鉴别器模型的损失,![](img/869b6fae-e95a-4138-9df9-033a8e157e49.png)是 对于生成器模型的损失, ![](img/17a59550-253c-4e61-b15e-637119f829ca.png)是分布 所有可能的图像。
训练 cGAN 网络涉及优化, 功能, ![](img/e08d1823-e871-40dc-b01f-d924c155a813.png)。 训练 cGAN 可以看作是 minimax 游戏,其中同时对生成器和判别器进行训练。 在上式中, ![](img/7ce6d943-ee01-4777-b805-c300627ec0ec.png)代表发电机网络的参数,![](img/2e9c2935-f734-48ee-afae-ee24ccfa0b0a.png) 代表`G``D`的 参数 , ![](img/6923fbb8-a6ef-4c14-ab83-c8586f272630.png)是判别器模型的损失,![](img/869b6fae-e95a-4138-9df9-033a8e157e49.png)是 对于生成器模型的损失, ![](img/17a59550-253c-4e61-b15e-637119f829ca.png)是分布 所有可能的图像。
......@@ -320,7 +320,7 @@ def calculate_age(taken, dob):
像普通 GAN 一样,cGAN 的实现非常简单。 Keras 提供了足够的灵活性来编码复杂的生成对抗网络。 在本节中,我们将实现 cGAN 中使用的生成器网络,别器网络和编码器网络。 让我们从实现编码器网络开始。
像普通 GAN 一样,cGAN 的实现非常简单。 Keras 提供了足够的灵活性来编码复杂的生成对抗网络。 在本节中,我们将实现 cGAN 中使用的生成器网络,别器网络和编码器网络。 让我们从实现编码器网络开始。
在开始编写实现之前,创建一个名为 `main.py` 的 Python 文件,并导入基本模块,如下所示:
......@@ -617,7 +617,7 @@ def build_generator():
return model
```
现在,我们已经成功创建了发电机网络。 接下来,我们将为别器网络编写代码。
现在,我们已经成功创建了发电机网络。 接下来,我们将为别器网络编写代码。
......@@ -627,11 +627,11 @@ def build_generator():
鉴别器网络是 CNN。 让我们在 Keras 框架中实现鉴别器网络。
判别器网络是 CNN。 让我们在 Keras 框架中实现判别器网络。
执行以下步骤以实现别器网络:
执行以下步骤以实现别器网络:
1. 首先创建两个输入层,因为我们的别器网络将处理两个输入:
1. 首先创建两个输入层,因为我们的别器网络将处理两个输入:
```py
# Specify hyperparameters
......@@ -720,13 +720,13 @@ x = Flatten()(x)
x = Dense(1, activation='sigmoid')(x)
```
9. 最后,创建 Keras 模型并指定别器网络的输入和输出:
9. 最后,创建 Keras 模型并指定别器网络的输入和输出:
```py
model = Model(inputs=[image_input, label_input], outputs=[x])
```
别器网络的整个代码如下:
别器网络的整个代码如下:
```py
def build_discriminator():
......@@ -762,7 +762,7 @@ def build_discriminator():
return model
```
现在,我们已经成功创建了编码器,生成器和别器网络。 在下一部分中,我们将组装所有内容并训练网络。
现在,我们已经成功创建了编码器,生成器和别器网络。 在下一部分中,我们将组装所有内容并训练网络。
......@@ -788,7 +788,7 @@ def build_discriminator():
这是培训过程的第一步。 在这一步中,我们训练生成器和别器网络。 执行以下步骤:
这是培训过程的第一步。 在这一步中,我们训练生成器和别器网络。 执行以下步骤:
1. 首先指定培训所需的参数:
......@@ -814,7 +814,7 @@ adversarial_optimizer = Adam(lr=0.0002, beta_1=0.5, beta_2=0.999, epsilon=10e-8)
对于所有优化程序,请使用等于`0.0002`的学习速率,等于`0.5``beta_1`值,等于`0.999``beta_2`值以及等于`10e-8`的 epsilon 值。
3. 接下来,加载并编译生成器和别器网络。 在 Keras 中,我们必须在训练网络之前编译网络:
3. 接下来,加载并编译生成器和别器网络。 在 Keras 中,我们必须在训练网络之前编译网络:
```py
# Build and compile the discriminator network discriminator = build_discriminator()
......@@ -1026,16 +1026,16 @@ for epoch in range(epochs):
生成器网络有两个输入`z_noise``y_batch`,它们是我们在步骤 11 和 12 中创建的。
14. 现在,在真实图像和伪图像上训练别器网络:
14. 现在,在真实图像和伪图像上训练别器网络:
```py
d_loss_real = discriminator.train_on_batch([images_batch, y_batch], real_labels)
d_loss_fake = discriminator.train_on_batch([initial_recon_images, y_batch], fake_labels)
```
此代码应在一批图像上训练别器网络。 在每个步骤中,将对一批样本进行鉴别。
此代码应在一批图像上训练别器网络。 在每个步骤中,将对一批样本进行鉴别。
15. 接下来,训练对抗网络。 通过冻结别器网络,我们将仅训练生成器网络:
15. 接下来,训练对抗网络。 通过冻结别器网络,我们将仅训练生成器网络:
```py
# Again sample a batch of noise vectors from a Gaussian(normal) distribution
......@@ -1115,7 +1115,7 @@ generator.save("generator.h5)
discriminator.save("discriminator.h5")
```
如果您已成功执行本节中给出的代码,则说明您已成功训练了生成器和别器网络。 在此步骤之后,生成器网络将开始生成模糊的面部图像。 在下一部分中,我们将训练编码器模型以进行初始潜在向量近似。
如果您已成功执行本节中给出的代码,则说明您已成功训练了生成器和别器网络。 在此步骤之后,生成器网络将开始生成模糊的面部图像。 在下一部分中,我们将训练编码器模型以进行初始潜在向量近似。
......@@ -1224,7 +1224,7 @@ encoder.save_weights("encoder.h5")
在前面的两个步骤中,我们成功地训练了生成器网络,别器网络和编码器网络。 在本节中,我们将改进编码器和发电机网络。 在这些步骤中,我们将使用**人脸识别****FR**)网络,该网络会生成输入给它的特定输入的 128 维嵌入,以改善生成器和编码器 网络。
在前面的两个步骤中,我们成功地训练了生成器网络,别器网络和编码器网络。 在本节中,我们将改进编码器和发电机网络。 在这些步骤中,我们将使用**人脸识别****FR**)网络,该网络会生成输入给它的特定输入的 128 维嵌入,以改善生成器和编码器 网络。
执行以下步骤:
......@@ -1338,7 +1338,7 @@ for epoch in range(epochs):
encoder.save_weights("encoder_optimized.h5")
```
恭喜你! 我们现在已经成功地训练了 Age-cGAN 进行面部衰老
恭喜你! 我们现在已经成功地训练了 Age-cGAN 进行面部老化
......
......@@ -26,9 +26,9 @@
CNN 在计算机视觉任务中非常出色,无论是用于分类图像还是检测图像中的对象。 CNN 善于理解图像,以至于激发研究人员在 GAN 网络中使用 CNN。 最初,GAN 官方论文的作者介绍了仅具有密集层的**深层神经网络****DNN**)。 在 GAN 网络的原始实现中未使用卷积层。 在以前的 GAN 中,生成器和别器网络仅使用密集的隐藏层。 相反,作者建议在 GAN 设置中可以使用不同的神经网络体系结构。
CNN 在计算机视觉任务中非常出色,无论是用于分类图像还是检测图像中的对象。 CNN 善于理解图像,以至于激发研究人员在 GAN 网络中使用 CNN。 最初,GAN 官方论文的作者介绍了仅具有密集层的**深层神经网络****DNN**)。 在 GAN 网络的原始实现中未使用卷积层。 在以前的 GAN 中,生成器和别器网络仅使用密集的隐藏层。 相反,作者建议在 GAN 设置中可以使用不同的神经网络体系结构。
DCGAN 扩展了在鉴别器和生成器网络中使用卷积层的思想。 DCGAN 的设置类似于香草 GAN。 它由两个网络组成:生成器和鉴别器。 生成器是具有卷积层的 DNN,而鉴别器是具有卷积层的 DNN。 训练 DCGAN 类似于训练普通 GAN 网络。 在第一章中,我们了解到网络参与了非合作博弈,其中鉴别器网络将其错误反向传播到生成器网络,生成器网络使用此错误来提高其权重。
DCGAN 扩展了在判别器和生成器网络中使用卷积层的思想。 DCGAN 的设置类似于朴素 GAN。 它由两个网络组成:生成器和判别器。 生成器是具有卷积层的 DNN,而判别器是具有卷积层的 DNN。 训练 DCGAN 类似于训练普通 GAN 网络。 在第一章中,我们了解到网络参与了非合作博弈,其中判别器网络将其错误反向传播到生成器网络,生成器网络使用此错误来提高其权重。
在下一部分中,我们将探索两个网络的体系结构。
......@@ -40,7 +40,7 @@ DCGAN 扩展了在鉴别器和生成器网络中使用卷积层的思想。 DCGA
如前所述,DCGAN 网络在两个网络中都使用卷积层。 重申一下,CNN 是一个具有卷积层,紧随其后的归一化或池化层以及紧随其后的激活功能的网络。 在 DCGAN 中,别器网络会拍摄图像,在卷积和池化层的帮助下对图像进行降采样,然后使用密集的分类层将图像分类为真实图像或伪图像。 生成器网络从潜在空间中获取随机噪声向量,使用上采样机制对其进行上采样,最后生成图像。 我们使用 Leaky ReLU 作为隐藏层的激活函数,并在 0.4 和 0.7 之间进行滤除以避免过拟合。
如前所述,DCGAN 网络在两个网络中都使用卷积层。 重申一下,CNN 是一个具有卷积层,紧随其后的归一化或池化层以及紧随其后的激活功能的网络。 在 DCGAN 中,别器网络会拍摄图像,在卷积和池化层的帮助下对图像进行降采样,然后使用密集的分类层将图像分类为真实图像或伪图像。 生成器网络从潜在空间中获取随机噪声向量,使用上采样机制对其进行上采样,最后生成图像。 我们使用 Leaky ReLU 作为隐藏层的激活函数,并在 0.4 和 0.7 之间进行滤除以避免过拟合。
让我们看一下两个网络的配置。
......@@ -84,19 +84,19 @@ This configuration is valid for Keras APIs with the TensorFlow backend and the `
# 配置别器网络
# 配置别器网络
在继续之前,让我们看一下别器网络的架构:
在继续之前,让我们看一下别器网络的架构:
![](img/0bbb9055-1c43-4f7d-a900-fdf515b6d068.png)
上图给出了发电机网络架构的顶层概述。
如前所述,鉴别器网络是一个包含 10 层的 CNN(您可以根据需要向网络添加更多层)。 基本上,它会拍摄尺寸为 64 x 64 x 3 的图像,使用 2D 卷积层对其进行下采样,然后将其传递到完全连接的层进行分类。 它的输出是对给定图像是伪图像还是真实图像的预测。 可以为 0 或 1;可以为 0。 如果输出为 1,则传递到鉴别器的图像是真实的;如果输出为 0,则传递的图像是伪图像。
如前所述,判别器网络是一个包含 10 层的 CNN(您可以根据需要向网络添加更多层)。 基本上,它会拍摄尺寸为 64 x 64 x 3 的图像,使用 2D 卷积层对其进行下采样,然后将其传递到完全连接的层进行分类。 它的输出是对给定图像是伪图像还是真实图像的预测。 可以为 0 或 1;可以为 0。 如果输出为 1,则传递到判别器的图像是真实的;如果输出为 0,则传递的图像是伪图像。
让我们看一下别器网络中的各层:
让我们看一下别器网络中的各层:
| **层#** | **图层名称** | **配置** |
| 1. | 输入层 | `input_shape=(batch_size, 64, 64, 3)``output_shape=(batch_size, 64, 64, 3)` |
......@@ -347,7 +347,7 @@ total_num_faces = 0 for index, filename in enumerate(glob.glob('/path/to/direc
print("Total number of faces:{}".format(total_num_faces))
```
前面的脚本将从包含下载图像的文件夹中加载所有图像,使用`python-animeface`库检测脸部,然后**从初始图像中裁剪出**脸部。 然后,裁切后的图像将被调整为 64 x 64 的尺寸。如果要更改图像的尺寸,请相应地更改生成器和别器的体系结构。 我们现在准备在我们的网络上工作。
前面的脚本将从包含下载图像的文件夹中加载所有图像,使用`python-animeface`库检测脸部,然后**从初始图像中裁剪出**脸部。 然后,裁切后的图像将被调整为 64 x 64 的尺寸。如果要更改图像的尺寸,请相应地更改生成器和别器的体系结构。 我们现在准备在我们的网络上工作。
......@@ -475,17 +475,17 @@ def get_generator():
return gen_model
```
现在我们已经创建了生成器网络,让我们开始创建别器网络。
现在我们已经创建了生成器网络,让我们开始创建别器网络。
# 别器
# 别器
如 DCGAN 的*体系结构中所述,鉴别器网络具有三个 2D 卷积层,每个层均具有激活函数,后跟两个最大合并层。 网络的尾部包含两个完全连接的(密集)层,用作分类层。 首先,让我们看一下鉴别器网络中的不同层:*
如 DCGAN 的*体系结构中所述,判别器网络具有三个 2D 卷积层,每个层均具有激活函数,后跟两个最大合并层。 网络的尾部包含两个完全连接的(密集)层,用作分类层。 首先,让我们看一下判别器网络中的不同层:*
* 所有卷积层都具有`LeakyReLU`作为激活函数,其 alpha 值为 0.2
* 卷积层分别具有 128、256 和 512 个滤波器。 它们的内核大小分别为(5、5),(3、3)和(3、3)。
......@@ -493,7 +493,7 @@ def get_generator():
* 此后,网络具有两个密集层,分别具有 1,024 个神经元和一个神经元。
* 第一密集层具有`LeakyReLU`作为激活功能,而第二层具有乙状结肠作为激活功能。 乙状结肠激活用于二进制分类。 我们正在训练辨别器网络,以区分真实图像还是伪图像。
执行以下步骤来创建别器网络:
执行以下步骤来创建别器网络:
1. 让我们开始创建一个`Sequential` Keras 模型:
......@@ -572,7 +572,7 @@ dis_model.add(Activation('tanh'))
网络将生成形状为`(batch_size, 1)`的输出张量。 输出张量包含类的概率。
包裹在 Python 方法中的别器网络的完整代码如下:
包裹在 Python 方法中的别器网络的完整代码如下:
```py
def get_discriminator():
......@@ -603,7 +603,7 @@ def get_discriminator():
return dis_model
```
在本节中,我们已成功实现了别器和生成器网络。 在下一部分中,我们将在*下载和准备动漫角色数据集*部分中准备的数据集上训练模型。
在本节中,我们已成功实现了别器和生成器网络。 在下一部分中,我们将在*下载和准备动漫角色数据集*部分中准备的数据集上训练模型。
......@@ -617,7 +617,7 @@ def get_discriminator():
1. 加载数据集。
2. 构建和编译网络。
3. 训练别器网络。
3. 训练别器网络。
4. 训练发电机网络。
我们将在本节中一步一步地进行这些步骤。
......@@ -692,10 +692,10 @@ dis_model = build_discriminator()
dis_model.compile(loss='binary_crossentropy', optimizer=dis_optimizer)
```
同样,使用`binary_crossentropy`作为别器网络的损失函数,并使用`dis_optimizer`作为优化器。
同样,使用`binary_crossentropy`作为别器网络的损失函数,并使用`dis_optimizer`作为优化器。
4. 接下来,创建一个对抗模型。 一个对抗者将两个网络都包含在一个模型中。 对抗模型的架构如下:
* *输入->生成器->别器->输出*
* *输入->生成器->别器->输出*
创建和编译对抗模型的代码如下:
......@@ -705,7 +705,7 @@ adversarial_model.add(gen_model)
dis_model.trainable = False adversarial_model.add(dis_model)
```
当我们训练该网络时,我们不想训练别器网络,因此在将其添加到对抗模型之前,使其变为不可训练的。
当我们训练该网络时,我们不想训练别器网络,因此在将其添加到对抗模型之前,使其变为不可训练的。
编译对抗模型,如下所示:
......@@ -736,20 +736,20 @@ for epoch in range(epcohs):
现在,我们将仔细研究培训过程。 以下几点说明了 DCGAN 培训中涉及的不同步骤:
* 最初,这两个网络都是幼稚的并且具有随机权重。
* 训练 DCGAN 网络的标准过程是首先对一批样品进行别器训练。
* 训练 DCGAN 网络的标准过程是首先对一批样品进行别器训练。
* 为此,我们需要假样品和真实样品。 我们已经有了真实的样本,因此现在需要生成伪样本。
* 要生成伪样本,请在均匀分布上创建形状为(100,)的潜向量。 将此潜向量馈入未经训练的发电机网络。 生成器网络将生成伪样本,我们将其用于训练别器网络。
* 要生成伪样本,请在均匀分布上创建形状为(100,)的潜向量。 将此潜向量馈入未经训练的发电机网络。 生成器网络将生成伪样本,我们将其用于训练别器网络。
* 合并真实图像和伪图像以创建一组新的样本图像。 我们还需要创建一个标签数组:真实图像使用标签 1,伪图像使用标签 0。
# 训练别器网络
# 训练别器网络
执行以下步骤来训练别器网络:
执行以下步骤来训练别器网络:
1. 首先从正态分布中采样一批噪声向量,如下所示:
......@@ -777,7 +777,7 @@ generated_images = gen_model.predict_on_batch(z_noise)
y_real = np.ones(batch_size) - np.random.random_sample(batch_size) * 0.2 y_fake = np.random.random_sample(batch_size) * 0.2
```
5. 接下来,在真实图像和真实标签上训练别器网络:
5. 接下来,在真实图像和真实标签上训练别器网络:
```py
dis_loss_real = dis_model.train_on_batch(image_batch, y_real)
......@@ -795,7 +795,7 @@ dis_loss_fake = dis_model.train_on_batch(generated_images, y_fake)
d_loss = (dis_loss_real+dis_loss_fake)/2 print("d_loss:", d_loss)
```
到目前为止,我们一直在训练别器网络。 在下一部分中,让我们训练发电机网络。
到目前为止,我们一直在训练别器网络。 在下一部分中,让我们训练发电机网络。
......@@ -805,7 +805,7 @@ d_loss = (dis_loss_real+dis_loss_fake)/2 print("d_loss:", d_loss)
为了训练发电机网络,我们必须训练对抗模型。 当我们训练对抗模型时,它只训练发电机网络,而冻结鉴别器网络。 由于我们已经训练过鉴别器网络,因此我们不会对其进行训练。 执行以下步骤来训练对抗模型:
为了训练发电机网络,我们必须训练对抗模型。 当我们训练对抗模型时,它只训练发电机网络,而冻结判别器网络。 由于我们已经训练过判别器网络,因此我们不会对其进行训练。 执行以下步骤来训练对抗模型:
1. 首先重新创建一批噪声向量。 从高斯/正态分布中采样以下噪声向量:
......@@ -819,7 +819,7 @@ z_noise = np.random.normal(0, 1, size=(batch_size, z_shape))
g_loss = adversarial_model.train_on_batch(z_noise, [1] * batch_size)
```
我们在一批噪声向量和实数标签上训练对抗模型。 在这里,*实数标签*是一个所有值均等于 1 的向量。我们还在训练生成器,以欺骗别器网络。 为此,我们为它提供一个向量,该向量的所有值均等于 1。在此步骤中,生成器将接收来自生成器网络的反馈,并相应地进行改进。
我们在一批噪声向量和实数标签上训练对抗模型。 在这里,*实数标签*是一个所有值均等于 1 的向量。我们还在训练生成器,以欺骗别器网络。 为此,我们为它提供一个向量,该向量的所有值均等于 1。在此步骤中,生成器将接收来自生成器网络的反馈,并相应地进行改进。
3. 最后,将生成器损耗打印到控制台以跟踪损耗:
......@@ -887,7 +887,7 @@ imsave('results/image_{}.jpg'.format(epoch),gen_images[0])
gen_model.save("directory/for/the/generator/model.h5")
```
同样,通过添加以下行来保存别器模型:
同样,通过添加以下行来保存别器模型:
```py
# Specify the path for the discriminator model
......@@ -960,13 +960,13 @@ Tensorboard 的 **GRAPHS** 部分包含两个网络的图形。 如果网络性
* 批量大小
* 纪元数
* 发电机优化器
* 别器优化器
* 别器优化器
* 层数
* 致密层中的单位数
* 激活功能
* 损失函数
*使用 Keras* 实现 DCGAN 的部分中,学习率是固定的:生成器模型为 0.0005,别器模型为 0.0005。 批处理大小为 128。调整这些值可能会导致我们创建更好的模型。 如果您的模型没有生成合理的图像,请尝试更改这些值,然后再次运行模型。
*使用 Keras* 实现 DCGAN 的部分中,学习率是固定的:生成器模型为 0.0005,别器模型为 0.0005。 批处理大小为 128。调整这些值可能会导致我们创建更好的模型。 如果您的模型没有生成合理的图像,请尝试更改这些值,然后再次运行模型。
......@@ -983,7 +983,7 @@ Tensorboard 的 **GRAPHS** 部分包含两个网络的图形。 如果网络性
* **MNIST 字符的生成**:MNIST 数据集包含 60,000 张手写数字图像。 要训​​练复杂的监督学习模型,MNIST 数据集是不够的。 DCGAN 一旦受过训练,将生成可以添加到原始数据集中的新数字。
* **人脸生成**:DCGAN 使用卷积神经网络,非常擅长生成逼真的图像。
* **特征提取器**:训练后,可以使用别器从中间层提取特征。 这些提取的功能在样式转移和面部识别等任务中很有用。 样式转移涉及生成图像的内部表示,用于计算样式和内容损失。 请参阅[以下论文](https://arxiv.org/pdf/1508.06576.pdf),以了解有关样式转换的更多信息。
* **特征提取器**:训练后,可以使用别器从中间层提取特征。 这些提取的功能在样式转移和面部识别等任务中很有用。 样式转移涉及生成图像的内部表示,用于计算样式和内容损失。 请参阅[以下论文](https://arxiv.org/pdf/1508.06576.pdf),以了解有关样式转换的更多信息。
......
......@@ -23,7 +23,7 @@
与其他 GAN 一样,SRGAN 包含一个生成器网络和一个别器网络。 两个网络都很深。 这两个网络的功能指定如下:
与其他 GAN 一样,SRGAN 包含一个生成器网络和一个别器网络。 两个网络都很深。 这两个网络的功能指定如下:
* **生成器**:生成器网络拍摄尺寸为 64x64x3 的低分辨率图像,并且在一系列卷积和上采样层之后, 生成超分辨率 形状为 256x256x3 的图片
* **鉴别符** :鉴别符网络拍摄高分辨率图像,并尝试识别给定的图像是真实的(来自真实数据样本)还是伪造的(由 发电机)
......@@ -103,11 +103,11 @@ These hyperparameters are best-suited for the Keras framework. If you are using
# 别器网络的架构
# 别器网络的架构
鉴别器网络也是一个深度卷积网络。 它包含八个卷积块,后跟两个密集(完全连接)层。 每个卷积块后面都有一个批处理归一化层。 网络的末端有两个密集层,它们充当分类块。 最后一层预测图像属于真实数据集或伪数据集的概率。 鉴别器网络的详细配置如下表所示:
判别器网络也是一个深度卷积网络。 它包含八个卷积块,后跟两个密集(完全连接)层。 每个卷积块后面都有一个批处理归一化层。 网络的末端有两个密集层,它们充当分类块。 最后一层预测图像属于真实数据集或伪数据集的概率。 判别器网络的详细配置如下表所示:
| **图层名称** | **超参数** | **输入形状** | **输出形状** |
| 输入层 | 没有 | (256, 256, 3) | (256, 256, 3) |
......@@ -192,7 +192,7 @@ VGG 丢失是另一个内容丢失功能,可应用于生成的图像和真实
根据鉴别器网络返回的概率计算对抗损失。 在对抗模型中,鉴别器网络被馈送有由生成的网络生成的生成的图像。 对抗损失可以用以下等式表示:
根据判别器网络返回的概率计算对抗损失。 在对抗模型中,判别器网络被馈送有由生成的网络生成的生成的图像。 对抗损失可以用以下等式表示:
![](img/cf90c58f-3995-48a8-b78a-0ab81cb7ae9d.png)
......@@ -204,7 +204,7 @@ VGG 丢失是另一个内容丢失功能,可应用于生成的图像和真实
在此,总的感知损失由![](img/1ce9659c-27e3-423a-a3b8-be7e3e05b096.png)表示。 ![](img/1629f39f-eccc-4ba0-bec4-6263e873ed59.png)是内容损失,可以是像素级 MSE 损失或 VGG 损失。
通过最小化感知损失值,生成器网络试图欺骗别器。 随着感知损失的值减小,生成器网络开始生成更逼真的图像。
通过最小化感知损失值,生成器网络试图欺骗别器。 随着感知损失的值减小,生成器网络开始生成更逼真的图像。
现在开始进行该项目。
......@@ -296,7 +296,7 @@ unzip img_align_celeba.zip
正如我们所讨论的,SRGAN 在 Imagenet 数据集上具有三个神经网络,一个生成器,一个别器和一个预训练的 VGG19 网络。 在本节中,我们将编写所有网络的实现。 让我们从实现生成器网络开始。
正如我们所讨论的,SRGAN 在 Imagenet 数据集上具有三个神经网络,一个生成器,一个别器和一个预训练的 VGG19 网络。 在本节中,我们将编写所有网络的实现。 让我们从实现生成器网络开始。
在开始编写实现之前,创建一个名为`main.py`的 Python 文件并导入基本模块,如下所示:
......@@ -510,7 +510,7 @@ def build_generator():
return model
```
我们已经成功地为发电机网络创建了 Keras 模型。 在下一节中,我们将为别器网络创建 Keras 模型。
我们已经成功地为发电机网络创建了 Keras 模型。 在下一节中,我们将为别器网络创建 Keras 模型。
......@@ -520,11 +520,11 @@ def build_generator():
我们已经在*中探讨了别器网络的体系结构。 让我们 首先在 Keras 框架中编写区分网络的层,然后使用 Keras 框架的功能 API 创建 Keras 模型。*
我们已经在*中探讨了别器网络的体系结构。 让我们 首先在 Keras 框架中编写区分网络的层,然后使用 Keras 框架的功能 API 创建 Keras 模型。*
执行以下步骤以在 Keras 中实现别器网络:
执行以下步骤以在 Keras 中实现别器网络:
1. 首先定义别器网络所需的超参数:
1. 首先定义别器网络所需的超参数:
```py
leakyrelu_alpha = 0.2 momentum = 0.8 input_shape = (256, 256, 3)
......@@ -610,7 +610,7 @@ model = Model(inputs=[input_layer], outputs=[output],
name='discriminator')
```
W 将功能内的别器网络的整个代码说唱如下:
W 将功能内的别器网络的整个代码说唱如下:
```py
def build_discriminator():
......@@ -672,7 +672,7 @@ def build_discriminator():
return model
```
在这一部分,我们已经成功地为别器网络创建了 Keras 模型。 在下一节中,我们将构建 VGG19 网络,如 *SRGAN* 简介中所示。
在这一部分,我们已经成功地为别器网络创建了 Keras 模型。 在下一节中,我们将构建 VGG19 网络,如 *SRGAN* 简介中所示。
......@@ -744,7 +744,7 @@ def build_vgg():
对抗网络是使用生成器,别器和 VGG19 的组合网络。 在本节中,我们将创建一个对抗网络。
对抗网络是使用生成器,别器和 VGG19 的组合网络。 在本节中,我们将创建一个对抗网络。
执行以下步骤来创建对抗网络:
......@@ -768,15 +768,15 @@ fake_hr_images = generator(input_low_resolution)
fake_features = vgg(fake_hr_images)
```
4. 接下来,使别器网络在对抗网络中不可训练:
4. 接下来,使别器网络在对抗网络中不可训练:
```py
discriminator.trainable = False
```
我们使鉴别器网络不可训练,因为我们不想在训练生成器网络时训练鉴别器网络。
我们使判别器网络不可训练,因为我们不想在训练生成器网络时训练判别器网络。
5. 接下来,将伪造的图像传递到别器网络:
5. 接下来,将伪造的图像传递到别器网络:
```py
output = discriminator(fake_hr_images)
......@@ -821,7 +821,7 @@ def build_adversarial_model(generator, discriminator, vgg):
培训 SRGAN 网络是一个分为两个步骤的过程。 第一步,我们训练别器网络。 在第二步中,我们训练对抗网络,最终训练发电机网络。 让我们开始训练网络。
培训 SRGAN 网络是一个分为两个步骤的过程。 第一步,我们训练别器网络。 在第二步中,我们训练对抗网络,最终训练发电机网络。 让我们开始训练网络。
执行以下步骤来训练 SRGAN 网络:
......@@ -866,7 +866,7 @@ discriminator.compile(loss='mse', optimizer=common_optimizer,
metrics=['accuracy'])
```
要编译别器网络,使用 `mse` 作为损耗, `accuracy` 作为度量,并使用 `common_optimizer` 作为优化器。
要编译别器网络,使用 `mse` 作为损耗, `accuracy` 作为度量,并使用 `common_optimizer` 作为优化器。
3. 接下来,构建发电机网络:
......@@ -893,13 +893,13 @@ generated_high_resolution_images = generator(input_low_resolution)
features = vgg(generated_high_resolution_images)
```
使鉴别器网络不可训练,因为我们不想在对抗模型训练期间训练鉴别器模型 :
使判别器网络不可训练,因为我们不想在对抗模型训练期间训练判别器模型 :
```py
discriminator.trainable = False
```
6. 接下来,使用别器网络获取生成的高分辨率伪图像的概率:
6. 接下来,使用别器网络获取生成的高分辨率伪图像的概率:
```py
probs = discriminator(generated_high_resolution_images)
......@@ -989,11 +989,11 @@ def sample_images(data_dir, batch_size, high_resolution_shape, low_resolution_sh
# 训练别器网络
# 训练别器网络
本节中给出的步骤显示了如何训练别器网络。 这是最后一系列步骤的延续:
本节中给出的步骤显示了如何训练别器网络。 这是最后一系列步骤的延续:
1. 使用`generator`网络生成伪造的高分辨率图像:
......@@ -1009,26 +1009,26 @@ generated_high_resolution_images =
fake_labels = np.zeros((batch_size, 16, 16, 1))
```
3. 在真实图像和真实标签上训练别器网络:
3. 在真实图像和真实标签上训练别器网络:
```py
d_loss_real = discriminator.train_on_batch(high_resolution_images,
real_labels)
```
4. 在生成的图像和伪造标签上训练别器:
4. 在生成的图像和伪造标签上训练别器:
```py
d_loss_fake = discriminator.train_on_batch(generated_high_resolution_images, fake_labels)
```
5. 最后,计算总的别器损失:
5. 最后,计算总的别器损失:
```py
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
```
现在,我们添加了代码来训练别器网络。 接下来,添加代码以训练对抗模型,从而训练生成器网络。
现在,我们添加了代码来训练别器网络。 接下来,添加代码以训练对抗模型,从而训练生成器网络。
......@@ -1199,7 +1199,7 @@ TensorBoard 的 GRAPHS 部分包含两个网络的图形。 如果网络性能
在本章中,我们首先介绍 SRGAN。 然后,我们研究了生成器和别器网络的体系结构。 后来,我们执行了该项目所需的设置。 然后,我们收集并探索了数据集。 之后,我们在训练 SRGAN 之前先在 Keras 中实施了该项目,评估了训练后的 SRGAN 网络,并使用超参数优化技术对训练后的模型进行了优化。 最后,我们简要介绍了 SRGAN 的一些不同应用。
在本章中,我们首先介绍 SRGAN。 然后,我们研究了生成器和别器网络的体系结构。 后来,我们执行了该项目所需的设置。 然后,我们收集并探索了数据集。 之后,我们在训练 SRGAN 之前先在 Keras 中实施了该项目,评估了训练后的 SRGAN 网络,并使用超参数优化技术对训练后的模型进行了优化。 最后,我们简要介绍了 SRGAN 的一些不同应用。
在下一章中,我们将介绍 StackGAN 及其不同的应用程序。
......
......@@ -36,10 +36,10 @@
StackGAN 是一个两阶段的网络。 每个阶段都有两个生成器和两个别器。 StackGAN 由许多网络组成,这些网络如下:
StackGAN 是一个两阶段的网络。 每个阶段都有两个生成器和两个别器。 StackGAN 由许多网络组成,这些网络如下:
* **Stack-I GAN** :文本编码器,条件增强网络,生成器网络,别器网络,嵌入压缩器网络
* **Stack-II GAN** :t ext 编码器,条件增强网络,生成器网络,别器网络,嵌入压缩器网络
* **Stack-I GAN** :文本编码器,条件增强网络,生成器网络,别器网络,嵌入压缩器网络
* **Stack-II GAN** :t ext 编码器,条件增强网络,生成器网络,别器网络,嵌入压缩器网络
![](img/6f2f1522-849c-4ee4-9c08-57884ea1b6b1.png)
......@@ -57,9 +57,9 @@ Source: arXiv:1612.03242 [cs.CV]
| ![](img/d857d518-1a01-4b38-a794-c85183029413.png) | 这是一个对角协方差矩阵。 |
| 数据 | 这是真正的数据分配。 |
| 个人电脑 | 这就是高斯分布。 |
| D1 | 这是第一阶段的别器。 |
| D1 | 这是第一阶段的别器。 |
| G1 | 这是 Stage-I 生成器。 |
| D2 | 这是第二阶段的别器。 |
| D2 | 这是第二阶段的别器。 |
| G2 | 这是 Stage-II 生成器。 |
| N2 | 这些是随机噪声变量的尺寸。 |
| ![](img/c9a26056-2b9d-44f1-bc1b-4fbb29cfd2af.png) | 这些是 Stack-II GAN 的高斯潜在变量。 |
......@@ -114,7 +114,7 @@ Source: arXiv:1612.03242 [cs.CV]
StackGAN 网络的主要组成部分是生成器网络和别器网络。 在本节中,我们将详细探讨这两个网络。
StackGAN 网络的主要组成部分是生成器网络和别器网络。 在本节中,我们将详细探讨这两个网络。
......@@ -132,7 +132,7 @@ Stage-I 生成器网络是具有几个上采样层的深度卷积神经网络。
The architecture of the generator network in Stage-I
如您所见,生成器网络包含几个卷积层,其中每个卷积层后跟一个批处理规范化层或一个激活层。 它的唯一目的是生成尺寸为`64x64x3`的图像。 现在我们有了生成器网络的基本概念,让我们探索别器网络。
如您所见,生成器网络包含几个卷积层,其中每个卷积层后跟一个批处理规范化层或一个激活层。 它的唯一目的是生成尺寸为`64x64x3`的图像。 现在我们有了生成器网络的基本概念,让我们探索别器网络。
......@@ -142,7 +142,7 @@ The architecture of the generator network in Stage-I
类似于生成器网络,鉴别器网络是一个深度卷积神经网络,其中包含一系列下采样卷积层。 下采样层从图像生成特征图,无论它们是真实数据分布![](img/c534d4df-c504-4ff3-83b6-61db0e52035b.png)的真实图像还是生成器网络生成的图像。 然后,我们将特征映射连接到文本嵌入。 我们使用压缩和空间复制将嵌入的文本转换为连接所需的格式。 空间压缩和复制包括一个完全连接的层,该层用于压缩嵌入到![](img/31009ecb-449c-41d6-81c4-dd1d976fb6f2.png)维输出的文本,然后通过空间复制将其转换为![](img/42f86eb5-0593-4986-8a38-397be9b66e56.png)维张量。 然后将特征图以及压缩的和空间复制的文本嵌入沿通道维级联。 最后,我们具有一个节点的完全连接层,该层用于二进制分类。 让我们看一下鉴别器网络的架构,如以下屏幕截图所示:
类似于生成器网络,判别器网络是一个深度卷积神经网络,其中包含一系列下采样卷积层。 下采样层从图像生成特征图,无论它们是真实数据分布![](img/c534d4df-c504-4ff3-83b6-61db0e52035b.png)的真实图像还是生成器网络生成的图像。 然后,我们将特征映射连接到文本嵌入。 我们使用压缩和空间复制将嵌入的文本转换为连接所需的格式。 空间压缩和复制包括一个完全连接的层,该层用于压缩嵌入到![](img/31009ecb-449c-41d6-81c4-dd1d976fb6f2.png)维输出的文本,然后通过空间复制将其转换为![](img/42f86eb5-0593-4986-8a38-397be9b66e56.png)维张量。 然后将特征图以及压缩的和空间复制的文本嵌入沿通道维级联。 最后,我们具有一个节点的完全连接层,该层用于二进制分类。 让我们看一下判别器网络的架构,如以下屏幕截图所示:
![](img/fc0175ae-38b7-42aa-99ec-1bdbe36a8edf.png)
......@@ -150,7 +150,7 @@ The architecture of the generator network in Stage-I
The architecture of the Stage-I discriminator network
如您所见,生成器网络包含几个卷积层。 别器网络的唯一目的是区分来自真实数据分布的图像和生成器网络生成的图像。 现在,我们来看看 StackGAN 的 Stage I 中使用的损耗。
如您所见,生成器网络包含几个卷积层。 别器网络的唯一目的是区分来自真实数据分布的图像和生成器网络生成的图像。 现在,我们来看看 StackGAN 的 Stage I 中使用的损耗。
......@@ -163,13 +163,13 @@ The architecture of the Stage-I discriminator network
StackGAN 的阶段 I 中使用了两个损失,如下所示:
* 发电机损耗
* 别器损失
* 别器损失
鉴别符损失![](img/0a355bdc-0c6f-4cd3-a62e-4b46a301c9f6.png)可以表示为:
![](img/01fddc7c-38fb-4dc6-ac3b-3c73b448e65a.png)
公式前面的很不言自明。 它代表了别器网络的损失函数,其中两个网络都以文本嵌入为条件。
公式前面的很不言自明。 它代表了别器网络的损失函数,其中两个网络都以文本嵌入为条件。
发电机损耗![](img/b46d75ce-88c8-480a-ba3d-572b93f4c717.png)可以表示为:
......@@ -185,7 +185,7 @@ StackGAN 的阶段 I 中使用了两个损失,如下所示:
Stage-II StackGAN 的主要组件是发电机网络和别器网络。 生成器网络是编码器-解码器类型的网络。 在此阶段不使用随机噪声`z`,假设 ![](img/94999cb2-2d49-4263-b900-3deef877ccd1.png)已保留了随机性,其中![](img/94999cb2-2d49-4263-b900-3deef877ccd1.png)是发生器网络生成的图像 第一阶段
Stage-II StackGAN 的主要组件是发电机网络和别器网络。 生成器网络是编码器-解码器类型的网络。 在此阶段不使用随机噪声`z`,假设 ![](img/94999cb2-2d49-4263-b900-3deef877ccd1.png)已保留了随机性,其中![](img/94999cb2-2d49-4263-b900-3deef877ccd1.png)是发生器网络生成的图像 第一阶段
我们首先使用预训练的文本编码器生成高斯条件变量 ![](img/308050a3-9d10-4f05-9e8e-d1e4e07bbb93.png) 。 这将生成嵌入 ![](img/b7167483-2ee2-469e-af9f-278f36699c79.png) 的相同文本。 第一阶段和第二阶段条件增强具有不同的完全连接层,用于生成不同的均值和标准 偏差。 这意味着 Stage-II GAN 学会了在文本嵌入中捕获有用的信息,而这些信息被 Stage-I GAN 省略了。
......@@ -223,7 +223,7 @@ The architecture of the Stage-II generator
类似于生成器网络,鉴别器网络是一个深度卷积神经网络,并且包含额外的下采样层,因为图像的大小比 Stage-I 中的鉴别器网络大。 鉴别器是一个可识别匹配的鉴别器(有关更多信息,[请参见以下链接](https://arxiv.org/pdf/1605.05396.pdf),它使我们可以更好地实现 图片和条件文字。 在训练期间,鉴别器将真实图像及其对应的文本描述作为正样本对,而负样本对则由两组组成。 第一组是具有不匹配的文本嵌入的真实图像,而第二组是具有相应的文本嵌入的合成图像。 让我们看一下鉴别器网络的体系结构,如下图所示:
类似于生成器网络,判别器网络是一个深度卷积神经网络,并且包含额外的下采样层,因为图像的大小比 Stage-I 中的判别器网络大。 判别器是一个可识别匹配的判别器(有关更多信息,[请参见以下链接](https://arxiv.org/pdf/1605.05396.pdf),它使我们可以更好地实现 图片和条件文字。 在训练期间,判别器将真实图像及其对应的文本描述作为正样本对,而负样本对则由两组组成。 第一组是具有不匹配的文本嵌入的真实图像,而第二组是具有相应的文本嵌入的合成图像。 让我们看一下判别器网络的体系结构,如下图所示:
![](img/a8c04bff-bd5a-4350-8b08-bd2ef6ae193b.png)
......@@ -233,7 +233,7 @@ The architecture of the Stage-II generator
The architecture of the Stage-II discriminator network.
关于别器网络架构的 M 矿石信息可以在 StackGAN 部分的 *Keras 实现中找到。*
关于别器网络架构的 M 矿石信息可以在 StackGAN 部分的 *Keras 实现中找到。*
......@@ -243,13 +243,13 @@ The architecture of the Stage-II discriminator network.
与任何其他 GAN 相似,Stack-II GAN 中的生成器`G`鉴别器`D`也可以通过最大化鉴别器的损耗并将生成器网络的损耗最小化来训练 。
与任何其他 GAN 相似,Stack-II GAN 中的生成器`G`判别器`D`也可以通过最大化判别器的损耗并将生成器网络的损耗最小化来训练 。
发电机损耗![](img/d0ecd579-7d64-4b7c-a9c7-666c14c0e1cc.png)可以表示为:
![](img/24684f0c-814c-4b33-bfe7-c177cfe19a46.png)
前面的方程式非常不言自明。 它代表了别器网络的损失函数,其中两个网络都以文本嵌入为条件。 一个主要区别是生成器网络以![](img/2fc3c44d-59b8-4da3-b9b7-b5daabb95bb6.png)和![](img/3720bf75-1dba-477b-b833-865282482a25.png)作为输入,其中![](img/134a6916-3b21-48a7-88ee-a115d848fbe5.png)是 Stage-I 生成的图像,![](img/885a0848-1055-4c3b-976f-11f36d73232b.png)是 CA 变量。
前面的方程式非常不言自明。 它代表了别器网络的损失函数,其中两个网络都以文本嵌入为条件。 一个主要区别是生成器网络以![](img/2fc3c44d-59b8-4da3-b9b7-b5daabb95bb6.png)和![](img/3720bf75-1dba-477b-b833-865282482a25.png)作为输入,其中![](img/134a6916-3b21-48a7-88ee-a115d848fbe5.png)是 Stage-I 生成的图像,![](img/885a0848-1055-4c3b-976f-11f36d73232b.png)是 CA 变量。
鉴别符损失![](img/a1fce921-d434-45e3-8f15-472f02dcebc5.png)可以表示为:
......@@ -393,7 +393,7 @@ StackGAN 的 Keras 实现分为两部分:第一阶段和第二阶段。 我们
Stage-I StackGAN 包含生成器网络和鉴别器网络。 它还具有一个文本编码器网络和一个条件增强网络(CA 网络),下面将对此进行详细说明。 生成器网络获取文本条件变量(![](img/5636ece2-f10e-4485-bd3b-527ba2c14606.png))以及噪声向量(`x`)。 经过一组上采样层后,它会生成尺寸为`64x64x3`的低分辨率图像。 鉴别器网络拍摄此低分辨率图像,并尝试识别图像是真实的还是伪造的。 生成器网络是具有一组下采样层的网络,其后是连接,然后是分类层。 在以下各节中,我们将详细探讨 StackGAN 的体系结构。
Stage-I StackGAN 包含生成器网络和判别器网络。 它还具有一个文本编码器网络和一个条件增强网络(CA 网络),下面将对此进行详细说明。 生成器网络获取文本条件变量(![](img/5636ece2-f10e-4485-bd3b-527ba2c14606.png))以及噪声向量(`x`)。 经过一组上采样层后,它会生成尺寸为`64x64x3`的低分辨率图像。 判别器网络拍摄此低分辨率图像,并尝试识别图像是真实的还是伪造的。 生成器网络是具有一组下采样层的网络,其后是连接,然后是分类层。 在以下各节中,我们将详细探讨 StackGAN 的体系结构。
Stage-I StackGAN 网络中使用的网络如下:
......@@ -635,7 +635,7 @@ def build_stage1_generator():
此模型在单个网络中同时包含 CA 网络和生成器网络。 它需要两个输入并返回两个输出。 输入是文本嵌入和噪声变量,而输出是生成的图像和`mean_logsigma`
我们现在已经成功实现了发电机网络。 让我们进入别器网络。
我们现在已经成功实现了发电机网络。 让我们进入别器网络。
......@@ -645,7 +645,7 @@ def build_stage1_generator():
别器网络是分类器网络。 它包含一组下采样层,并对给定图像是真实的还是伪造的进行分类。
别器网络是分类器网络。 它包含一组下采样层,并对给定图像是真实的还是伪造的进行分类。
让我们从编写网络代码开始:
......@@ -756,7 +756,7 @@ x2 = Activation('sigmoid')(x2)
stage1_dis = Model(inputs=[input_layer, input_layer2], outputs=[x2])
```
该模型输出输入图像属于真实类别或伪类别的概率。 别器网络的完整代码如下:
该模型输出输入图像属于真实类别或伪类别的概率。 别器网络的完整代码如下:
```py
def build_stage1_discriminator(): input_layer = Input(shape=(64, 64, 3))
......@@ -804,7 +804,7 @@ def build_stage1_discriminator(): input_layer = Input(shape=(64, 64, 3))
要创建对抗模型,请同时使用生成器网络和别器网络,并创建一个新的 Keras 模型。
要创建对抗模型,请同时使用生成器网络和别器网络,并创建一个新的 Keras 模型。
1. 首先创建三个输入层以将输入馈送到网络:
......@@ -825,7 +825,7 @@ def build_adversarial_model(gen_model, dis_model):
dis_model.trainable = False
```
3. 接下来,使用别器网络获得概率:
3. 接下来,使用别器网络获得概率:
```py
# Get output of the discriminator models valid = dis_model([x, input_layer3])
......@@ -1138,7 +1138,7 @@ def build_stage2_generator():
Stage-II StackGAN 的别器网络是一系列下采样层,然后是串联块,然后是分类器。 让我们为每个块编写代码。
Stage-II StackGAN 的别器网络是一系列下采样层,然后是串联块,然后是分类器。 让我们为每个块编写代码。
首先创建输入层,如下所示:
......@@ -1249,7 +1249,7 @@ x3 = Dense(1)(x3)
x3 = Activation('sigmoid')(x3)
```
`x3`是此别器网络的输出。 这将输出通过的图像是真实的还是伪造的概率。
`x3`是此别器网络的输出。 这将输出通过的图像是真实的还是伪造的概率。
最后,创建一个模型:
......@@ -1259,7 +1259,7 @@ stage2_dis = Model(inputs=[input_layer, input_layer2], outputs=[x3])
如您所见,此模型采用两个输入并返回一个输出。
别器网络的完整代码如下:
别器网络的完整代码如下:
```py
def build_stage2_discriminator():
......@@ -1509,7 +1509,7 @@ X_test, y_test, embeddings_test = load_dataset(filenames_file_path=filenames_fil
让我们使用 *StackGAN* 的 Keras 实现下的 *Stage-I StackGAN* 的 部分中的方法创建模型。 我们将使用四个模型:生成器模型,鉴别器模型,压缩文本嵌入的压缩器模型以及同时包含生成器和鉴别器的对抗模型:
让我们使用 *StackGAN* 的 Keras 实现下的 *Stage-I StackGAN* 的 部分中的方法创建模型。 我们将使用四个模型:生成器模型,判别器模型,压缩文本嵌入的压缩器模型以及同时包含生成器和判别器的对抗模型:
1. 首先定义培训所需的优化器:
......@@ -1571,7 +1571,7 @@ tensorboard.set_model(embedding_compressor_model)
训练模型需要几个步骤:
1. 用真实和假标签创建两个张量。 在训练生成器和别器时将需要这些。 使用标签平滑处理,该内容在第 1 章,“生成对抗网络”中介绍:
1. 用真实和假标签创建两个张量。 在训练生成器和别器时将需要这些。 使用标签平滑处理,该内容在第 1 章,“生成对抗网络”中介绍:
```py
real_labels = np.ones((batch_size, 1), dtype=float) * 0.9 fake_labels = np.zeros((batch_size, 1), dtype=float) * 0.1
......@@ -1625,7 +1625,7 @@ for epoch in range(epochs):
compressed_embedding = np.tile(compressed_embedding, (1, 4, 4, 1))
```
7. 接下来,在生成器生成的伪图像,真实数据集中的真实图像和错误图像上训练别器模型:
7. 接下来,在生成器生成的伪图像,真实数据集中的真实图像和错误图像上训练别器模型:
```py
dis_loss_real = stage1_dis.train_on_batch([image_batch, compressed_embedding],
......@@ -1636,7 +1636,7 @@ for epoch in range(epochs):
np.reshape(fake_labels[1:], (batch_size-1, 1)))
```
现在,我们已经成功地在三组数据上训练了别器:真实图像,伪图像和错误图像。 现在让我们训练对抗模型:
现在,我们已经成功地在三组数据上训练了别器:真实图像,伪图像和错误图像。 现在让我们训练对抗模型:
8. 接下来,训练对抗模型。 为它提供三个输入和相应的真值。 此操作将计算梯度并更新一批数据的权重。
......@@ -1816,7 +1816,7 @@ tensorboard.set_model(stage2_gen)
tensorboard.set_model(stage2_dis)
```
2. 然后,创建两个张量分别为`real``fake`的张量。 在训练生成器和别器时将需要这些。 使用标签平滑处理,第 1 章,“生成对抗网络”对此进行了介绍:
2. 然后,创建两个张量分别为`real``fake`的张量。 在训练生成器和别器时将需要这些。 使用标签平滑处理,第 1 章,“生成对抗网络”对此进行了介绍:
```py
real_labels = np.ones((batch_size, 1), dtype=float) * 0.9 fake_labels = np.zeros((batch_size, 1), dtype=float) * 0.1
......@@ -1867,7 +1867,7 @@ for epoch in range(epochs):
compressed_embedding = np.tile(compressed_embedding, (1, 4, 4, 1))
```
8. 之后,在伪图像,真实图像和错误图像上训练别器模型:
8. 之后,在伪图像,真实图像和错误图像上训练别器模型:
```py
dis_loss_real = stage2_dis.train_on_batch([X_hr_train_batch, compressed_embedding],
......@@ -1878,7 +1878,7 @@ for epoch in range(epochs):
np.reshape(fake_labels[1:], (batch_size-1, 1)))
```
9. 接下来,训练对抗模型。 这是生成器模型和别器模型的组合。 我们为它提供三个输入和相应的真值:
9. 接下来,训练对抗模型。 这是生成器模型和别器模型的组合。 我们为它提供三个输入和相应的真值:
```py
g_loss = adversarial_model.train_on_batch([embedding_batch, z_noise, compressed_embedding],[K.ones((batch_size, 1)) * 0.9, K.ones((batch_size, 256)) * 0.9])
......@@ -1959,7 +1959,7 @@ tensorboard --logdir=logs
现在,在浏览器中打开 `localhost:6006` 。 TensorBoard 的 **标量** 部分包含两个损失的曲线图,如下所示:
阶段 I 的别器网络的损耗图如下所示:
阶段 I 的别器网络的损耗图如下所示:
![](img/8d391386-69b9-4890-bd5a-a078ba996754.png)
......@@ -1967,7 +1967,7 @@ tensorboard --logdir=logs
![](img/905056c0-7994-444e-b42b-4ebce2f093d9.png)
可以类似地从 Tensorboard 获得 Stage II 的发电机网络和别器网络的损耗图。
可以类似地从 Tensorboard 获得 Stage II 的发电机网络和别器网络的损耗图。
这些图将帮助您决定是继续还是停止训练。 如果损失不再减少,您就可以停止培训,因为没有改善的机会。 如果损失持续增加,则必须停止训练。 使用超参数,然后选择一组您认为可以提供更好结果的超参数。 如果损失逐渐减少,请继续训练模型。
......
......@@ -24,7 +24,7 @@ CycleGAN 是一种**生成对抗性** **网络**(**GAN**)的类型,用于
为了将照片变成一幅画或一幅画,再将它们变成照片,普通 GAN 需要一对图像。 CycleGAN 是一种 GAN 网络,可以将图像从一个域 X 转换为另一个域 Y,而无需配对图像。 CycleGAN 尝试学习发电机网络,而发电机网络又学习了两个映射。 CycleGAN 无需训练大多数 GAN 中使用的单个发电机网络,而是训练两个发电机和两个别器网络。
为了将照片变成一幅画或一幅画,再将它们变成照片,普通 GAN 需要一对图像。 CycleGAN 是一种 GAN 网络,可以将图像从一个域 X 转换为另一个域 Y,而无需配对图像。 CycleGAN 尝试学习发电机网络,而发电机网络又学习了两个映射。 CycleGAN 无需训练大多数 GAN 中使用的单个发电机网络,而是训练两个发电机和两个别器网络。
CycleGAN 中有两个发电机网络,如下所示:
......@@ -33,9 +33,9 @@ CycleGAN 中有两个发电机网络,如下所示:
这两个网络的架构相同,但我们分别对其进行培训。
CycleGAN 中有两个别器网络,如下所示:
CycleGAN 中有两个别器网络,如下所示:
1. **鉴别器 A** :鉴别器`A`的工作是区分由生成器网络`A`生成的图像,这些图像表示为 *G(X)* 和来自源域`A`的真实图像,它们表示为`X`
1. **判别器 A** :判别器`A`的工作是区分由生成器网络`A`生成的图像,这些图像表示为 *G(X)* 和来自源域`A`的真实图像,它们表示为`X`
2. **鉴别符 B** :鉴别符`B`的工作是区分由生成器网络`B`生成的图像,这些图像表示为 *F(Y)* 以及来自源域`B`的真实图像,它们表示为`Y`
两个网络的架构是相同的。 与生成器网络类似,我们分别训练区分器网络。 如下图所示:
......@@ -54,7 +54,7 @@ Illustration of a CycleGAN with two generator and two adversarial discriminator
CycleGAN 总体上由两种体系结构组成:生成器和鉴别器。 生成器体系结构用于创建两个模型,生成器 A 和生成器 B。鉴别器体系结构用于创建另外两个模型,鉴别器 A 和鉴别器 B。我们现在将在接下来的两节中介绍两个网络的体系结构。
CycleGAN 总体上由两种体系结构组成:生成器和判别器。 生成器体系结构用于创建两个模型,生成器 A 和生成器 B。判别器体系结构用于创建另外两个模型,判别器 A 和判别器 B。我们现在将在接下来的两节中介绍两个网络的体系结构。
......@@ -124,11 +124,11 @@ These hyperparameters are best suited for the Keras framework. If you are using
# 别器的架构
# 别器的架构
鉴别器网络的架构类似于 PatchGAN 网络中的鉴别器架构。 它是一个深度卷积神经网络,包含多个卷积块。 基本上,它会拍摄形状为(128、128、3)的图像,并预测该图像是真实的还是假的。 它包含几个 ZeroPadding2D 层,[可以在以下链接中找到其文档](https://keras.io/layers/convolutional/#zeropadding2d)。 下表详细显示了鉴别器网络的体系结构:
判别器网络的架构类似于 PatchGAN 网络中的判别器架构。 它是一个深度卷积神经网络,包含多个卷积块。 基本上,它会拍摄形状为(128、128、3)的图像,并预测该图像是真实的还是假的。 它包含几个 ZeroPadding2D 层,[可以在以下链接中找到其文档](https://keras.io/layers/convolutional/#zeropadding2d)。 下表详细显示了判别器网络的体系结构:
| **图层名称** | **超参数** | **输入形状** | **输出形状** |
| 输入层 | `none` | (128, 128, 3) | (128, 128, 3) |
......@@ -150,7 +150,7 @@ These hyperparameters are best suited for the Keras framework. If you are using
| ZeroPadding2D 层 | `padding(1, 1)` | (8,8,512) | (10, 10, 512) |
| 2D 卷积层 | `filters=1, kernel_size=4, strides=1, padding='valid', activation='sigmoid'` | (10, 10, 512) | (7,7,1) |
别器网络返回形状为(7,7,1)的张量。 现在,我们已经介绍了这两个网络的详细架构。 在下一节中,我们将介绍训练 CycleGAN 所需的目标函数。
别器网络返回形状为(7,7,1)的张量。 现在,我们已经介绍了这两个网络的详细架构。 在下一节中,我们将介绍训练 CycleGAN 所需的目标函数。
The ZeroPadding2D layer adds rows and columns of zeros at the top, bottom, left, and right of an image tensor.
......@@ -181,7 +181,7 @@ The ZeroPadding2D layer adds rows and columns of zeros at the top, bottom, left,
![](img/f278fd84-eb49-4d88-a98e-31396fe4ea3a.png)
在此,x 是来自分布 A 的一个域的图像,y 是来自分布 B 的另一个域的图像。鉴别符![](img/c420501d-952a-4e5b-84b0-0aa891624a10.png)试图区分 G 映射(![](img/e57cd8de-afc5-4e00-a0d4-b87786d7318f.png))生成的图像和实数 图像 y 来自不同的分布 B。别器![](img/e0cef545-08a1-4089-a238-9b6945c1d821.png)试图区分 F 映射生成的图像(![](img/968121df-410e-4bff-9e76-57d447e34db5.png))和来自分布 A 的真实图像 x。G 的目的是使对抗损失函数最小 对抗对手 D,后者不断尝试使其最大化。
在此,x 是来自分布 A 的一个域的图像,y 是来自分布 B 的另一个域的图像。鉴别符![](img/c420501d-952a-4e5b-84b0-0aa891624a10.png)试图区分 G 映射(![](img/e57cd8de-afc5-4e00-a0d4-b87786d7318f.png))生成的图像和实数 图像 y 来自不同的分布 B。别器![](img/e0cef545-08a1-4089-a238-9b6945c1d821.png)试图区分 F 映射生成的图像(![](img/968121df-410e-4bff-9e76-57d447e34db5.png))和来自分布 A 的真实图像 x。G 的目的是使对抗损失函数最小 对抗对手 D,后者不断尝试使其最大化。
......@@ -219,13 +219,13 @@ The ZeroPadding2D layer adds rows and columns of zeros at the top, bottom, left,
![](img/b72c39e8-2d9b-487b-83df-3b73ab2c550f.png)
在此,![](img/a04311c3-8eb2-45e2-98c0-e691deb818e0.png)是第一个对抗性损失,![](img/c9de7008-1df0-4381-92f5-fcfc5aa276a3.png)是第二个对抗性损失。 在生成器 A 和鉴别器 B 上计算第一个对抗损失。在生成器 B 和鉴别器 A 上计算第二个对抗损失。
在此,![](img/a04311c3-8eb2-45e2-98c0-e691deb818e0.png)是第一个对抗性损失,![](img/c9de7008-1df0-4381-92f5-fcfc5aa276a3.png)是第二个对抗性损失。 在生成器 A 和判别器 B 上计算第一个对抗损失。在生成器 B 和判别器 A 上计算第二个对抗损失。
要训​​练 CycleGAN,我们需要优化以下功能:
![](img/b0e30420-c79d-434a-b6d9-6fcaaa2a61ad.png)
前面的等式表明,训练一个 CycleGAN,需要最小化发电机网络的损耗,并使别器网络的损耗最大化。 优化之后,我们将获得一组训练有素的网络,能够从绘画中生成照片。
前面的等式表明,训练一个 CycleGAN,需要最小化发电机网络的损耗,并使别器网络的损耗最大化。 优化之后,我们将获得一组训练有素的网络,能够从绘画中生成照片。
......@@ -308,7 +308,7 @@ The `monet2photo` dataset is available for educational purposes only. To use it
如本章前面的 *CycleGAN 简介*部分中所述,CycleGAN 具有两种网络体系结构,即生成器网络和别器网络。 在本节中,我们将编写所有网络的实现。
如本章前面的 *CycleGAN 简介*部分中所述,CycleGAN 具有两种网络体系结构,即生成器网络和别器网络。 在本节中,我们将编写所有网络的实现。
但是,在开始编写实现之前,请创建一个 Python 文件`main.py`并导入基本模块,如下所示:
......@@ -474,7 +474,7 @@ def build_generator():
return model
```
我们已经成功地为发电机网络创建了 Keras 模型。 在下一节中,我们将为别器网络创建 Keras 模型。
我们已经成功地为发电机网络创建了 Keras 模型。 在下一节中,我们将为别器网络创建 Keras 模型。
......@@ -484,11 +484,11 @@ def build_generator():
我们已经在 *中探索了别器网络的体系结构。*部分 让我们 首先在 Keras 框架中编写区分网络的层,然后使用 Keras 框架的功能 API 创建 Keras 模型。
我们已经在 *中探索了别器网络的体系结构。*部分 让我们 首先在 Keras 框架中编写区分网络的层,然后使用 Keras 框架的功能 API 创建 Keras 模型。
执行以下步骤以在 Keras 中实现别器网络:
执行以下步骤以在 Keras 中实现别器网络:
1. 首先定义别器网络所需的超参数,如下所示:
1. 首先定义别器网络所需的超参数,如下所示:
```py
input_shape = (128, 128, 3)
......@@ -509,7 +509,7 @@ x = ZeroPadding2D(padding=(1, 1))(input_layer)
该层将在`x``y`轴上为输入张量添加填充。
4. 接下来,使用先前在*别器网络*部分的体系结构中指定的超参数添加卷积块,如下所示:
4. 接下来,使用先前在*别器网络*部分的体系结构中指定的超参数添加卷积块,如下所示:
```py
x = Conv2D(filters=64, kernel_size=4, strides=2, padding="valid")(x)
......@@ -522,7 +522,7 @@ x = LeakyReLU(alpha=0.2)(x)
x = ZeroPadding2D(padding=(1, 1))(x)
```
6. 接下来,使用先前在*别器网络* 部分中指定的超参数添加三个卷积块,如下所示:
6. 接下来,使用先前在*别器网络* 部分中指定的超参数添加三个卷积块,如下所示:
```py
for i in range(1, hidden_layers + 1):
......@@ -546,7 +546,7 @@ output = Conv2D(filters=1, kernel_size=4, strides=1, activation="sigmoid")(x)
model = Model(inputs=[input_layer], outputs=[output])
```
别器网络的整个代码如下所示:
别器网络的整个代码如下所示:
```py
def build_discriminator():
......@@ -577,7 +577,7 @@ def build_discriminator():
return model
```
我们也已经成功地为别器网络创建了 Keras 模型。 在下一部分中,我们将训练网络。
我们也已经成功地为别器网络创建了 Keras 模型。 在下一部分中,我们将训练网络。
......@@ -590,7 +590,7 @@ def build_discriminator():
我们已经在 *CycleGANs 简介*部分中介绍了训练目标功能。 我们还为两个网络分别创建了 Keras 模型。 训练 CycleGAN 是一个多步骤的过程。 我们将执行以下步骤来训练网络:
1. 加载数据集
2. 创建生成器和别器网络
2. 创建生成器和别器网络
3. 训练网络以达到指定次数
4. 绘制损失
5. 生成新图像
......@@ -702,14 +702,14 @@ def load_images(data_dir):
我们将使用`Adam`优化器,其中`learning_rate`等于 0.0002,并且`beta_1`值等于 0.5。
2. 首先创建别器网络,如以下代码所示:
2. 首先创建别器网络,如以下代码所示:
```py
discriminatorA = build_discriminator()
discriminatorB = build_discriminator()
```
*鉴别器网络的架构*部分所述,CycleGAN 具有两个鉴别器网络。
*判别器网络的架构*部分所述,CycleGAN 具有两个判别器网络。
3. 接下来,编译网络,如下所示:
......@@ -729,7 +729,7 @@ generatorBToA = build_generator()
*CycleGAN 的体系结构*部分所述,CycleGAN 具有两个生成器网络。 `generatorAToB`会将图像从域 A 转换为域 B。`generatorBToA`会将图像从域 B 转换为域 A。
现在,我们已经创建了两个生成器网络和两个别器网络。 在下一个小节中,我们将创建并编译一个对抗网络。
现在,我们已经创建了两个生成器网络和两个别器网络。 在下一个小节中,我们将创建并编译一个对抗网络。
......@@ -739,7 +739,7 @@ generatorBToA = build_generator()
对抗网络是一个组合网络。 它在单个 Keras 模型中使用所有四个网络。 创建对抗网络的主要目的是训练生成器网络。 当我们训练对抗网络时,它只训练生成器网络,但冻结了别器网络的训练。 让我们创建一个具有所需功能的对抗模型。
对抗网络是一个组合网络。 它在单个 Keras 模型中使用所有四个网络。 创建对抗网络的主要目的是训练生成器网络。 当我们训练对抗网络时,它只训练生成器网络,但冻结了别器网络的训练。 让我们创建一个具有所需功能的对抗模型。
1. 首先为网络创建两个输入层,如下所示:
......@@ -775,15 +775,15 @@ generatedBId = generatorAToB(inputB)
生成器网络 A(`generatorAToB`)将图像从域 A 转换为域 B。类似地,生成器网络 B(`generatorBToA`)将图像从域 B 转换为域 A。
5. 接下来,使两个别器网络均不可训练,如下所示:
5. 接下来,使两个别器网络均不可训练,如下所示:
```py
discriminatorA.trainable = False discriminatorB.trainable = False
```
我们不想在我们的对抗网络中训练别器网络。
我们不想在我们的对抗网络中训练别器网络。
6. 使用别器网络来预测每个生成的图像是真实的还是伪造的,如下所示:
6. 使用别器网络来预测每个生成的图像是真实的还是伪造的,如下所示:
```py
probsA = discriminatorA(generatedA)
......@@ -885,11 +885,11 @@ print("Number of batches:{}".format(num_batches))
# 训练别器网络
# 训练别器网络
本小节中的代码是上一节中代码的延续。 在这里,您将看到如何训练别器网络:
本小节中的代码是上一节中代码的延续。 在这里,您将看到如何训练别器网络:
1. 首先对两个域的图像进行小批量采样,如以下代码所示:
......@@ -905,30 +905,30 @@ print("Number of batches:{}".format(num_batches))
generatedA = generatorBToA.predict(batchB)
```
3. 然后,对别器网络 A 进行真实图像和伪图像(由生成器网络生成)的训练,如下所示:
3. 然后,对别器网络 A 进行真实图像和伪图像(由生成器网络生成)的训练,如下所示:
```py
dALoss1 = discriminatorA.train_on_batch(batchA, real_labels)
dALoss2 = discriminatorB.train_on_batch(generatedA, fake_labels)
```
此步骤将在真实图像和伪图像的微型批次上训练别器 A,并会稍微改善网络。
此步骤将在真实图像和伪图像的微型批次上训练别器 A,并会稍微改善网络。
4. 接下来,对别器 B 进行真实图像和伪图像的训练,如下所示:
4. 接下来,对别器 B 进行真实图像和伪图像的训练,如下所示:
```py
dBLoss1 = discriminatorB.train_on_batch(batchB, real_labels)
dbLoss2 = discriminatorB.train_on_batch(generatedB, fake_labels)
```
5. 现在,计算别器网络的总损耗值,如下所示:
5. 现在,计算别器网络的总损耗值,如下所示:
```py
d_loss = 0.5 * np.add(0.5 * np.add(dALoss1, dALoss2), 0.5 *
np.add(dBLoss1, dbLoss2))
```
到目前为止,我们一直在添加代码来训练别器网络。 在下一部分中,我们将训练对抗性网络以训练生成器网络。
到目前为止,我们一直在添加代码来训练别器网络。 在下一部分中,我们将训练对抗性网络以训练生成器网络。
......@@ -978,7 +978,7 @@ d_loss = 0.5 * np.add(0.5 * np.add(dALoss1, dALoss2), 0.5 *
将前面的代码块放入`epochs`循环中。 每隔 10 个时间段,它将生成一批伪图像并将其保存到结果目录。
接下来,将平均损失存储到 TensorBoard 中以进行可视化。 既存储损失,也要存储生成器网络的平均损失和别器网络的平均损失,如以下示例所示:
接下来,将平均损失存储到 TensorBoard 中以进行可视化。 既存储损失,也要存储生成器网络的平均损失和别器网络的平均损失,如以下示例所示:
```py
write_log(tensorboard, 'discriminator_loss', np.mean(dis_losses),
......@@ -1006,7 +1006,7 @@ generatorAToB.save("directory/for/the/generatorAToB/model.h5")
generatorBToA.save("directory/for/the/generatorBToA/model.h5")
```
同样,通过添加以下行来保存别器模型:
同样,通过添加以下行来保存别器模型:
```py
# Specify the path for the discriminator A model
......@@ -1052,7 +1052,7 @@ tensorboard --logdir=logs
现在,在浏览器中打开`localhost:6006`。 TensorBoard 的**标量**部分包含两个损失的图,如以下示例所示:
别器网络的损耗图如下所示:
别器网络的损耗图如下所示:
![](img/69b11dd7-e38d-46ad-a293-69d3827daf0d.png)
......
......@@ -25,7 +25,7 @@ Pix2pix 是一种**生成对抗网络**(**GAN**),用于图像到图像的
Pix2pix 是条件 GAN 的变体。 我们已经在第 3 章,“使用条件 GAN(cGAN)进行面部老化处理”中介绍。 在继续之前,请确保您了解什么是 cGAN。 一旦熟悉了 cGAN,就可以继续本章。 Pix2pix 是一种 GAN,能够使用**机器学习****ML**)的无监督方法执行图像到图像的翻译。 经过训练后,pix2pix 可以将图像从域 A 转换为域 B。香草 CNN 也可以用于图像到图像的转换,但是它们不会生成逼真的图像。 另一方面,pix2pix 显示出巨大的潜力,能够生成逼真的图像。 我们将训练 pix2pix 将立面的标签转换为立面的图像。 让我们从了解 pix2pix 的体系结构开始。
Pix2pix 是条件 GAN 的变体。 我们已经在第 3 章,“使用条件 GAN(cGAN)进行面部老化处理”中介绍。 在继续之前,请确保您了解什么是 cGAN。 一旦熟悉了 cGAN,就可以继续本章。 Pix2pix 是一种 GAN,能够使用**机器学习****ML**)的无监督方法执行图像到图像的翻译。 经过训练后,pix2pix 可以将图像从域 A 转换为域 B。朴素 CNN 也可以用于图像到图像的转换,但是它们不会生成逼真的图像。 另一方面,pix2pix 显示出巨大的潜力,能够生成逼真的图像。 我们将训练 pix2pix 将立面的标签转换为立面的图像。 让我们从了解 pix2pix 的体系结构开始。
......@@ -35,7 +35,7 @@ Pix2pix 是条件 GAN 的变体。 我们已经在第 3 章,“使用条件 GA
与其他 GAN 相似,pix2pix 由两个网络组成:生成器网络和鉴别器网络。 发电机网络的体系结构受 [U-Net](https://arxiv.org/pdf/1505.04597.pdf) 的体系结构的启发。 同样,鉴别器网络的架构也受到 [PatchGAN](https://arxiv.org/pdf/1604.04382.pdf) 架构的启发。 这两个网络都是深度卷积神经网络。 在本节中,我们将详细探讨 pix2pix。
与其他 GAN 相似,pix2pix 由两个网络组成:生成器网络和判别器网络。 发电机网络的体系结构受 [U-Net](https://arxiv.org/pdf/1505.04597.pdf) 的体系结构的启发。 同样,判别器网络的架构也受到 [PatchGAN](https://arxiv.org/pdf/1604.04382.pdf) 架构的启发。 这两个网络都是深度卷积神经网络。 在本节中,我们将详细探讨 pix2pix。
......@@ -163,7 +163,7 @@ We will cover more on the architecture in the *Keras implementation of pix2pix*
pix2pix 中别器网络的架构受到 PatchGAN 网络架构的启发。 PatchGAN 网络包含八个卷积块,如下所示:
pix2pix 中别器网络的架构受到 PatchGAN 网络架构的启发。 PatchGAN 网络包含八个卷积块,如下所示:
| **图层名称** | **超参数** | **输入形状** | **输出形状** |
| 第一 2D 卷积层 | 过滤器= 64,kernel_size = 4,步幅= 2,padding ='same', | (256, 256, 1) | ( 256、256、64) |
......@@ -192,7 +192,7 @@ pix2pix 中鉴别器网络的架构受到 PatchGAN 网络架构的启发。 Patc
| 展平层 | 没有 | (1、1、512) | (512, ) |
| 致密层 | 单位= 2,激活='softmax' | (1、1、512) | (2, ) |
下表突出显示了别器网络的体系结构和配置。 fl1 tten 层将张量展平为一维数组。
下表突出显示了别器网络的体系结构和配置。 fl1 tten 层将张量展平为一维数组。
The remaining layers in the discriminator network are covered in the *The Keras implementation of pix2pix* section of this chapter.
......@@ -210,9 +210,9 @@ Pix2pix 是一个条件生成对抗网络,并且对于 c 附加 GAN s 的目
![](img/a2a19bc3-64c1-48bd-b2d8-4b1303293dce.png)
在这里,网络`G`(生成器)正试图使针对对手`D`别器)的先前功能最小化,而对手`D`则试图使先前的功能最大化 功能。
在这里,网络`G`(生成器)正试图使针对对手`D`别器)的先前功能最小化,而对手`D`则试图使先前的功能最大化 功能。
如果必须比较香草 GAN 和条件 GAN 的目标函数,则香草 GAN 的目标函数如下:
如果必须比较朴素 GAN 和条件 GAN 的目标函数,则朴素 GAN 的目标函数如下:
![](img/b2a6e013-9ffb-4a51-93fb-91454976c9c4.png)
......@@ -442,7 +442,7 @@ visualize_bw_image(image)
![](img/1afafd90-be55-4633-97c5-a1d1eb7fd6c3.png)
我们将训练一个 pix2pix 网络,该网络能够从立面标签生成立面图像。 让我们开始使用生成器和别器的 Keras 实现。
我们将训练一个 pix2pix 网络,该网络能够从立面标签生成立面图像。 让我们开始使用生成器和别器的 Keras 实现。
......@@ -452,7 +452,7 @@ visualize_bw_image(image)
如前所述,pix2pix 具有两个网络:一个生成器和一个鉴别器。 该生成器受 U-Net 架构的启发。 同样,鉴别器网络也受到 PatchGAN 架构的启发。 我们将在以下部分中实现这两个网络。
如前所述,pix2pix 具有两个网络:一个生成器和一个判别器。 该生成器受 U-Net 架构的启发。 同样,判别器网络也受到 PatchGAN 架构的启发。 我们将在以下部分中实现这两个网络。
在开始编写实现之前,创建一个 Python 文件 `main.py` ,然后按以下方式导入基本模块:
......@@ -756,7 +756,7 @@ def build_unet_generator():
return model
```
我们现在已经成功地为发电机网络创建了 Keras 模型。 在下一节中,我们将为别器网络创建 Keras 模型。
我们现在已经成功地为发电机网络创建了 Keras 模型。 在下一节中,我们将为别器网络创建 Keras 模型。
......@@ -766,7 +766,7 @@ def build_unet_generator():
鉴别器网络受 PatchGAN 架构的启发。 它包含八个卷积块,一个密集层和一个平坦层。 鉴别器网络获取从尺寸为(256、256、1)的图像中提取的一组补丁,并预测给定补丁的概率。 让我们在 Keras 中实现鉴别器。
判别器网络受 PatchGAN 架构的启发。 它包含八个卷积块,一个密集层和一个平坦层。 判别器网络获取从尺寸为(256、256、1)的图像中提取的一组补丁,并预测给定补丁的概率。 让我们在 Keras 中实现判别器。
1. 首先初始化生成器网络所需的超参数:
......@@ -831,7 +831,7 @@ dense_layer = Dense(units=2, activation='softmax')(flatten_layer)
model_patch_gan = Model(inputs=[input_layer], outputs=[dense_layer, flatten_layer])
```
PatchGAN 模型将输入张量作为输入,并输出两个张量,一个来自密集层,另一个来自平坦层。 我们的 PatchGAN 网络现已准备就绪。 但是,它本身不能用作鉴别器。 而是将单个补丁分类为真实或伪造类别。 要创建完整的鉴别器,请按照下列步骤操作:
PatchGAN 模型将输入张量作为输入,并输出两个张量,一个来自密集层,另一个来自平坦层。 我们的 PatchGAN 网络现已准备就绪。 但是,它本身不能用作判别器。 而是将单个补丁分类为真实或伪造类别。 要创建完整的判别器,请按照下列步骤操作:
1. 我们将从输入图像中提取色块,并将它们逐一馈送到 PatchGAN。 创建一个等于补丁数量的输入层列表,如下所示:
......@@ -902,13 +902,13 @@ final_output = Dense(2, activation="softmax")(output1)
`"softmax"`用作最后一个密集层的激活功能。 这将返回概率分布。
10. 最后,通过如下指定网络的输入和输出来创建别器模型:
10. 最后,通过如下指定网络的输入和输出来创建别器模型:
```py
discriminator = Model(inputs=list_input_layers, outputs=[final_output])
```
别器网络的完整代码如下:
别器网络的完整代码如下:
```py
def build_patchgan_discriminator():
......@@ -993,7 +993,7 @@ def build_patchgan_discriminator():
return discriminator
```
我们现在已经成功创建了别器网络。 接下来,让我们创建一个对抗网络。
我们现在已经成功创建了别器网络。 接下来,让我们创建一个对抗网络。
......@@ -1003,7 +1003,7 @@ def build_patchgan_discriminator():
在本节中,我们将创建一个**对抗网络**,其中包含 U-Net 生成器网络和 PatchGAN 别器网络。 执行以下步骤来创建对抗网络:
在本节中,我们将创建一个**对抗网络**,其中包含 U-Net 生成器网络和 PatchGAN 别器网络。 执行以下步骤来创建对抗网络:
1. 首先初始化超参数:
......@@ -1040,13 +1040,13 @@ for row_idx in row_idx_list:
output_shape=input_img_dim)(generated_images))
```
5. 冻结了鉴别器网络的训练,因为我们不想训练 鉴别器网络:
5. 冻结了判别器网络的训练,因为我们不想训练 判别器网络:
```py
discriminator.trainable = False
```
6. 现在,我们应该有一个补丁列表。 通过 PatchGAN 别器网络传递它们:
6. 现在,我们应该有一个补丁列表。 通过 PatchGAN 别器网络传递它们:
```py
dis_output = discriminator(generated_patches_list)
......@@ -1059,7 +1059,7 @@ model = Model(inputs=[input_layer], outputs=[generated_images,
dis_output])
```
这些步骤使用两个网络(生成器网络和别器网络)创建对抗模型。 对抗模型的整个代码如下:
这些步骤使用两个网络(生成器网络和别器网络)创建对抗模型。 对抗模型的整个代码如下:
```py
def build_adversarial_model(generator, discriminator):
......@@ -1094,7 +1094,7 @@ def build_adversarial_model(generator, discriminator):
return model
```
现在,我们已经成功地为发电机网络,别器网络和对抗模型创建了模型。 我们准备训练 pix2pix。 在下一部分中,我们将在 Facades 数据集中训练 pix2pix 网络。
现在,我们已经成功地为发电机网络,别器网络和对抗模型创建了模型。 我们准备训练 pix2pix。 在下一部分中,我们将在 Facades 数据集中训练 pix2pix 网络。
......@@ -1104,7 +1104,7 @@ def build_adversarial_model(generator, discriminator):
像任何其他 GAN 一样,训练 pix2pix 网络是一个两步过程。 第一步,我们训练别器网络。 在第二步中,我们训练对抗网络,最终训练发电机网络。 让我们开始训练网络。
像任何其他 GAN 一样,训练 pix2pix 网络是一个两步过程。 第一步,我们训练别器网络。 在第二步中,我们训练对抗网络,最终训练发电机网络。 让我们开始训练网络。
执行以下步骤来训练 SRGAN 网络:
......@@ -1127,14 +1127,14 @@ common_optimizer = Adam(lr=1E-4, beta_1=0.9, beta_2=0.999,
对于所有网络,我们将使用`Adam`优化器,其中`learning rate`等于 1e-4, `beta_1` 等于 0.9, `beta_2`等于 0.999,并且`epsilon`等于 1e-08。
3. 接下来,构建并编译 PatchGAN 别器网络,如下所示:
3. 接下来,构建并编译 PatchGAN 别器网络,如下所示:
```py
patchgan_discriminator = build_patchgan_discriminator()
patchgan_discriminator.compile(loss='binary_crossentropy', optimizer=common_optimizer)
```
要编译别器模型,请使用`binary_crossentropy`作为损失函数,并使用`common_optimizer`作为训练优化器。
要编译别器模型,请使用`binary_crossentropy`作为损失函数,并使用`common_optimizer`作为训练优化器。
4. 现在,构建并编译生成器网络,如下所示:
......@@ -1143,7 +1143,7 @@ unet_generator = build_unet_generator()
unet_generator.compile(loss='mae', optimizer=common_optimizer)
```
要编译别器模型,请使用 `mse` 作为损失函数,并使用 `common_optimizer` 作为训练优化器。
要编译别器模型,请使用 `mse` 作为损失函数,并使用 `common_optimizer` 作为训练优化器。
5. 接下来,构建并编译对抗模型,如下所示:
......@@ -1244,13 +1244,13 @@ def generate_and_extract_patches(images, facades, generator_model, batch_counter
前面的功能使用生成器网络生成伪图像,然后从生成的图像中提取补丁。 现在,我们应该有一个补丁列表及其基本真理值。
13. 现在,在生成的补丁上训练别器网络:
13. 现在,在生成的补丁上训练别器网络:
```py
d_loss = patchgan_discriminator.train_on_batch(patches, labels)
```
这将在提取的补丁和地面真相标签上训练别器网络。
这将在提取的补丁和地面真相标签上训练别器网络。
14. 接下来,训练对抗模型。 对抗性模型将训练生成器网络,但冻结区分器网络的训练。 使用以下代码:
......@@ -1272,7 +1272,7 @@ dis_losses.append(d_loss)
gen_losses.append(g_loss)
```
17. 另外,将平均损失存储到 TensorBoard 以进行可视化。 既存储损失,也要存储发电机网络的平均损失和别器网络的平均损失:
17. 另外,将平均损失存储到 TensorBoard 以进行可视化。 既存储损失,也要存储发电机网络的平均损失和别器网络的平均损失:
```py
write_log(tensorboard, 'discriminator_loss', np.mean(dis_losses),
......@@ -1330,7 +1330,7 @@ def save_images(real_images, real_sketches, generated_images, num_epoch, dataset
unet_generator.save_weights("generator.h5")
```
同样,通过添加以下行来保存别器模型:
同样,通过添加以下行来保存别器模型:
```py
# Specify the path for the discriminator model
......
......@@ -10,7 +10,7 @@
* 我们从对 GAN 的简要介绍开始,学习了各种重要概念。
* 然后,我们探索了 3D-GAN,这是一种可以生成 3D 图像的 GAN。 我们训练了 3D-GAN,以生成现实世界对象的 3D 模型,例如*飞机**桌子。*
* 在第三章中,我们探索了用于面部衰老的条件 GAN。 我们学习了如何使用条件 GAN 将处于年龄的的人脸图像转换为同一张脸的图像。 我们还讨论了 Age-cGAN 的各种实际应用。
* 在第三章中,我们探索了用于面部老化的条件 GAN。 我们学习了如何使用条件 GAN 将处于年龄的的人脸图像转换为同一张脸的图像。 我们还讨论了 Age-cGAN 的各种实际应用。
* 之后,我们探索了**深度卷积生成对抗网络****DCGANs**),该网络用于生成动漫人物的面孔。
* 在第五章中,我们探讨了**超分辨率生成对抗网络****SRGAN**),该网络可用于从低分辨率图像生成高分辨率图像。 之后,我们讨论了 SRGAN 如何解决一些非常有趣的现实问题。
* 然后,我们探索了 StackGAN,我们将其用于执行文本到图像的合成任务。 我们在训练 StackGAN 之前先探索了一个数据集,然后通过讨论 StackGAN 的实际应用来结束本章。
......
......@@ -61,11 +61,11 @@
![](img/956dc503-ac1c-451e-89a1-2f47d07bb5d1.png)
但是,与通过直接训练整个模型来实现这一目标的自动编码器相反,在 GAN 中,目标是通过在生成器和别器之间进行的游戏来实现的,这是另一个需要采样的参数化函数, *x <sub class="calibre20">i</sub> ∈ <sup class="calibre27">n</sup>* ,并返回概率:
但是,与通过直接训练整个模型来实现这一目标的自动编码器相反,在 GAN 中,目标是通过在生成器和别器之间进行的游戏来实现的,这是另一个需要采样的参数化函数, *x <sub class="calibre20">i</sub> ∈ <sup class="calibre27">n</sup>* ,并返回概率:
![](img/4bd5bc8f-ede6-45e8-80ea-543706b24852.png)
鉴别器的作用是区分从 *p <sub class="calibre20">数据</sub>* (返回大概率)提取的样本与由 *g(z;θ <sub class="calibre20">g</sub> )*(返回低概率)。 但是,由于生成器的目标是变得越来越有能力复制 *p <sub class="calibre20">数据</sub>* ,因此其作用是学习如何用几乎完美复制品中的样本来欺骗鉴别器 数据生成过程。 因此,考虑到区分因素,目标是最大化以下条件:
判别器的作用是区分从 *p <sub class="calibre20">数据</sub>* (返回大概率)提取的样本与由 *g(z;θ <sub class="calibre20">g</sub> )*(返回低概率)。 但是,由于生成器的目标是变得越来越有能力复制 *p <sub class="calibre20">数据</sub>* ,因此其作用是学习如何用几乎完美复制品中的样本来欺骗判别器 数据生成过程。 因此,考虑到区分因素,目标是最大化以下条件:
![](img/6776cf30-d26d-4c1b-aa66-65165ebac3a2.png)
......@@ -73,7 +73,7 @@
![](img/1c69083f-4200-4599-a7af-1b594ab3bc20.png)
实际上,当两个代理都成功地优化了目标时,鉴别器将能够区分从 *p <sub class="calibre20">数据</sub>* 提取的样本和异常值,并且生成器将能够输出合成样本 属于 *p <sub class="calibre20">数据</sub>* 。 但是,必须明确的是,可以通过使用单个目标来表达问题,并且训练过程的目标是找出最佳参数集,*θ= {θ <sub class="calibre20">d</sub> ,θ <sub class="calibre20">g</sub> }* ,因此鉴别器将其最大化,而生成器将其最小化。 必须同时优化两个代理,但是实际上,过程是交替的(例如,生成器,鉴别器,生成器等)。 目标可以用更紧凑的形式表示如下:
实际上,当两个代理都成功地优化了目标时,判别器将能够区分从 *p <sub class="calibre20">数据</sub>* 提取的样本和异常值,并且生成器将能够输出合成样本 属于 *p <sub class="calibre20">数据</sub>* 。 但是,必须明确的是,可以通过使用单个目标来表达问题,并且训练过程的目标是找出最佳参数集,*θ= {θ <sub class="calibre20">d</sub> ,θ <sub class="calibre20">g</sub> }* ,因此判别器将其最大化,而生成器将其最小化。 必须同时优化两个代理,但是实际上,过程是交替的(例如,生成器,判别器,生成器等)。 目标可以用更紧凑的形式表示如下:
![](img/304d8dd9-8212-4b27-a550-71c85664a763.png)
......@@ -81,7 +81,7 @@
![](img/3ef1bf38-3d09-434a-993d-0a410667c1fe.png)
根据博弈论,这是一个不合作的博弈,它承认**纳什均衡**点。 当满足这种条件时,如果我们假设双方都知道对手的策略,那么他们就没有理由再改变自己的策略了。 在 GAN 的情况下,这种情况意味着一旦达到平衡(甚至只是理论上),生成器就可以继续输出样本,并确保它们不会被鉴别器误分类。 同时,鉴别器没有理由改变其策略,因为它可以完美地区分 *p <sub class="calibre20">数据</sub>* 和任何其他分布。 从动态角度来看,两个组件的训练速度都是不对称的。 尽管生成器通常需要更多的迭代,但鉴别器可以非常迅速地收敛。 但是,这样的过早收敛对于整体性能可能非常危险。 实际上,由于鉴别器提供的反馈,发电机也达到了最佳状态。 不幸的是,当梯度很小时,这种贡献可以忽略不计,其明显的结果是,生成器错过了提高其输出更好样本能力的机会(例如,当样本是图像时,它们的质量可能会保持非常低,甚至 具有复杂的架构)。 这种情况并不取决于发生器固有的容量不足,而是取决于鉴别器收敛(或非常接近收敛)后开始应用的有限次校正。 在实践中,由于没有特定的规则,唯一有效的建议是在训练过程中检查两个损失函数。 如果鉴别器的损失下降得太快,而发电机的损失仍然很大,那么通常最好在单个鉴别器步骤中插入更多的发电机训练步骤。
根据博弈论,这是一个不合作的博弈,它承认**纳什均衡**点。 当满足这种条件时,如果我们假设双方都知道对手的策略,那么他们就没有理由再改变自己的策略了。 在 GAN 的情况下,这种情况意味着一旦达到平衡(甚至只是理论上),生成器就可以继续输出样本,并确保它们不会被判别器误分类。 同时,判别器没有理由改变其策略,因为它可以完美地区分 *p <sub class="calibre20">数据</sub>* 和任何其他分布。 从动态角度来看,两个组件的训练速度都是不对称的。 尽管生成器通常需要更多的迭代,但判别器可以非常迅速地收敛。 但是,这样的过早收敛对于整体性能可能非常危险。 实际上,由于判别器提供的反馈,发电机也达到了最佳状态。 不幸的是,当梯度很小时,这种贡献可以忽略不计,其明显的结果是,生成器错过了提高其输出更好样本能力的机会(例如,当样本是图像时,它们的质量可能会保持非常低,甚至 具有复杂的架构)。 这种情况并不取决于发生器固有的容量不足,而是取决于判别器收敛(或非常接近收敛)后开始应用的有限次校正。 在实践中,由于没有特定的规则,唯一有效的建议是在训练过程中检查两个损失函数。 如果判别器的损失下降得太快,而发电机的损失仍然很大,那么通常最好在单个判别器步骤中插入更多的发电机训练步骤。
......@@ -137,9 +137,9 @@ Examples of unimodal (left) and bimodal (right) distributions
现在,让我们想象一下我们正在处理人脸图片的多模式分布(例如下一节将要讨论的示例中的人脸图片)。 模式的内容是什么? 很难精确地回答这个问题,但是很容易理解,对应于最大数据生成过程的人脸应该包含数据集中最常见的元素(例如,如果 80% 的人留着胡须 ,我们可以合理地假设该模式将包含它)。
我们在使用 GAN 时面临的最著名,最棘手的问题之一就是**模式崩溃**,它涉及到次优的最终配置,其中生成器冻结在某个模式附近,并不断提供与 输出。 发生这种情况的原因非常难以分析(实际上,只有理论),但是我们可以理解如果重新考虑 minimax 游戏,为什么会发生这种情况。 当我们要训练两个不同的分量时,即使保证了纳什均衡,在几次迭代之后,对于最常见的模式,鉴别器也会变得非常有选择性。 当然,当训练发生器以欺骗鉴别器时,实现此目标的最简单方法是简单地避免所有采样远离模式。 这种行为增加了鉴别器的选择性,并创建了一个反馈过程,使 GAN 陷入只有数据生成过程只有一小部分区域的状态。
我们在使用 GAN 时面临的最著名,最棘手的问题之一就是**模式崩溃**,它涉及到次优的最终配置,其中生成器冻结在某个模式附近,并不断提供与 输出。 发生这种情况的原因非常难以分析(实际上,只有理论),但是我们可以理解如果重新考虑 minimax 游戏,为什么会发生这种情况。 当我们要训练两个不同的分量时,即使保证了纳什均衡,在几次迭代之后,对于最常见的模式,判别器也会变得非常有选择性。 当然,当训练发生器以欺骗判别器时,实现此目标的最简单方法是简单地避免所有采样远离模式。 这种行为增加了判别器的选择性,并创建了一个反馈过程,使 GAN 陷入只有数据生成过程只有一小部分区域的状态。
在梯度方面,鉴别器提供的用于优化发生器的信息很快变得非常稀缺,因为最常见的样本不需要任何调整。 另一方面,当生成器开始避免所有 *p(x)*不接近最大值的样本时,它们不会将鉴别器暴露给新的,可能有效的样本,因此梯度将 保持很小,直到消失为零。 不幸的是,没有可以用来避免此问题的全局策略,但是在本章中,我们将讨论一种建议的方法,以减轻模式崩溃(WGAN)的风险。 特别是,我们将把注意力集中在 Jensen-Shannon 发散的局限性上,在某些情况下,由于没有大的梯度,这可能导致 GAN 达到次优配置。 在本简介中,重要的是,不熟悉这些模型的读者应意识到风险,并能够在发生模式崩溃时识别出它。
在梯度方面,判别器提供的用于优化发生器的信息很快变得非常稀缺,因为最常见的样本不需要任何调整。 另一方面,当生成器开始避免所有 *p(x)*不接近最大值的样本时,它们不会将判别器暴露给新的,可能有效的样本,因此梯度将 保持很小,直到消失为零。 不幸的是,没有可以用来避免此问题的全局策略,但是在本章中,我们将讨论一种建议的方法,以减轻模式崩溃(WGAN)的风险。 特别是,我们将把注意力集中在 Jensen-Shannon 发散的局限性上,在某些情况下,由于没有大的梯度,这可能导致 GAN 达到次优配置。 在本简介中,重要的是,不熟悉这些模型的读者应意识到风险,并能够在发生模式崩溃时识别出它。
此时,我们可以继续进行实际操作,并使用 TensorFlow 建模真实的 GAN。
......@@ -187,7 +187,7 @@ nb_iterations = int(nb_samples / batch_size)
`400` 64×64 灰度样本(每个样本对应 4,096 个分量)。 在此示例中,我们选择采用具有`512`分量的噪声代码向量,并以`50`个样本批次训练`500`时期的模型。 这样的值不是基于黄金规则的,因为(尤其是对于 GAN)几乎不可能知道哪个设置会产生最佳结果。 因此,与往常一样,我强烈建议在做出决定之前检查不同的超参数集。
当训练过程不太长时,可以使用一组统一采样的超参数(例如*批大小∈{20,50,100,200}* 检查生成器和别器的平均损失 ])。 例如,如果某个最佳值似乎在范围内( *50,100* ),那么一个好的策略是提取一些随机值并重新训练模型。 可以重复进行此过程,直到采样值之间的差异可以忽略不计为止。 当然,考虑到这些模型的复杂性,只有使用专用硬件(即多个 GPU 或 TPU)才能进行彻底的搜索。 因此,另一个建议是从经过测试的配置开始(即使上下文不同),并进行小的修改,以便针对特定任务优化它们。 在此示例中,我们根据原始论文设置了许多值,但是我邀请读者在自定义更改后重新运行代码并观察差异。
当训练过程不太长时,可以使用一组统一采样的超参数(例如*批大小∈{20,50,100,200}* 检查生成器和别器的平均损失 ])。 例如,如果某个最佳值似乎在范围内( *50,100* ),那么一个好的策略是提取一些随机值并重新训练模型。 可以重复进行此过程,直到采样值之间的差异可以忽略不计为止。 当然,考虑到这些模型的复杂性,只有使用专用硬件(即多个 GPU 或 TPU)才能进行彻底的搜索。 因此,另一个建议是从经过测试的配置开始(即使上下文不同),并进行小的修改,以便针对特定任务优化它们。 在此示例中,我们根据原始论文设置了许多值,但是我邀请读者在自定义更改后重新运行代码并观察差异。
现在,我们可以基于以下结构为生成器定义 DAG:
......@@ -250,7 +250,7 @@ def generator(z, is_training=True):
该代码很简单,但是有助于阐明对变量范围上下文的需要(通过命令`tf.variable_scope('generator')`定义)。 由于我们需要以其他方式训练模型,因此在优化生成器时,仅必须更新其变量。 因此,我们在命名范围内定义了所有层,从而允许强制优化器仅工作所有可训练变量的子集。
别器的 DAG 基于以下对称结构:
别器的 DAG 基于以下对称结构:
* 具有( *2、2* )步幅的 128(4×4)个滤波器的 2D 卷积,,相同的 填充,以及泄漏的 ReLU 输出
* 256 个(4×4)滤波器的 2D 卷积,步幅为[ *2,2* ),,相同 填充,以及线性输出
......@@ -344,7 +344,7 @@ with graph.as_default():
第一块包含占位符的声明。 为了清楚起见,虽然`input_x``input_z`的目的很容易理解,但`is_training`可能不太明显。 此布尔值标志的目的是允许在生产阶段禁用批次归一化(必须仅在培训阶段有效)。 下一步包括声明生成器和两个鉴别符(它们在形式上是相同的,因为变量是共享的,但是其中一个被提供了真实的样本,而另一个必须评估生成器的输出)。 然后,是时候定义损耗函数了,它是基于一种可以加快计算速度并增加数值稳定性的技巧。
函数`tf.nn.sigmoid_cross_entropy_with_logits()`接受 *logit* (这就是为什么我们没有将 Sigmoid 变换直接应用于别器输出的原因),并允许我们执行以下向量计算:
函数`tf.nn.sigmoid_cross_entropy_with_logits()`接受 *logit* (这就是为什么我们没有将 Sigmoid 变换直接应用于别器输出的原因),并允许我们执行以下向量计算:
![](img/cb4a2f99-5422-4c6f-bc83-588e81037426.png)
......@@ -367,7 +367,7 @@ session = tf.InteractiveSession(graph=graph)
tf.global_variables_initializer().run()
```
一旦一切准备就绪,就可以开始培训过程。 以下代码片段显示了对别器和生成器进行交替训练的代码:
一旦一切准备就绪,就可以开始培训过程。 以下代码片段显示了对别器和生成器进行交替训练的代码:
```py
import numpy as np
......@@ -911,7 +911,7 @@ Kohonen map weight matrix at the end of the training process
在本章中,我们介绍了 GAN 的概念,并讨论了 DCGAN 的示例。 这种模型具有通过使用 minimax 游戏中涉及的两个神经网络来学习数据生成过程的能力。 生成器必须学习如何返回与训练过程中使用的其他样本没有区别的样本。 鉴别者或批评者必须变得越来越聪明,只为有效样本分配高概率。 对抗训练方法的基础是,通过学习如何用具有与真实属性相同的合成样本作弊的方法,迫使生成器与别器竞争。 同时,生成器被迫通过选择越来越多来与歧视者抗争。 在我们的示例中,我们还分析了一个称为 WGAN 的重要变体,当标准模型无法复制有效样本时可以使用该变体。
在本章中,我们介绍了 GAN 的概念,并讨论了 DCGAN 的示例。 这种模型具有通过使用 minimax 游戏中涉及的两个神经网络来学习数据生成过程的能力。 生成器必须学习如何返回与训练过程中使用的其他样本没有区别的样本。 鉴别者或批评者必须变得越来越聪明,只为有效样本分配高概率。 对抗训练方法的基础是,通过学习如何用具有与真实属性相同的合成样本作弊的方法,迫使生成器与别器竞争。 同时,生成器被迫通过选择越来越多来与歧视者抗争。 在我们的示例中,我们还分析了一个称为 WGAN 的重要变体,当标准模型无法复制有效样本时可以使用该变体。
SOM 是基于大脑特定区域功能的结构,该结构迫使其特定单元学习输入样本的特定特征。 这样的模型会自动进行自我组织,从而使响应相似模式的单位更加接近。 一旦提供了一个新样本,就足以计算获胜单位,该单位的权重与样本的距离最短; 并且在贴标过程之后,可以立即了解引起响应的特征(例如,垂直线或高级特征,例如是否有眼镜或胡须或脸部形状)。
......@@ -923,9 +923,9 @@ SOM 是基于大脑特定区域功能的结构,该结构迫使其特定单元
1. 在 GAN 中,生成器和别器的作用与自动编码器中的编码器和解码器相同。 它是否正确?
2. 别器能否输出*(-1,1)*范围内的值?
3. GAN 的问题之一是别器过早收敛。 这个正确吗?
1. 在 GAN 中,生成器和别器的作用与自动编码器中的编码器和解码器相同。 它是否正确?
2. 别器能否输出*(-1,1)*范围内的值?
3. GAN 的问题之一是别器过早收敛。 这个正确吗?
4. 在 Wasserstein GAN 中,批评家(区分者)在训练阶段是否比生成器慢?
5. 考虑到前面的问题,不同速度的原因是什么?
6. *U(-1,0)**U(1,2)*之间的 Jensen-Shannon 散度值是多少?
......
......@@ -147,9 +147,9 @@
1. 没有; 生成器和别器在功能上是不同的。
2. 不,不是这样,因为别器的输出必须是一个概率(即 *p <sub class="calibre20">i</sub> ∈(0,1)*)。
3. 是; 这是正确的。 别器可以学习非常快地输出不同的概率,,其损失函数的斜率可以变得接近于 0,从而减小了提供给发生器的校正反馈的幅度。
1. 没有; 生成器和别器在功能上是不同的。
2. 不,不是这样,因为别器的输出必须是一个概率(即 *p <sub class="calibre20">i</sub> ∈(0,1)*)。
3. 是; 这是正确的。 别器可以学习非常快地输出不同的概率,,其损失函数的斜率可以变得接近于 0,从而减小了提供给发生器的校正反馈的幅度。
4. 是; 通常会比较慢。
5. 评论者比较慢,因为每次更新后都会对变量进行裁剪。
6. 由于支撑脱节,Jensen-Shannon 散度等于 *log(2)*
......
......@@ -23,14 +23,14 @@
GAN 是学习生成类似于真实数据或训练集中数据的神经网络。 GAN 的关键思想是让生成器网络和鉴别器网络相互竞争:生成器试图生成看起来像真实数据的数据,而鉴别器试图分辨生成的数据是否真实(从已知实数 数据)或伪造(由生成器生成)。 生成器和鉴别器是一起训练的,在训练过程中,生成器学会生成看起来越来越像真实数据的数据,而鉴别器则学会将真实数据与伪数据区分开。 生成器通过尝试使鉴别器的输出概率为真实数据来学习,当将生成器的输出作为鉴别器的输入时,生成器的输出概率尽可能接近 1.0,而鉴别器通过尝试实现两个目标来学习:
GAN 是学习生成类似于真实数据或训练集中数据的神经网络。 GAN 的关键思想是让生成器网络和判别器网络相互竞争:生成器试图生成看起来像真实数据的数据,而判别器试图分辨生成的数据是否真实(从已知实数 数据)或伪造(由生成器生成)。 生成器和判别器是一起训练的,在训练过程中,生成器学会生成看起来越来越像真实数据的数据,而判别器则学会将真实数据与伪数据区分开。 生成器通过尝试使判别器的输出概率为真实数据来学习,当将生成器的输出作为判别器的输入时,生成器的输出概率尽可能接近 1.0,而判别器通过尝试实现两个目标来学习:
* 当以发电机的输出作为输入时,使其输出的可能性为实,尽可能接近 0.0,这恰好是发电机的相反目标
* 当输入真实数据作为输入时,使其输出的可能性为实数,尽可能接近 1.0
In the next section, you'll see a detailed code snippet that matches the given description of the generator and the discriminator networks and their training process. If you feel like understanding more about GANs, in addition to our summary overview here, you can search for *"Introduction to GANs"* on YouTube and watch Ian Goodfellow's introduction and tutorial videos on GAN at NIPS (Neural Information Processing Systems) Conference 2016 and ICCV (International Conference on Computer Vision) 2017\. In fact, there are 7 NIPS 2016 Workshop on Adversarial Training videos and 12 ICCV 2017 GAN Tutorial videos on YouTube that you can immerse yourself in.
在生成者和区分者两个参与者的竞争目标下,GAN 是一个寻求两个对手之间保持平衡的系统。 如果两个玩家都具有无限的能力并且可以进行最佳训练,那么纳什均衡(继 1994 年诺贝尔经济学奖得主约翰·纳什和电影主题 *A Beautiful Mind* 之后) 一种状态,在这种状态下,任何玩家都无法通过仅更改其自己的策略来获利,这对应于生成器生成数据的状态,该数据看起来像真实数据,而别器无法从假数据中分辨真实数据。
在生成者和区分者两个参与者的竞争目标下,GAN 是一个寻求两个对手之间保持平衡的系统。 如果两个玩家都具有无限的能力并且可以进行最佳训练,那么纳什均衡(继 1994 年诺贝尔经济学奖得主约翰·纳什和电影主题 *A Beautiful Mind* 之后) 一种状态,在这种状态下,任何玩家都无法通过仅更改其自己的策略来获利,这对应于生成器生成数据的状态,该数据看起来像真实数据,而别器无法从假数据中分辨真实数据。
If you're interested in knowing more about the Nash Equilibrium, Google *"khan academy nash equilibrium"* and watch the two fun videos on it by Sal Khan. The Wikipedia page on Nash Equilibrium and the article, *"**What is the Nash equilibrium and why does it matter?"* in The Economist explaining economics ([https://www.economist.com/blogs/economist-explains/2016/09/economist-explains-economics](https://www.economist.com/blogs/economist-explains/2016/09/economist-explains-economics)) are also a good read. Understanding the basic intuition and idea behind GANs will help you appreciate more why it has great potential.
......@@ -43,9 +43,9 @@ If you're interested in knowing more about the Nash Equilibrium, Google *"khan a
* 撰写看起来像真实新闻的新闻文章
* 生成与训练集中的音频相似的音频波形
基本上,GAN 可以从随机输入生成逼真的图像,文本或音频数据; 如果您具有一组源数据和目标数据的训练集,则 GAN 还可从类似于源数据的输入中生成类似于目标数据的数据。 GAN 模型中的生成器和别器以动态方式工作的这一通用特性,使 GAN 可以生成任何种类的现实输出,这使 GAN 十分令人兴奋。
基本上,GAN 可以从随机输入生成逼真的图像,文本或音频数据; 如果您具有一组源数据和目标数据的训练集,则 GAN 还可从类似于源数据的输入中生成类似于目标数据的数据。 GAN 模型中的生成器和别器以动态方式工作的这一通用特性,使 GAN 可以生成任何种类的现实输出,这使 GAN 十分令人兴奋。
但是,由于生成器和别器的动态或竞争目标,训练 GAN 达到 Nash 平衡状态是一个棘手且困难的问题。 实际上,这仍然是一个开放的研究问题–伊恩·古德费洛(Ian Goodfellow)在 2017 年 8 月对安德鲁·伍(Andrew Ng)进行的*深度学习英雄*采访中(YouTube 上的搜索 *ian goodfellow andrew ng* )说,如果我们 可以使 GAN 变得像深度学习一样可靠,我们将看到 GAN 取得更大的成功,否则我们最终将用其他形式的生成模型代替它们。
但是,由于生成器和别器的动态或竞争目标,训练 GAN 达到 Nash 平衡状态是一个棘手且困难的问题。 实际上,这仍然是一个开放的研究问题–伊恩·古德费洛(Ian Goodfellow)在 2017 年 8 月对安德鲁·伍(Andrew Ng)进行的*深度学习英雄*采访中(YouTube 上的搜索 *ian goodfellow andrew ng* )说,如果我们 可以使 GAN 变得像深度学习一样可靠,我们将看到 GAN 取得更大的成功,否则我们最终将用其他形式的生成模型代替它们。
尽管在 GAN 的培训方面存在挑战,但是在培训期间您已经可以应用[许多有效的已知技巧](https://github.com/soumith/ganhacks) – 我们在这里不会介绍它们,但是如果您有兴趣调整我们将在本章中描述的模型或[许多其他 GAN 模型](https://github.com/eriklindernoren/Keras-GAN) ),或构建自己的 GAN 模型。
......@@ -69,7 +69,7 @@ If you're interested in knowing more about the Nash Equilibrium, Google *"khan a
手写数字的训练模型基于[仓库](https://github.com/jeffxtang/generative-adversarial-networks),这是[这个页面](https://github.com/jonbruner/generative-adversarial-networks)的分支,并添加了显示生成的数字并使用输入占位符保存 TensorFlow 训练模型的脚本,因此我们的 iOS 和 Android 应用程序可以使用该模型。 是的您应该查看[原始仓库的博客](https://www.oreilly.com/learning/generative-adversarial-networks-for-beginners)。在继续之前,需要对具有代码的 GAN 模型有基本的了解。
在研究定义生成器和别器网络并进行 GAN 训练的核心代码片段之前,让我们先运行脚本以在克隆存储库并转到 repo 目录之后训练和测试模型:
在研究定义生成器和别器网络并进行 GAN 训练的核心代码片段之前,让我们先运行脚本以在克隆存储库并转到 repo 目录之后训练和测试模型:
```py
git clone https://github.com/jeffxtang/generative-adversarial-networks
......@@ -100,13 +100,13 @@ images = sess.run(generated_images, {z_placeholder: z_batch})
saver.save(sess, "newmodel/ckpt")
```
`gan-script-fast.py`脚本中,方法`def discriminator(images, reuse_variables=None)`定义了一个别器网络,该网络使用一个真实的手写图像输入或由生成器生成的一个手写输入,经过一个典型的小型 CNN 网络,该网络具有两层`conv2d`层,每一层都遵循 通过`relu`激活和平均池化层以及两个完全连接的层来输出一个标量值,该标量值将保持输入图像为真或假的概率。 另一种方法`def generator(batch_size, z_dim)`定义了生成器网络,该网络采用随机输入的图像向量并将其转换为具有 3 个`conv2d`层的 28 x 28 图像。
`gan-script-fast.py`脚本中,方法`def discriminator(images, reuse_variables=None)`定义了一个别器网络,该网络使用一个真实的手写图像输入或由生成器生成的一个手写输入,经过一个典型的小型 CNN 网络,该网络具有两层`conv2d`层,每一层都遵循 通过`relu`激活和平均池化层以及两个完全连接的层来输出一个标量值,该标量值将保持输入图像为真或假的概率。 另一种方法`def generator(batch_size, z_dim)`定义了生成器网络,该网络采用随机输入的图像向量并将其转换为具有 3 个`conv2d`层的 28 x 28 图像。
现在可以使用这两种方法来定义三个输出:
* `Gz`,即随机图像输入的生成器输出:`Gz = generator(batch_size, z_dimensions)`
* `Dx`,是真实图像输入的别器输出:`Dx = discriminator(x_placeholder)`
* `Dg``Gz`别器输出:`Dg = discriminator(Gz, reuse_variables=True)`
* `Dx`,是真实图像输入的别器输出:`Dx = discriminator(x_placeholder)`
* `Dg``Gz`别器输出:`Dg = discriminator(Gz, reuse_variables=True)`
和三个损失函数:
......@@ -114,11 +114,11 @@ saver.save(sess, "newmodel/ckpt")
* `d_loss_fake`,Dg 和 0 之间的差:`d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = Dg, labels = tf.zeros_like(Dg)))`
* `g_loss`,Dg 和 1 之差:`g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = Dg, labels = tf.ones_like(Dg)))`
请注意,别器尝试使 `d_loss_fake`最小化,而生成器尝试使`g_loss`最小化,两种情况下`Dg`之间的差分别为 0 和 1。
请注意,别器尝试使 `d_loss_fake`最小化,而生成器尝试使`g_loss`最小化,两种情况下`Dg`之间的差分别为 0 和 1。
最后,现在可以为三个损失函数设置三个优化器:`d_trainer_fake``d_trainer_real``g_trainer`,它们全部是通过`tf.train.AdamOptimizer``minimize`方法定义的。
现在,脚本仅创建一个 TensorFlow 会话,通过运行三个优化器将生成器和鉴别器进行 100,000 步训练,将随机图像输入馈入生成器,将真实和伪图像输入均馈入鉴别器。
现在,脚本仅创建一个 TensorFlow 会话,通过运行三个优化器将生成器和判别器进行 100,000 步训练,将随机图像输入馈入生成器,将真实和伪图像输入均馈入判别器。
在运行 `gan-script-fast.py``gan-script-test.py`之后,c 将检查点文件从`newmodel`目录运至`/tmp`,然后转到 TensorFlow 源根目录并运行:
......@@ -155,7 +155,7 @@ python tensorflow/python/tools/freeze_graph.py \
* 图像损坏到原始图像
* 从低分辨率图像到高分辨率图像
在所有情况下,生成器都将输入图像转换为输出图像,试图使输出看起来像真实的目标图像,鉴别器将训练集中的样本或生成器的输出作为输入,并尝试 告诉它是真实图像还是生成器生成的图像。 自然,与模型相比,pix2pix 中的生成器和鉴别器网络以更复杂的方式构建以生成手写数字,并且训练还应用了一些技巧来使过程稳定-有关详细信息,您可以阅读本文或 TensorFlow 实现链接 较早提供。 我们在这里仅向您展示如何设置训练集和训练 pix2pix 模型以增强低分辨率图像。
在所有情况下,生成器都将输入图像转换为输出图像,试图使输出看起来像真实的目标图像,判别器将训练集中的样本或生成器的输出作为输入,并尝试 告诉它是真实图像还是生成器生成的图像。 自然,与模型相比,pix2pix 中的生成器和判别器网络以更复杂的方式构建以生成手写数字,并且训练还应用了一些技巧来使过程稳定-有关详细信息,您可以阅读本文或 TensorFlow 实现链接 较早提供。 我们在这里仅向您展示如何设置训练集和训练 pix2pix 模型以增强低分辨率图像。
1. 通过在终端上运行来克隆仓库:
......@@ -541,7 +541,7 @@ No OpKernel was registered to support Op 'FIFOQueueV2' with these attrs. Registe
![](img/0e0f47b1-2efa-4ec0-9eaa-4b21356cad23.png)Figure 9.3: Showing GAN model selection and results of generated handwritten digits
这些数字看起来很像真实的人类手写数字,都是在训练了基本 GAN 模型之后完成的。 如果您返回并查看进行训练的代码,并且停下来思考一下 GAN 的工作原理,一般来说,则生成器和别器如何相互竞争,以及 尝试达到稳定的 Nash 平衡状态,在这种状态下,生成器可以生成区分器无法分辨出真实还是伪造的真实假数据,您可能会更欣赏 GAN 的魅力。
这些数字看起来很像真实的人类手写数字,都是在训练了基本 GAN 模型之后完成的。 如果您返回并查看进行训练的代码,并且停下来思考一下 GAN 的工作原理,一般来说,则生成器和别器如何相互竞争,以及 尝试达到稳定的 Nash 平衡状态,在这种状态下,生成器可以生成区分器无法分辨出真实还是伪造的真实假数据,您可能会更欣赏 GAN 的魅力。
现在,让我们选择 Enhance Image 选项,您将在图 9.4 中看到结果,该结果与图 9.1 中的 Python 测试代码生成的结果相同:
......@@ -791,7 +791,7 @@ void runPix2PixBlurryModel() {
在本章中,我们快速浏览了 GAN 的美好世界。 我们介绍了 GAN 的含义以及它们为何如此有趣的原因-生成器和别器相互竞争并尝试击败的方式听起来对大多数人来说很有吸引力。 然后,我们详细介绍了如何训练基本 GAN 模型和更高级的图像分辨率增强模型以及如何为移动设备准备它们的详细步骤。 最后,我们向您展示了如何使用这些模型构建 iOS 和 Android 应用程序。 如果您对整个过程和结果感到兴奋,那么您肯定会想进一步探索 GAN,这是一个快速发展的领域,在该领域中,新型 GAN 已经迅速开发出来,以克服先前模型的缺点; 例如,正如我们在*增强图像分辨率*小节的 GAN 高级模型中看到的那样,开发了需要配对图像进行训练的 pix2pix 模型的同一位研究人员提出了一种称为 [CycleGAN](https://junyanz.github.io/CycleGAN) 的模型,删除了图像配对的要求。 如果您对我们生成的数字或增强的图像的质量不满意,则可能还应该进一步探索 GAN,以了解如何改进 GAN 模型。 正如我们之前提到的,GAN 仍很年轻,研究人员仍在努力稳定培训,如果可以稳定的话,将会取得更大的成功。 至少到目前为止,您已经获得了如何在移动应用中快速部署 GAN 模型的经验。 由您决定是关注最新,最出色的 GAN 并在移动设备上使用它们,还是暂时搁置您的移动开发人员的帽子,会全力以赴来构建新的或改进现有的 GAN 模型。
在本章中,我们快速浏览了 GAN 的美好世界。 我们介绍了 GAN 的含义以及它们为何如此有趣的原因-生成器和别器相互竞争并尝试击败的方式听起来对大多数人来说很有吸引力。 然后,我们详细介绍了如何训练基本 GAN 模型和更高级的图像分辨率增强模型以及如何为移动设备准备它们的详细步骤。 最后,我们向您展示了如何使用这些模型构建 iOS 和 Android 应用程序。 如果您对整个过程和结果感到兴奋,那么您肯定会想进一步探索 GAN,这是一个快速发展的领域,在该领域中,新型 GAN 已经迅速开发出来,以克服先前模型的缺点; 例如,正如我们在*增强图像分辨率*小节的 GAN 高级模型中看到的那样,开发了需要配对图像进行训练的 pix2pix 模型的同一位研究人员提出了一种称为 [CycleGAN](https://junyanz.github.io/CycleGAN) 的模型,删除了图像配对的要求。 如果您对我们生成的数字或增强的图像的质量不满意,则可能还应该进一步探索 GAN,以了解如何改进 GAN 模型。 正如我们之前提到的,GAN 仍很年轻,研究人员仍在努力稳定培训,如果可以稳定的话,将会取得更大的成功。 至少到目前为止,您已经获得了如何在移动应用中快速部署 GAN 模型的经验。 由您决定是关注最新,最出色的 GAN 并在移动设备上使用它们,还是暂时搁置您的移动开发人员的帽子,会全力以赴来构建新的或改进现有的 GAN 模型。
如果 GAN 在深度学习社区中引起了极大的兴奋,那么 AlphaGo 在 2016 年和 2017 年击败最优秀的人类 GO 玩家的成就无疑令所有人都感到惊讶。 此外,在 2017 年 10 月,AlphaGo Zero(一种完全基于自学强化学习而无需任何人类知识的新算法)被推举为击败 AlphaGo 100-0,令人难以置信。 2017 年 12 月,与仅在 GO 游戏中定位的 AlphaGo 和 AlphaGo Zero 不同,AlphaZero(一种可在许多具有挑战性的领域实现*“超人表现”* 的算法)被发布。 在下一章中,我们将看到如何使用最新最酷的 AlphaZero 来构建和训练用于玩简单游戏的模型,以及如何在移动设备上运行该模型。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册