[Deep-Learning-with-Python]GAN图片生成

GAN

由Goodfellow等人于2014年引入的生成对抗网络(GAN)是用于学习图像潜在空间的VAE的替代方案。它们通过强制生成的图像在统计上几乎与真实图像几乎无法区分,从而能够生成相当逼真的合成图像。

理解GAN的直观方式是想象一个伪造者试图创造一幅伪造的毕加索作品。起初,伪造者的任务非常糟糕。他将他的一些假货与真正的毕加索混合在一起,并将它们全部展示给艺术品经销商。艺术品经销商对每幅画进行真实性评估,并给出关于毕加索看起来像毕加索的原因的伪造反馈。伪造者回到他的工作室准备一些新的假货。随着时间的推移,伪造者越来越有能力模仿毕加索的风格,艺术品经销商越来越专业地发现假货。最后,他们手上拿着一些优秀的假毕加索。

这就是GAN的意义:伪造网络和专家网络,每个网络都经过最好的培训。因此,GAN由两部分组成:

  • 生成网络(generator): 将随机向量(潜在空间中的随机点)作为输入,并将其解码为合成图像;
  • 辨别网络(discriminator): 将图像(真实的或合成的)作为输入,并预测图像是来自训练集还是由生成器网络创建。

生成器网络经过训练,能够欺骗鉴别器网络,因此随着训练的进行,它逐渐产生越来越逼真的图像:人工图像看起来与真实图像无法区分,只要鉴别器网络不可能鉴别两张图片。同时,鉴别器不断适应发生器逐渐改进的能力,为生成的图像设置了高度的真实感。一旦训练结束,生成器就能够将其输入空间中的任何点转换为可信的图像。与VAE不同,这个潜在空间对有意义结构的明确保证较少;特别是,它不是连续的。
[图片上传失败...(image-599f61-1536326082049)]

值得注意的是,GAN是一个优化最小值不固定的系统。通常,梯度下降包括在静态损失中滚下山丘。但是使用GAN,从山上下来的每一步都会改变整个景观。这是一个动态系统,其中优化过程寻求的不是最小,而是两个力之间的平衡。出于这个原因,GAN是众所周知的难以训练 - 让GAN工作需要大量仔细调整模型架构和训练参数。

GAN实现示意图

使用keras实现一个简单的GAN网络:DCGAN,Generator和Discriminator都是由卷积网络组成。使用Conv2DTranspose网络层在Generator用来对图片上采样。

在CIFAR10,50000张32x32 RGB图片数据集上训练。为了训练更容易,仅使用“青蛙"类图片。

实现GAN网络流程:

  1. generator网络将(latent_dim, )向量转换成(32,32,3)图片;
  2. discriminator将(32,32,3)图片映射到2分类得分上,得到图片为真的概率;
  3. gan网络将generator和discriminator结合起来:gan(x) = discriminator(generator(x))。gan网络将隐空间向量映射到鉴别器鉴别generator由隐空间向量生成图片为真的概率上;
  4. 使用带real/fake标签的real、fake图片对Discriminator训练;
  5. 要训练Generator,可以使用gan模型损失对Generator权重的梯度。这意味着,在每个步骤中,将生成器的权重移动到使鉴别器更可能将生成器解码的图像归类为“真实”的方向上。换句话说,你训练生成器来欺骗鉴别器。

A bag of tricks

