PyTorch 生成对抗网络 01.生成对抗网络

1. 简介本教程通过一个例子来对 DCGANs 进行介绍。我们将会训练一个生成对抗网络(GAN)用于在展示了许多真正的名人的图片后产生新的名人。 这里的大部分代码来自pytorch/examples中的 dcgan 实现,本文档将对实现进行进行全面 的介绍,并阐明该模型的工作原理以及为什么如此。但是不需要担心,你并不需要事先了解 GAN,但可能需要花一些事件来推理一下底层 实际发生的事情。此外,为了有助于节省时间,最好是使用一个GPU,或者两个。让我们从头开始。2. 生成对抗网络(Generativ
摘要由CSDN通过智能技术生成

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

from __future__ import print_function
#%matplotlib inline
import argparse
import os
import random
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torch.utils.data
import torchvision.datasets as dset
import torchvision.transforms as transforms
import torchvision.utils as vutils
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML
# 为再现性设置随机seem
manualSeed = 999
#manualSeed = random.randint(1, 10000) # 如果你想要新的结果就是要这段代码
print("Random Seed: ", manualSeed)
random.seed(manualSeed)
torch.manual_seed(manualSeed)

输出结果:

Random Seed:  999

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上运行

# 数据集的根目录
dataroot = "data/celeba"
# 加载数据的工作线程数
workers = 2
# 训练期间的batch大小
batch_size = 128
# 训练图像的空间大小。所有图像将使用变压器调整为此大小。
image_size = 64
# 训练图像中的通道数。对于彩色图像,这是3
nc = 3
# 潜在向量 z 的大小(例如: 生成器输入的大小)
nz = 100
# 生成器中特征图的大小
ngf = 64
# 判别器中的特征映射的大小
ndf = 64
# 训练epochs的大小
num_epochs = 5
# 优化器的学习速率
lr = 0.0002
# 适用于Adam优化器的Beta1超级参数
beta1 = 0.5
# 可用的GPU数量。使用0表示CPU模式。
ngpu = 1

3.2 数据

在本教程中,我们将使用Celeb-A Faces数据集,该数据集可以在链接或Google Drive中下载。 数据集将下载为名为img_align_celeba.zip的文件。下载后,创建名为celeba的目录并将zip文件解压缩到该目录中。然后,将此笔记中 的数据对象输入设置为刚刚创建的celeba目录。生成的目录结构应该是:

/path/to/celeba
    -> img_align_celeba
        -> 188242.jpg
        -> 173822.jpg
        -> 284702.jpg
        -> 537394.jpg

这是一个重要的步骤,因为我们将使用ImageFolder数据集类,它要求在数据集的根文件夹中有子目录。现在,我们可以创建数据集,创 建数据加载器,设置要运行的设备,以及最后可视化一些训练数据。

# 我们可以按照设置的方式使用图像文件夹数据集。
# 创建数据集
dataset = dset.ImageFolder(root=dataroot,
                           transform=transforms.Compose([
                               transforms.Resize(image_size),
                               transforms.CenterCrop(image_size),
                               transforms.ToTensor(),
                               transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
                           ]))
# 创建加载器
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size,
                                         shuffle=True, num_workers=workers)
# 选择我们运行在上面的设备
device = torch.device("cuda:0" if (torch.cuda.is_available() and ngpu > 0) else "cpu")
# 绘制部分我们的输入图像
real_batch = next(iter(dataloader))
plt.figure(figsize=(8,8))
plt.axis("off")
plt.title("Training Images")
plt.imshow(np.transpose(vutils.make_grid(real_batch[0].to(device)[:64], padding=2, normalize=True).cpu(),(1,2,0)))

 

 

3.3 实现

通过设置输入参数和准备好的数据集,我们现在可以进入真正的实现步骤。我们将从权重初始化策略开始,然后详细讨论生成器,鉴别器, 损失函数和训练循环。

3.3.1 权重初始化

在DCGAN论文中,作者指出所有模型权重应从正态分布中随机初始化,mean = 0,stdev = 0.02。weights_init函数将初始化模型作为 输入,并重新初始化所有卷积,卷积转置和batch标准化层以满足此标准。初始化后立即将此函数应用于模型。

# custom weights initialization called on netG and netD
def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        nn.init.normal_(m.weight.data, 0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        nn.init.normal_(m.weight.data, 1.0, 0.02)
        nn.init.constant_(m.bias.data, 0)

3.3.2 生成器

生成器G用于将潜在空间矢量(z)映射到数据空间。由于我们的数据是图像,因此将 转换为数据空间意味着最终创建与训练图像具有相同大小的RGB图像(即3x64x64)。实际上,这是通过一系列跨步的二维卷

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值