Path: blob/master/site/zh-cn/tutorials/generative/cvae.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
卷积变分自编码器
导入 Tensorflow 与其他库
加载 MNIST 数据集
每个 MNIST 图像最初都是一个由 784 个整数组成的向量,每个整数在 0-255 之间,代表一个像素的强度。在我们的模型中使用伯努利分布对每个像素进行建模,并对数据集进行静态二值化。
使用 tf.data 来将数据分批和打乱
通过 tf.keras.Sequential 连接生成网络与推理网络
在此 VAE 示例中,对编码器和解码器网络使用两个小型 ConvNet。在文献中,这些网络也分别称为推断/识别和生成模型。使用 tf.keras.Sequential
来简化实现。在下面的描述中,使 和 分别表示观测值和隐变量。
生成网络
这定义了近似后验分布 ,它会将输入取作观测值并输出一组参数,用于指定隐变量表示 的条件分布。在本例中,简单地将分布建模为对角高斯分布,网络会输出分解高斯分布的均值和对数方差参数。输出对数方差而不是直接用于数值稳定性的方差。
推理网络
这定义了观测值的条件分布 ,它会将隐变量样本 取作输入并输出观测值条件分布的参数。将隐变量先验分布 建模为单位高斯分布。
重参数化技巧
要在训练期间为解码器生成样本 ,您可以在给定输入观测值 的情况下从编码器输出的参数所定义的隐变量分布中采样。然而,这种采样操作会产生瓶颈,因为反向传播不能流经随机节点。
要解决这个问题,请使用重参数化技巧。在我们的示例中,使用解码器参数和另一个参数 来逼近 ,如下所示:
其中 和 分别代表高斯分布的均值和标准差。它们可通过解码器输出推导得出。 可被认为是用于保持 的随机性的随机噪声。从标准正态分布生成 。
隐变量 现在由 、 和 的函数生成,这将使模型能够分别通过 和 在编码器中反向传播梯度,同时通过 保持随机性。
网络架构
对于编码器网络,使用两个卷积层后接一个全连接层。在解码器网络中,通过使用一个全连接层后接三个卷积转置层(在某些背景下也称为反卷积层)来镜像此架构。请注意,通常的做法是在训练 VAE 时避免使用批量归一化,因为使用 mini-batch 导致的额外随机性可能会在提高采样随机性的同时加剧不稳定性。
定义损失函数和优化器
VAE 通过最大化边际对数似然的证据下界(ELBO)进行训练:
在实践中,优化此期望的单样本蒙特卡罗估值:
注:您也可以分析计算 KL 项,但为了简单起见,您在此处会将三个项全部应用到蒙特卡罗 Estimator 中。
训练
首先迭代数据集
在每次迭代期间,将图像传递给编码器以获取近似后验分布 的一组均值和对数方差参数
然后,应用重参数化技巧以从 中采样
最后,将重参数化的样本传递给解码器以获取生成分布 的 logit
注:由于您使用由 Keras 加载的数据集,训练集中有 6 万个数据点,测试集中有 1 万个数据点,因此我们基于测试集得出的 ELBO 会略高于使用 Larochelle 的 MNIST 动态二值化的文献中报告的结果。
生成图像
进行训练后,可以生成一些图片了
首先从单位高斯先验分布 中采样一组隐向量
随后生成器将潜在样本 转换为观测值的 logit,得到分布
在此处,绘制伯努利分布的概率分布图
使用 epoch 编号显示图片
生成所有保存图片的 GIF
显示隐空间中数字的二维流形
运行下面的代码将显示不同数字类的连续分布,每个数字都会在二维隐空间中变形为另一数字。使用 TensorFlow Probability 为隐空间生成标准正态分布。
后续步骤
本教程演示了使用 TensorFlow 实现卷积变分自编码器的方式。
下一步,您可以尝试通过增大网络来改进模型输出。例如,您可以尝试将每个 Conv2D
和 Conv2DTranspose
层的 filter
参数设置为 512。请注意,为了生成最终的二维隐空间图像,您需要将 latent_dim
保持为 2。此外,训练时间会随网络的增大而延长。
您还可以尝试使用不同的数据集实现 VAE,例如 CIFAR-10。
VAE 支持以多种不同的风格和不同的复杂性实现。您可以从以下资源中找到其他实现:
如果您想了解有关 VAE 的更多详细信息,请参阅变分自编码器简介。