0%

读论文:Glow:generative flow with invertible 1x1 convolutions

论文背景

这里,作者照例总结了几个生成模型:

  • 自回归模型(Autoregressive models):简易,但并行化不够
  • 变分编码器(VAEs):对数据的对数似然的下界进行优化,相较于变分编码器,有并行化的优势,但优化起来比较困难
  • 基于流的生成模型(Flow-based generative models):在NICE中首次描述,在Real NVP中进行了扩展

基于流的生成模型有如下的优点:

  • 精确隐变量推理和对数似然评价
    • 在VAEs中,只能推断出数据点对应的隐变量的估计值。在可逆生成模型中,这可以在没有近似的情况下精确地实现。这不仅可以导致准确的推断,还可以优化数据的精确对数似然值,而不是数据的下界
  • 高效的推理与训练
    • 在自回归模型,如Pixel-CNN中,难以并行化。而基于流的生成模型解决了这个问题
  • 隐空间对下游任务有用
    • 在自回归模型中,隐层的边缘分布是未知的,这使得执行有效的数据操作更加困难。在GANs中,数据点通常不能直接表示在潜在空间中,因为GAN没有Encoder。
  • 内存节省
    • 正如RevNet论文(Gomez et al.,2017)中所解释的,可逆神经网络中计算梯度需要的记忆量是恒定的,而不是线性的。

问题定义

\(\mathbf x\)是一个高维向量,分布\(\mathbf{x} \sim p^{*}(\mathbf{x})\)是未知的。我们收集了一个独立同分布的数据集\(\mathcal{D}\),要选择一个模型\(p_{\boldsymbol \theta}(\mathbf x)\)的参数\(\theta\)。对于离散的数据\(\mathbf x\),以对数似然形式构建的目标函数为: \[ \mathcal{L}(\mathcal{D})=\frac{1}{N} \sum_{i=1}^{N}-\log p_{\boldsymbol{\theta}}\left(\mathbf{x}^{(i)}\right) \] 上述目标函数使用小批量数据的随机梯度下降进行优化。

而生成过程被描述为: \[ \begin{array}{l} \mathbf{z} \sim p_{\boldsymbol{\theta}}(\mathbf{z}) \\ \mathbf{x}=\mathbf{g}_{\boldsymbol{\theta}}(\mathbf{z}) \end{array} \] \(\mathbf z\)是一个隐变量,有着一个易于处理的简单分布\(p_{\boldsymbol{\theta}}(\mathbf{z})\),比如多变量高斯分布\(p_{\boldsymbol{\theta}}(\mathbf{z})=\mathcal{N}(\mathbf{z} ; 0, \mathbf{I})\)。而\(\mathbf g(\cdot)\)是可逆的:\(\mathbf{z}=\mathbf{f}_{\boldsymbol{\theta}}(\mathbf{x})=\mathbf{g}_{\boldsymbol \theta}^{-1}(\mathbf{x})\)

而作者这次关注的主要问题是,当\(\mathbf f\)由一个变换序列组合而成:\(\mathbf{f}=\mathbf{f}_{1} \circ \mathbf{f}_{2} \circ \cdots \circ \mathbf{f}_{K}\),那么\(\mathbf x\)\(\mathbf z\)之间的关系表示为: \[ \mathbf{x} \stackrel{\mathbf{f}_{1}}{\longleftrightarrow} \mathbf{h}_{1} \stackrel{\mathbf{f}_{2}}{\longleftrightarrow} \mathbf{h}_{2} \cdots \stackrel{\mathbf{f}_{K}}{\longleftrightarrow} \mathbf{z} \] 根据变量代换公式,原本的密度可以表示为: \[ \begin{aligned} \log p_{\boldsymbol{\theta}}(\mathbf{x}) &=\log p_{\boldsymbol{\theta}}(\mathbf{z})+\log |\operatorname{det}(d \mathbf{z} / d \mathbf{x})| \\ &=\log p_{\boldsymbol{\theta}}(\mathbf{z})+\sum_{i=1}^{K} \log \left|\operatorname{det}\left(d \mathbf{h}_{i} / d \mathbf{h}_{i-1}\right)\right| \end{aligned} \]

