想象一场大型航拍表演:一千名志愿者站在草坪上,围成一个松散的圆形人海,导演要把这片人海变成两颗紧挨着的爱心。老办法是预先打印五十张站位图——第一步按图一移动,第二步按图二移动……五十张图全执行完,队形才勉强成型。这就是“离散标准化流”的思路:用一长串固定的、可逆的步骤,把简单分布一点点改造成复杂分布。可地图越多,要背、要存、要倒放的成本就越高。 新导演换了一种方式:给每人发一副实时导航眼镜。镜片上的箭头随时告诉每个人——此时此刻、在你现在的位置、该往哪个方向走、走多快。人群不需要记任何一张图,只需持续跟随箭头,就能自然流动成两颗爱心;想倒回去也很简单,把时间倒放,箭头全部反向。这个“实时箭头”就是速度场,而“跟随箭头走路”就是解一个常微分方程(ODE)。把几十个离散步骤“压”成一条连续轨迹,就是今天的主角:连续标准化流(CNF)。它对 AI 从业者的价值在于:用 ODE 重新定义了“可逆变换”,是神经 ODE、FFJORD 等前沿生成模型的地基,也是研究高表达力生成模型绕不开的核心范式。

岗位关联

需要学习连续标准化流CNF,CV几乎完全依赖深度学习,CNN/ViT/DETR等架构是你的核心技术栈。本篇涵盖CNN/RNN/Transformer、反向传播、正则化、训练技巧,帮助你理解深度模型原理与调优。

目录
  1. 可视化演示
  2. 从离散到连续
  3. ODE核心公式
  4. 密度变换法则
  5. 伴随方法
  6. 对比离散流
  7. 求解与训练
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示连续标准化流的核心机制,通过入门/进阶/实战/优化四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

连续标准化流:CNF核 CNF核心思想与动机 ODE定义的可逆变换 核心机制可视化 连续标准化流整体架构与关键组件

从离散到连续

老导演的“连环地图册”执行起来有个麻烦:五十张站位图,每张都要保存好才能“倒放”,而且再多图也是“一格一格跳”,队形始终带着生硬的折角。离散标准化流正是如此——把简单分布(如高斯)通过 K 个可逆函数一层层推成复杂分布,每一层都是精心设计的可逆映射,中间状态全都要留下。

细看标准的残差结构,会发现一个惊人的巧合:step 的写法 z_{k+1} = z_k + f(z_k) 和数值积分里的“欧拉步”长得一模一样。如果把层数 K 无限增加、每步位移无限缩小,离散递推就会收敛成一个常微分方程(ODE)——地图的“一格一格跳”变成了导航眼镜的“连续流动”。

从这一极限出发,导演彻底扔掉了地图册:不用再记“第几步该往哪走”,只要无限细分下去,“深层”这个概念自动消失,取而代之的是数学上真正的无限深度。

lim⁡Δt→0z(t+Δt)−z(t)Δt=f(z(t),t)\displaystyle \lim_{\Delta t \to 0} \frac{\mathbf{z}(t+\Delta t) - \mathbf{z}(t)}{\Delta t} = \mathbf{f}(\mathbf{z}(t), t)
  1. 位置变化量极短时间 $\Delta t$ 内位置向量 $\mathbf{z}$ 的位移,就是导航眼镜“眨眼之间”看到的脚步变化。
    z(t+Δt)−z(t)\mathbf{z}(t+\Delta t) - \mathbf{z}(t)
  2. 单位化把位移除以 $\Delta t$,得到单位时间内的平均变化,也就是这段极短时间里的“平均速度”。
    z(t+Δt)−z(t)Δt\frac{\mathbf{z}(t+\Delta t) - \mathbf{z}(t)}{\Delta t}
  3. 取极限当时间片无限细分时,离散“跳格”退化成瞬时“流动”,平均速度变成瞬时速度。
    lim⁡Δt→0z(t+Δt)−z(t)Δt\lim_{\Delta t \to 0} \frac{\mathbf{z}(t+\Delta t) - \mathbf{z}(t)}{\Delta t}
  4. 速度场赋值极限的极限值正是速度场 $\mathbf{f}$ 在当前位置、当前时刻的输出——眼睛里的实时箭头。
    f(z(t),t)\mathbf{f}(\mathbf{z}(t), t)

