PyTorch 生成对抗网络 01.生成对抗网络
1. 简介
本教程通过一个例子来对 DCGANs 进行介绍。我们将会训练一个生成对抗网络(GAN)用于在展示了许多真正的名人的图片后产生新的名人。 这里的大部分代码来自pytorch/examples中的 dcgan 实现,本文档将对实现进行进行全面 的介绍,并阐明该模型的工作原理以及为什么如此。但是不需要担心,你并不需要事先了解 GAN,但可能需要花一些事件来推理一下底层 实际发生的事情。此外,为了有助于节省时间,最好是使用一个GPU,或者两个。让我们从头开始。
2. 生成对抗网络(Generative Adversarial Networks)
2.1 什么是 GAN
GANs是用于 DL (Deep Learning)模型去捕获训练数据分布情况的框架,以此我们可以从同一分布中生成新的数据。GANs是有Ian Goodfellow 于2014年提出,并且首次在论文Generative Adversarial Nets中 描述。它们由两个不同的模型组成,一个是生成器一个是判别器。生成器的工作是产生看起来像训练图像的“假”图像;判别器的工作是 查看图像并输出它是否是真实的训练图像或来自生成器的伪图像。在训练期间,产生器不断尝试通过产生越来越好的假动作来超越判别器, 而判别器则是为了更好地检测并准确地对真实和假图像进行分类。这个游戏的平衡是当生成器产生完美的假动作以使假图像看起来像是来自 训练数据,而判别器总是猜测生成器输出图像为真或假的概率为50%。
现在,我们开始定义在这个教程中使用到的一些符号。
判别器的符号定义

生成器的符号定义

Goodfellow 论文
理论上,这个极小极大游戏的解决方案是,如果输入的是真实的或假的,则判别器会随机猜测。然而,GAN 的收敛理论仍在积极研究中,实际上模型并不总是训练到这一点。
2.2 什么是 DCGAN
DCGAN 是上述 GAN 的直接扩展,区别的是它分别在判别器和生成器中明确地使用了卷积和卷积转置层。它首先是由Radford等人在论文Unsupervised Representation Learning With Deep Convolutional Generative Adversarial Networks 中提出。判别器由 strided convolutionlayers、batch norm layers 和 LeakyReLU activations 组成,它输入 3x64x64 的图像, 然后输出的是一个代表输入是来自实际数据分布的标量概率。生成器则是由 convolutional-transpose layers、 batch norm layers 和 ReLU activations 组成。它的输入是从标准正态分布中绘制的潜在向量,输出是 3x64x64 的 RGB 图像。strided conv-transpose layers 允许潜在标量转换成具有与图像相同形状的体积。在本文中,作者还提供了一些有关如何设置优化器,如何计算损失函数以及如何初始化 模型权重的提示,所有这些都将在后面的章节中进行说明。
相关链接:
论文:https://arxiv.org/pdf/1511.06434.pdf
strided convolution layers:https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d
batch norm layers:https://pytorch.org/docs/stable/nn.html#torch.nn.BatchNorm2d
LeakyReLU activations:https://pytorch.org/docs/stable/nn.html#torch.nn.LeakyReLU
convolutional-transpose layers:https://pytorch.org/docs/stable/nn.html#torch.nn.ConvTranspose2d
ReLU activations :https://pytorch.org/docs/stable/nn.html#relu
输出结果:
3. DCGAN实现过程
3.1 输入
让我们定义输入数据去运行我们的教程:
dataroot:存放数据集根目录的路径。我们将在下一节中详细讨论数据集
workers:使用DataLoader加载数据的工作线程数
batch_size:训练中使用的batch大小。在DCGAN论文中batch的大小为128
image_size:用于训练的图像的空间大小。此实现默认 64×64。如果需要其他尺寸,则必须改变D和G的结构。有关详细信息,请参见此处。
nc:输入图像中的颜色通道数。对于彩色图像,这是参数设置为3
nz:潜在向量的长度
ngf:与通过生成器携带的特征图的深度有关
ndf:设置通过判别器传播的特征映射的深度
num_epochs:要运行的训练的epoch数量。长时间的训练可能会带来更好的结果,但也需要更长的时间
lr:学习速率。如DCGAN论文中所述,此数字应为0.0002
beta1:适用于Adam优化器的beta1超参数。如论文所述,此数字应为0.5
ngpu:可用的GPU数量。如果为0,则代码将以CPU模式运行。如果此数字大于0,它将在该数量的GPU上运行
3.2 数据
在本教程中,我们将使用Celeb-A Faces数据集,该数据集可以在链接或Google Drive中下载。 数据集将下载为名为img_align_celeba.zip的文件。下载后,创建名为celeba的目录并将zip文件解压缩到该目录中。然后,将此笔记中 的数据对象输入设置为刚刚创建的celeba目录。生成的目录结构应该是:
这是一个重要的步骤,因为我们将使用ImageFolder数据集类,它要求在数据集的根文件夹中有子目录。现在,我们可以创建数据集,创 建数据加载器,设置要运行的设备,以及最后可视化一些训练数据。