众所周知,训练GAN和调整GAN实现的过程非常困难。你应该记住一些已知的技巧。像深度学习中的大多数事情一样:这些技巧是启发式的,而不是理论支持的指导方针。 他们得到了对手头现象的直观理解的支持,并且他们已经知道在经验上运作良好,尽管不一定在每种情况下都有效。
以下是实现GAN生成器和鉴别器时使用的一些技巧。它不是GAN相关技巧的详尽列表;你会在GAN文献中找到更多:

  • Generator使用tanh作为最后一层的激活函数,而不是sigmoid;
  • 隐空间取样时使用正态分布(高斯分布),而不是均匀分布;
  • 为了健壮性可以增加随机性。由于GAN训练导致动态平衡,GAN可能会以各种方式陷入困境。在训练期间引入随机性有助于防止这种情况。我们以两种方式引入随机性:通过在鉴别器中使用dropout并通过向鉴别器的标签添加随机噪声。
  • 稀疏梯度可能会阻碍GAN训练在深度学习中,稀疏性通常是理想的属性,但在GAN中则不然。有两件事可以引起梯度稀疏:最大池操作和ReLU激活。建议使用跨步卷积进行下采样,而不是最大池化,建议使用LeakyReLU层而不是ReLU激活。它与ReLU类似,但它通过允许小的负激活值来放宽稀疏性约束。
  • 在生成的图像中,通常会看到由于生成器中像素空间的不均匀覆盖而导致的棋盘格伪影(见图8.17)。为了解决这个问题,每当我们在生成器和鉴别器中使用跨步的Conv2DTranpose或Conv2D时,我们使用可以被步长大小整除的内核大小。

Generator

首先,开发一个生成器模型,该模型将矢量(从潜在空间 - 在训练期间将随机采样)转换为候选图像。 GAN通常出现的许多问题之一是生成器卡在生成的看起来像噪声的图像。一种可能的解决方案是在鉴别器和发生器上使用dropout。
GAN 生成器网络

import keras
from keras import layers
import numpy as np

latent_dim = 2
height = 32
width = 32
channels = 3
generator_input = keras.Input(shape=(latent_dim,))

x = layers.Dense(128 * 16 * 16)(generator_input)
x = layers.LeakyReLU()(x)
x = layers.Reshape((16, 16, 128))(x)#将输入转换成16*16 128通道的特征图

x = layers.Conv2D(256, 5, padding='same')(x)
x = layers.LeakyReLU()(x)

x=layers.Conv2DTranspose(256, 4, strides=2, padding='same')(x)#上采样32*32
x = layers.LeakyReLU()(x)

x = layers.Conv2D(256, 5, padding='same')(x)
x = layers.LeakyReLU()(x)
x = layers.Conv2D(256, 5, padding='same')(x)
x = layers.LeakyReLU()(x)

#产生32x32 1通道的特征图
x = layers.Conv2D(channels, 7, activation='tanh', padding='same')(x)
generator = keras.models.Model(generator_input, x)#将(latent_dim,)->(32,32,3)
generator.summary()

Discriminator

接下来,将开发一个鉴别器模型,将候选图像(真实的或合成的)作为输入,并将其分为两类:“生成的图像”或“来自训练集的真实图像”。
GANs 鉴别器网络

discriminator_input = layers.Input(shape=(height, width, channels))
x = layers.Conv2D(128, 3)(discriminator_input)
x = layers.LeakyReLU()(x)
x = layers.Conv2D(128, 4, strides=2)(x)
x = layers.LeakyReLU()(x)
x = layers.Conv2D(128, 4, strides=2)(x)
x = layers.LeakyReLU()(x)
x = layers.Conv2D(128, 4, strides=2)(x)
x = layers.LeakyReLU()(x)
x = layers.Flatten()(x)

x = layers.Dropout(0.4)(x)

x = layers.Dense(1, activation='sigmoid')(x)#二分类

discriminator = keras.models.Model(discriminator_input, x)
discriminator.summary()

discriminator_optimizer = keras.optimizers.RMSprop(lr=0.0008,
        clipvalue=1.0,decay=1e-8)
discriminator.compile(optimizer=discriminator_optimizer,
    loss='binary_crossentropy')

对抗网络

最后,设置GAN,它链接生成器和鉴别器。经过训练,该模型将使生成器向一个方向移动,从而提高其欺骗鉴别器的能力。这个模型将潜在空间点转换为分类决策(“假”或“真实”) 并且它意味着使用始终“这些是真实图像”的标签进行训练。因此,训练gan将更新生成器的权重。在查看假图像时,使鉴别器更有可能预测“真实”的方式。非常重要的是要注意在训练期间将鉴别器设置为冻结(不可训练):训练gan时不会更新其权重。如果在此过程中可以更新鉴别器权重,那么将训练鉴别器始终预测“真实”,这不是我们想要的!
对抗网络

discriminator.trainable = False

gan_input = keras.Input(shape=(latent_dim,))
gan_output = discriminator(generator(gan_input))
gan = keras.models.Model(gan_input,gan_output)