ODE核心公式

导航眼镜的箭头不是死板的固定路线,而是一套规则:无论你站在哪儿、无论是几点,它都告诉你此刻该往哪走、走多快。这套规则写成数学语言就是速度场 $\mathbf{f}(\mathbf{z}, t)$——输入当前位置和时刻,输出速度向量。对每个戴眼镜的人,从自己的起点出发,一路跟随箭头,走出的那条光滑曲线就是 ODE 的解。

给定起点求终点的问题,叫初值问题(IVP):知道“现在的位置 $\mathbf{z}(t_0)$”,推算“未来的位置 $\mathbf{z}(t_1)$”。在 CNF 里,速度场由一个神经网络参数化,它不必是刻意构造的可逆函数——只要输出对位置是利普希茨连续的,解就存在且唯一,而且整条轨迹自动可逆:把箭头倒放就能回到起点。这是离散流梦寐以求却做不到的“免费可逆性”。

眼镜没有换地图,它只是把“下一步去哪”从一张张静态图,换成了每时每刻的微分指令——这就是 ODE 定义可逆变换的核心:一步一指令,轨迹即变换。

dz(t)dt=f(z(t),t),z(t0)=z0\displaystyle \frac{d\mathbf{z}(t)}{dt} = \mathbf{f}(\mathbf{z}(t), t), \qquad \mathbf{z}(t_0) = \mathbf{z}_0
  1. 导数位置向量对时间的瞬时变化率,即此刻的“瞬时速度”。
    dz(t)dt\frac{d\mathbf{z}(t)}{dt}
  2. 速度场赋值导数等于速度场在当前位置与时刻的输出——“速度=场上指令”。
    f(z(t),t)\mathbf{f}(\mathbf{z}(t), t)
  3. 初值条件$\mathbf{z}(t_0)=\mathbf{z}_0$ 给出每个人的出发位置,方程加上初值构成初值问题。
    z(t0)=z0\mathbf{z}(t_0) = \mathbf{z}_0
  4. 整体语义从初值出发、沿着场的箭头持续积分,得到的整条平滑轨迹就是变换结果。
    z(t1)=z(t0)+∫t0t1f(z(t),t) dt\mathbf{z}(t_1) = \mathbf{z}(t_0) + \int_{t_0}^{t_1} \mathbf{f}(\mathbf{z}(t), t)\, dt

密度变换法则

人群不断流动,地面各处的“拥挤程度”也在变:大家朝两颗爱心聚拢时,小片区域会越来越挤。概率密度 $p(\mathbf{z})$ 正是这种拥挤程度的数学刻画。做生成模型时我们需要回答:一段轨迹走完,密度变成了多少?

离散流里每次变换用“乘以雅可比行列式”来更新密度;连续流没有“每一步”,只有“每瞬间”,所以要先问瞬时变化率。答案就是著名的瞬时变量变换法则:对数密度的瞬时变化率等于速度场雅可比矩阵的迹取负号。迹衡量的是速度场在那个点的“收缩/膨胀”快慢——负号表示膨胀会稀释密度。全程的对数密度变化,就是把瞬时变化率从 $t_0$ 积分到 $t_1$。

看到演示里人群呼啦啦挤向两个红点,那就是迹为负、对数密度一路上升的直观画面。训练 CNF 时,我们正是用这条法则计算每个样本的对数似然,从而优化速度场网络。

dlog⁡p(z(t))dt=−tr⁡ ⁣(∂f∂z)\displaystyle \frac{d \log p(\mathbf{z}(t))}{dt} = -\operatorname{tr}\!\left( \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \right)
  1. 对数密度$\log p(\mathbf{z}(t))$ 度量轨迹上当前点的“拥挤程度”,取对数便于把乘法变成加法。
    log⁡p(z(t))\log p(\mathbf{z}(t))
  2. 左端求导对时间求导得到密度随流动的瞬时变化速度,是“此刻变挤了还是变松了”。
    dlog⁡p(z(t))dt\frac{d \log p(\mathbf{z}(t))}{dt}
  3. 雅可比矩阵$\frac{\partial \mathbf{f}}{\partial \mathbf{z}}$ 刻画速度场在该点邻域的拉伸、压缩与旋转方式。
    ∂f∂z\frac{\partial \mathbf{f}}{\partial \mathbf{z}}
  4. 迹运算$\operatorname{tr}(\cdot)$ 取矩阵对角线之和,等于局部体积变化率;负号让“膨胀”对应“密度下降”。
    −tr⁡ ⁣(∂f∂z)-\operatorname{tr}\!\left( \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \right)