3.3 实现
通过设置输入参数和准备好的数据集,我们现在可以进入真正的实现步骤。我们将从权重初始化策略开始,然后详细讨论生成器,鉴别器, 损失函数和训练循环。
3.3.1 权重初始化
在DCGAN论文中,作者指出所有模型权重应从正态分布中随机初始化,mean = 0,stdev = 0.02。weights_init函数将初始化模型作为 输入,并重新初始化所有卷积,卷积转置和batch标准化层以满足此标准。初始化后立即将此函数应用于模型。
3.3.2 生成器
生成器G用于将潜在空间矢量(z)映射到数据空间。由于我们的数据是图像,因此将 转换为数据空间意味着最终创建与训练图像具有相同大小的RGB图像(即3x64x64)。实际上,这是通过一系列跨步的二维卷积转置层实现的, 每个转换层与二维批量标准层和relu activation进行配对。生成器的输出通过tanh函数输入,使其返回到[-1,1]范围的输入数据。值得 注意的是在转换层之后存在批量范数函数,因为这是DCGAN论文的关键贡献。这些层有助于训练期间的梯度流动。DCGAN论文中的生成器中 的图像如下所示:

请注意,我们对输入怎么设置(nz,ngf和nc)会影响代码中的生成器体系结构。nz 是输入向量的长度, ngf与通过生成器传播的特征图的大小有关,nc是输出图像中的通道数(对于RGB图像,设置为3)。下面是生成器的代码。
生成器代码
现在,我们可以实例化生成器并应用weights_init函数。查看打印的模型以查看生成器对象的结构。
输出结果:
3.3.3 判别器
如上所述,判别器D是二进制分类网络,它将图像作为输入并输出输入图像是真实的标量概率(与假的相反)。这里, D采用 3x64x64 的输入图像,通过一系列Conv2d,BatchNorm2d和LeakyReLU层处理它,并通过Sigmoid激活函数输出 最终概率。如果问题需要,可以使用更多层扩展此体系结构,但使用strided convolution(跨步卷积),BatchNorm和LeakyReLU具有重要 意义。DCGAN论文提到使用跨步卷积而不是池化到降低采样是一种很好的做法,因为它可以让网络学习自己的池化功能。批量标准和 leaky relu函数也促进良好的梯度流,这对于和的学习过程都是至关重要的。
判别器代码
现在,与生成器一样,我们可以创建判别器,应用weights_init函数,并打印模型的结构。
输出结果:
3.3.4 损失函数和优化器
通过D和G设置,我们可以指定他们如何通过损失函数和优化器学习。我们将使用PyTorch中定义的 二进制交叉熵损失(BCELoss)函数:
3.3.4 训练
最后,既然已经定义了 GAN 框架的所有部分,我们就可以对其进行训练了。请注意,训练GAN在某种程度上是一种艺术形式,因为不正确 的超参数设置会导致对错误的解释很少的模式崩溃,在这里,我们将密切关注Goodfellow的论文中的算法1,同时遵守ganhacks 中展示的一些最佳实践。也就是说,我们将“为真实和虚假”图像构建不同的 mini-batches ,并且还调整G的目标函 数以最大化

训练分为两个主要部分,第1部分更新判别器,第2部分更新生成器。
-
第一部分:训练判别器

-
第二部分:更新判别器


此步骤可能需要一段时间,具体取决于您运行的epoch数以及是否从数据集中删除了一些数据。
输出结果:
3.3.5 结果
最后,让我们看看我们是如何做到的。在这里,我们将看看三个不同的结果。首先,我们将看到D和G的损失在训练期间是如何变化的。其次,我们将可视化在每个epoch的 fixed_noise batch中G的输出。第三,我们将 查看来自G的紧邻一批实际数据的一批假数据。
损失与训练迭代
下面是D&G的损失与训练迭代的关系图。
G的过程可视化
记住在每个训练epoch之后我们如何在fixed_noise batch中保存生成器的输出。现在,我们可以通过动画可视化G的训练进度。按播放按钮 开始动画。


真实图像 vs 伪图像
最后,让我们一起看看一些真实的图像和伪图像。

进一步的工作
我们已经完成了我们的整个教程,但是你可以从下面几个方向进一步探讨。 你可以:
训练更长时间,看看结果有多好
修改此模型以获取不同的数据集,并或者更改图像和模型体系结构的大小
在这里查看其他一些很酷的GAN项目
创建生成音乐的GAN
文章来源:https://zhiya360.com/docs/pytorchstudy/pytorch-dcgan/01-duikang
