PyTorch 实现GAN ⽣成式对抗⽹络含代码
GAN
⽹络结构
GAN 公式的理解
理解 GAN 公式是进⼀步理解 GAN 的必经过程,所以下⾯就来简单讲讲该公式。⼀开始我们要定义出判别器和⽣成器,这⾥将 定义为判别器,将 定义成⽣成器。接着要做的就是训练判别器,让它可以识别真实数据,也就有了 GAN 公式的前半部分。
其中, 表⽰期望 从 分布中获取; 表⽰真实数据, 表⽰真实数据的分布。
前半部分的意思就是:判别器判别出真实数据的概率,判别器的⽬的就是要最⼤化这⼀项,简单来说,就是对于服从 分布的 ,判别器可以准确得出 。
接着看 GAN 公式略微复杂的后半部分。
其中, 表⽰期望 是从 分布中获取; 表⽰⽣成数据; 表⽰⽣成数据的分布。
对于判别器 ⽽⾔,如果向其输⼊的是⽣成数据,即 ,判别器的⽬标就是最⼩化 ,即判别器希望 ,也就是判别器希望 最⼤化。
min max V (D ,G )=G D E [logD (x )]+x ∼P (x )data E [log (1−z ∼P (z )z D (G (z )))]
D G
E [logD (x )]
x ∼P (x )data E x ∼P (x )data x P data x P data P data x D (x )≈1E [log (1−z ∼P (z )z D (G (z )))]
E z ∼P (z )z z P (z )z z P (z )z D D (G (z ))D (G (z ))D (G (z ))≈0log (1−D (G (z )))
但对⽣成器来说,它的⽬标却与判别器相反,⽣成器希望⾃⼰⽣成的数据被判别器打上⾼分,即希望 ,也就是最⼩化 。⽣成器只能影响 GAN 公式的后半部分,对前半部分没有影响。
现在可以理解公式 ,但为什么 GAN 公式中还有 呢?要理解 ,就要先回忆⼀下 GAN 的训练流程。⼀开始,固定⽣成器 的参数专门去训练判别器 。GAN 公式表达的意思也⼀样,先针对判别器 去训练,也就是最⼤化 和 的值,从⽽达到最⼤化 的⽬的,表达如下:
当训练完判别器 后,就会固定判别器 的参数去训练⽣成器 ,因为此时判别器已经经过⼀次训练了,所以⽣成器 的⽬标就变成:当 时,最⼩化 的值,从⽽达到最⼩化 的⽬的。表达如下:通过上⾯分成两步的分析,我们可以理解 的含义,简单来说,就是先从判别器 的⾓度最⼤化 ,再从⽣成器 的⾓度最⼩化 。
上边公式讲解中,⼤量使⽤对数,对数函数在它的定义域内是单调增函数,数据取对数后,并不会改变数据间的相对关系,这⾥使⽤对数是为了让计算更加⽅便。
Ref:《深⼊浅出GAN⽣成对抗⽹络》-廖茂⽂简单线性 GAN 代码如下
import torch
import torchvision
import torch .nn as nn
import torch .nn .functional as F
厦门鼓浪屿怎么去方便
from torchvision import datats
from torchvision import transforms
from torchvision .utils import save_image
from torch .autograd import Variable
import os
if not os .path .exists ('./img'):
同归于尽的意思
os .mkdir ('./img')
def to_img (x ):
out = 0.5 * (x + 1)
out = out .clamp (0, 1)
out = out .view (-1, 1, 28, 28)
return out
batch_size = 128
num_epoch = 100
z_dimension = 100
# Image processing
大学生演讲稿
img_transform = transforms .Compo ([
transforms .ToTensor (),
transforms .Normalize (mean =(0.5), std =(0.5))
])
# MNIST datat
mnist = datats .MNIST (
吴磊个人资料简介root ='./data/', train =True , transform =img_transform , download =True )
# Data loader
dataloader = torch .utils .data .DataLoader (
datat =mnist , batch_size =batch_size , shuffle =True )
D (G (z ))≈1log (1−D (G (z )))V (D ,G )=
E [logD (x )]+x ∼P (x )data E [log (1−z ∼P (z )z D (G (z )))]min max G D min max G D G D D D (x )log (1−D (G (z )))V (D ,G )D =G ⋆argmax V (D ,G )
D D D G G D =D G ⋆
log (1−D (G (z )))V (D ,G )G =⋆argmin V (G ,D )
G G ⋆
min max G D D V (D ,G )G V (D ,G )
# Discriminator
class discriminator(nn.Module):
def__init__(lf):
super(discriminator, lf).__init__()
lf.dis = nn.Sequential(
nn.Linear(784,256),
nn.LeakyReLU(0.2),
nn.Linear(256,256),
nn.LeakyReLU(0.2),
nn.Linear(256,1),
nn.Sigmoid())
def forward(lf, x):
x = lf.dis(x)
return x
# Generator
class generator(nn.Module):
def__init__(lf):
super(generator, lf).__init__()
< = nn.Sequential(
nn.Linear(100,256),
nn.ReLU(True),
nn.Linear(256,256),
nn.ReLU(True),
nn.Linear(256,784),
nn.Tanh())
def forward(lf, x):
x = lf.gen(x)
return x
D = discriminator()
怎么哄对象开心
G = generator()
if torch.cuda.is_available():
D = D.cuda()
G = G.cuda()
# Binary cross entropy loss and optimizer
criterion = nn.BCELoss()
d_optimizer = torch.optim.Adam(D.parameters(), lr=0.0003) g_optimizer = torch.optim.Adam(G.parameters(), lr=0.0003)
# Start training
for epoch in range(num_epoch):
for i,(img, _)in enumerate(dataloader):
num_img = img.size(0)
# =================train discriminator
img = img.view(num_img,-1)
real_img = Variable(img).cuda()
real_label = s(num_img,1)).cuda()
fake_label = s(num_img,1)).cuda()
# compute loss of real_img
real_out = D(real_img)
d_loss_real = criterion(real_out, real_label)
real_scores = real_out # clor to 1 means better
# compute loss of fake_img
z = Variable(torch.randn(num_img, z_dimension)).cuda() fake_img = G(z)
锅碗瓢盆交响曲
fake_out = D(fake_img)
d_loss_fake = criterion(fake_out, fake_label)
fake_scores = fake_out # clor to 0 means better
# bp and optimize
d_loss = d_loss_real + d_loss_fake
_grad()
d_loss.backward()
d_optimizer.step()
# ===============train generator
# compute loss of fake_img
z = Variable(torch.randn(num_img, z_dimension)).cuda()
fake_img = G(z)
output = D(fake_img)
g_loss = criterion(output, real_label)
# bp and optimize
_grad()
g_loss.backward()
g_optimizer.step()
if(i +1)%100==0:
print('Epoch [{}/{}], d_loss: {:.6f}, g_loss: {:.6f} '
'D real: {:.6f}, D fake: {:.6f}'.format(
epoch, num_epoch, d_loss.item(), g_loss.item(),
real_an(), fake_an()))
if epoch ==0:
real_images = to_img(real_img.cpu().data)
save_image(real_images,'./img/real_images.png')
fake_images = to_img(fake_img.cpu().data)
save_image(fake_images,'./img/fake_images-{}.png'.format(epoch +1))
torch.save(G.state_dict(),'./generator.pth')
torch.save(D.state_dict(),'./discriminator.pth')
卷积 GAN 代码如下
__author__ ='ShelockLiao'
import torch
as nn
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datats
from torchvision.utils import save_image
import os
if not ists('./dc_img'):
os.mkdir('./dc_img')
def to_img(x):
out =0.5*(x +1)
out = out.clamp(0,1)
out = out.view(-1,1,28,28)
return out
batch_size =128
num_epoch =100
z_dimension =100# noi dimension
img_transform = transforms.Compo([
img_transform = transforms.Compo([
transforms.ToTensor(),
transforms.Normalize((0.5),(0.5))
])
mnist = datats.MNIST('./data', transform=img_transform) dataloader = DataLoader(mnist, batch_size=batch_size, shuffle=True,
num_workers=4)
class discriminator(nn.Module):
def__init__(lf):
super(discriminator, lf).__init__()
nn.Conv2d(1,32,5, padding=2),# batch, 32, 28, 28
nn.LeakyReLU(0.2,True),
蒙卦
nn.AvgPool2d(2, stride=2),# batch, 32, 14, 14
)
nn.Conv2d(32,64,5, padding=2),# batch, 64, 14, 14
nn.LeakyReLU(0.2,True),
nn.AvgPool2d(2, stride=2)# batch, 64, 7, 7
)
lf.fc = nn.Sequential(
nn.Linear(64*7*7,1024),
nn.LeakyReLU(0.2,True),
nn.Linear(1024,1),
nn.Sigmoid()
)
def forward(lf, x):
'''
x: batch, width, height, channel=1
'''
x = lf.conv1(x)
x = lf.conv2(x)
x = x.view(x.size(0),-1)
x = lf.fc(x)
return x
去图书馆英语class generator(nn.Module):
def__init__(lf, input_size, num_feature):
super(generator, lf).__init__()
lf.fc = nn.Linear(input_size, num_feature)# batch, 3136=1x56x56 lf.br = nn.Sequential(
nn.BatchNorm2d(1),
nn.ReLU(True)
)
lf.downsample1 = nn.Sequential(
nn.Conv2d(1,50,3, stride=1, padding=1),# batch, 50, 56, 56
nn.BatchNorm2d(50),
nn.ReLU(True)
)
lf.downsample2 = nn.Sequential(
nn.Conv2d(50,25,3, stride=1, padding=1),# batch, 25, 56, 56 nn.BatchNorm2d(25),
nn.ReLU(True)
)
lf.downsample3 = nn.Sequential(
nn.Conv2d(25,1,2, stride=2),# batch, 1, 28, 28
nn.Tanh()
)
def forward(lf, x):
x = lf.fc(x)