苏剑林作者

细水长flow之f-VAEs:Glow与VAEs的联姻

前言:这篇文章是我们前几天挂到 arXiv 上的论文的中文版。在这篇论文中,我们给出了结合流模型(如前面介绍的 Glow)和变分自编码器的一种思路,称之为 f-VAEs。理论可以证明 f-VAEs 是囊括流模型和变分自编码器的更一般的框架,而实验表明相比于原始的 Glow 模型,f-VAEs 收敛更快,并且能在更小的网络规模下达到同样的生成效果。

■ 论文 | f-VAEs: Improve VAEs with Conditional Flows

■ 链接 | https://www.paperweekly.site/papers/2313

■ 作者 | Jianlin Su / Guang Wu

近来,生成模型得到了广泛关注,其中变分自编码器(VAEs)和流模型是不同于生成对抗网络(GANs)的两种生成模型,它们亦得到了广泛研究。然而它们各有自身的优势和缺点,本文试图将它们结合起来。

▲ 由f-VAEs实现的两个真实样本之间的线性插值

基础

设给定数据集的证据分布为生成模型的基本思路是希望用如下的分布形式来拟合给定数据集分布:

其中 q(z) 一般取标准高斯分布,而 q(x|z) 一般取高斯分布(VAEs 中)或者狄拉克分布(GANs 和流模型中)。理想情况下,优化方式是最大化似然函数 E[logq(x)],或者等价地,最小化

由于积分可能难以显式计算,所以需要一些特殊的求解技巧,这导致了不同的生成模型。其中,VAE 引入后验分布 p(z|x),将优化目标改为更容易计算的上界。众所周知,VAE 有着收敛快、训练稳定等优点,但一般情况下生成图像存在模糊等问题,其原因我们在后面会稍加探讨。

而在流模型中,q(x|z)=δ(x−G(z)),并精心设计 G(z)(通过流的组合)直接把这个积分算出来。流模型的主要组件是“耦合层”:首先将 x 分区为两部分 x1,x2,然后进行如下运算:

这个变换是可逆的,逆变换为: 

它的雅可比行列式是。这种变换我们通常称之为“仿射耦合”(如果 s(x1)≡1,那么通常称为“加性耦合”),用 f 表示。通过很多耦合层的组合,我们可以得到复杂的非线性变换,即 G=f1∘f2∘⋯∘fn,这就是所谓的“(无条件)流”。

由于直接算出来积分,因此流模型可以直接完成最大似然优化。最近发布的 Glow 模型显示出强大的生成效果,引起了许多人的讨论和关注。但是流模型通常相当庞大,训练时间长(其中 256 x 256 的图像生成模型用 40 个 GPU 训练了一周,参考这里 [1] 和这里 [2]),显然还不够友好。

分析

VAEs 生成图像模糊的解释有很多,有人认为是 mse 误差的问题,也有人认为是 KL 散度的固有性质。但留意到一点是:即使去掉隐变量的 KL 散度那一项,变成普通的自编码器,重构出来的图像通常也是模糊的。这表明,VAEs 图像模糊可能是低维重构原始图像的固有问题。

如果将隐变量维度取输入维度一样大小呢?似乎还不够,因为标准的 VAE 将后验分布也假设为高斯分布,这限制了模型的表达能力,因为高斯分布簇只是众多可能的后验分布中极小的一部分,如果后验分布的性质与高斯分布差很远,那么拟合效果就会很糟糕。

那 Glow 之类的流模型的问题是什么呢?流模型通过设计一个可逆的(强非线性的)变换将输入分布转化为高斯分布。在这个过程中,不仅仅要保证变换的可逆性,还需要保证其雅可比行列式容易计算,这导致了“加性耦合层”或“仿射耦合层”的设计。然而这些耦合层只能带来非常弱的非线性能力,所以需要足够多的耦合层才能累积为强非线性变换,因此 Glow 模型通常比较庞大,训练时间较长。

f-VAEs