伴随方法

训练导航算法需要梯度:损失对起点位置、对网络参数各“调整一丁点”,输出会怎么变?离散流行反向传播时必须把每张地图的中间状态全部记下——五十张地图一张都不能少。而 CNF 的轨迹由几千个积分步构成,若照搬这套方法,内存会瞬间爆炸。

伴随方法解决这个问题的方式很巧妙:派一架“逆飞无人机”从终点倒着飞回起点,边飞边记录一个叫伴随状态的信号 $\mathbf{a}(t)=\partial L/\partial \mathbf{z}(t)$。它不保存任何中间地图,只在飞行中不断询问速度场:“这个位置对最终损失有多敏感?”

无人机空手去、空手回,只靠一路记录“敏感度”,就完成了训练中最贵的梯度计算——内存与积分步数无关,这就是 CNF 的 O(1) 内存反向传播。

da(t)dt=−a(t)T∂f∂z,a(t)=∂L∂z(t)\displaystyle \frac{d\mathbf{a}(t)}{dt} = -\mathbf{a}(t)^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}}, \qquad \mathbf{a}(t) = \frac{\partial L}{\partial \mathbf{z}(t)}
  1. 伴随状态$\mathbf{a}(t)$ 是损失 $L$ 对轨迹上时刻 $t$ 位置的梯度,相当于“敏感性信号”。
    a(t)=∂L∂z(t)\mathbf{a}(t) = \frac{\partial L}{\partial \mathbf{z}(t)}
  2. 反向递推$\frac{d\mathbf{a}}{dt}$ 描述伴随状态沿时间的演化,由速度场对位置的导数决定。
    da(t)dt\frac{d\mathbf{a}(t)}{dt}
  3. 转置与负号$-\mathbf{a}(t)^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}}$ 表示要从终点 $t_1$ 逆时间方向积分回起点 $t_0$。
    −a(t)T∂f∂z-\mathbf{a}(t)^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}}
  4. 完整方程把 $\mathbf{z}$、$\mathbf{a}$ 和参数梯度拼成增广状态,用一个求解器反向积分,能量损失和参数梯度一次算齐。
    ddt[za∂L∂θ]=[f−aT∂f∂z−aT∂f∂θ]\frac{d}{dt}\begin{bmatrix} \mathbf{z} \\ \mathbf{a} \\ \frac{\partial L}{\partial \boldsymbol{\theta}} \end{bmatrix} = \begin{bmatrix} \mathbf{f} \\ -\mathbf{a}^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \\ -\mathbf{a}^T \frac{\partial \mathbf{f}}{\partial \boldsymbol{\theta}} \end{bmatrix}

对比离散流

老导演的地图册和新导演的导航眼镜各有拥趸。地图册每一步都明明白白,但五十张图必须全部保存才能“倒放”;导航眼镜只存一份箭头规则,正放倒放都随心。数学上,两者的密度更新方式形成了优雅的对照:离散流是逐层求和,每项都要一个雅可比行列式;CNF 是连续积分,每瞬间只需要一个迹。

| 维度 | 离散标准化流 | 连续标准化流 CNF |

| --- | --- | --- |

| 中间状态 | 每层都要保存 | 无需保存 |

| 内存 | 随层数 K 增长 | 与积分步数无关 |

| 可逆性 | 需精心设计可逆层 | 速度场自动保证 |

| 深度 | 有限 K 层 | 概念上无限深 |

| 计算 | 前向较快 | 串行积分较慢 |

导演最终的选择取决于场地与预算:要极致节省内存、追求表达力,就上实时导航;要每步可控、层数不多,地图册依然好用。

