CNF
Continuous Normalizing Flow(连续归一化流)
CNF 是一种用连续时间动力系统构造生成模型的方法。
它做的事情可以概括为:从一个简单分布中采样一个点,让这个点沿着一个可学习的速度场移动,最后得到数据空间里的样本。移动过程中,模型同时记录概率密度怎样变化,因此既可以采样,也可以计算似然。
从 Normalizing Flow 开始
Normalizing Flow 的目标是学习一个可逆变换,把简单分布变成复杂数据分布。
先从简单分布采样:
再通过一个可逆映射生成数据:
因为
根据变量替换公式,数据密度可以写成:
这条公式说明,生成模型不只要知道
离散的 Normalizing Flow 通常由很多层可逆网络组成。每一层都要满足两个要求:映射可逆,Jacobian 行列式容易算。这个要求会限制网络结构。
CNF 采用连续时间写法,把变换表示为一个 ODE。
用 ODE 定义一个 flow
CNF 用下面的 ODE 描述样本的位置变化:
这里:
是时刻 的样本位置; 是速度场,由神经网络参数化; 来自简单分布; 是最终生成的样本。
从初始点
这个由 ODE 诱导出来的映射就是 flow map:
在常见的光滑条件下,ODE 轨迹可以反向求解。所以如果知道
密度也会随 flow 改变
点在移动时,整团概率质量也在移动。概率密度
它表达的是概率质量守恒。某个区域里概率质量减少,说明概率从边界流出;概率质量增加,说明概率从边界流入。
沿着某一条轨迹
右边的散度是:
这条式子叫瞬时变量替换公式。
它的含义很直接:
当速度场在某处把空间往外撑开,体积变大,密度会下降;当速度场把空间往内压缩,体积变小,密度会上升。
瞬时变量替换公式怎么来
从连续性方程开始:
把散度展开:
所以:
两边除以
沿着轨迹
又因为:
代入后,前面的两项会抵消,只剩:
这就是 CNF 做密度计算时使用的公式。
如何计算一个样本的似然
假设数据样本是
沿轨迹积分上面的密度变化公式:
这就是 CNF 的似然计算公式。
它包含两部分:
:反向积分得到的起点在简单分布下有多可能; :流动过程中密度的变化量。
训练时通常最大化数据的对数似然,或者等价地最小化负对数似然:
采样怎么做
采样比似然计算更直接。
先从简单分布采样:
然后解 ODE:
从
这个
因此,CNF 的采样过程就是:先采一个简单噪声,再沿着学到的速度场移动到数据空间。
一个一维例子
看一个简单的一维 ODE:
它的解是:
如果
一维情况下,散度就是导数:
所以密度变化是:
积分后得到:
这和直觉一致。
散度计算为什么麻烦
CNF 的似然公式需要计算散度:
如果
FFJORD 使用 Hutchinson 估计器来近似 trace:
其中
这个技巧让 CNF 可以扩展到更高维的问题。
和离散 Normalizing Flow 的差别
离散 Normalizing Flow 通常写成多层可逆变换:
每一层都要计算 Jacobian 行列式。为了让这个行列式便宜,模型结构常常要专门设计。
CNF 写成连续时间形式:
它用散度积分代替一层层的 log-determinant:
这样可以使用更自由的神经网络来参数化速度场。代价是每次训练和采样都要调用 ODE 求解器。
CNF 的优点
CNF 的优势主要来自连续时间建模。
它给出了一个可逆的生成过程,可以从简单分布生成样本,也可以反向计算似然。密度变化由散度积分控制,不需要为每一层专门设计容易求行列式的结构。ODE 求解器还可以根据误差容忍度调整步长,在精度和计算量之间做权衡。
CNF 的限制
CNF 的训练和采样通常比普通前向网络更慢,因为每次都需要数值求解 ODE。
似然计算还需要散度项。高维情况下,即使用 Hutchinson 估计器,也会增加额外计算和方差。
另外,ODE 轨迹在常见条件下不会相交,映射保持可逆。这给似然计算带来好处,也会限制某些变换形式。实际表现取决于速度场设计、ODE 求解器设置和训练稳定性。
总结
CNF 用一个 ODE 定义从简单分布到数据分布的连续变换:
样本沿速度场移动,密度沿轨迹按散度变化:
最终得到似然公式:
因此,CNF 可以同时用于采样和似然估计。它把生成建模问题写成连续时间流动问题:样本的位置由 ODE 控制,样本密度由散度控制。