使用Python进行生成对抗网络速成班。
7天内将生成对抗网络应用于您的项目。
生成对抗网络,简称GANs,是一种用于训练生成模型的深度学习技术。
GANs 的研究和应用只有几年历史,但其取得的成果令人瞩目。由于该领域尚处于起步阶段,因此很难知道如何入门、关注什么以及如何最好地利用现有技术。
在本速成班中,您将学习如何在七天内使用 Python 轻松开发深度学习生成对抗网络。
注意:这是一篇重要且内容丰富的帖子。您可能需要将其添加书签。
让我们开始吧。
- 更新 2019年7月:更改了 LeakyReLU 和 BatchNorm 层的顺序(感谢 Chee)。

如何开始使用生成对抗网络(7 天迷你课程)
图片由 Matthias Ripp 提供,保留部分权利。
本速成课程适合谁?
在开始之前,让我们确保您来对了地方。
以下列表提供了一些关于本课程设计对象的一般性指导。
如果您未能完全掌握这些要点,请不要惊慌;您可能只需要在某个方面稍作复习即可跟上。
您需要了解
- 您熟悉基本的 Python、NumPy 和 Keras 深度学习。
您不需要是
- 成为数学高手!
- 一位深度学习专家!
- 一位计算机视觉研究员!
本速成班将把您从一位略懂机器学习的开发者培养成一位能够将 GANs 应用于您自己的计算机视觉项目的开发者。
注意:本速成班假设您拥有一个正常运行的 Python 2 或 3 SciPy 环境,并至少安装了 NumPy、Pandas、scikit-learn 和 Keras 2。如果您在环境设置方面需要帮助,可以按照此处的逐步教程进行操作
速成课程概览
本速成课程分为七节课。
您可以每天完成一节课(推荐),或者在一天内完成所有课程(硬核)。这真的取决于您的可用时间和热情程度。
以下是七个课程,它们将帮助您开始使用 Python 中的生成对抗网络并提高效率
- 课程 01:什么是生成对抗网络?
- 课程 02:GANs 技巧、窍门和黑科技
- 课程 03:判别器和生成器模型
- 课程 04:GAN 损失函数
- 课程 05:GAN 训练算法
- 课程 06:用于图像转换的 GANs
- 课程 07:高级 GANs
每节课可能需要 60 秒到 30 分钟不等。请花时间按照自己的节奏完成课程。在下面的评论中提问甚至发布结果。
这些课程可能会要求您自行探索如何完成某些任务。我将为您提供提示,但每节课的重点之一是迫使您学习如何在深度学习和 GANs 方面寻求帮助(提示:我的博客上包含了所有答案;只需使用搜索框)。
在评论中发布您的结果;我会为您加油!
坚持下去;不要放弃。
注意:这只是一个速成班。有关更多详细信息和完善的教程,请参阅我关于“使用 Python 的生成对抗网络”一书。
想从零开始开发GAN吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
课程 01:什么是生成对抗网络?
在本课程中,您将了解 GANs 是什么以及基本的模型架构。
生成对抗网络,简称 GANs,是一种使用深度学习方法(例如卷积神经网络)进行生成建模的方法。
GANs 是一种巧妙地训练生成模型的方法,它将问题框架为一个包含两个子模型的监督学习问题:我们训练的生成器模型用于生成新样本,以及判别器模型用于将样本分类为真实(来自领域)或虚假(生成)。
- 生成器。用于从问题域生成新的合理示例的模型。
- 鉴别器。用于将示例分类为真实(来自该域)或虚假(生成的)的模型。
这两个模型以零和博弈的方式进行对抗性训练,直到判别器模型被欺骗约一半时间,这意味着生成器模型正在生成可信的样本。
生成器
生成器模型将固定长度的随机向量作为输入,并在领域中生成一张图像。
该向量从高斯分布(称为潜在空间)中随机抽取,并用于为生成过程提供种子。
训练后,生成器模型被保留并用于生成新样本。
判别器
判别器模型将来自领域的一个样本作为输入(真实或生成),并预测一个二元类别标签:真实或虚假(生成)。
真实样本来自训练数据集。生成的样本由生成器模型输出。
判别器是一个正常的(且易于理解的)分类模型。
训练过程结束后,判别器模型被丢弃,因为我们关心的是生成器。
GAN 训练
生成器和判别器这两个模型一起训练。
一个训练周期首先涉及从问题领域中选择一批真实图像。生成一批潜在点并将其馈送到生成器模型以合成一批图像。
然后使用真实和生成的图像批次更新判别器,最小化任何二元分类问题中使用的二元交叉熵损失。
然后通过判别器模型更新生成器。这意味着生成的图像被呈现给判别器,就好像它们是真实(未生成)的一样,并且误差通过生成器模型反向传播。这会使生成器模型更新,使其生成更可能欺骗判别器的图像。
然后重复此过程,进行给定次数的训练迭代。
您的任务
您在本课中的任务是列出生成对抗网络的三个可能应用。您可以从查阅最近发表的研究论文中获取想法。
在下面的评论中发布您的发现。我很想知道您的发现。
在下一课中,您将学习成功训练 GAN 模型的一些技巧和窍门。
课程 02:GAN 技巧、窍门和黑科技
在本课程中,您将发现成功训练 GAN 模型所需了解的技巧、窍门和黑科技。
生成对抗网络训练起来具有挑战性。
这是因为该架构涉及一个生成器和一个判别器模型,它们在一个零和博弈中竞争。一个模型的改进是以另一个模型性能下降为代价的。结果是一个非常不稳定的训练过程,通常会导致失败,例如生成器总是生成相同的图像或生成无意义的图像。
因此,在配置和训练您的 GAN 模型时,有一些启发式方法或最佳实践(称为“GAN 黑科技”)可以使用。
在稳定 GAN 模型设计和训练方面,也许最重要的进步之一是被称为深度卷积 GAN 或 DCGAN 的方法。
该架构包含在实现 GAN 模型时需要考虑的七个最佳实践
- 使用带步长的卷积进行下采样(例如,不使用池化层)。
- 使用带步长的卷积进行上采样(例如,使用转置卷积层)。
- 使用 LeakyReLU(例如,不使用标准 ReLU)。
- 使用批量归一化(例如,在激活后标准化层输出)。
- 使用高斯权重初始化(例如,均值为 0.0,标准差为 0.02)。
- 使用Adam 随机梯度下降(例如,学习率为 0.0002,beta1 为 0.5)。
- 将图像缩放到 [-1,1] 范围(例如,在生成器输出中使用 tanh)。
这些启发式方法是实践者在各种问题上测试和评估了数百或数千种配置操作组合后,才艰难获得的。
您的任务
您在本课中的任务是列出可以在训练期间使用的三个额外的 GAN 技巧或黑科技。
在下面的评论中发布您的发现。我很想知道您的发现。
在下一课中,您将学习如何实现简单的判别器和生成器模型。
课程 03:判别器和生成器模型
在本课程中,您将学习如何使用 Keras 深度学习库实现一个简单的判别器和生成器模型。
我们将假设我们领域中的图像大小为 28×28 像素,并且是彩色的,这意味着它们有三个颜色通道。
判别器模型
判别器模型接收大小为 28x28x3 像素的图像,并且必须通过 Sigmoid 激活函数将其分类为真实(1)或虚假(0)。
我们的模型有两个卷积层,每个层有 64 个滤波器,并使用相同填充。每个卷积层将使用2×2 步幅对输入进行下采样,这是 GANs 的最佳实践,而不是使用池化层。
同样遵循最佳实践,卷积层之后是斜率为 0.2 的 LeakyReLU 激活层和批量归一化层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
... # 定义判别器模型 model = Sequential() # 下采样到 14x14 model.add(Conv2D(64, (3,3), strides=(2, 2), padding='same', input_shape=(28,28,3))) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) # 下采样到 7x7 model.add(Conv2D(64, (3,3), strides=(2, 2), padding='same')) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) # 分类 model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) |
生成器模型
生成器模型接收一个 100 维潜在空间点作为输入,并生成一个 28x28x3 的图像。
潜在空间中的点是高斯随机数向量。通过一个全连接层将其投影到 64 个微小 7×7 图像的基础上。
然后,小图像使用两个步长为 2×2 的转置卷积层上采样两次,接着是批量归一化层和 LeakyReLU 层,这是 GANs 的最佳实践。
输出是一个具有三个通道的图像,像素值通过 tanh 激活函数在 [-1,1] 范围内。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
... # 定义生成器模型 model = Sequential() # 7x7 图像的基础 n_nodes = 64 * 7 * 7 model.add(Dense(n_nodes, input_dim=100)) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) model.add(Reshape((7, 7,64))) # 上采样到 14x14 model.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding='same')) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) # 上采样到 28x28 model.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding='same')) model.add(BatchNormalization()) model.add(LeakyReLU(alpha=0.2)) model.add(Conv2D(3, (3,3), activation='tanh', padding='same')) |
您的任务
您在本课中的任务是实现判别器模型并总结其结构。
获得额外分数:将模型更新为支持 64×64 像素大小的图像。
在下面的评论中发布您的发现。我很想知道您的发现。
在下一课中,您将学习如何配置用于训练 GAN 模型的损失函数。
课程 04:GAN 损失函数
在本课程中,您将学习如何配置用于训练 GAN 模型权重的损失函数。
判别器损失
判别器模型经过优化,旨在最大限度地正确识别数据集中的真实图像和生成器输出的虚假或合成图像的概率。
这可以作为一个二元分类问题来实现,其中判别器输出给定图像的概率,范围在 0 到 1 之间,分别表示虚假和真实。
然后,模型可以直接在真实和虚假图像批次上进行训练,并最小化负对数似然,最常见的是实现为二元交叉熵损失函数。
按照最佳实践,该模型可以使用具有小学习率和保守动量的Adam 版本的随机梯度下降进行优化。
1 2 3 |
... # 编译模型 model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5)) |
生成器损失
生成器不直接更新,该模型没有损失。
相反,判别器用于为生成器提供学习的或间接的损失函数。
这是通过创建复合模型实现的,其中生成器输出的图像直接馈送到判别器进行分类。
然后,可以通过提供潜在空间中的随机点作为输入,并向判别器指示生成的图像实际上是真实的来训练复合模型。这会更新生成器的权重,使其输出更可能被判别器分类为真实的图像。
重要的是,在此过程中判别器权重不会更新,并且被标记为不可训练。
复合模型使用与独立判别器模型相同的分类交叉熵损失,以及相同的 Adam 版随机梯度下降来执行优化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 为训练生成器创建复合模型 generator = ... discriminator = ... ... # 使判别器中的权重不可训练 d_model.trainable = False # 连接它们 model = Sequential() # 添加生成器 model.add(generator) # 添加判别器 model.add(discriminator) # 编译模型 model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5)) |
您的任务
您在本课中的任务是研究并总结可用于训练 GAN 模型的其他三种损失函数类型。
在下面的评论中发布您的发现。我很想知道您的发现。
在下一课中,您将学习用于更新 GAN 模型权重的训练算法。
课程 05:GAN 训练算法
在本课程中,您将学习 GAN 训练算法。
定义 GAN 模型是困难的部分。GAN 训练算法相对简单。
该算法的一个周期包括首先选择一批真实图像,然后使用当前生成器模型生成一批虚假图像。您可以开发小函数来执行这两个操作。
然后,这些真实和虚假图像用于通过调用 train_on_batch() Keras 函数直接更新判别器模型。
接下来,可以在潜在空间中生成点作为复合生成器-判别器模型的输入,并且可以提供“真实”(class=1)标签来更新生成器模型的权重。
然后训练过程重复数千次。
生成器模型可以定期保存,稍后加载以检查生成的图像的质量。
以下示例演示了 GAN 训练算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
... # gan 训练算法 discriminator = ... generator = ... gan_model = ... n_batch = 16 latent_dim = 100 for i in range(10000) # 获取随机选择的“真实”样本 X_real, y_real = select_real_samples(dataset, n_batch) # 生成“假”示例 X_fake, y_fake = generate_fake_samples(generator, latent_dim, n_batch) # 为判别器创建训练集 X, y = vstack((X_real, X_fake)), vstack((y_real, y_fake)) # 更新判别器模型权重 d_loss = discriminator.train_on_batch(X, y) # 准备潜在空间中的点作为生成器的输入 X_gan = generate_latent_points(latent_dim, n_batch) # 为伪样本创建反转标签 y_gan = ones((n_batch, 1)) # 通过判别器的误差更新生成器 g_loss = gan_model.train_on_batch(X_gan, y_gan) |
您的任务
您在本课中的任务是将本课和之前课程的元素结合起来,在小型图像数据集(如 MNIST 或 CIFAR-10)上训练一个 GAN。
在下面的评论中发布您的发现。我很想知道您的发现。
在下一课中,您将学习 GANs 在图像转换中的应用。
课程 06:用于图像转换的 GANs
在本课程中,您将学习 GANs 用于图像转换。
图像到图像转换是将给定源图像受控地转换为目标图像。一个例子可能是将黑白照片转换为彩色照片。
图像到图像转换是一个具有挑战性的问题,通常需要针对给定转换任务或数据集的专用模型和损失函数。
GANs 可以训练以执行图像到图像转换,其中两个例子包括 Pix2Pix 和 CycleGAN。
Pix2Pix
Pix2Pix GAN 是一种通用的图像到图像转换方法。
该模型在成对示例的数据集上进行训练,其中每对示例都包含所需转换前后的图像示例。
Pix2Pix 模型基于条件生成对抗网络,其中生成目标图像,条件是给定输入图像。
判别器模型接收输入图像和真实或生成的成对图像,并必须确定成对图像是真实还是虚假。
生成器模型接收给定图像作为输入,并生成该图像的转换版本。生成器模型旨在同时欺骗判别器模型并最小化生成图像与预期目标图像之间的损失。
Pix2Pix 中使用了更复杂的深度卷积神经网络模型。具体来说,U-Net 模型用于生成器模型,PatchGAN 用于判别器模型。
生成器的损失由正常 GAN 模型的对抗性损失和生成图像与预期转换图像之间的 L1 损失的复合组成。
CycleGAN
Pix2Pix 模型的一个限制是它需要在所需转换前后成对的示例数据集。
有许多图像到图像的转换任务,我们可能没有转换示例,例如将斑马照片转换为马。还有其他图像转换任务,不存在此类成对示例,例如将风景艺术转换为照片。
CycleGAN 是一种涉及在没有成对示例的情况下自动训练图像到图像转换模型的技术。模型以无监督的方式进行训练,使用来自源域和目标域的图像集合,这些图像不需要以任何方式相关。
CycleGAN 是 GAN 架构的扩展,涉及同时训练两个生成器模型和两个判别器模型。
一个生成器将来自第一个域的图像作为输入,并为第二个域输出图像,而另一个生成器将来自第二个域的图像作为输入,并从第一个域生成图像。然后,判别器模型用于确定生成的图像的可信度,并相应地更新生成器模型。
CycleGAN 采用了一种称为循环一致性的额外架构扩展。其思想是,第一个生成器输出的图像可以用作第二个生成器的输入,而第二个生成器的输出应与原始图像匹配。反之亦然:第二个生成器的输出可以作为输入馈送到第一个生成器,结果应与第二个生成器的输入匹配。
您的任务
您在本课中的任务是列出五个您可能希望使用 GAN 模型探索的图像到图像转换示例。
在下面的评论中发布您的发现。我很想知道您的发现。
在下一课中,您将学习 GAN 模型的一些最新进展。
课程 07:高级 GANs
在本课程中,您将学习一些展示出卓越成果的更高级 GAN。
BigGAN
BigGAN 是一种将 GAN 训练中一系列最新最佳实践以及扩展批量大小和模型参数数量的方法结合在一起的方法。
顾名思义,BigGAN 专注于扩展 GAN 模型。这包括具有以下特点的 GAN 模型:
- 更多模型参数(例如,更多特征图)。
- 更大的批量大小(例如,数百或数千张图像)。
- 架构变更(例如,自注意力模块)。
由此产生的 BigGAN 生成器模型能够生成各种图像类别的高质量 256×256 和 512×512 图像。
渐进增长 GAN
渐进增长 GAN 是 GAN 训练过程的扩展,它允许稳定训练能够输出大型高质量图像的生成器模型。
它涉及从一个非常小的图像开始,并逐步添加层块,增加生成器模型的输出大小和判别器模型的输入大小,直到达到所需的图像大小。
渐进增长 GAN 最令人印象深刻的成就也许是生成了 1024×1024 像素的逼真人脸图像。
StyleGAN
Style 生成对抗网络,简称 StyleGAN,是 GAN 架构的扩展,它对生成器模型提出了重大改变。
这包括使用映射网络将潜在空间中的点映射到中间潜在空间,使用中间潜在空间在生成器模型中的每个点控制样式,以及在生成器模型中的每个点引入噪声作为变化源。
由此产生的模型不仅能够生成令人印象深刻的逼真高质量人脸照片,而且通过改变样式向量和噪声,还可以在不同细节级别上控制生成图像的样式。
例如,合成网络中较低分辨率的层块控制姿态和发型等高级样式,而较高分辨率的层块控制配色方案和非常精细的细节,如雀斑和发丝的放置。
您的任务
您在本课中的任务是列出您可能希望使用能够生成大型逼真图像的模型的三种应用示例。
在下面的评论中发布您的发现。我很想知道您的发现。
这是最后一课。
结束!
(看看您已经走了多远)
您做到了。干得好!
花点时间回顾一下您已经走了多远。
您发现了:
- GANs 是一种用于训练能够合成高质量图像的生成模型的深度学习技术。
- 训练 GANs 本质上是不稳定的,容易失败,这可以通过在 GAN 模型的设计、配置和训练中采用最佳实践启发式方法来克服。
- GAN 架构中使用的生成器和判别器模型可以在 Keras 深度学习库中简单直接地定义。
- 判别器模型像任何其他二元分类深度学习模型一样进行训练。
- 生成器模型通过判别器模型在复合模型架构中进行训练。
- GANs 能够进行条件图像生成,例如带成对和不成对示例的图像到图像转换。
- GANs 的进步,例如模型的扩展和渐进增长,允许生成更大、更高质量的图像。
迈出下一步,查看我的关于 Python 生成对抗网络的书。
总结
您在迷你课程中的表现如何?
您喜欢这个速成课程吗?
您有任何问题吗?有没有遇到什么难点?
告诉我。在下面留言。
判别器和生成器模型的示例代码可能存在错误?
批量归一化层不应该在激活之前添加吗?
即
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.2))
可能,这取决于情况。
我会将其更改为符合惯例。谢谢。
嗨,Jason,
感谢您的精彩文章。
您能详细说明为什么判别器模型不应该可训练吗?
我不明白如果判别器没有优化,生成怎么会有意义。我肯定遗漏了什么。
谢谢
很好的问题。
生成器没有直接的损失函数。相反,我们使用判别器作为损失函数,并通过判别器更新权重——例如,错误通过反向传播回到生成器。当我们这样做时,我们只想更新生成器权重,而不是判别器,因为我们可以直接更新判别器。
我在这里解释了更多
https://machinelearning.org.cn/how-to-develop-a-generative-adversarial-network-for-a-1-dimensional-function-from-scratch-in-keras/
嗨,使用 Keras 还是 tf.keras 有区别吗?
所有示例都使用 Keras 开发,您可以尝试使用 tf.keras,但我无法确认它会如所述那样工作。
1. 提出了两时间尺度更新规则,为生成器和判别器提供单独的学习率,因为 GAN 的收敛性尚未得到证实。
2. Fréchet Inception Distance 可以找到生成的图像与真实图像的更多相似性,而不是 Inception Score。
3. GAN 可以学习更复杂的生成模型,对于这些模型,最大似然不切实际。
4. 批评者-行动者学习已通过随机近似进行分析,表明 TTUR 确保 GAN 训练达到平稳的局部纳什均衡,如果批评者学习速度快于行动者,则通过常微分方程证明收敛性,其稳定极限点与平稳的局部纳什均衡重合。
5. 在新的 GAN 中,判别器学习速度快于生成器,以避免当前判别器中出现过拟合。
干得好!
尊敬的先生,
感谢您分享您的知识
您能告诉我如果数据集是 csv 文件,如何加载它吗?
请参阅本教程,了解如何从 CSV 加载数据
https://machinelearning.org.cn/load-machine-learning-data-python/
嗨,Jason,
对于第一天的任务
我发现 GAN 更精细的应用有:
1. 文本到图像转换;
2. 通过 GAN 通过数据增强增加训练样本来改进训练数据集较差的模型;
3. 生成不同姿势的人脸,以训练生物识别面部识别系统,即使在不利的面部姿势下也能识别一个人。
干得好!
第二天任务
还有一些 GAN 的技巧
1. 使用替代损失函数,即用 max log D 代替 min log D
2. 从高斯分布而不是正态分布中采样
3. 在生成器的每一层添加高斯噪声
干得漂亮!
对于教程的第一天,一些可能的 GAN 应用(我专注于文本 GAN)
1. 机器翻译:将文本或语音从一种语言翻译成另一种语言
2. 语言建模:一个或多个词序列,构成句子或句子的一部分,然后
3. 文本摘要:提供大量句子或语料库的高级摘要
干得好!
第一天任务……
我试着在学会走之前就跑。
为了确认我的学生身份,购买了《机器学习概率论》。
我想知道人工智能领域是否存在一种人们贪多嚼不烂的概率分布,以及如何从他们访问您的《温和入门》和迷你课程的历史中预测这一点。
Harikrishna 的关注点与我的一致。
我认为我们必须贪多嚼不烂才能成长。
坚持住,如果我能提供帮助,请联系我。
https://machinelearning.org.cn/contact/
第三天附加题
# 定义判别器模型
model = Sequential()
# 下采样至 32x32
model.add(Conv2D(64, (3,3), strides=(2, 2), padding= 'same' , input_shape=(64,64,3)))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 下采样至 16x16
model.add(Conv2D(64, (3,3), strides=(2, 2), padding= 'same' ))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 分类
model.add(Flatten())
model.add(Dense(1, activation= 'sigmoid' ))
# 定义生成器模型
model = Sequential()
# 7x7 图像的基础
n_nodes = 64 * 8 * 8
model.add(Dense(n_nodes, input_dim=100))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
model.add(Reshape((8, 8, 64)))
# 上采样至 16x16
model.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding= 'same' ))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 上采样至 32x32
model.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding= 'same' ))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 上采样至 64x64
model.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding= 'same' ))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
model.add(Conv2D(3, (3,3), activation= 'tanh' , padding= 'same' ))
谢谢 Jason!
干得好!
第04天 - GAN 损失函数
可用于训练 GAN 模型的其他三种损失函数类型
极小极大损失
Wasserstein 损失
最小二乘损失
我实际上对极小极大损失感到困惑——它似乎是您定义的二元交叉熵损失。因此我有一些问题:
1) 您使用 binary_crossentropy 和 Adam 编译判别器,但随后您说判别器不需要训练……我是否遗漏了什么?
2) GAN_model.compile(loss= loss_function , optimizer=optimizer) 中,GAN_model 是按课程中那样顺序构建的,它是否本质上实现了极小极大对抗博弈?
非常感谢 Jason!
好问题,这会澄清一些事情
https://machinelearning.org.cn/how-to-code-the-generative-adversarial-network-training-algorithm-and-loss-functions/
啊!所以当你计算判别器损失时,它当然是可训练的,但是当你训练 GAN 时,判别器是不可训练的。是这样吗?
不,判别器和生成器都经过训练。
第 5 天:GAN 训练算法
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, LeakyReLU, BatchNormalization, Flatten, Dense, Reshape, Conv2DTranspose
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import numpy as np
# 定义判别器模型
model = Sequential()
# 下采样到 14x14
model.add(Conv2D(64, (3,3), strides=(2, 2), padding= 'same' , input_shape=(28,28,1)))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 下采样到 7x7
model.add(Conv2D(64, (3,3), strides=(2, 2), padding= 'same' ))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 分类
model.add(Flatten())
model.add(Dense(1, activation= 'sigmoid' ))
# 定义生成器模型
gmodel = Sequential()
# 7x7 图像的基础
n_nodes = 64 * 7 * 7
gmodel.add(Dense(n_nodes, input_dim=100))
gmodel.add(LeakyReLU(alpha=0.2))
gmodel.add(BatchNormalization())
gmodel.add(Reshape((7, 7, 64)))
# 上采样到 14x14
gmodel.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding= 'same' ))
gmodel.add(LeakyReLU(alpha=0.2))
gmodel.add(BatchNormalization())
# 上采样到 28x28
gmodel.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding= 'same' ))
gmodel.add(LeakyReLU(alpha=0.2))
gmodel.add(BatchNormalization())
gmodel.add(Conv2D(1, (3,3), activation= 'tanh' , padding= 'same' ))
generator = gmodel
discriminator=model
discriminator.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5))
discriminator.trainable=False
GAN=Sequential()
GAN.add(generator)
GAN.add(discriminator)
GAN.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5))
discriminator.trainable=True # 因为 d_loss 需要它……我错了吗?
n_batch = 16
latent_dim = 100
(train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data()
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
train_images = (train_images - 127.5) / 127.5 # 将图像归一化到 [-1, 1]
def generate_fake_samples(generator, latent_dim, n_batch)
generated=generator.predict(tf.random.normal(shape=(n_batch,latent_dim)))
return generated
def generate_latent_points(latent_dim,n_batch)
return tf.random.normal(shape=(n_batch,latent_dim))
for i in range(10000)
X_real,_ = train_test_split(train_images, train_size=n_batch)
y_real = tf.ones(tf.constant([len(X_real)]))
X_fake=generate_fake_samples(generator, latent_dim, n_batch)
y_fake = tf.zeros(tf.constant([len(X_fake)]))
X, y = np.vstack((X_real, X_fake)), np.vstack((y_real, y_fake))
y=np.reshape(y,n_batch*2)
d_loss = discriminator.train_on_batch(X, y)
X_gan = generate_latent_points(latent_dim, n_batch)
y_gan = tf.ones((n_batch, 1))
g_loss = GAN.train_on_batch(X_gan, y_gan)
如果您能回答代码中关于 discriminator.trainable=True/False 的问题,我将不胜感激!
祝好
干得好!
嗨,Jason,
第01天任务
在此之前我想问一下,模型是否也使用了一些安全算法,以确保它不会被滥用做坏事(只是现实地考虑),因为我们正在获取逼真的虚假数据?
我发现一些应用如下:
1) 图像到图像转换:我们可以使用 GAN 模型生成星系图像并对其进行研究
2) 语音翻译:使用 GAN 我们可以进行音频风格转换,例如爵士乐到古典音乐
3) 我们可以从头开始生成图像,包含用于研究宇宙中暗物质或暗能量性质的统计摘要
干得好!
嗨,Jason,
第二天任务
我发现的一些技巧和黑科技如下:
1) 图像数据增强:我们可以在训练时使用这项技术。因为它用于扩展训练数据集,以提高 GAN 模型的性能。
2) 单边标签平滑:我们可以用它来避免过度自信和过拟合。
3) 损失函数:为了模型在训练中表现更好(来源:WGAN 论文)。
4) 在将真实数据和生成数据输入判别器之前,向其添加噪声。
5) 正交正则化(来源:BigGAN)。
干得好!
嗨,Jason,
第一天任务
GAN 的应用有:
1. 数据集增强,这是广泛使用的应用。
2. 不同类型的翻译,如图像到图像和文本到图像翻译。
3. 运动稳定和超分辨率,可以从模糊图像生成清晰图像。
干得好!
第二天任务
一些技巧和窍门如下:
1) 损失函数在训练中起着重要作用,因此在训练时应使用适当的损失函数。我们可以使用 Wasserstein 损失函数,该函数在 WGAN 论文中使用。
2) 模式崩溃是训练 GAN 模型时的痛点,可以通过学习率等参数解决。出现这个问题时,模型将开始生成相同模式的图像,并会忘记生成其他模式。
3) 软标签和噪声标签在训练判别器时很重要。例如,假图像标签将在 0 到 0.1 之间,真实图像标签将在 0.9 到 1.0 之间。
干得好!
嗨,Jason,
第一天任务
1. 用于训练和测试应用的数据增强
2. 增强图像/视频以实现个性化体验
3. 创意艺术,以增强人类创造力
干得好!
乔·杰森,
第二天任务
训练期间额外的 GAN 技巧和窍门
1. 使用高斯潜在空间——这确保了生成输入时的随机性
2. 分离真实图像和虚假图像的批次,以确保数据结构清晰且易于管理
3. 使用噪声标签——混合真实数据和虚假数据
干得漂亮!
第三天附加题
# 判别器、生成器模型代码以接受 64 X 64 X 3 大小的输入
# 判别器模型设计
model = Sequential()
# 提取 64 个特征图并将输入下采样到 50% 32 X 32
model.add(Conv2D(64, (3,3), strides = (2,2), padding='same', input_shape=(64,64,3)))
model.add(LeakyReLU())
model.add(BatchNormalization())
# 提取 64 个特征图并将输入下采样到 50% 16 X 16
model.add(Conv2D(64, (3,3), strides = (2,2), padding='same'))
model.add(LeakyReLU())
model.add(BatchNormalization())
# 分类输入
model.add(Flatten())
model.add(Dense(1, activation=’sigmoid’))
打印(model.summary())
# 定义生成器模型
model = Sequential()
# 节点的基础
n_node = 64 * 16* 16
model.add(Dense(n_node,input_dim=100))
model.add(LeakyReLU())
model.add(BatchNormalization())
model.add(Reshape((16,16,64)))
# 上采样 32 X 32
model.add(Conv2DTranspose(64, (3,3), strides =(2,2), padding ='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
# 上采样 64 X 64
model.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding = 'same'))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization())
model.add(Conv2D(3,(3,3),activation='tanh', padding='same'))
打印(model.summary())
做得好!!
第四天任务
GAN 的其他损失函数类型
1. acgan
2. 最小二乘
3. 极小极大
4. Wasserstein
当我看到这些损失在 python 中的实现时,它总是单独被称为 xxx_generator_loss 和 xxx_discriminator_loss,所以我的问题是,当我们指定损失时,我们没有为生成器或判别器指定,但上述损失的实现是不同的。无法理解这是如何工作的,或者说我们到目前为止只使用了 binary_crossentropy,但对于高级实现我们需要指定。
干得好!
有些损失函数需要自定义函数,有些可以直接从库中使用。这取决于情况。
第1课
首先,我将尝试找出 GANs 的 3 个应用,然后做一些研究并添加到我的帖子中。
1. 生成像人一样的图像(例如,用于电影中的数字“演员”)
2. 创作艺术品以复制著名艺术家的作品(但请注意此类产品的使用以防欺诈)
3. 它们是否可以用于复制著名作者的作品的文本?
现在说说我的研究结果
1. 照片编辑以清理照片
2. 人脸老化;这可以用于法医学和追踪事件发生多年后的失踪人口或罪犯
3. 虚拟试衣
我的研究前建议中的前两个也在我发现的研究中。文章提到了文本到图像,但没有提到文本到文本,所以不确定我的第三个建议是否有效。
研究来源:https://machinelearning.org.cn/impressive-applications-of-generative-adversarial-networks/
干得好!
Jason,很棒的教程,谢谢!我在以下链接中找到了您讨论过的更多 GAN 技巧:
https://github.com/soumith/ganhacks
谢谢!
不错的教程。GAN 可以在不同的应用中发挥奇妙的作用,例如:生物医学信号中的数据增强、图像复制、文本校正。
谢谢!
嗨,Jason,
第01天任务
1- 生成图像
Wang 等人,《使用样式和结构对抗网络的生成图像建模》。
两步生成
– 草图 → 颜色。
– 二项式随机种子而不是高斯。
2- 图像翻译
Perarnau 等人,《用于图像编辑的可逆条件 GAN》。
3- 领域自适应
Taigman 等人,《无监督跨领域图像生成》。
干得好!
第一天任务
1. 生成高质量测试数据(这可能很难生成)
2. 从真实照片制作卡通图像
3. 以特定风格(口音/语调)生成音频——我不知道这是否真的可能!
对于(3)——这实际上是可能的。这可能与此相关:https://blog.tensorflowcn.cn/2020/01/building-ai-empowered-music-library-tensorflow.html
第一天任务
首先,我要感谢您免费提供这个 7 天速成课程。它肯定会对我的学习有所帮助!
GANs,如前所述,可用于各种与计算机视觉相关的任务。鉴于我们目前正经历一场大流行,我发现并提出的应用是:
1. 生成一组高质量的 X 射线图像,用于训练其他神经网络,从而获得更好的结果。
2. 一旦判别器训练得足够好,它也可以用于图像分类。
3. 图像超采样。例如,获取一张低质量的 X 射线图像,通过 GAN 处理,然后生成一个更高质量的版本。
感谢您的反馈,威尔逊!继续努力!
第二天任务
在研究和尝试训练我自己的 GAN 时,我发现了这些在课程中未提及的技巧:
1. 及早发现失败。通过打印每个 epoch 中判别器和生成器的损失输出,我们可以判断训练是否顺利,从而避免浪费时间训练不正确的模型。
2. 不要通过统计数据平衡损失。大多数时候,根据其损失函数的输出情况来训练生成器或判别器是毫无意义的。不如等到它完成或更新输入后再尝试。
3. 修改学习率。我有时能成功,但并非总是如此。如果我们注意到生成器无法生成好的副本,而判别器学习如何快速找到伪造品,反之,如果生成器损失函数稳步下降,那么它正在用垃圾欺骗判别器。
感谢您的反馈,Wilson!
尊敬的先生您好,
运行代码后我遇到了以下错误
“未知损失函数:binary-crossentropy。请确保将此对象传递给‘custom_objects’参数。”
我应该怎么做才能解决这个问题?
谢谢你
你好,Pouya…你是复制粘贴的代码还是手动输入的?另外,你可能还想在Google Colab中实现它。
实际上我做了一些改动,我会在Google Colab中尝试。谢谢。
感谢您的反馈!继续努力!
GAN 用于图像到图像的转换
GAN 用于隐写术
GAN 用于语音再现
感谢您的反馈,Celia!您可能会对以下内容感兴趣
https://machinelearning.org.cn/impressive-applications-of-generative-adversarial-networks/
我遇到了 CycleGAN 的问题,我卡在一个错误中,即使我尝试了 StackOverflow 上给出的方法也无法解决。这是一个关于 DS_store 的问题,它是 macOS 的隐藏文件,我使用的是 HP i3 处理器上的普通 COLAB。
你好 Sankar…你收到了什么错误信息?另外,你可能想使用 Google Colab 中的 GPU 选项。
你好,
我刚开始学习 GAN,阅读了一些文章和教程。它说生成器通过损失函数进行更新。但我仍然不明白生成器是如何或者从哪里获取真实图像的信息,以便从随机生成的噪声中复制和生成相似图像的。
你好 Fidha…你可能想从这里开始
https://machinelearning.org.cn/start-here/#gans
我刚完成第一课。这真的很有用。你要求提供三个 GAN 应用示例。这是我的想法:
1. 根据所需情绪生成情绪音乐,例如用于电影或公共场所。
2. 生成对话摘要,例如在电话会议中,以便进行翻译和/或帮助有听力障碍的人。
3. 在监督训练模型中为训练数据生成标签。
Nic,很棒的实用例子!如果您对迷你课程的内容有任何疑问,请告诉我们。
课程 01:什么是生成对抗网络?
在我们机构,有超过5000篇PDF格式的博士论文。我正在考虑如何将GAN应用于这些博士论文中的选定数据集。
感谢 Dusan 的反馈!请告诉我们您的项目进展如何!
第2课:什么是生成对抗网络?
有趣的是,互联网上有大量的 GAN 方法。其中一些是:
1. 将图像从一个领域转换到另一个领域 (CycleGAN),
2. 从文本描述生成图像 (text-to-image),
3. 生成超高分辨率图像 (ProgressiveGAN) 等等。
GAN 的三个应用
1) 改进网络安全
黑客通过向图像添加恶意数据来操纵图像。GAN 可以被训练来识别这些欺诈行为。
2) 改善医疗保健
GAN 可以协助药物发现。研究人员可以用现有数据库训练生成器,以找到可能用于治疗新疾病的新化合物。
3) 文本到图像合成
GAN 网络可以根据文本描述生成图像。
感谢您的反馈,Rohit!继续在课程中努力!