log⁡p(xK)=log⁡p(x0)−∑k=1Klog⁡∣det⁡∂fk∂xk−1∣⟷log⁡p(z(t1))=log⁡p(z(t0))−∫t0t1tr⁡ ⁣(∂f∂z)dt\displaystyle \log p(\mathbf{x}_K) = \log p(\mathbf{x}_0) - \sum_{k=1}^{K} \log\left|\det \frac{\partial \mathbf{f}_k}{\partial \mathbf{x}_{k-1}}\right| \quad \longleftrightarrow \quad \log p(\mathbf{z}(t_1)) = \log p(\mathbf{z}(t_0)) - \int_{t_0}^{t_1} \operatorname{tr}\!\left( \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \right) dt
  1. 左式求和离散流把 $K$ 层各自的对数雅可比行列式逐项相加,每一项都要构造并存储完整的行列式。
    ∑k=1Klog⁡∣det⁡∂fk∂xk−1∣\sum_{k=1}^{K} \log\left|\det \frac{\partial \mathbf{f}_k}{\partial \mathbf{x}_{k-1}}\right|
  2. 右式积分CNF 把求和换成连续积分,每瞬间只计算一个迹,不再需要行列式。
    ∫t0t1tr⁡ ⁣(∂f∂z)dt\int_{t_0}^{t_1} \operatorname{tr}\!\left( \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \right) dt
  3. 行列式 vs 迹$\det$ 计算开销约 $O(D^3)$,$\operatorname{tr}$ 朴素计算约 $O(D^2)$,配合随机估计可降到 $O(D)$。
    det⁡(J)    vs    tr⁡(J)\det(\mathbf{J}) \;\; \text{vs} \;\; \operatorname{tr}(\mathbf{J})
  4. 对应关系求和取极限成为积分,正是“五十张地图”退化成“一条连续轨迹”的数学表达。
    ∑k=1Klog⁡→∫t0t1dt\sum_{k=1}^{K} \log \to \int_{t_0}^{t_1} dt

求解与训练

导航眼镜的芯片得实时“解微分方程”,靠的是数值积分器。最简单的欧拉法就像“每 0.01 秒按当前箭头走一步”;更聪明的是龙格-库塔法,一步内多次采样箭头方向,精度大幅提升。实际训练中常用自适应步长的 Dormand-Prince 45 积分器,它根据前后两步的误差自动调整步长,精度由容差 atol/rtol 控制——就像眼镜自动决定“箭头该多频繁地刷新”。

高维场景下还有一个隐藏瓶颈:迹的朴素计算要构造完整的雅可比矩阵,开销 $O(D^2)$。FFJORD 提出用Hutchinson 随机迹估计把它降到 $O(D)$:抽几个随机探针向量,测量速度场沿探针方向的局部变化,再取平均。

这套引擎已经落地:密度估计与生成有 FFJORD 类模型,不规则时间序列建模用神经 ODE 的连续隐状态。把箭头规则学到手后,任意起点都能顺流到目标分布、任意目标分布也都能逆流回噪声——这就是“用 ODE 定义可逆变换”的完整故事。

tr⁡ ⁣(∂f∂z)=Ev∼N(0,I) ⁣[vT∂f∂zv]≈1M∑k=1MvkT∂f∂zvk\displaystyle \operatorname{tr}\!\left( \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \right) = \mathbb{E}_{\mathbf{v} \sim \mathcal{N}(0, I)}\!\left[ \mathbf{v}^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \mathbf{v} \right] \approx \frac{1}{M} \sum_{k=1}^{M} \mathbf{v}_k^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \mathbf{v}_k
  1. 随机探针$\mathbf{v} \sim \mathcal{N}(0, I)$ 是抽出的标准正态随机向量,相当于随机挑一个方向去“试探”速度场。
    v∼N(0,I)\mathbf{v} \sim \mathcal{N}(0, I)
  2. 二次型$\mathbf{v}^T \mathbf{J} \mathbf{v}$ 沿探针方向测量雅可比矩阵的变化,是无偏的迹估计。
    vT∂f∂zv\mathbf{v}^T \frac{\partial \mathbf{f}}{\partial \mathbf{z}} \mathbf{v}
  3. 期望还原因为 $\mathbb{E}[\mathbf{v}\mathbf{v}^T]=I$,随机二次型的期望恰好等于迹本身。
    E[vTJv]=tr⁡(J)\mathbb{E}[\mathbf{v}^T \mathbf{J} \mathbf{v}] = \operatorname{tr}(\mathbf{J})
  4. 有限平均用 $M$ 个探针的均值近似期望,绕开完整雅可比矩阵,把开销压到 $O(D)$。
    1M∑k=1MvkTJvk\frac{1}{M} \sum_{k=1}^{M} \mathbf{v}_k^T \mathbf{J} \mathbf{v}_k

