Normalizing Flow(归一化流)Normalizing Flows
把一个简单的高斯分布,经过一串可逆、可微的变形,捏成你想要的任何形状:这就是 normalizing flow。因为每一步都可逆,它既能一次前向就采样,也能精确算出任意一点的概率密度,代价只是每一层雅可比行列式的对数。本节从 1.5 节的行列式和 3.3 节的雅可比出发,推出换元公式,搭起 RealNVP 的耦合层并在浏览器里现场训练,再看连续时间的流(通向 19.7 节的 flow matching),最后用一个条件 flow 给冗余机械臂一次采样出许多组逆运动学解。 Take a simple Gaussian and push it through a chain of invertible, differentiable deformations until it has any shape you like: that is a normalizing flow. Because every step can be undone, a flow can draw a sample in one forward pass and also compute the exact probability density of any point, at the price of the log of each layer's Jacobian determinant. This lesson starts from the determinant of Lesson 1.5 and the Jacobian of Lesson 3.3, derives the change-of-variables formula, builds RealNVP coupling layers and trains them live in your browser, looks at continuous-time flows (the road to flow matching in Lesson 19.7), and ends with a conditional flow that samples many inverse-kinematics solutions for a redundant arm at once.
1为什么机器人需要它Why robots need this
机器人经常需要的不是“一个答案”,而是“答案的分布”。一个 7 自由度机械臂够到同一个杯子有无数种姿态;同一张桌面能有很多个好的抓取位姿;示教数据里,同一个场景下人有时从左绕、有时从右绕。我们想要一个模型,能做两件事:采样(给我 50 个不同的可行姿态),以及打分(这个姿态在数据里有多常见,\(p_\theta(\mathbf x)\) 是多少)。打分还能用来做异常检测:读数的似然低得离谱,说明遇到了没见过的情况。
前两节的生成模型各缺一半。19.1 节的 VAE 能采样,但只给出似然的一个下界(ELBO);19.2 节的 GAN 采样质量好,却完全没有密度可算。Normalizing flow 的做法很直接:拿一个能精确算密度的分布(标准高斯 \(p_Z\)),再用一个可逆的神经网络 \(f\) 把它变形成数据的样子。采样就是 \(\mathbf x=f(\mathbf z)\);打分就是把 \(\mathbf x\) 倒推回 \(\mathbf z=f^{-1}(\mathbf x)\),读出那里的高斯密度,再按 \(f\) 把体积放大了多少倍做修正。这个“修正”就是 1.5 节说过的那句话:变换之后,密度要除以 \(|\det|\)。
本节的关键问题是工程上的:一般的神经网络既不可逆,雅可比行列式也要 \(O(D^3)\) 才能算。RealNVP 的耦合层用一个巧妙的结构同时解决了两个问题,于是可以直接用最大似然(4.6 节)训练。在机器人里,这让 flow 成了逆运动学采样器、策略分布和位姿不确定性模型的一个选项;它的连续时间版本则直接引出了今天机器人策略里常用的 flow matching(19.7 节)。
Often a robot does not need "an answer" but "the distribution of answers". A 7-DoF arm can reach the same cup in infinitely many postures; one tabletop admits many good grasp poses; in demonstration data a person sometimes walks around an obstacle on the left and sometimes on the right. We want a model that does two things: sample (give me 50 different feasible postures) and score (how common is this posture in the data, what is \(p_\theta(\mathbf x)\)). Scoring also gives anomaly detection: an absurdly low likelihood means the robot is seeing something new.
The previous two lessons' generative models each miss one half. The VAE of Lesson 19.1 samples, but only gives a lower bound on the likelihood (the ELBO); the GAN of Lesson 19.2 produces good samples but has no density at all. A normalizing flow takes the direct route: start from a distribution whose density is known exactly (the standard Gaussian \(p_Z\)) and deform it into the shape of the data with an invertible neural network \(f\). Sampling is \(\mathbf x=f(\mathbf z)\); scoring runs \(\mathbf x\) backwards to \(\mathbf z=f^{-1}(\mathbf x)\), reads the Gaussian density there, and corrects for how much \(f\) magnified volume. That correction is the sentence from Lesson 1.5: after a transformation, the density must be divided by \(|\det|\).
The key problem of this lesson is an engineering one: a generic neural network is not invertible, and its Jacobian determinant costs \(O(D^3)\). The coupling layer of RealNVP solves both at once with a clever structure, so the model can be trained directly by maximum likelihood (Lesson 4.6). In robotics this makes flows an option for inverse-kinematics samplers, policy distributions and pose-uncertainty models, and their continuous-time version leads straight to flow matching (Lesson 19.7), which today's robot policies use widely.
2直觉:概率像橡皮泥,捏哪里哪里就变稀Intuition: probability is putty; stretch it and it thins
先看一维。\(z\) 服从标准正态,再取一个单调递增的函数 \(x=f(z)\)。把 \(z\) 轴想成一条橡皮筋,上面均匀撒着“概率沙子”,\(f\) 把橡皮筋的各段拉长或压短。沙子总量不变:落在 \([z,z+dz]\) 里的沙子,变换后全部落在 \([f(z),f(z)+f'(z)\,dz]\) 里。所以那一段被拉长 \(f'(z)\) 倍,沙子的密度就变为原来的 \(1/f'(z)\):
Start in one dimension. Let \(z\) be standard normal and take a monotonically increasing function \(x=f(z)\). Think of the \(z\) axis as a rubber band sprinkled with "probability sand"; \(f\) stretches some pieces of the band and squeezes others. The amount of sand does not change: the sand in \([z,z+dz]\) all lands in \([f(z),f(z)+f'(z)\,dz]\) after the map. So if a piece is stretched by a factor \(f'(z)\), the density of the sand there becomes \(1/f'(z)\) of what it was:
下图的 \(f\) 是一条折线,经过 7 个节点 \(z=-3,-2,\dots,3\)。你可以拖动每个节点在下方 \(x\) 轴上的落点(保持单调)。每一段的斜率就是 \(f'\):段被拉长(斜率 > 1)的地方密度变低,被压扁(斜率 < 1)的地方密度变高。4.9 节的逆 CDF 采样其实就是一个一维 flow:它把均匀分布捏成目标分布,用的正是这个公式。
In the figure below \(f\) is a broken line through 7 knots at \(z=-3,-2,\dots,3\). Drag where each knot lands on the lower \(x\) axis (order is kept). The slope of each piece is \(f'\): where a piece is stretched (slope > 1) the density drops, where it is squeezed (slope < 1) the density rises. The inverse-CDF sampling of Lesson 4.9 is in fact a 1-D flow: it moulds the uniform distribution into the target with exactly this formula.
- 拖动节点,把 \(|z|\le2\) 范围内的某一段压到斜率小于 0.25:那一段上的 \(p_X\) 至少是 \(p_Z\) 的 4 倍,直方图也跟着冒出一个尖峰。Drag the knots to squeeze one piece inside \(|z|\le2\) to a slope below 0.25: on that piece \(p_X\) is at least 4 times \(p_Z\), and the histogram grows a spike with it.
- 只靠拖动节点,把单峰的高斯捏成双峰:\(p_X\) 有两个峰,中间的谷低于较矮峰的一半。提示:把中间几段拉长,把两侧压扁。By dragging knots only, mould the one-peaked Gaussian into a two-peaked density: \(p_X\) has two peaks with a valley between them lower than half the smaller peak. Hint: stretch the middle pieces and squeeze the outer ones.
一个单调(可逆)的函数,配上“除以斜率”这条规则,就能把一个简单分布变成复杂分布,并且新分布的密度处处可算:先倒推 \(z=f^{-1}(x)\),再算 \(p_Z(z)/|f'(z)|\)。高维时,“斜率”换成雅可比行列式 \(|\det J_f|\)(3.3 节:一个小区域的面积被放大 \(|\det J|\) 倍),其余一字不改。Normalizing flow 的全部难点,都在于造出一个既灵活、又可逆、行列式又便宜的 \(f\)。
A monotone (invertible) function plus the rule "divide by the slope" turns a simple distribution into a complex one whose density is computable everywhere: run back to \(z=f^{-1}(x)\), then evaluate \(p_Z(z)/|f'(z)|\). In higher dimensions the slope becomes the Jacobian determinant \(|\det J_f|\) (Lesson 3.3: a small region's area is multiplied by \(|\det J|\)), and nothing else changes. All the difficulty of normalizing flows lies in building an \(f\) that is flexible, invertible and has a cheap determinant.
3动手:耦合层,然后现场训练一个 flowPlay: a coupling layer, then train a flow live
二维时,flow 需要一个可逆的 \(f:\R^2\to\R^2\),并且要能便宜地算出 \(\det J_f\)。RealNVP(Dinh 等,2017)的仿射耦合层是这样的:把坐标分成两半,第一半原样通过,第二半被缩放再平移,而缩放量 \(\hl{s}{s}\) 和平移量 \(\hl{t}{t}\) 由第一半算出来(可以是任意神经网络):
In two dimensions a flow needs an invertible \(f:\R^2\to\R^2\) with a cheap \(\det J_f\). The affine coupling layer of RealNVP (Dinh et al., 2017) works like this: split the coordinates into two halves; the first half passes through unchanged, the second half is scaled and then shifted, and the scale \(\hl{s}{s}\) and shift \(\hl{t}{t}\) are computed from the first half (by any neural network you like):
两个好处一眼可见。可逆:因为 \(z_1=x_1\) 原样保留,倒推时先拿到 \(z_1\),就能重新算出 \(s\) 和 \(t\),再把缩放平移撤销;\(s\)、\(t\) 本身完全不需要可逆。行列式便宜:\(x_1\) 不依赖 \(z_2\),所以雅可比是下三角的,行列式就是对角线的乘积 \(1\cdot e^{s(z_1)}\),不管 \(s\) 和 \(t\) 多复杂。下图用两个手写的函数 \(s(z_1)=\alpha\sin(1.3z_1)\)、\(t(z_1)=\beta(\tfrac12z_1^2-0.8)\) 代替神经网络,让你看清一层到底做了什么。
Two benefits are visible at once. Invertible: since \(z_1=x_1\) is kept as is, running backwards you get \(z_1\) first, recompute \(s\) and \(t\) from it, and undo the scale and shift; \(s\) and \(t\) themselves need not be invertible at all. Cheap determinant: \(x_1\) does not depend on \(z_2\), so the Jacobian is lower triangular and its determinant is the product of the diagonal, \(1\cdot e^{s(z_1)}\), however complicated \(s\) and \(t\) are. The figure below replaces the networks with two hand-written functions, \(s(z_1)=\alpha\sin(1.3z_1)\) and \(t(z_1)=\beta(\tfrac12z_1^2-0.8)\), so you can see exactly what one layer does.
- 调节 \(\alpha\) 并拖动探针,找到一个位置使方块的像面积超过原来的 2 倍(\(\det J>2\))。默认的 \(\alpha=0.5\) 在一层模式下做不到:\(e^{0.5}\approx1.65\)。Adjust \(\alpha\) and drag the probe until the image of the square is more than twice its original area (\(\det J>2\)). The default \(\alpha=0.5\) cannot do it with one layer: \(e^{0.5}\approx1.65\).
- 把 \(\alpha\) 调到 0,并让 \(|\beta|\ge0.5\):网格照样弯曲,但无论探针放在哪里,\(\det J\) 都恰好是 1。这是 NICE(Dinh 等,2015)的“加性耦合”,保体积。Set \(\alpha\) to 0 with \(|\beta|\ge0.5\): the grid still bends, yet \(\det J\) is exactly 1 wherever the probe is. This is the "additive coupling" of NICE (Dinh et al., 2015), which preserves volume.
现场训练:最大似然Training live: maximum likelihood
现在把 \(s\) 和 \(t\) 换成小神经网络(每层一个 \([1,16,16,2]\) 的 tanh MLP,同时输出 \(s\) 和 \(t\)),叠 8 层,两半坐标轮流被变换,一共 2704 个参数。训练目标就是 4.6 节的最大似然:对每个数据点倒推到 \(\mathbf z\),累加每层的对数行列式,最小化平均负对数似然(NLL,单位 nat):
Now replace \(s\) and \(t\) by small neural networks (one \([1,16,16,2]\) tanh MLP per layer, outputting \(s\) and \(t\) together), stack 8 layers with the two halves taking turns being transformed: 2704 parameters in all. The training objective is the maximum likelihood of Lesson 4.6: run each data point back to \(\mathbf z\), add up every layer's log-determinant, and minimize the mean negative log-likelihood (NLL, in nats):
第一项 \(\tfrac12\|\mathbf z\|^2\) 要求数据被推到高斯的中心,单独用它,网络会把所有点压成一个点(逆变换的缩放 \(e^{-s}\to0\),即 \(s\to+\infty\));第二项 \(\sum s\) 惩罚这种压缩,因为压缩就是 \(\det J_{f^{-1}}\) 很小。两项拉锯的结果是:把数据均匀地铺满一个标准高斯。梯度用 16.3 节的反向传播逐层算出(页面里与有限差分对过,误差约 \(10^{-9}\)),优化器是 Adam(学习率 0.005,2000 步后降到 0.002),每步 64 个样本。
The first term \(\tfrac12\|\mathbf z\|^2\) wants the data pushed to the centre of the Gaussian; on its own it would let the network crush every point into one (the inverse scale \(e^{-s}\to0\), that is \(s\to+\infty\)). The second term \(\sum s\) penalizes exactly that crushing, because crushing means a tiny \(\det J_{f^{-1}}\). The tug of war between them ends with the data spread evenly over a standard Gaussian. The gradients come from the backpropagation of Lesson 16.3, layer by layer (checked against finite differences while writing this page, error about \(10^{-9}\)); the optimizer is Adam (learning rate 0.005, dropped to 0.002 after 2000 steps) on mini-batches of 64.
- 在“双月”上按“训练”,直到测试 NLL 低于 1.40(默认种子约 1150 步)。初始时它是 2.51;最好的单个高斯是 2.25,真实熵是 1.14。Press "Train" on "two moons" until the test NLL is below 1.40 (about 1150 steps with the default seed). It starts at 2.51; the best single Gaussian scores 2.25 and the true entropy is 1.14.
- 训练到测试 NLL < 1.40 之后,把温度 \(T\) 降到 0.6 以下:样本向两条月牙的“脊线”收拢,散在月牙之间的样本几乎消失。Once the test NLL is below 1.40, lower the temperature \(T\) below 0.6: the samples gather onto the spines of the two moons and the strays between them almost vanish.
- 把耦合方式换成“总是变换 \(x_2\)”,在双月上训练至少 2000 步:NLL 停在 1.75 附近下不去,因为 \(x_1=z_1\) 始终原样通过,模型的 \(x_1\) 边缘分布永远是标准正态。Switch the coupling to "always transform \(x_2\)" and train on two moons for at least 2000 steps: the NLL stalls near 1.75, because \(x_1=z_1\) always passes straight through, so the model's marginal of \(x_1\) stays standard normal forever.
(1) 训练集 NLL(约 1.19)比测试集(约 1.30)低:2704 个参数对 1000 个点已经开始过拟合,精确似然让你能像监督学习一样量出泛化差距(16.2 节)。 (2) 到 4000 步,测试 NLL 约 1.30,离真实熵 1.14 还差 0.16 nat:两条月牙之间总留着一道淡淡的密度“桥”。flow 是连续可逆映射,不能把一个连通的高斯撕成两块,只能把中间拉得很薄(误区 2)。 (3) “三团”数据最难看清这一点:要把一个高斯分成三个孤立的团,中间的桥永远去不掉,测试 NLL 还会随训练上下波动。 (4) 螺旋需要的变形最剧烈,8 层小网络 4000 步只到 2.26 左右,真实熵是 1.79。
(1) The training NLL (about 1.19) is below the test NLL (about 1.30): 2704 parameters on 1000 points already overfit, and the exact likelihood lets you measure the generalization gap just as in supervised learning (Lesson 16.2). (2) At 4000 steps the test NLL is about 1.30, still 0.16 nat above the true entropy 1.14: a faint "bridge" of density always remains between the two moons. A flow is a continuous invertible map; it cannot tear one connected Gaussian into two pieces, only stretch the middle very thin (Pitfall 2). (3) The "three blobs" data shows this most clearly: splitting one Gaussian into three isolated blobs always leaves bridges, and the test NLL even wobbles up and down during training. (4) The spiral needs the most violent deformation; 8 small layers reach only about 2.26 after 4000 steps, against a true entropy of 1.79.
4另外两个视角:逐层看,以及无穷多层Two more views: layer by layer, and infinitely many layers
逐层看:数据怎样被“高斯化”Layer by layer: how data gets "Gaussianized"
“Normalizing”这个名字来自密度估计的方向:从数据 \(\mathbf x\) 出发,一层一层倒推,直到分布变成标准正态(normal)。下图取 FIG 3 正在训练的那个模型,把 500 个测试点逐层推过去,按它们来自哪条月牙(或哪个团)着色。反过来选“\(\mathbf z\to\) 数据”,看到的就是采样:一团高斯一层层被捏成数据的形状。
The name "normalizing" comes from the density-estimation direction: start from the data \(\mathbf x\) and undo the layers one by one until the distribution becomes standard normal. The figure below takes the very model FIG 3 is training and pushes the 500 test points through it layer by layer, coloured by which moon (or blob) they came from. Choose "\(\mathbf z\to\) data" instead and you see sampling: a Gaussian cloud being moulded layer by layer into the shape of the data.
- FIG 3 的模型训练至少 2000 步后,在“数据 → \(\mathbf z\)”方向把阶段滑块从 0 拉到 8:两条月牙被逐层拉直、摊开,最后各占圆形高斯的一边,平均 \(\tfrac12\|\mathbf z\|^2\) 接近 1。After FIG 3's model has trained for at least 2000 steps, drag the stage slider from 0 to 8 in the "data → \(\mathbf z\)" direction: the two moons are straightened and spread out layer by layer and end up each filling one side of a round Gaussian, with the mean \(\tfrac12\|\mathbf z\|^2\) close to 1.
注意 \(\mathbf z\) 端的颜色:两类数据被分到高斯的两边,中间只有一条细缝。flow 学到的 \(\mathbf z\) 是数据的一种坐标系,和数据同维度、一一对应,不像 VAE 的隐变量那样可以更低维、并带着噪声(19.1 节)。按默认种子训练到 4000 步时,平均 \(\tfrac12\|\mathbf z\|^2\) 约为 1.16,略大于 1:模型还没把数据完全“高斯化”。
Look at the colours at the \(\mathbf z\) end: the two classes are sent to two sides of the Gaussian with only a thin seam between them. The \(\mathbf z\) a flow learns is a coordinate system for the data, of the same dimension and one-to-one, unlike a VAE's latent, which can be lower-dimensional and noisy (Lesson 19.1). With the default seed, after 4000 steps the mean \(\tfrac12\|\mathbf z\|^2\) is about 1.16, a little above 1: the model has not quite "Gaussianized" the data yet.
无穷多层:连续时间的流Infinitely many layers: continuous-time flows
如果每一层只做一个极小的变形 \(\mathbf x\leftarrow\mathbf x+\Delta t\,\mathbf v(\mathbf x)\),叠无穷多层,flow 就变成了一个常微分方程(2.5 节):每个样本沿着向量场 \(\hl{vf}{\mathbf v(\mathbf x,t)}\) 漂流(3.6 节)。这时“对数行列式之和”变成了沿轨迹对散度的积分:一小块区域的面积按 \(\tfrac{d}{dt}\log A=\hl{div}{\nabla\cdot\mathbf v}\) 变化(3.6 节说过:散度就是面积的增长率),密度则按相反的符号变化。这就是 Neural ODE(Chen 等,2018)提出的瞬时换元公式。下图用三个解析的向量场演示它;底色是散度。
If each layer makes only a tiny deformation \(\mathbf x\leftarrow\mathbf x+\Delta t\,\mathbf v(\mathbf x)\) and we stack infinitely many, the flow becomes an ordinary differential equation (Lesson 2.5): every sample drifts along a vector field \(\hl{vf}{\mathbf v(\mathbf x,t)}\) (Lesson 3.6). The "sum of log-determinants" then becomes an integral of the divergence along the trajectory: a small patch's area changes as \(\tfrac{d}{dt}\log A=\hl{div}{\nabla\cdot\mathbf v}\) (Lesson 3.6: divergence is the growth rate of area), and the density changes with the opposite sign. This is the instantaneous change of variables introduced with Neural ODEs (Chen et al., 2018). The figure demonstrates it with three analytic vector fields; the background shading is the divergence.
- 选“旋转成环”场,把绿色方块拖到底色琥珀的区域(离原点小于 1.4),按“运行”到 \(t\ge1\):面积比超过 2,并且与 \(e^{\int\nabla\cdot\mathbf v\,dt}\) 相差不到 3%。同时看紫色样本:高斯被这个场捏成了一个半径 2 的环。Pick the "swirl into a ring" field, drag the green square into the amber region (closer than 1.4 to the origin) and press "Run" until \(t\ge1\): the area ratio exceeds 2 and differs from \(e^{\int\nabla\cdot\mathbf v\,dt}\) by less than 3%. Watch the purple samples too: the field moulds the Gaussian into a ring of radius 2.
几何:一个可逆变形,概率质量守恒,密度按体积缩放(1.5、3.3 节)。 统计:精确似然下的最大似然估计,等价于最小化 \(\mathrm{KL}(p_{\mathcal D}\,\|\,p_\theta)\)(4.6、4.11 节)。 坐标:学一套和数据一一对应的新坐标 \(\mathbf z\),在这套坐标下数据是标准高斯。 动力学:无穷多层的极限是一个向量场,对数行列式变成散度的积分;19.6 节的扩散模型和 19.7 节的 flow matching 学的也是这样的场(扩散模型通过 score 间接给出它),只是不再用最大似然去训练。
Geometry: an invertible deformation; probability mass is conserved and density scales with volume (Lessons 1.5 and 3.3). Statistics: maximum likelihood with an exact likelihood, equivalent to minimizing \(\mathrm{KL}(p_{\mathcal D}\,\|\,p_\theta)\) (Lessons 4.6 and 4.11). Coordinates: learn a new coordinate system \(\mathbf z\), one-to-one with the data, in which the data is a standard Gaussian. Dynamics: the limit of infinitely many layers is a vector field and the log-determinant becomes an integral of the divergence; the diffusion models of Lesson 19.6 and the flow matching of Lesson 19.7 learn such fields too (diffusion through the score, which defines one), only no longer by maximum likelihood.
5再看数学The math
提示:把鼠标悬停在公式中带底色的符号上,图中对应的元素会被高亮(FIG 1 的两条密度曲线与探针带,FIG 2 的面积、平移箭头与雅可比列,FIG 3 的损失曲线,FIG 4 的高斯等高线,FIG 5 的散度底色与箭头,FIG 6 的目标点)。Tip: hover the highlighted symbols in the formulas; matching elements in the figures light up (FIG 1's two density curves and probe band, FIG 2's area, shift arrow and Jacobian columns, FIG 3's loss curves, FIG 4's Gaussian contours, FIG 5's divergence shading and arrows, FIG 6's target).
换元公式The change-of-variables formula
设 \(f:\R^D\to\R^D\) 是可逆且可微的(微分同胚),\(\mathbf z\sim p_Z\),\(\mathbf x=f(\mathbf z)\)。对任意区域 \(\Omega\),\(\mathbf x\) 落在 \(f(\Omega)\) 的概率等于 \(\mathbf z\) 落在 \(\Omega\) 的概率;而 3.3 节告诉我们,\(f\) 把 \(\mathbf z\) 附近的小体积放大 \(|\det J_f(\mathbf z)|\) 倍。于是
Let \(f:\R^D\to\R^D\) be invertible and differentiable (a diffeomorphism), \(\mathbf z\sim p_Z\), \(\mathbf x=f(\mathbf z)\). For any region \(\Omega\), the probability that \(\mathbf x\) lands in \(f(\Omega)\) equals the probability that \(\mathbf z\) lands in \(\Omega\), and Lesson 3.3 tells us \(f\) magnifies small volumes near \(\mathbf z\) by \(|\det J_f(\mathbf z)|\). Hence
两种写法等价,因为反函数的雅可比是雅可比的逆(反函数定理:\(J_{f^{-1}}(\mathbf x)=J_f(\mathbf z)^{-1}\)),行列式取倒数。把 \(f\) 写成 \(K\) 层的复合 \(f=f_K\circ\cdots\circ f_1\),中间量 \(\mathbf h_0=\mathbf z,\ \mathbf h_k=f_k(\mathbf h_{k-1}),\ \mathbf h_K=\mathbf x\)。链式法则让雅可比相乘,行列式也相乘,取对数后变成求和:
The two forms are equivalent because the Jacobian of the inverse is the inverse of the Jacobian (the inverse function theorem: \(J_{f^{-1}}(\mathbf x)=J_f(\mathbf z)^{-1}\)), whose determinant is the reciprocal. Write \(f\) as a composition of \(K\) layers, \(f=f_K\circ\cdots\circ f_1\), with intermediates \(\mathbf h_0=\mathbf z,\ \mathbf h_k=f_k(\mathbf h_{k-1}),\ \mathbf h_K=\mathbf x\). The chain rule multiplies the Jacobians, so the determinants multiply too, and after taking logs they add:
这就是 FIG 4 读数里的那笔账:在 \(\mathbf z\) 端,平均 \(\tfrac12\|\mathbf z\|^2\) 加上 \(\tfrac D2\log2\pi\)(\(D=2\) 时就是 \(\log2\pi\)),减去累积的平均 \(\log|\det J_{f^{-1}}|\),正好是测试 NLL。
This is the bookkeeping in FIG 4's readout: at the \(\mathbf z\) end, the mean \(\tfrac12\|\mathbf z\|^2\) plus \(\tfrac D2\log2\pi\) (just \(\log2\pi\) for \(D=2\)) minus the accumulated mean \(\log|\det J_{f^{-1}}|\) is exactly the test NLL.
最大似然 = 最小化 KLMaximum likelihood = minimizing KL
训练目标 \(\hl{nll}{L(\theta)}=-\tfrac1N\sum_i\log p_\theta(\mathbf x_i)\) 是期望 \(-\mathbb E_{p_{\mathcal D}}[\log p_\theta]\) 的样本估计,即交叉熵 \(H(p_{\mathcal D},p_\theta)=H(p_{\mathcal D})+\mathrm{KL}(p_{\mathcal D}\|p_\theta)\)(4.11 节)。熵 \(H(p_{\mathcal D})\) 与 \(\theta\) 无关,所以最小化 NLL 就是最小化 KL,并且 NLL 永远不低于 \(H(p_{\mathcal D})\):这就是 FIG 3 那条绿色虚线。两者之差就是模型离真实分布还有多远,以 nat 计。注意 KL 的这个方向(数据在前)惩罚的是“数据有、模型没有”,所以最大似然训练的模型倾向于覆盖所有模式,宁可在模式之间留一些多余的密度,这和 GAN 容易丢模式(19.2 节)正好相反。
The objective \(\hl{nll}{L(\theta)}=-\tfrac1N\sum_i\log p_\theta(\mathbf x_i)\) is a sample estimate of \(-\mathbb E_{p_{\mathcal D}}[\log p_\theta]\), the cross-entropy \(H(p_{\mathcal D},p_\theta)=H(p_{\mathcal D})+\mathrm{KL}(p_{\mathcal D}\|p_\theta)\) (Lesson 4.11). The entropy \(H(p_{\mathcal D})\) does not depend on \(\theta\), so minimizing the NLL is minimizing the KL, and the NLL can never go below \(H(p_{\mathcal D})\): that is the green dashed line of FIG 3. The gap between them is how far the model still is from the truth, in nats. Note that this direction of KL (data first) penalizes "the data has it, the model does not", so maximum-likelihood models tend to cover every mode, leaving some extra density between modes rather than dropping one, the opposite of the GAN's tendency to drop modes (Lesson 19.2).
耦合层:三角雅可比Coupling layers: a triangular Jacobian
一般地,把 \(\mathbf z\) 分成 \((\mathbf z_a,\mathbf z_b)\),仿射耦合层是 \(\mathbf x_a=\mathbf z_a\),\(\mathbf x_b=\mathbf z_b\odot e^{\hl{s}{\mathbf s(\mathbf z_a)}}+\hl{t}{\mathbf t(\mathbf z_a)}\)(\(\odot\) 是逐元素乘)。它的雅可比是
In general, split \(\mathbf z\) into \((\mathbf z_a,\mathbf z_b)\); the affine coupling layer is \(\mathbf x_a=\mathbf z_a\), \(\mathbf x_b=\mathbf z_b\odot e^{\hl{s}{\mathbf s(\mathbf z_a)}}+\hl{t}{\mathbf t(\mathbf z_a)}\) (\(\odot\) is the elementwise product). Its Jacobian is
左下块 \(\partial\mathbf x_b/\partial\mathbf z_a\) 牵涉 \(\mathbf s\) 和 \(\mathbf t\) 网络的导数,可能非常复杂,但三角矩阵的行列式只看对角线,所以根本用不着它。这就是全部窍门:网络的表达能力放在 \(\mathbf s,\mathbf t\) 里,可逆性和行列式由结构保证。代价是每层只变换一半坐标,所以必须轮换哪一半被变换(FIG 3 的“总是变换 \(x_2\)”就是反例);高维时在层之间插入固定的置换,Glow(Kingma 和 Dhariwal,2018)则学一个可逆的 \(1\times1\) 卷积来混合通道,用 LU 分解让它的行列式也便宜。
成本对比。一般的 \(D\times D\) 雅可比求行列式要 \(O(D^3)\) 次运算;耦合层只要 \(O(D)\),加上一次网络前向。对一张 \(64\times64\) 的 RGB 图像,\(D=12288\),\(D^3/3\approx6\times10^{11}\):每个样本、每一层都要这么多次运算,是不可能用于训练的。
其他结构。自回归 flow(MAF,Papamakarios 等,2017;IAF,Kingma 等,2016)让第 \(i\) 个坐标的 \(s_i,t_i\) 依赖前面所有坐标,雅可比同样是三角的,但两个方向里有一个必须逐坐标串行计算:MAF 算密度快、采样慢,IAF 反之(19.4 节的自回归模型是同一种因式分解)。样条 flow(Durkan 等,2019)把仿射的 \(e^sz+t\) 换成单调的有理二次样条,表达力更强,FIG 1 的折线就是它最简陋的版本。
The lower-left block \(\partial\mathbf x_b/\partial\mathbf z_a\) involves the derivatives of the \(\mathbf s\) and \(\mathbf t\) networks and may be very complicated, but the determinant of a triangular matrix only looks at the diagonal, so it is never needed. That is the whole trick: the expressive power lives in \(\mathbf s,\mathbf t\), while invertibility and the determinant are guaranteed by the structure. The price is that each layer transforms only half the coordinates, so the transformed half must alternate (FIG 3's "always transform \(x_2\)" is the counterexample); in high dimensions fixed permutations are inserted between layers, and Glow (Kingma and Dhariwal, 2018) learns an invertible \(1\times1\) convolution to mix channels, LU-factorized so that its determinant is cheap too.
Cost comparison. The determinant of a generic \(D\times D\) Jacobian takes \(O(D^3)\) operations; a coupling layer takes \(O(D)\) plus one network pass. For a \(64\times64\) RGB image \(D=12288\) and \(D^3/3\approx6\times10^{11}\) operations, for every sample and every layer: hopeless for training.
Other designs. Autoregressive flows (MAF, Papamakarios et al., 2017; IAF, Kingma et al., 2016) let the \(s_i,t_i\) of coordinate \(i\) depend on all earlier coordinates; the Jacobian is again triangular, but one of the two directions must run coordinate by coordinate: MAF evaluates densities fast and samples slowly, IAF the reverse (the autoregressive models of Lesson 19.4 use the same factorization). Spline flows (Durkan et al., 2019) replace the affine \(e^sz+t\) with monotone rational-quadratic splines for more expressive power; FIG 1's broken line is their crudest version.
梯度The gradient
训练时走的是密度方向:每层 \(w_b=(u_b-t)e^{-s}\),损失 \(\ell=\tfrac12\|\mathbf z\|^2+\sum s\)。设 \(g=\partial\ell/\partial w_b\)(最后一层 \(g=z_b\)),反向传播一层需要的三个局部导数是
Training runs in the density direction: each layer computes \(w_b=(u_b-t)e^{-s}\) and the loss is \(\ell=\tfrac12\|\mathbf z\|^2+\sum s\). With \(g=\partial\ell/\partial w_b\) (at the last layer \(g=z_b\)), backpropagating through one layer needs three local derivatives:
后两个再经网络反传到 \(\mathbf u_a\),与直通的 \(\partial\ell/\partial w_a\) 相加。注意 \(\partial\ell/\partial s\) 里的 “1”:它来自对数行列式,没有它就没有阻止塌缩的力。页面里的 \(s\) 是 \(2\tanh(\cdot/2)\) 限幅后的网络输出,防止 \(e^{s}\) 溢出(误区 5)。
The last two are backpropagated through the network to \(\mathbf u_a\) and added to the pass-through \(\partial\ell/\partial w_a\). Notice the "1" in \(\partial\ell/\partial s\): it comes from the log-determinant, and without it nothing would resist collapse. On this page \(s\) is the network output squashed by \(2\tanh(\cdot/2)\), so \(e^{s}\) cannot overflow (Pitfall 5).
连续时间的流,以及为什么要 flow matchingContinuous-time flows, and why flow matching
把一层 \(\mathbf x\leftarrow\mathbf x+\Delta t\,\mathbf v\) 的雅可比写成 \(I+\Delta t\,\partial\mathbf v/\partial\mathbf x\),则 \(\log\det(I+\Delta t A)=\Delta t\operatorname{tr}A+O(\Delta t^2)\),而 \(\operatorname{tr}(\partial\mathbf v/\partial\mathbf x)\) 正是散度 \(\hl{div}{\nabla\cdot\mathbf v}\)。让 \(\Delta t\to0\),就得到 FIG 5 上方那个公式。连续 flow 的好处是 \(\mathbf v\) 可以是任意神经网络,不需要特殊结构就自动可逆(ODE 的解在合理条件下唯一,倒着积分就是逆)。坏处是按最大似然训练它要在每一步都把 ODE 积分一遍,还要算散度;FFJORD(Grathwohl 等,2019)用 Hutchinson 随机迹估计降低了散度的成本,但积分仍然昂贵。19.7 节的 flow matching 换了一条路:不再最大化似然,而是直接对一个事先选好的概率路径上的速度场做回归,训练时完全不用积分 ODE。
Write the Jacobian of one layer \(\mathbf x\leftarrow\mathbf x+\Delta t\,\mathbf v\) as \(I+\Delta t\,\partial\mathbf v/\partial\mathbf x\). Then \(\log\det(I+\Delta t A)=\Delta t\operatorname{tr}A+O(\Delta t^2)\), and \(\operatorname{tr}(\partial\mathbf v/\partial\mathbf x)\) is exactly the divergence \(\hl{div}{\nabla\cdot\mathbf v}\). Let \(\Delta t\to0\) and you get the formula above FIG 5. The appeal of continuous flows is that \(\mathbf v\) can be any neural network: no special structure is needed for invertibility (under mild conditions the ODE solution is unique, and integrating backwards inverts it). The drawback is that maximum-likelihood training must integrate the ODE at every step and compute the divergence along the way; FFJORD (Grathwohl et al., 2019) cut the cost of the divergence with Hutchinson's stochastic trace estimator, but the integration remains expensive. Flow matching in Lesson 19.7 takes another road: instead of maximizing likelihood it regresses the velocity field of a probability path chosen in advance, so training never integrates the ODE at all.
VAE(19.1):可以降维,似然只有下界。GAN(19.2):样本锐利,没有似然。自回归(19.4):精确似然,采样要逐个生成。EBM(19.5):密度只到一个未知常数。扩散(19.6)与 flow matching(19.7):样本质量最好,也能通过一个 ODE 求似然,只是贵。离散 flow 的位置:精确似然、一次前向采样、一次前向求密度,代价是隐变量必须与数据同维,网络结构受限。
VAE (19.1): can reduce dimension, likelihood only as a bound. GAN (19.2): sharp samples, no likelihood. Autoregressive (19.4): exact likelihood, sampling one element at a time. EBM (19.5): density only up to an unknown constant. Diffusion (19.6) and flow matching (19.7): the best sample quality, with likelihoods available through an ODE, but expensive. Where discrete flows sit: exact likelihood, one pass to sample, one pass to evaluate a density, at the price of a latent of the same dimension as the data and a constrained architecture.
6机器人中的它:一次采样许多组 IK 解In robotics: sampling many IK solutions at once
冗余机械臂的逆运动学(7.5 节)有无穷多个解。数值 IK 每次从一个初值出发收敛到一个解;想要很多个不同的解(比如避障时挑一个离障碍最远的),只能换很多初值反复跑。条件 flow 换个思路:学一个分布 \(p_\theta(\mathbf q\mid\hl{cond}{\mathbf c})\),给定末端目标 \(\mathbf c\),一次就采出一批关节角。条件的做法很简单:把 \(\mathbf c\) 拼进每个耦合层 \(\mathbf s,\mathbf t\) 网络的输入,\(\mathbf s(\mathbf q_a,\mathbf c)\)、\(\mathbf t(\mathbf q_a,\mathbf c)\);可逆性只针对 \(\mathbf q\),所以三角结构照旧成立。
训练数据来自正运动学,几乎不要钱:随机采关节角 \(q_i\sim\mathcal N(0,0.9^2)\),算出末端位置,加上 0.04 m 的噪声作为 \(\mathbf c\)。下图是一个三连杆平面臂(杆长 1.0、0.8、0.6 m),目标是二维位置,所以每个目标对应一条一维的解曲线(自运动流形)。模型有 6 个耦合层(每层只变换一个关节角,三个关节轮流),每层一个 \([4,24,24,2]\) 的网络,共 4620 个参数。
The inverse kinematics of a redundant arm (Lesson 7.5) has infinitely many solutions. Numerical IK converges from one start to one solution; if you want many different ones (say, to pick the one farthest from an obstacle) you must rerun it from many starts. A conditional flow does it differently: learn a distribution \(p_\theta(\mathbf q\mid\hl{cond}{\mathbf c})\) and, given an end-effector target \(\mathbf c\), sample a whole batch of joint angles in one go. Conditioning is simple: append \(\mathbf c\) to the input of every coupling layer's networks, \(\mathbf s(\mathbf q_a,\mathbf c)\) and \(\mathbf t(\mathbf q_a,\mathbf c)\); invertibility is only needed in \(\mathbf q\), so the triangular structure still holds.
Training data comes from forward kinematics almost for free: sample joint angles \(q_i\sim\mathcal N(0,0.9^2)\), compute the tip position, add 0.04 m of noise and call it \(\mathbf c\). The figure uses a planar three-link arm (links 1.0, 0.8 and 0.6 m) with a 2-D position target, so each target has a one-dimensional curve of solutions (the self-motion manifold). The model has 6 coupling layers (each transforms one joint angle, the three joints taking turns), each with a \([4,24,24,2]\) network: 4620 parameters.
- 按“训练”,直到 40 个测试目标上的平均末端误差低于 0.20 m(默认种子约 2250 步,开始时约 2.1 m)。姿态明显各不相同:flow 采到的是一整条解曲线,而不是一个解。Press "Train" until the mean tip error over the 40 test targets drops below 0.20 m (about 2250 steps with the default seed; it starts near 2.1 m). The postures are clearly different from one another: the flow samples a whole curve of solutions, not one solution.
- 训练到误差 < 0.20 m 后打开“+ 精修”:当前目标的误差降到 2 cm 以下,而肘部散布几乎不变。flow 负责“多样的好初值”,雅可比 IK 负责最后几厘米。After the error is below 0.20 m, turn on "+ refine": the current target's error drops below 2 cm while the elbow spread barely changes. The flow supplies diverse good starts, Jacobian IK the last few centimetres.
- 训练到误差 < 0.20 m 后,把目标拖到离基座超过 2.2 m 的地方:解曲线变短,姿态向伸直的手臂收拢,肘部散布降到 0.4 m 以下(默认目标处约 0.6 m)。After the error is below 0.20 m, drag the target more than 2.2 m from the base: the solution curve shortens, the postures close in on the straight arm, and the elbow spread falls below 0.4 m (about 0.6 m at the default target).
逆运动学:Ardizzone 等(ICLR 2019)用可逆网络分析逆问题,例子之一就是平面机械臂的 IK 后验;IKFlow(Ames、Morgan 和 Konidaris,IEEE RA-L 2022)为 7 自由度机械臂训练条件 normalizing flow,一次批量生成大量不同的 IK 解;再用几步数值 IK 把这些样本精修到高精度(FIG 6 的做法),是很自然的搭配。 策略分布:SAC(20.4 节)默认用高斯策略,它只有一个峰;有些工作在高斯隐变量之上用可逆的 flow 层构造策略(例如 Haarnoja 等 2018 年的分层潜空间策略),表达力比单个高斯强,同时保留精确的 \(\log\pi(a\mid s)\),熵正则需要它。 旋转与位姿:flow 可以定义在流形上(例如环面和球面,Rezende 等,2020),也被用来建模 \(\mathrm{SO}(3)\) 上的旋转不确定性(例如 Liu 等,CVPR 2023),比如对称物体有多个等价朝向时。 异常检测:精确似然可以拿来给传感器读数或状态打分,但要小心误区 4。 今天的主流:在大规模机器人策略里,离散 flow 大多让位给了扩散模型(Diffusion Policy,22.2 节)和 flow matching(例如 π0 的动作头,19.7 节),它们学的仍然是“把高斯变成动作分布”的流,只是训练方式不同。
Inverse kinematics: Ardizzone et al. (ICLR 2019) analysed inverse problems with invertible networks, one example being the IK posterior of a planar arm; IKFlow (Ames, Morgan and Konidaris, IEEE RA-L 2022) trains conditional normalizing flows for 7-DoF arms that generate many different IK solutions in one batch; polishing such samples to high accuracy with a few steps of numerical IK (FIG 6's recipe) is a natural complement. Policy distributions: SAC (Lesson 20.4) uses a Gaussian policy by default, which has a single peak; some works build the policy from invertible flow layers on top of a Gaussian latent (for example the latent-space hierarchical policies of Haarnoja et al., 2018), more expressive than a single Gaussian while keeping the exact \(\log\pi(a\mid s)\) that entropy regularization needs. Rotations and poses: flows can be defined on manifolds (for example tori and spheres, Rezende et al., 2020) and have been used to model rotation uncertainty on \(\mathrm{SO}(3)\) (for example Liu et al., CVPR 2023), such as when a symmetric object has several equivalent orientations. Anomaly detection: the exact likelihood can score sensor readings or states, but mind Pitfall 4. Today's mainstream: in large robot policies, discrete flows have mostly given way to diffusion (Diffusion Policy, Lesson 22.2) and flow matching (for example the action head of π0, Lesson 19.7); these still learn a flow that turns a Gaussian into the action distribution, only trained differently.
7常见误区Common pitfalls
只最小化 \(\tfrac12\|\mathbf z\|^2\),模型会把所有数据压到原点附近,损失看起来一路下降,其实密度没有归一化,“似然”毫无意义。符号反了则相反:模型拼命放大体积。检查方法:在一个已知答案的例子上核对,比如 \(f(\mathbf z)=A\mathbf z\) 时 \(\log p_X(\mathbf x)\) 应等于 \(\mathcal N(\mathbf 0,AA^\top)\) 的对数密度;或者像 FIG 1 那样,拿样本直方图和公式比。还要分清方向:密度方向(\(\mathbf x\to\mathbf z\))加 \(\log|\det J_{f^{-1}}|\),采样方向(\(\mathbf z\to\mathbf x\))减 \(\log|\det J_f|\)。
Minimize only \(\tfrac12\|\mathbf z\|^2\) and the model squeezes all the data towards the origin; the loss keeps falling, but the density is no longer normalized and the "likelihood" means nothing. Flip the sign and the model inflates volume instead. Check it on a case with a known answer: for \(f(\mathbf z)=A\mathbf z\), \(\log p_X(\mathbf x)\) must equal the log density of \(\mathcal N(\mathbf 0,AA^\top)\); or compare a sample histogram with the formula as in FIG 1. Keep the directions straight too: the density direction (\(\mathbf x\to\mathbf z\)) adds \(\log|\det J_{f^{-1}}|\), the sampling direction (\(\mathbf z\to\mathbf x\)) subtracts \(\log|\det J_f|\).
flow 是连续的可逆映射,它保持拓扑:一个连通的高斯永远变不成严格分离的几块,也挖不出一个真正的洞。FIG 3 里双月和三团之间总有一道密度桥,NLL 离真实熵始终差一截。要逼近这类分布,只能叠更多层、用更强的层(样条),让桥越来越细,代价是 \(s\) 很大、数值上更陡峭。另外,标准 flow 的隐变量必须与数据同维:数据如果其实躺在一个低维曲面上(例如 FIG 6 的解曲线),密度在曲面上是无穷大,flow 只能靠噪声把它“撑厚”(我们给目标加了 0.04 m 噪声,部分原因就是这个)。
A flow is a continuous invertible map and preserves topology: a connected Gaussian can never become strictly separated pieces, nor can it punch a true hole. In FIG 3 a bridge of density always joins the moons and the blobs, and the NLL stays short of the true entropy. The only way to approximate such distributions is more layers and stronger layers (splines), making the bridges ever thinner at the cost of large \(s\) and steeper numerics. Also, a standard flow's latent must have the same dimension as the data: if the data really lies on a lower-dimensional surface (such as FIG 6's solution curves), the density on that surface is infinite, and a flow can only "thicken" it with noise (part of why we added 0.04 m of noise to the targets).
每层不动的那一半,如果每一层都是同一半,它就从头到尾原样通过:FIG 3 的“总是变换 \(x_2\)”里,模型的 \(x_1\) 永远是标准正态,NLL 停在 1.75 附近,而轮换时 1150 步就到 1.40 以下。高维时同理,层与层之间要换掩码或插入置换(RealNVP 的棋盘与通道掩码,Glow 的 \(1\times1\) 卷积),保证每个坐标都会被其他坐标影响到。
If the untouched half is the same in every layer, it passes through the whole flow unchanged: in FIG 3's "always transform \(x_2\)" the model's \(x_1\) stays standard normal forever and the NLL stalls near 1.75, whereas alternating gets below 1.40 in 1150 steps. The same holds in high dimensions: change the mask or insert a permutation between layers (RealNVP's checkerboard and channel masks, Glow's \(1\times1\) convolutions) so that every coordinate gets influenced by the others.
似然高不等于“像训练数据”。Nalisnick 等(ICLR 2019)发现,在 CIFAR-10 上训练的 Glow 给 SVHN(门牌号图片)打出的似然反而更高:似然很大程度上由图像的简单程度(平滑、低方差)决定,而不是语义。在机器人上用 flow 做异常检测前,要在真实的分布外数据上验证。另外,离散数据(8 位像素、编码器计数)直接拟合连续密度时,模型可以把无穷大的密度堆在离散值上,必须先去量化(加 \([0,1)\) 的均匀噪声)。
High likelihood does not mean "looks like the training data". Nalisnick et al. (ICLR 2019) found that a Glow trained on CIFAR-10 assigns higher likelihood to SVHN (house-number images): the likelihood is driven largely by how simple an image is (smooth, low variance), not by its meaning. Before using a flow for anomaly detection on a robot, validate it on real out-of-distribution data. Also, when fitting a continuous density to discrete data (8-bit pixels, encoder counts), the model can pile infinite density onto the discrete values; dequantize first (add uniform noise on \([0,1)\)).
\(e^{s}\) 不加限制时,几个大的 \(s\) 就能溢出,或者让逆变换的误差层层放大。常见的保护:把 \(s\) 用 \(c\tanh(\cdot/c)\) 限幅(本页 \(c=2\)),把最后一层初始化为接近零让 flow 从恒等映射开始,把数据标准化到单位尺度,并定期检查往返误差 \(\|f^{-1}(f(\mathbf z))-\mathbf z\|\)(FIG 2 的读数)。另外别忘了:flow 只在训练数据覆盖的区域可靠,FIG 6 把目标拖到基座左侧,采出来的姿态就够不着了。
With \(e^{s}\) unconstrained, a few large \(s\) overflow, or the errors of the inverse are amplified layer after layer. Common safeguards: squash \(s\) with \(c\tanh(\cdot/c)\) (\(c=2\) on this page), initialize the last layer near zero so the flow starts as the identity, standardize the data to unit scale, and check the round-trip error \(\|f^{-1}(f(\mathbf z))-\mathbf z\|\) now and then (FIG 2's readout). And remember that a flow is only reliable where its training data was: in FIG 6, drag the target to the left of the base and the sampled postures no longer reach it.
8小练习Check yourself
9延伸阅读Further reading
- G. Papamakarios, E. Nalisnick, D. J. Rezende, S. Mohamed & B. Lakshminarayanan, Normalizing Flows for Probabilistic Modeling and Inference, JMLR, 2021 — 最全面的综述:换元、耦合与自回归 flow、连续 flowthe most complete survey: change of variables, coupling and autoregressive flows, continuous flows
- E. G. Tabak & C. V. Turner, A Family of Nonparametric Density Estimation Algorithms, Communications on Pure and Applied Mathematics, 2013 — “normalizing flow”这一思想的早期来源之一one of the early sources of the "normalizing flow" idea
- D. J. Rezende & S. Mohamed, Variational Inference with Normalizing Flows, ICML 2015 — 把 flow 用于变分推断的后验,让这个名字流行起来flows for variational posteriors; made the name popular
- L. Dinh, D. Krueger & Y. Bengio, NICE: Non-linear Independent Components Estimation, ICLR 2015 (workshop) — 加性耦合层the additive coupling layer
- L. Dinh, J. Sohl-Dickstein & S. Bengio, Density Estimation Using Real NVP, ICLR 2017 — 仿射耦合层、掩码与多尺度结构affine coupling, masks and the multi-scale architecture
- D. P. Kingma & P. Dhariwal, Glow: Generative Flow with Invertible 1×1 Convolutions, NeurIPS 2018
- G. Papamakarios, T. Pavlakou & I. Murray, Masked Autoregressive Flow for Density Estimation, NeurIPS 2017; D. P. Kingma, T. Salimans, R. Jozefowicz, X. Chen, I. Sutskever & M. Welling, Improved Variational Inference with Inverse Autoregressive Flow, NeurIPS 2016
- C. Durkan, A. Bekasov, I. Murray & G. Papamakarios, Neural Spline Flows, NeurIPS 2019
- R. T. Q. Chen, Y. Rubanova, J. Bettencourt & D. Duvenaud, Neural Ordinary Differential Equations, NeurIPS 2018; W. Grathwohl, R. T. Q. Chen, J. Bettencourt, I. Sutskever & D. Duvenaud, FFJORD: Free-Form Continuous Dynamics for Scalable Reversible Generative Models, ICLR 2019 — 连续时间的 flow 与瞬时换元公式continuous-time flows and the instantaneous change of variables
- E. Nalisnick, A. Matsukawa, Y. W. Teh, D. Gorur & B. Lakshminarayanan, Do Deep Generative Models Know What They Don't Know?, ICLR 2019 — 误区 4Pitfall 4
- L. Ardizzone et al., Analyzing Inverse Problems with Invertible Neural Networks, ICLR 2019; B. Ames, J. Morgan & G. Konidaris, IKFlow: Generating Diverse Inverse Kinematics Solutions, IEEE Robotics and Automation Letters, 2022 — FIG 6 的真实版本the real versions of FIG 6