我们的解决思路是将流模型引入到 VAEs 中,用流模型来拟合更一般的后验分布 p(z|x) ,而不是简单地设为高斯分布,我们称之为 f-VAEs(Flow-based Variational Autoencoders,基于流的变分自编码器

相比于标准的 VAEs,f-VAEs 跳出了关于后验分布为高斯分布的局限,最终导致 VAEs 也能生成清晰的图像;相比于原始的流模型(如 Glow),f-VAEs 的编码器给模型带来了更强的非线性能力,从而可以减少对耦合层的依赖,从而实现更小的模型规模来达到同样的生成效果。 

推导过程

我们从 VAEs 的原始目标出发,VAEs 的 loss 可以写为:

其中 p(z|x),q(x|z) 都是带参数的分布,跟标准 VAEs 不同的是,p(z|x) 不再假设为高斯分布,而是通过流模型构建:

这里 q(u) 是标准高斯分布,Fx(u) 是关于 x,u 的二元函数,但关于 u 是可逆的,可以理解为 Fx(u) 是关于 u 的流模型,但它的参数可能跟 x 有关,这里我们称为“条件流”。代入 (4) 计算得到:

这便是一般的 f-VAEs 的 loss,具体推导过程请参考下面的注释。

联立 (4) 和 (5),我们有:

设 v=Fx(u′),u′=Hx(v),对于雅可比行列式,我们有关系:

从而 (7) 变成:

两个特例

式 (6) 描述了一般化的框架,而不同的 Fx(u) 对应于不同的生成模型。如果我们设:

那么就有:

以及:

这两项组合起来,正好是后验分布和先验分布的 KL 散度;代入到 (6) 中正好是标准 VAE 的 loss。意外的是,这个结果自动包含了重参数的过程。

另一个可以考察的简单例子是:

其中 σ 是一个小的常数,而F是任意的流模型,但参数与 x 无关(无条件流)。这样一来:

所以它并没有包含训练参数。这样一来,整个 loss 包含训练参数的部分只有:

这等价于普通的流模型,其输入加上了方差为的高斯噪声。有趣的是,标准的 Glow 模型确实都会在训练的时候给输入图像加入一定量的噪声。

我们的模型

上面两个特例表明,式 (6) 原则上包含了 VAEs 和流模型。 Fx(u) 实际上描述了 u, x 的不同的混合方式,原则上我们可以选择任意复杂的 Fx(u) ,来提升后验分布的表达能力,比如:

这里的 F1,F2 是无条件流。

同时,到目前为止,我们并没有明确约束隐变量 z 的维度大小(也就是 u 的维度大小),事实上它是一个可以随意选择的超参数,由此我们可以训练更好的降维变分自编码模型。但就图像生成这个任务而言,考虑到低维重构会导致模糊的固有问题,因此我们这里选择 z 的大小跟 x 的大小一致。

出于实用主义和简洁主义,我们把式 (13) 和 (10) 结合起来,选择:

其中 σ1,σ2 都是待训练参数(标量即可),E(⋅),G(⋅) 是待训练的编码器和解码器(生成器),而F (⋅) 是参数与 x 无关的流模型。代入 (6),等效的 loss 为:

而生成采样过程为:

相关

事实上,流模型是一大类模型的总称。除了上述以耦合层为基础的流模型(NICE、RealNVP、Glow)之外,我们还有“自回归流(autoregressive flows)”,代表作有 PixelRNNs 和 PixelCNNs 等。自回归流通常效果也不错,但是它们是逐像素地生成图片,无法并行,所以生成速度比较慢。 

诸如 RealNVP、Glow 的流模型我们通常称为 Normalizing flows(常规流),则算是另外一种流模型。尤其是 Glow 出来后让这类流模型再次火了一把。事实上,Glow 生成图片的速度还是挺快的,就是训练周期太长了,训练成本也很大。 

据我们了解,首次尝试整合 VAEs 和模型的是 Variational Inference with Normalizing Flows [3],后面还有两个改进工作 Improving Variational Inference with Inverse Autoregressive Flow [4] 和 Variational Lossy Autoencoder [5]。其实这类工作(包括本文)都是类似的。不过前面的工作都没有导出类似 (6) 式的一般框架,而且它们都没有在图片生成上实现较大的突破。 

目测我们的工作是首次将 RealNVP 和 Glow 的流模型引入到 VAEs 中的结果。这些“流”基于耦合层,容易并行计算。所以它们通常比自回归流要高效率,可以堆叠得很深。同时我们还保证隐变量维度跟输入维度一样,这个不降维的选择也能避免图像模糊问题。

实验

受 GPU 设备所限,我们仅仅在 CelebA HQ 上做了 64x64 和 128x128 的实验。我们先在 64x64 图像上对类似规模的 VAEs、Glow 和 f-VAEs 做了个对比,然后再详细展示了 128x128 的生成效果。

实验流程

首先,我们的编码器 E(⋅) 是卷积和 Squeeze 算子的堆叠。具体来说, E(⋅) 由几个 block 组成,并且在每个 block 之前都进行一次 Squeeze。而每个 block 由若干步复合而成,每步的形式为 x+CNN(x) ,其中 CNN(x) 是 3x3 和 1x1 的卷积组成。具体细节可以参考代码。 

至于解码器(生成器)G (⋅) 则是卷积和 UnSqueeze 算子的堆叠,结构上就是 E(⋅) 的逆。解码器的最后可以加上 tanh(⋅) 激活函数,但这也不是必须的。而无条件流 F(⋅) 的结果是照搬自 Glow 模型,只不过没有那么深,卷积核的数目也没有那么多。

源码(基于Keras 2.2 + Tensorflow 1.8 + Python 2.7): 

https://github.com/bojone/flow/blob/master/f-VAEs.py

实验结果

对比 VAEs 和 f-VAEs 的结果,我们可以认为 f-VAEs 已经基本解决了 VAEs 的模糊问题。对于同样规模下的 Glow 和 f-VAEs,我们发现 f-VAEs 在同样的 epoch 下表现得更好。当然,我们不怀疑 Glow 在更深的时候也表现得很好甚至更好,但很明显,在同样的复杂度和同样的训练时间下,f-VAEs 有着更好的表现。

f-VAEs 在 64x64 上面的结果,只需要用 GTX1060 训练约 120-150 个 epoch,大概需要 7-8 小时。

准确来说,f-VAEs 的完整的编码器应该是 F(E(⋅)),即 F 和 E 的复合函数。如果在标准的流模型中,我们需要计算 E 的雅可比行列式,但是在 f-VAEs 中则不需要。所以 E 可以是一个普通的卷积网络,它可以实现大部分的非线性,从而简化对流模型 F 的依赖。

下面是 128x128 的结果(退火参数 T 指的是先验分布的方差)。128x128 的模型大概在 GTX1060 上训练了 1.5 天(约 150 个 epoch)。

随机采样结果

隐变量线性插值

▲ 两个真实样本之间的线性插值

退火参数影响

总结

文章综述

事实上,我们这个工作的原始目标是解决针对 Glow 提出的两个问题: 

  • 如何降低 Glow 的计算量?

  • 如何得到一个“降维”版本的 Glow? 

我们的结果表明,一个不降维的 f-VAEs 基本相当于一个迷你版本的 Glow,但是能达到较好的效果。而式 (6) 确实也允许我们训练一个降维版本的流模型。我们也从理论上证明了普通的 VAEs 和流模型自然地包含在我们的框架中。因此,我们的原始目标已经基本完成,得到了一个更一般的生成和推断框架。 

未来工作

当然,我们可以看到随机生成的图片依然有一种油画的感觉。可能的原因是模型还不够复杂,但我们猜测还有一个重要原因是 3x3 卷积的“滥用”,导致了感知野的无限放大,使得模型无法聚焦细节。 

因此,一个挑战性的任务是如何设计更好的、更合理的编码器和解码器。看起来Network in Network 那一套会有一定的价值,还有 PGGAN 的结构也值得一试,但是这些都还没有验证过。

PaperWeekly
PaperWeekly

推荐、解读、讨论和报道人工智能前沿论文成果的学术平台。

理论f-VAEs
4
相关数据
自动编码器技术

自动编码器是用于无监督学习高效编码的人工神经网络。 自动编码器的目的是学习一组数据的表示(编码),通常用于降维。 最近,自动编码器已经越来越广泛地用于生成模型的训练。

激活函数技术

在 计算网络中, 一个节点的激活函数定义了该节点在给定的输入或输入的集合下的输出。标准的计算机芯片电路可以看作是根据输入得到"开"(1)或"关"(0)输出的数字网络激活函数。这与神经网络中的线性感知机的行为类似。 一种函数(例如 ReLU 或 S 型函数),用于对上一层的所有输入求加权和,然后生成一个输出值(通常为非线性值),并将其传递给下一层。

感知技术

知觉或感知是外界刺激作用于感官时,脑对外界的整体的看法和理解,为我们对外界的感官信息进行组织和解释。在认知科学中,也可看作一组程序,包括获取信息、理解信息、筛选信息、组织信息。与感觉不同,知觉反映的是由对象的各样属性及关系构成的整体。

高斯分布技术

正态分布是一个非常常见的连续概率分布。由于中心极限定理(Central Limit Theorem)的广泛应用,正态分布在统计学上非常重要。中心极限定理表明,由一组独立同分布,并且具有有限的数学期望和方差的随机变量X1,X2,X3,...Xn构成的平均随机变量Y近似的服从正态分布当n趋近于无穷。另外众多物理计量是由许多独立随机过程的和构成,因而往往也具有正态分布。

重构技术

代码重构(英语:Code refactoring)指对软件代码做任何更动以增加可读性或者简化结构而不影响输出结果。 软件重构需要借助工具完成,重构工具能够修改代码同时修改所有引用该代码的地方。在极限编程的方法学中,重构需要单元测试来支持。

变分自编码器技术

变分自编码器可用于对先验数据分布进行建模。从名字上就可以看出,它包括两部分:编码器和解码器。编码器将数据分布的高级特征映射到数据的低级表征,低级表征叫作本征向量(latent vector)。解码器吸收数据的低级表征,然后输出同样数据的高级表征。变分编码器是自动编码器的升级版本,其结构跟自动编码器是类似的,也由编码器和解码器构成。在自动编码器中,需要输入一张图片,然后将一张图片编码之后得到一个隐含向量,这比原始方法的随机取一个随机噪声更好,因为这包含着原图片的信息,然后隐含向量解码得到与原图片对应的照片。但是这样其实并不能任意生成图片,因为没有办法自己去构造隐藏向量,所以它需要通过一张图片输入编码才知道得到的隐含向量是什么,这时就可以通过变分自动编码器来解决这个问题。解决办法就是在编码过程给它增加一些限制,迫使其生成的隐含向量能够粗略的遵循一个标准正态分布,这就是其与一般的自动编码器最大的不同。这样生成一张新图片就比较容易,只需要给它一个标准正态分布的随机隐含向量,这样通过解码器就能够生成想要的图片,而不需要给它一张原始图片先编码。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

降维技术

降维算法是将 p+1 个系数的问题简化为 M+1 个系数的问题,其中 M<p。算法执行包括计算变量的 M 个不同线性组合或投射(projection)。然后这 M 个投射作为预测器通过最小二乘法拟合一个线性回归模型。两个主要的方法是主成分回归(principal component regression)和偏最小二乘法(partial least squares)。

似然函数技术

在数理统计学中,似然函数是一种关于统计模型中的参数的函数,表示模型参数中的似然性。 似然函数在统计推断中有重大作用,如在最大似然估计和费雪信息之中的应用等等。“ 似然性”与“或然性”或“概率”意思相近,都是指某种事件发生的可能性,但是在统计学中,“似然性”和“或然性”或“概率”又有明确的区分。

生成模型技术

在概率统计理论中, 生成模型是指能够随机生成观测数据的模型,尤其是在给定某些隐含参数的条件下。 它给观测值和标注数据序列指定一个联合概率分布。 在机器学习中,生成模型可以用来直接对数据建模(例如根据某个变量的概率密度函数进行数据采样),也可以用来建立变量间的条件概率分布。

生成对抗网络技术

生成对抗网络是一种无监督学习方法,是一种通过用对抗网络来训练生成模型的架构。它由两个网络组成:用来拟合数据分布的生成网络G,和用来判断输入是否“真实”的判别网络D。在训练过程中,生成网络-G通过接受一个随机的噪声来尽量模仿训练集中的真实图片去“欺骗”D,而D则尽可能的分辨真实数据和生成网络的输出,从而形成两个网络的博弈过程。理想的情况下,博弈的结果会得到一个可以“以假乱真”的生成模型。

堆叠技术

堆叠泛化是一种用于最小化一个或多个泛化器的泛化误差率的方法。它通过推导泛化器相对于所提供的学习集的偏差来发挥其作用。这个推导的过程包括:在第二层中将第一层的原始泛化器对部分学习集的猜测进行泛化,以及尝试对学习集的剩余部分进行猜测,并且输出正确的结果。当与多个泛化器一起使用时,堆叠泛化可以被看作是一个交叉验证的复杂版本,利用比交叉验证更为复杂的策略来组合各个泛化器。当与单个泛化器一起使用时,堆叠泛化是一种用于估计(然后纠正)泛化器的错误的方法,该泛化器已经在特定学习集上进行了训练并被询问了特定问题。

推荐文章
暂无评论
暂无评论~