AI 应用场景

不规则时间序列建模(医疗监测 / 金融高频数据)

阶段:模型设计(序列预测与生成)

解决的问题:传统 RNN 要求等间隔、整齐的时间序列,遇到漏采或乱序时刻要插值补全、效率低下。CNF/神经 ODE 把隐状态看作连续轨迹,任何观测时刻都能通过积分得到对应状态——就像导航眼镜在任何时间点都能给出当前位置,不用等“下一张地图”。

具体案例:心电图传感器以不固定间隔上传数据,用连续 ODE 隐状态建模心跳动态,在缺失 30% 采样点的情况下仍能重构图谱并提前预警心律异常。

高维连续密度估计与生成(FFJORD 图像生成 / 异常检测)

阶段:生成模型训练与推理

解决的问题:传统离散流必须设计特殊可逆层、层数有限导致表达受限。CNF 用任意连续网络作速度场,配合随机迹估计直接最大化对数似然,且“倒放时间”即可精确采样。

具体案例:FFJORD 在图像数据集上以 $O(D)$ 的随机迹估计训练 CNF,得到可逆变换:既能量化每张图的似然分数用于异常检测,又能从高斯噪声反向采样生成新图像。

Python 演示

python69 行
import numpy as np  class LinearCNF:    """一维线性速度场 f(z,t)=k*(z-c): 解析解已知, 便于数值验证.     连续标准化流三件套演示:    1) forward : 欧拉法正向解 ODE, 同时累计 log 密度变化    2) adjoint : 逆向解伴随方程, 求 dL/dz(t0)    3) 与解析解及有限差分对比, 验证实现    """     def __init__(self, k=-1.0, c=2.0):        self.k = k        self.c = c     def f(self, z, t):        return self.k * (z - self.c)     def jac(self, t):        return self.k  # 1x1 雅可比退化为标量 k     def forward(self, z0, t0, t1, n=2000):        dt = (t1 - t0) / n        z, logdet = z0, 0.0        for i in range(n):            t = t0 + (i + 0.5) * dt            logdet += -self.jac(t) * dt   # dlogp/dt = -tr(J)            z = z + self.f(z, t) * dt     # 欧拉步进        return z, logdet     def adjoint(self, a1, t0, t1, n=2000):        """逆向积分 da/dt = -a*df/dz, 得到 dL/dz(t0)"""        dt = (t1 - t0) / n        a = a1        for i in range(n):            t = t1 - (i + 0.5) * dt            a = a + a * self.jac(t) * dt  # 反向欧拉: 每一步乘 (1+k*dt)        return a  def main():    model = LinearCNF(k=-1.0, c=2.0)    z0 = np.array([1.0])    t0, t1 = 0.0, 1.0     # 1) 正向变换与密度变化    z1, logdet = model.forward(z0, t0, t1)    z1_exact = model.c + (z0 - model.c) * np.exp(model.k * (t1 - t0))    logdet_exact = -model.k * (t1 - t0)    print("z(1) 数值: %.6f, 解析: %.6f" % (z1[0], z1_exact[0]))    print("logdet 数值: %.6f, 解析: %.6f" % (logdet, logdet_exact))     # 2) 伴随方法求梯度 dL/dz(t0), 设损失 L=(z1-3)^2    a1 = 2.0 * (z1 - 3.0)  # dL/dz(t1)    a0 = model.adjoint(a1, t0, t1)    a0_exact = a1 * np.exp(model.k * (t1 - t0))  # dz1/dz0 = exp(kT)    print("伴随梯度: %.6f, 解析: %.6f" % (a0[0], a0_exact[0]))     # 3) 有限差分交叉验证    eps = 1e-6    zp, _ = model.forward(z0 + eps, t0, t1)    zm, _ = model.forward(z0 - eps, t0, t1)    fd = ((zp - 3.0) ** 2 - (zm - 3.0) ** 2) / (2.0 * eps)    print("有限差分: %.6f" % fd[0])  if __name__ == "__main__":    main()
目的:用一个人人都能读懂的一维线性速度场,把 CNF 的三件套——ODE 正向变换、瞬时密度累积、伴随方法反向梯度——完整跑通,并用解析解和有限差分双重验证数值实现。
  1. logdet += -self.jac(t) * dt每一步按瞬时变化率 $-tr(J)$ 累积对数密度变化,对应正文“密度变换法则”。
  2. z = z + self.f(z, t) * dt欧拉法正向积分 ODE,对应“轨迹积分”。
  3. a = a + a * self.jac(t) * dt反向欧拉步进求解伴随方程,对应“伴随方法”。
  4. z1_exact = model.c + (z0 - model.c) * np.exp(model.k * (t1 - t0))线性场解析解,用来验证数值求解器。
  5. a1 = 2.0 * (z1 - 3.0)从终点初始化伴随状态 $a(t_1)=dL/dz(t_1)$。
  6. fd = ((zp - 3.0) ** 2 - (zm - 3.0) ** 2) / (2.0 * eps)用中心差分独立计算梯度,交叉验证伴随方法的结果。

