当前位置:   article > 正文

Python深度学习之GAN

Python深度学习之GAN

Deep Learning with Python

这篇文章是我学习《Deep Learning with Python》(第二版,François Chollet 著) 时写的系列笔记之一。文章的内容是从 Jupyter notebooks 转成 Markdown 的,你可以去 GitHubGitee 找到原始的 .ipynb 笔记本。

你可以去这个网站在线阅读这本书的正版原文(英文)。这本书的作者也给出了配套的 Jupyter notebooks

本文为 第8章 生成式深度学习 (Chapter 8. Generative deep learning) 的笔记之一。

8.5 Introduction to generative adversarial networks

生成式对抗网络简介

GAN,中文是,错了,生成式对抗网络(Generative Adversarial Network)。和 VAE 一样,是用来学习图像的潜在空间的。这东西可以使生成图像与真实图像“在统计上”别无二致,说人话就是,生成的图像相当逼真。但与 VAE 不同,GAN 的潜在空间无法保证具有有意义的结构,并且是不连续的。

GAN 由两部分组成:

  • 生成器网络(generator network):输入一个随机向量(潜在空间中的一个随机点),并将其解码为图像。
  • 判别器网络(discriminator network):输入一张图像(真实的或生成器画的),预测该图像是真实的还是由生成器网络创建的。(判别器网络也叫「对手」,adversary)

训练 GAN 的目的是使「生成器网络」能够欺骗「判别器网络」。

直观理解 GAN 是一个很励志的故事:就是说有两个人,一个伪造者,一个鉴定师。伪造者仿造大师的画,然后把自己的仿制品混在真迹里交给鉴定师鉴定,鉴定师评估每一幅画的真伪,一样看穿了哪些是伪造的。好心的鉴定师反馈了伪造者,告诉他真迹有哪些特征。伪造者根据鉴定师的意见,一步步提升自己的仿造能力。两人不厌其烦地重复这个过程,伪造者变得越来越擅长复制大师的画,鉴定师也越来越擅长找出假画。到最后,伪造者造出了一批鉴定师也无可挑剔的“仿制正品”。

生成器将随机潜在向量转换成图像,判别器试图分辨真实图像与生成图像。生成器的训练是为了欺骗判别器

GAN 的训练方式很特殊,它的优化最小值是不固定的。我们通常的「梯度下降」是沿着静态的损失地形滚下山,但 GAN 训练时每下山一步都会对整个地形造成改变。它是一个动态系统,其最优化过程是两股力量之间的平衡。所以,GAN 很难训练。想要让 GAN 正常运行,需要进行大量的模型构建、超参数调节工作。

深度卷积生成式对抗网络

我们来尝试用 Keras 实现最最最简单的 GAN。具体来说,我们会做一个深度卷积生成式对抗网络(deep convolutional GAN,DCGAN),这种东西的生成器和判别器都是深度卷积神经网络。

我们将用 CIFAR10 数据集中“frog”类别的图像训练 DCGAN。这个数据集包含 50000 张 32×32 的 RGB 图像,这些图像属于 10 个类别(每个类别 5000 张图像)。

实现流程
  1. generator 网络将形状为 (latent_dim,) 的向量映射到形状为 (32, 32, 3) 的图像。
  2. discriminator 网络将形状为 (32, 32, 3) 的图像映射到一个二进制得分(a binary score),用于评估图像为真的概率。
  3. gan 网络将 generatordiscriminator 连接在一起: gan(x) = discriminator(generator(x))。这个网络是将潜在向量映射到判别器的评估结果。
  4. 使用带有 "real""fake" 标签的真假图像样本来训练判别器,用常规训练普通的图像分类模型的方法。
  5. 为了训练生成器,使用 gan 模型的损失相对于生成器权重的梯度。在每一步都要向「让判别器更有可能将生成器解码的图像划分为“真”」移动生成器的权重,即训练生成器来欺骗判别器。
实用技巧

训练和调节 GAN 的过程非常困难。所以我们需要记住一些前人总结出的实用技巧。这些技巧一般很有用,但并不能适用于所有情况。这些东西都没有理论依据,都是玄学,所以不解释直接写结论:

  • 使用 tanh 作为生成器最后一层的激活,而不用 sigmoid。
  • 使用正态分布(高斯分布)对潜在空间中的点进行采样,而不用均匀分布。
  • 随机性能够提高稳健性。GAN 训练时可能以各种方式“卡住”(达到错误的动态平衡),在训练过程中引入随机性有助于防止出现这种情况,引入随机性的方式有两种:
    1. 在判别器中使用 dropout;
    2. 向判别器的标签添加随机噪声;
  • 稀疏的梯度会妨碍 GAN 的训练。「最大池化运算」和 「ReLU 激活」可能导致梯度稀疏,所以推荐:
    1. 使用「步进卷积」代替「最大池化」来进行下采样;
    2. 使用 LeakyReLU 层来代替 ReLU 激活;
  • 在生成的图像中,常会见到棋盘状伪影,这是由于生成器中像素空间覆盖不均匀。解决这个问题的办法是:每当在生成器和判别器中都使用步进 Conv2DTranpose 或 Conv2D 时,内核大小要能够被步幅整除。

由于步幅大小和内核大小不匹配而导致的棋盘状伪影示例图:

由于步幅大小和内核大小不匹配而导致的棋盘状伪影

生成器的实现

开始构建年轻人的第一个 GAN 了!!

首先开发 generator 模型:将来自潜在空间的向量转换为一张候选图像。

为了避免训练时“卡住”,在判别器和生成器中都使用 dropout。

# GAN 生成器网络

from tensorflow import keras
from tensorflow.keras import layers
import numpy as np

height = 32
width = 32
channels = 3

latent_dim = 32

generator_input = keras.Input(shape=(latent_dim,))

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

x = layers.Conv2D(256, 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/543980
推荐阅读
相关标签
  

闽ICP备14008679号