gan_optimizer = keras.optimizers.RMSprop(lr=0.0004,clipvalue=1.0,
        decay=1e-8)
gan.compile(optimizer=gan_optimizer,loss='binary_crossentropy')

训练DCGAN

现在可以开始训练了。总结一下,这就是训练循环的流程。对于每个epoch,执行以下操作:

  1. 在潜在空间中绘制随机点(随机噪声);
  2. 在生成器中使用随机噪声生成图像;
  3. 将生成的图像与实际图像混合;
  4. 使用这些混合图像训练鉴别器,并使用相应的目标:要么“真实”(对于真实图像)要么“假”(对于生成的图像);
  5. 在潜在空间中绘制新的随机点;
  6. 使用这些随机向量训练gan,目标都是“这些都是真实的图像。”这会更新生成器的权重(仅因为鉴别器在gan内被冻结)以使它们朝向让鉴别器预测“这些是真实的图像“用于生成的图像:这会训练发生器欺骗鉴别器。

GAN训练

import os
from keras.preprocessing import image

(x_train, y_train), (_, _) = keras.datasets.cifar10.load_data()
x_train = x_train[y_train.flatten() == 6]#第6类

x_train = x_train.reshape((x_train.shape[0],)+(height, width,               channels)).astype('float32') / 255.

iterations = 10000
batch_size = 20
save_dir = 'your_dir'#保存生成图片

start = 0
for step in range(iterations):
    random_latent_vectors = np.random.normal(size=(batch_size,
        latent_dim))#正态分布随机取点

    generated_images = generator.predict(random_latent_vectors)#fake图

    stop = start + batch_size
    real_images = x_train[start: stop]
    #混合真、假图片
    combined_images = np.concatenate([generated_images, real_images])
    #标签
    labels = np.concatenate([np.ones((batch_size, 1)),
        np.zeros((batch_size, 1))])
    labels += 0.05 * np.random.random(labels.shape)#加随机噪声

    d_loss = discriminator.train_on_batch(combined_images, labels)

    random_latent_vectors = np.random.normal(size=(batch_size,
        latent_dim))
    isleading_targets = np.zeros((batch_size, 1))
    #gan训练:训练generator,固定discriminator
    a_loss = gan.train_on_batch(random_latent_vectors,
        misleading_targets)

    start += batch_size
    if start > len(x_train) - batch_size:
        start = 0

    if step % 100 == 0:#每100步保存一次
        gan.save_weights('gan.h5')

        print('discriminator loss:', d_loss)
        print('adversarial loss:', a_loss)

        img = image.array_to_img(generated_images[0] * 255., scale=False)
        img.save(os.path.join(save_dir,'generated_frog'            +str(step)+'.png'))

        img = image.array_to_img(real_images[0] * 255., scale=False)
        img.save(os.path.join(save_dir,'real_frog' + str(step) + '.png'))

训练时,可能会看到对抗性损失开始显着增加,而判别性损失往往为零 - 鉴别者最终可能主导生成器。如果是这种情况,尝试降低鉴别器学习速率,并提高鉴别器的丢失率dropout。

小结

  • GAN由与鉴别器网络和生成器网络组成。训练鉴别器以在生成器的输出和来自训练数据集的真实图像之间进行区分,并且训练生成器以欺骗鉴别器。值得注意的是,生成器组不能直接从训练集中看到图像;它对数据的信息来自鉴别器。
  • GAN难以训练,因为训练GAN是一个动态过程,而不是具有固定损失的简单梯度下降过程。GAN正确训练需要使用一些启发式技巧,以及大量的参数调整。
  • GAN可以产生高度逼真的图像。但是与VAE不同,他们学到的潜在空间没有整齐的连续结构,因此可能不适合某些实际应用,例如通过潜在空间概念向量进行图像编辑

原文地址:https://www.cnblogs.com/ysugyl/p/9607125.html

时间: 2024-08-29 18:48:46

[Deep-Learning-with-Python]GAN图片生成的相关文章

Machine and Deep Learning with Python