常见误区

误区我一直以为 CNF 就是拿现成的 ODE 求解器把数据跑一遍,根本不用训练网络,解完方程分布就自动变好了。

正解速度场 $f$ 本身是神经网络,需要通过最大化数据对数似然来训练。ODE 求解器只是“把当前学到的速度场积分成轨迹”的数值工具——就像导航眼镜里的箭头规则是算法团队辛辛苦苦调出来的,眼镜本身只是负责执行。

为何常见:很多教程重点讲求解器和伴随方法,让人误以为 CNF 是个“无参数求解过程”,忽略了背后的网络训练。

误区伴随方法既然能“免存储”地算梯度,那它一定完全绕开了反向传播,训练几乎是零成本的。

正解伴随方法仍然需要自动微分去算 $\partial f/\partial z$ 与 $\partial f/\partial \theta$ 的向量积,而且还要额外解一条逆时间 ODE。它省的是“存储每个积分步中间激活”的内存,不是梯度计算本身,时间开销通常反而更高。

为何常见:“无需存储中间状态”被误读成“无需任何梯度计算”,两个概念被混为一谈。

误区CNF 内存又省、表达力又强,那肯定全面碾压离散流,以后所有任务都该用 CNF。

正解连续化换来的是 O(1) 内存和无限深度表达,但积分必须串行推进,数值求解通常比同规模离散流更慢,还引入容差、数值误差等新问题。实践中要根据任务权衡,不能一概而论。

为何常见:只看到“省内存、表达强”这些优点,忽略了“串行积分慢”这个硬成本,以为免费午餐真的存在。

误区数值方法不是步长越小越准吗?那把容差调到最小、步长压到极小,训练肯定又稳又准。

正解过小的容差会急剧增加积分步数,训练慢到不可用,而且浮点误差累积后并不一定更准。自适应求解器配合理想的 atol/rtol(如 $10^{-3}$ 量级)才是速度与精度兼得的做法。

为何常见:“步长越小越精确”在无限精度、无限算力下成立,但现实是有限浮点与有限算力,必须做折中。

面试题

Q1. 连续标准化流之所以“连续”,主要是因为:

单选题 · easy

  • A.训练数据是连续采集的样本
  • B.变换由 ODE 轨迹定义而非离散层叠← 正确答案
  • C.网络输出的数值是连续实数
  • D.损失函数必须处处可微连续

答案:B。CNF 的“连续”指的是把离散层叠的变换换成一条由 ODE 定义的连续轨迹,B 正确。数据采集方式、输出值域、损失可微性都与“连续流”的核心思想无关,是干扰项。

Q2. 在 CNF 中,速度场 f(z,t) 的主要作用是:

单选题 · easy

  • A.直接输出变换后的最终结果
  • B.每时每刻给出移动方向与快慢← 正确答案
  • C.计算损失函数的具体数值大小
  • D.保存所有中间层的特征张量

答案:B。速度场输入当前位置和时刻,输出速度向量,相当于导航眼镜的实时箭头,B 正确。它不直接给出终点,也不算损失,更不是用来存中间状态的。

Q3. CNF 中概率密度变化的瞬时公式包含哪个算子?

单选题 · mid

  • A.雅可比矩阵的行列式取对数
  • B.速度场雅可比矩阵的迹← 正确答案
  • C.损失函数的海森矩阵的迹
  • D.状态向量的欧几里得范数

