GAN

presentation: 前端时间defect detect中很多思想也和GAN相关。通过重建误差定义了异常分数。所以最近有时间就在看GAN, 代码都是基于Pytorch的。

GAN(生成对抗网络)

Generative Adversarial network

2-1:概述

GAN(生成对抗网络),顾名思义,这个网络第一部分是生成网络,第二部分对抗模型严格来讲是一个判别器;简单来说,就是让两个网络相互竞争,生成网络来生成假的数据,对抗网络通过判别器去判别真伪,最后希望生成器生成的数据能够以假乱真。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

核心思想:判断器的任务是尽力将假的判断为假的,将真的判断为真的;生成器的任务是使生成的越真越好。两者交替迭代训练。

Discriminator Network

对抗网络:

对抗过程简单来说就是一个判断真假的判别器,相当于一个二分类问题,我们输入一张真的图片希望判别器输出的结果是1,输入一张假的图片希望判别器输出的结果是0。

这其实已经和原图片的label没有关系了,不管原图片到底是一个多少类别的图片,他们都统一称为真的图片,label是1表示真实的;而生成的假的图片的label是0表示假的。

我们训练的过程就是希望这个判别器能够正确的判出真的图片和假的图片,这其实就是一个简单的二分类问题,对于这个问题可以用我们前面讲过的很多方法去处理,比如logistic回归,深层网络,卷积神经网络,循环神经网络都可以。

Network:

以下是以mnist手写数字来做数据,通过生成对抗网络我们希望生成一些“以假乱真”的手写字体。

为了加快训练过程,我们不使用卷积网络来做判别器,我们使用简单的多层网络来进行判别。

#定义判别器  #####Discriminator######使用多层网络来作为判别器
#将图片28x28展开成784,然后通过多层感知器,中间经过斜率设置为0.2的LeakyReLU激活函数,
# 最后接sigmoid激活函数得到一个0到1之间的概率进行二分类。
#之所以使用LeakyRelu而不是用ReLU激活函数是因为经过实验LeakyReLU的表现更好。
class discriminator(nn.Module):
    def __init__(self):
        super(discriminator, self).__init__()
        self.dis = nn.Sequential(
            nn.Linear(784, 256),#输入特征数为784,输出为256
            nn.LeakyReLU(0.2),  #进行非线性映射
            nn.Linear(256, 256),#进行一个线性映射
            nn.LeakyReLU(0.2),
            nn.Linear(256, 1),
            nn.Sigmoid()		#也是一个激活函数,二分类问题中,
            					#sigmoid可以班实数映射到【0,1】,作为概率值,
            					#多分类用softmax函数
        )
 
    def forward(self, x):
        x = self.dis(x)
        return x
Train:

判别器的训练由两部分组成,第一部分是真的图像判别为真,第二部分是假的图片判别为假,在这两个过程中,生成器的参数不参与更新。

首先我们需要定义loss的度量方式和优化器,loss度量使用二分类的交叉熵,优化器注意使用的学习率是0.0003
criterion = nn.BCELoss()
d_optimizer = torch.optim.Adam(D.parameters(), lr=0.0003)
g_optimizer = torch.optim.Adam(G.parameters(), lr=0.0003)

训练:

img = img.view(num_img, -1)  # 将图片展开乘28x28=784
real_img = Variable(img).cuda()  # 将tensor变成Variable放入计算图中
real_label = Variable(torch.ones(num_img)).cuda()  # 定义真实label为1
fake_label = Variable(torch.zeros(num_img)).cuda()  # 定义假的label为0
 
# compute loss of real_img 计算真实图片的损失
real_out = D(real_img)  # 将真实的图片放入判别器中
d_loss_real = criterion(real_out, real_label)  # 得到真实图片的loss  
real_scores = real_out  # 得到真实图片的判别值,真实图片放入判别器输出越接近1越好
 
# 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)  # 得到假的图片的loss
fake_scores = fake_out  # 得到假图片的判别值,假的图片放入判别器越接近0越好
 
# bp and optimize 损失函数和优化
d_loss = d_loss_real + d_loss_fake  # 将真假图片的loss加起来
d_optimizer.zero_grad()  # 在反向传播之前,归0梯度
d_loss.backward()  # 反向传播(将误差反向传播)
d_optimizer.step()  # 更新参数

这是一个判别器的训练过程,我们希望判别器能够正确辨别出真假图片。

Generative Network

生成网络:

生成一张假的图片,逐渐优化生成器,让生成器生成的图片能够以假乱真。

首先给出一个简单的高维的正态分布的噪声向量,如上图所示的D-dimensional noise vector,这个时候我们可以通过仿射变换,也就是xw+b将其映射到一个更高的维度,然后将他重新排列成一个矩形,这样看着更像一张图片,接着进行一些卷积、池化、激活函数处理,最后得到了一个与我们输入图片大小一模一样的噪音矩阵,这就是我们所说的假的图片,这个时候我们如何去训练这个生成器呢?就是通过判别器来得到结果,然后希望增大判别器判别这个结果为真的概率,在这一步我们不会更新判别器的参数,只会更新生成器的参数。

Network:

输入一个100维的0~1之间的高斯分布,然后通过第一层线性变换将其映射到256维,然后通过ReLU激活函数,接着进行一个线性变换,再经过一个ReLU激活函数,然后经过线性变换将其变成784维,最后经过Tanh激活函数是希望生成的假的图片数据分布能够在-1~1之间。
class generator(nn.Module):
    def __init__(self, input_size):
        super(generator, self).__init__()
        self.gen = nn.Sequential(
            nn.Linear(input_size, 256), #用线性变换将输入映射到256维
            nn.ReLU(True),			    #relu激活
            nn.Linear(256, 256),	    #线性变换
            nn.ReLU(True),				#relu激活
            nn.Linear(256, 784),		#线性变换
            nn.Tanh()					#Tanh激活使得生成数据分布在【-1,1】之间
        )
 
    def forward(self, x):
        x = self.gen(x)
        return x

Train:

在生成网络的训练中,我们希望生成一张假的图片,然后经过判别器之后希望他能够判断为真的图片,在这个过程中,我们将判别器固定,将假的图片传入判别器的结果与真实label对应,反向传播更新的参数是生成网络里面的参数,这样我们就可以通过更新生成网络里面的参数来使得判别器判断生成的假的图片为真,这样就达到了生成对抗的作用。

# 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)  # 得到假的图片与真实图片label的loss
 
# bp and optimize
g_optimizer.zero_grad()  # 归0梯度
g_loss.backward()  # 反向传播
g_optimizer.step()  # ( .step()一般用在反向传播后面)更新生成网络的参数

这样我们就写好了一个简单的生成网络,通过不断地训练我们希望能够生成很真的图片。

2-2:环境配置与测试

CUDA10.1; Pytorch1.5.1; Python3.7; 其他各种包
GitHub:
https://github.com/eriklindernoren/PyTorch-GAN#context-encoder

2-3:Implementations

0、前置

本文概述;

台大李宏毅:https://www.bilibili.com/video/av36779012?from=search&seid=4463323497592419170

1、简单的多层神经网络(Multilayer neural network)

训练速度快:10轮:CPU——14mins, GPU——6mins ;50轮之后才有效果

2、简单的卷积神经网络(Convolutional Neural Network)

GPU, 10轮左右效果就能展现出来了。

1、Auxiliary Classifier GAN

cd implementations/acgan/
python3 acgan.py
resource:
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值