Machine and Deep Learning with Python Education Tutorials and courses Supervised learning superstitions cheat sheet Introduction to Deep Learning with Python How to implement a neural network How to build and run your first deep learning network Neur

Deep Learning with Python

Deep Learning with Python 适合立志研究人工智能.深度学习的初学者及有经验的开发者,本书分为两部分,第一部分是入门篇,讲解什么叫人工智能和深度学习,介绍一些基础概念,初级实例,适合初学者了解什么是深度学习:第二部分是高级篇,深度学习在计算机视觉.文本处理的方法和理论方法,也有很多的实际例子和最佳实践等,适合有经验开发者,学习梯度明显,是一本经典的人工智能书籍. 本书是 Google 推荐的学习深度学习的书籍,它深入精确的讲解了深度学习最基本的概念知识结构,对于宏观把握深度

Python深度学习 deep learning with Python 人民邮电出版社

内容简介 本书由Keras之父.现任Google人工智能研究员的弗朗索瓦?肖莱(Fran?ois Chollet)执笔,详尽介绍了用Python和Keras进行深度学习的探索实践,涉及计算机视觉.自然语言处理.生成式模型等应用.书中包含30多个代码示例,步骤讲解详细透彻.由于本书立足于人工智能的可达性和大众化,读者无须具备机器学习相关背景知识即可展开阅读.在学习完本书后,读者将具备搭建自己的深度学习环境.建立图像识别模型.生成图像和文字等能力. 作者简介 [作者简介] 弗朗索瓦?肖莱(Fran?

通过python将图片生成字符画

基础知识: 1.python基础知识   快速学习链接:https://www.shiyanlou.com/courses/214 2.linux命令行操作   快速学习链接:https://www.shiyanlou.com/courses/1 3.pillow库的使用     快速学习链接:http://pillow.readthedocs.io/en/latest/index.html(英文) http://www.cnblogs.com/apexchu/p/4231041.html(中文

Deep Learning with Python第二章(翻译)5

为了让它更具体一些,让我们回去看看MNIST例子的过程.首先,我们下载了MNIST的数据包: (略) 下一步,我们展示了张量train_images的轴的数量,ndim属性: (略) 这是它的shape: (略) 并且这是它的数据类型,dtype属性: (略) 所以我们有了一个8位int的3D张量.更准确的说,这是一个每个包含了28*8个整数的60000个矩阵.每个矩阵是一个有着0到255之间系数的灰度图片. 让我们使用Matplotlib库(标准科学python套中的一部分)来展示四个3D张量

【转载】机器学习——深度学习(Deep Learning)

机器学习——深度学习(Deep Learning) 分类: Machine Learning2012-08-04 09:49 142028人阅读 评论(70) 收藏 举报 algorithmclassificationfeaturesfunctionhierarchy Deep Learning是机器学习中一个非常接近AI的领域,其动机在于建立.模拟人脑进行分析学习的神经网络,最近研究了机器学习中一些深度学习的相关知识,本文给出一些很有用的资料和心得. Key Words:有监督学习与无监督学习

(转) Deep Learning Resources

转自:http://www.jeremydjacksonphd.com/category/deep-learning/ Deep Learning Resources Posted on May 13, 2015 Videos Deep Learning and Neural Networks with Kevin Duh: course page NY Course by Yann LeCun: 2014 version, 2015 version NIPS 2015 Deep Learnin

机器学习——深度学习(Deep Learning)

Deep Learning是机器学习中一个非常接近AI的领域,其动机在于建立.模拟人脑进行分析学习的神经网络,最近研究了机器学习中一些深度学习的相关知识,本文给出一些很有用的资料和心得. Key Words:有监督学习与无监督学习,分类.回归,密度估计.聚类,深度学习,Sparse DBN, 1. 有监督学习和无监督学习 给定一组数据(input,target)为Z=(X,Y). 有监督学习:最常见的是regression & classification. regression:Y是实数vec

Python (1) - 7 Steps to Mastering Machine Learning With Python

Step 1: Basic Python Skills install Anacondaincluding numpy, scikit-learn, and matplotlib Step 2: Foundational Machine Learning Skills Unofficial Andrew Ng course notes Tom Mitchell Machine Learning Lectures Step 3: Scientific Python Packages Overvie