答案:B。瞬时变量变换法则用的是 $-\operatorname{tr}(\partial f/\partial z)$,迹是对角线之和,代表局部体积变化率。离散流才用行列式取对数,海森矩阵和范数与本题无关。

Q4. 使用伴随方法计算梯度最主要的好处是:

单选题 · mid

  • A.放弃数值求解直接得到闭式解
  • B.无需存储每个积分步的中间状态← 正确答案
  • C.使损失函数完全不需要可微性
  • D.把 ODE 求解时间降为零成本

答案:B。伴随方法用一条逆时间 ODE 反向传递梯度,省的是中间状态的存储(O(1) 内存),B 正确。它并没有闭式解,也不免除可微性,更没有把求解时间变成零。

Q5. 离散标准化流保证变换可逆的主要手段是:

单选题 · easy

  • A.每层使用精心设计的可逆映射← 正确答案
  • B.训练时添加随机噪声正则化
  • C.把输出强行归一化到单位区间
  • D.让网络宽度大于输入维度

答案:A。离散流靠每层都是可逆函数(如仿射耦合层)来保证整体可逆。随机噪声、归一化、加宽网络都不能凭空带来可逆性,是经典干扰项。

Q6. 关于 CNF 与离散流的对比,下列说法正确的有:

多选题 · mid

  • A.CNF 内存开销与积分步数基本无关← 正确答案
  • B.离散流必须显式保存每一层状态← 正确答案
  • C.CNF 的表达力受层数限制很大
  • D.CNF 通常比同层数离散流更省内存← 正确答案

答案:ABD。CNF 用伴随方法反向求梯度,无需存每个积分步的中间态,故 A 正确;离散流要一层层存状态以便反向,B 正确;CNF 的深度概念上无限,表达力不受层数限制,C 错误;正因免存中间态,同等规模下 CNF 显著省内存,D 正确。

Q7. 关于 CNF 内存复杂度的说法,正确的是:

单选题 · hard

  • A.反向传播需要存储全部积分点
  • B.伴随方法使内存与积分步数无关← 正确答案
  • C.雅可比矩阵永远不需要被计算
  • D.内存随维度平方增长无法避免

答案:B。伴随方法沿逆时间 ODE 传播梯度,不需要保存每步激活,内存与步数无关,B 正确。A 是离散流的做法;C 错误,仍需通过自动微分计算向量-雅可比积;D 错误,随机迹估计可缓解维度开销。

Q8. 训练 CNF 时常用的数值技巧包括:

多选题 · mid

  • A.自适应步长的龙格库塔积分器← 正确答案
  • B.用随机向量估计迹来降低开销← 正确答案
  • C.固定使用最小步长保证精确
  • D.对雅可比矩阵做蒙特卡洛估计← 正确答案

答案:ABD。自适应积分器能按容差自动调步长,A 正确;Hutchinson 技巧用随机向量无偏估计迹,B、D 本质是同一件事的正确表述;固定最小步长会拖慢训练甚至累积浮点误差,C 错误。

Q9. CNF 与离散流在架构上的关键区别是:

单选题 · hard

  • A.CNF 无需可逆层,连续网络即可作速度场← 正确答案
  • B.离散流不需要任何网络参数参与训练
  • C.CNF 的变换结果完全没有解析形式
  • D.离散流必须用卷积网络来构建

答案:A。CNF 的速度场只要利普希茨连续就自动可逆,不必设计特殊可逆层,A 正确。离散流的每层同样是可学习网络,B 错误;“没有解析式”不是关键区别也不是必然,C 错误;离散流不一定用卷积,D 错误。

Q10. 关于伴随方法表述正确的是:

多选题 · hard

  • A.逆时积分需从终点初始化伴随态← 正确答案
  • B.伴随态刻画损失对轨迹点的敏感度← 正确答案
  • C.伴随方法必须保存所有中间状态
  • D.参数梯度可由伴随态积分一并求出← 正确答案

答案:ABD。伴随态在终点取 $\mathbf{a}(t_1)=\partial L/\partial z(t_1)$,再逆时积分,A 正确;$\mathbf{a}(t)$ 正是损失对轨迹点的敏感性信号,B 正确;伴随方法恰恰不需要保存中间状态,C 错误;把参数增广进状态后,反向积分可同时得到参数梯度,D 正确。