一、简述
Flow模型是生成模型,目标是找到输入样本的分布。Flow模型选择直接直面生成模型的概率计算。
流模型有一个非常与众不同的特点是,它的转换通常是可逆的。也就是说,流模型不仅能找到从A分布变化到B分布的网络通路,并且该通路也能让B变化到A,简言之流模型找到的是一条A、B分布间的双工通路。当然,这样的可逆性是具有代价的——A、B的数据维度必须是一致的。
A、B分布间的转换并不是轻易能做到的,流模型为实现这一点经历了三个步骤:最初的NICE实现了从A分布到高斯分布的可逆求解;后来RealNVP实现了从A分布到条件非高斯分布的可逆求解;而最新的GLOW,实现了从A分布到B分布的可逆求解,其中B分布可以是与A分布同样复杂的分布。
二、建模思想
给定两组数据z和x,其中z服从已知的简单先验分布π(z)(通常是高斯分布),x服从复杂的分布p(x)(即训练数据代表的分布),现在我们想要找到一个变换函数f,它能建立一种z到x的映射f。
如果这个变换函数能找到的话,那么我们就实现了一个生成模型的构造。因为现在如果我们想要有新的生成,只需要从π(z)中随机采样一个点,然后通过映射f,就可以得到新的样本点x。
三、数学基础
3.1
假设x、z满足简单的均匀分布,那么构建z与x之间的变换关系只需要构造一个线性函数即可:x=f(z)=2z+1。
3.2 下面再考虑非均匀分布的更复杂的情况:
我们可以考虑在很短的间隔上将二者视为简单均匀分布,然后应用前边方法计算小段上的,最后将每个小段变换累加起来(每个小段实际对应一个采样样本)就得到最终的完整变换式f。
(相同的面积可以确保它们处理了对应信息量的任务)
又考虑到dz/dx有可能是负值(如下图所示),而p(x’)Π(z’)都为非负,所以p(x’)、Π(z’)的实际关系为p(x’)=Π(z’)|dz/dx|。
3.3
3.4 (注意:这个地方将上文中的f换成G,其实只是一个符号,本质是一样的)
G*是我们要求的。
四、如何求解3.4中的G*
4.1 要求解G*,就是要计算
有着一些困难
① 不好计算,因为的 Jacobian矩阵一般维度不低(譬如256*256矩阵),其行列式的计算量是异常巨大的,所以在实际计算中,我们必须对的Jacobian行列式做一定优化,使其能够在计算上变得简洁高效。
②需要巧妙地设计G的结构使得也是好计算的
4.2 逐步设计的结构
要求:G的输入和输出的维度必须是一致的并且G的行列式不能为0。
从上面的表达式中我们可以看出其只和有关,所以在实际训练中我们可以训练对应的网络,然后想办法算出G来并且在真实运行的时候改用G做图像生成。
4.2.1
这样设计的耦合层能快速计算出,其在G的Jacobian行列式的计算上也是非常简便。注:就是在学习β、γ。
4.2.2
上述措施对G做了诸多限制,导致G的变换能力有限,所以我们可以堆叠多个G,去增强模型的变换拟合能力。
多个耦合层堆叠在一起,从而形成一个更完整的生成器。但是这样会有一个新问题,就是最终生成数据的前d维与初始数据的前d维是一致的,这会导致生成数据中总有一片区域看起来像是固定的图样(实际上它代表着来自初始高斯噪音的一个部分)
4.2.3
我们可以通过将复制模块(copy)与仿射模块(affine)交换顺序的方式去解决4.2.2一问题。
如上图所示,通过将某些耦合层的copy与affine模块进行位置上的互换,使得每一部分数据都能走向copy->affine->copy->affine的交替变换通道,这样最终的生成图像就不会包含完全copy自初始图像的部分。值得说明的是,在图像生成当中,这种copy与affine模块互换的方式有很多种。
4.2.4
W矩阵,帮我们决定按什么样的顺序做copy和affine变换,这种方法叫做1×1 convolution。1×1 convolution只需要让机器决定在每次仿射计算前对图片哪些区域实行像素对调,而保持copy和affine模块的顺序不变,这实际上和对调copy和affine模块顺序产生的效果是一致的。其中W矩阵是可以由机器来学习的。引入1×1 convolution后的G的Jacobian行列式计算依然非常简单。