为了方便,我们设置\(\mathbf{h}_{0} \triangleq \mathbf{x} , \mathbf{h}_{K} \triangleq \mathbf{z}\)。虽然这个雅克比行列式看起来很吓人,但是它的值对于某些变换的选择计算起来却出奇的简单。其基本思想是选择其雅可比矩阵为三角矩阵的变换,这样一来其对数雅克比就很简单: \[ \log \left|\operatorname{det}\left(d \mathbf{h}_{i} / d \mathbf{h}_{i-1}\right)\right|=\operatorname{sum}\left(\log \left|\operatorname{diag}\left(d \mathbf{h}_{i} / d \mathbf{h}_{i-1}\right)\right|\right) \]

主要方法

可逆1x1卷积

如题目所述,这篇文章的主要重点为1x1可逆卷积。

置换矩阵

对向量的置换操作,可以用矩阵乘法来描述,比如原来向量是 [1,2,3,4],分别交换第一、二和第三、四两个数,得到 [2,1,4,3],这个操作可以用矩阵乘法来描述:

img

其中右端第一项是“由单位矩阵不断交换两行或两列最终得到的矩阵”称为置换矩阵。

一般化置换

既然这样,那很自然的想法就是:为什么不将置换矩阵换成一般的可训练的参数矩阵呢?所谓 1x1 可逆卷积,就是这个想法的结果。

一开始提出 flow 模型的思路时就已经明确指出,flow 模型中的变换要满足两个条件:一是可逆,二是雅可比行列式容易计算。如果直接写出变换: \[ h=xW \] 那么它就只是一个普通的没有 bias 的全连接层,并不能保证满足这两个条件。为此,要做一些准备工作。首先,让 h 和 x 的维度一样,也就是说 W 是一个方阵,这是最基本的设置;其次,由于这只是一个线性变换,因此它的雅可比矩阵就是\(\left[\frac{\partial h}{\partial x}\right]=W\),所以它的行列式就是 det W,因此需要把 −log |det W| 这一项加入到 loss 中;最后,初始化时为了保证 W 的可逆性,一般使用“随机正交矩阵”初始化。

利用LU分解

由于算矩阵的行列式运算量特别大,还容易溢出。而 Glow 给出了一个非常巧妙的解决方案:LU 分解的逆运用。具体来说,是因为任意矩阵都可以分解为: \[ W = PLU \] 其中 P 是一个置换矩阵,也就是前面说的 shuffle 的等价矩阵;L 是一个下三角阵,对角线元素全为 1;U 是一个上三角阵。这种形式的分解称为 LU 分解。如果知道这种矩阵的表达形式,显然求雅可比行列式是很容易的,它等于: \[ \log |\operatorname{det} \boldsymbol{W}|=\sum \log |\operatorname{diag}(\boldsymbol{U})| \]

本文中给出的技巧:先随机生成一个正交矩阵,然后做 LU 分解,得到 P,L,U,固定 P,也固定 U 的对角线的正负号,然后约束 L 为对角线全 1 的下三角阵,U 为上三角阵,优化训练 L,U 的其余参数。

Actnorm

RealNVP 中用到了 BN 层,而 Glow 中提出了名为 Actnorm 的层来取代 BN。不过,所谓 Actnorm 层事实上只不过是 NICE 中的尺度变换层的一般化,也就是 (5) 式提到的缩放平移变换: \[ \hat{z}=\frac{z-\boldsymbol{\mu}}{\boldsymbol{\sigma}} \] 其中 μ,σ 都是训练参数。Glow 在论文中提出的创新点是用初始的 batch 的均值和方差去初始化 μ,σ 这两个参数。

相比于加性耦合层,仿射耦合层多了一个尺度变换层,从而计算量翻了一倍。但事实上相比加性耦合,仿射耦合效果的提升并不高(尤其是加入了 Actnorm 后),所以要训练大型的模型,为了节省资源,一般都只用加性耦合,比如 Glow 训练 256x256 的高清人脸生成模型,就只用到了加性耦合。

实验结果

使用Glow训练人脸:

image-20201107161822636

总结与思考

整体来看,Glow 模型在 RealNVP 的基础上引入了 1x1 可逆卷积来代替前面说的打乱通道轴的操作,并且对 RealNVP 的原始模型做了简化和规范,使得它更易于理解和使用。