赞
踩
这篇文章是我学习《Deep Learning with Python》(第二版,François Chollet 著) 时写的系列笔记之一。文章的内容是从 Jupyter notebooks 转成 Markdown 的,你可以去 GitHub 或 Gitee 找到原始的 .ipynb
笔记本。
你可以去这个网站在线阅读这本书的正版原文(英文)。这本书的作者也给出了配套的 Jupyter notebooks。
本文为 第8章 生成式深度学习 (Chapter 8. Generative deep learning) 的笔记之一。
生成式对抗网络简介
GAN,中文是淦,错了,生成式对抗网络(Generative Adversarial Network)。和 VAE 一样,是用来学习图像的潜在空间的。这东西可以使生成图像与真实图像“在统计上”别无二致,说人话就是,生成的图像相当逼真。但与 VAE 不同,GAN 的潜在空间无法保证具有有意义的结构,并且是不连续的。
GAN 由两部分组成:
训练 GAN 的目的是使「生成器网络」能够欺骗「判别器网络」。
直观理解 GAN 是一个很励志的故事:就是说有两个人,一个伪造者,一个鉴定师。伪造者仿造大师的画,然后把自己的仿制品混在真迹里交给鉴定师鉴定,鉴定师评估每一幅画的真伪,一样看穿了哪些是伪造的。好心的鉴定师反馈了伪造者,告诉他真迹有哪些特征。伪造者根据鉴定师的意见,一步步提升自己的仿造能力。两人不厌其烦地重复这个过程,伪造者变得越来越擅长复制大师的画,鉴定师也越来越擅长找出假画。到最后,伪造者造出了一批鉴定师也无可挑剔的“仿制正品”。
GAN 的训练方式很特殊,它的优化最小值是不固定的。我们通常的「梯度下降」是沿着静态的损失地形滚下山,但 GAN 训练时每下山一步都会对整个地形造成改变。它是一个动态系统,其最优化过程是两股力量之间的平衡。所以,GAN 很难训练。想要让 GAN 正常运行,需要进行大量的模型构建、超参数调节工作。
我们来尝试用 Keras 实现最最最简单的 GAN。具体来说,我们会做一个深度卷积生成式对抗网络(deep convolutional GAN,DCGAN),这种东西的生成器和判别器都是深度卷积神经网络。
我们将用 CIFAR10 数据集中“frog”类别的图像训练 DCGAN。这个数据集包含 50000 张 32×32 的 RGB 图像,这些图像属于 10 个类别(每个类别 5000 张图像)。
generator
网络将形状为 (latent_dim,)
的向量映射到形状为 (32, 32, 3)
的图像。discriminator
网络将形状为 (32, 32, 3)
的图像映射到一个二进制得分(a binary score),用于评估图像为真的概率。gan
网络将 generator
和 discriminator
连接在一起: gan(x) = discriminator(generator(x))
。这个网络是将潜在向量映射到判别器的评估结果。"real"
或 "fake"
标签的真假图像样本来训练判别器,用常规训练普通的图像分类模型的方法。gan
模型的损失相对于生成器权重的梯度。在每一步都要向「让判别器更有可能将生成器解码的图像划分为“真”」移动生成器的权重,即训练生成器来欺骗判别器。训练和调节 GAN 的过程非常困难。所以我们需要记住一些前人总结出的实用技巧。这些技巧一般很有用,但并不能适用于所有情况。这些东西都没有理论依据,都是玄学,所以不解释直接写结论:
由于步幅大小和内核大小不匹配而导致的棋盘状伪影示例图:
开始构建年轻人的第一个 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。