Flow-Based Generative Models · UFRJ · 2026.2
U1.T2 ended on a residual stack with a step size, and on one question:
What does \(\log\lvert\det J\rvert\) become in continuous time?
Today pays the first half of that debt, and leaves the question where it is:
| Today | Not today |
|---|---|
| residual steps \(\to\) an ODE, honestly | the log-determinant |
| the flow exists, is unique, is invertible | any density |
| how to differentiate through a solver | any divergence |
| Family | Density | Sampling | Trick, and its price |
|---|---|---|---|
| NICE / RealNVP | exact, triangular | direct | coupling; depth |
| Glow | exact | direct | mixing, multi-scale |
| MAF | parallel | sequential | AR, data side |
| IAF | sequential | parallel | AR, source side |
| Residual flow | direct; series log-det | iterative | contraction, traces |
Every row pays with an architectural constraint: a coupling, a mixing layer, an autoregressive (AR) ordering, a contraction. What if depth \(\to \infty\)?
Put \(h = 1/K\) in front of each residual branch, and let the branch depend on \(t_k = k h\):
\[ x_{k+1} = x_k + h\, f(t_k, x_k), \qquad k = 0, \dots, K-1 . \]
This is forward Euler for \(\dot x = f(t, x)\), \(x(0) = x_0\), \(t \in [0, 1]\) — the course’s f(t, x), time first. U1.T2 measured that the stack’s output converges as \(h \to 0\) (error halves when \(h\) halves).
What U1.T2 did not say: what the limit is; when it exists; whether it is unique; whether \(x_0 \mapsto x(1)\) is invertible; how to differentiate through it. That is today.
Let \(f_\theta \colon [0,1] \times \mathbb{R}^{d} \to \mathbb{R}^{d}\) be a network with parameters \(\theta \in \mathbb{R}^{p}\), and suppose \[ \dot x(t) = f_\theta\big(t, x(t)\big), \qquad x(0) = x_0 \] has a unique solution on \([0, 1]\), and so does the same equation started from any \(x(t_0) = x\) with \(t_0 \in [0, 1]\) (the well-posedness block says when). The flow map is \(\psi_t(x_0) = x(t)\), with \(\psi_0 = \mathrm{id}\); the Neural ODE is \(x_0 \mapsto \psi_1(x_0)\). For \(t_0 < t_1\), \(\psi_{t_0 \to t_1}\) carries the state at \(t_0\) to the state at \(t_1\).
\(d = 1\), \(f_\theta(t, x) = -\theta x\), \(\theta > 0\). Then \(\dot x = -\theta x\), \(x(0) = x_0\) gives \(x(t) = x_0 e^{-\theta t}\): \[ \psi_t(x_0) = e^{-\theta t} x_0, \qquad \psi_0 = \mathrm{id}, \qquad \psi_1(x_0) = e^{-\theta} x_0 . \] The \(K\)-block Euler stack computes \((1 - \theta/K)^{K} x_0 \to e^{-\theta} x_0\).
Keep this example: in the adjoint block its gradient is computed twice, once directly and once by the adjoint.
The Neural ODE with one depth-independent \(\theta\) is the \(h \to 0\) limit of the Euler stack in which every block evaluates the same \(f_\theta\). It is not the literal continuum limit of a generic ResNet: a ResNet has its own \(\theta_k\) per block, so its natural continuum object carries a depth-dependent path \(t \mapsto \theta(t)\), not a single \(\theta\) (Massaroli et al. 2020, sec. 3).
The ODE limit is a disciplined motivation for the model, not an identity between arbitrary finite ResNets and autonomous-parameter ODEs.
Let \(f \colon [0,1] \times \mathbb{R}^{d} \to \mathbb{R}^{d}\) be continuous.
Local. If \(f\) is locally Lipschitz in \(x\), uniformly in \(t\) — on every bounded set \(B\), \(\lVert f(t, x) - f(t, y)\rVert \le L_B \lVert x - y \rVert\) for all \(t\) and \(x, y \in B\) — then for every \(x_0\) there is \(\delta > 0\) and a unique \(C^{1}\) solution on \([0, \delta]\).
Global — the course’s hypothesis. If \(f\) is globally Lipschitz in \(x\), uniformly in \(t\), then for every \(x_0\) the solution exists, is unique and is \(C^{1}\) on all of \([0, 1]\). (Locally Lipschitz + linear growth also suffices.)
Panel (a) failed the Lipschitz hypothesis at \(0\); panel (b) failed linear growth. One hypothesis per failure.
Write the problem as a fixed-point equation \(x = Tx\) (the map \(T\) is in the table), and let \(L = \operatorname{Lip}(f)\) in \(x\):
| There — PS1.5 (U1.T2) | Here — Picard–Lindelöf | |
|---|---|---|
| space | \(\mathbb{R}^{d}\), Euclidean norm | \(C([0,1]; \mathbb{R}^{d})\), weighted norm \(\sup_t e^{-2Lt}\lVert x(t)\rVert\) |
| map | \(T_z(x) = z - g(x)\) | \((Tx)(t) = x_0 + \int_0^{t} f(\tau, x(\tau))\,\mathrm{d}\tau\) |
| contraction | constant \(\operatorname{Lip}(g) < 1\) | constant \(\tfrac{1}{2}\), bought by the weight \(e^{-2Lt}\) |
| what buys it | an architectural condition | any finite \(L\) — nothing asked of its size |
The line to remember: the residual block needed \(L < 1\); the flow needs \(L < \infty\).
Tier 1 — well-posedness. \(f_\theta\) continuous in \((t, x)\), globally Lipschitz in \(x\) uniformly in \(t\). Enough for existence, uniqueness, invertibility of \(\psi_t\).
Tier 2 — differential identities. In addition, \(f_\theta\) is \(C^{1}\) in \(x\) and in \(\theta\) with continuous partials. Enough for the adjoint (today) and for the divergence identities (U2.T2). Then \(\psi_t\) is \(C^{1}\) in \(x_0\) with invertible Jacobian, and \(t \mapsto J_{\psi_t}(x_0)\) is continuous.
Course models use tanh / softplus and satisfy both tiers. ReLU is Lipschitz and not \(C^{1}\): Tier 1 only. The two roles are never conflated in this unit.
Under Tier 1, for \(t_0 < t_1\) the map \(\psi_{t_0 \to t_1}\) is a bijection of \(\mathbb{R}^{d}\), and its inverse is obtained by integrating the same equation backward in time from \(t_1\) to \(t_0\); both directions are continuous (Grönwall), so it is a homeomorphism. Under Tier 2 it is a diffeomorphism.
Proof in one line each. Injective: two solutions meeting at time \(t_1\) coincide (uniqueness, run backward). Surjective: solve backward from any \(y\) at \(t_1\). Continuous: Grönwall bounds the spread of two solutions by \(e^{L}\) times their initial spread, in both directions.
Let \(f\) satisfy Tier 1 and \(\psi_t\) be its flow.
(i) \(d = 1\): order is preserved. \(x_0 < y_0 \Rightarrow \psi_t(x_0) < \psi_t(y_0)\) for all \(t\). So \(\psi_1\) is strictly increasing, and \(x \mapsto -x\) is not a 1-D regular flow map.
(ii) Any \(d\): orientation is preserved. Under Tier 2, \(\det J_{\psi_t}(x) > 0\) for all \(x, t\): continuous in \(t\), equal to \(1\) at \(t = 0\), never zero. So \(x \mapsto -x\) (determinant \((-1)^{d}\)) is not a regular flow map in odd \(d\); in \(d = 2\) it is a rotation.
(iii) Orientation is necessary, not a characterization; finer claims are dimension-specific and not made here.
topology-obstruction-argument. That one is about supports under a homeomorphism — still true here, unchanged, because \(\psi_1\) is a homeomorphism. Today’s is about which maps arise as flows at all.
| Family | Density | Sampling | Trick, and its price |
|---|---|---|---|
| NICE / RealNVP | exact, triangular | direct | coupling; depth |
| Glow | exact | direct | mixing, multi-scale |
| MAF | parallel | sequential | AR, data side |
| IAF | sequential | parallel | AR, source side |
| Residual flow | direct; series log-det | iterative | contraction, traces |
| Neural ODE | inverse: ODE solve / NFE; \(\log\lvert\det J\rvert\) ??? | ODE solve / NFE | no inverse layer; Lipschitz field |
Fix \(x_0\); \(x\) solves \(\dot x = f_\theta(t, x)\) under Tier 2; the loss reads the endpoint:
\[ \ell(\theta) = L\big(x(1)\big), \qquad L \in C^{1}. \qquad\text{Wanted: } \frac{\mathrm{d}\ell}{\mathrm{d}\theta} \in \mathbb{R}^{1 \times p}. \]
For \(F = f_K \circ \cdots \circ f_1\) (\(K\) maps), \(x^{k} = f_k(x^{k-1})\), \(x^{0} = x\), and a cotangent \(v^{\top}\) on the output: \[ \begin{aligned} v_K^{\top} &= v^{\top}, \qquad v_{k-1}^{\top} = v_k^{\top} J_{f_k}(x^{k-1}) \;\; (k = K, \dots, 1), \\ v_0^{\top} &= v^{\top} J_F(x). \end{aligned} \] Each step is a vector–Jacobian product (VJP): about one \(f_k\)-evaluation, no Jacobian formed.
Backprop pushes a cotangent backward through composed maps. The adjoint pushes a cotangent backward through continuously composed maps.
Let the layers be Euler steps, \(f_k(x) = x + h f(t_{k-1}, x)\), so \(J_{f_k} = I + h\,\partial f/\partial x\): \[ v_{k-1}^{\top} = v_k^{\top} + h\, v_k^{\top}\, \frac{\partial f}{\partial x}(t_{k-1}, x_{k-1}) \quad\xrightarrow{\;h \to 0\;}\quad \dot a^{\top} = -\,a^{\top}\, \frac{\partial f}{\partial x}. \]
The adjoint state is the running VJP. Whether the recursion is exactly the discrete adjoint is PS2.1(g).
Fix \(\theta_0\). For any \(C^{1}\) function \(a \colon [0,1] \to \mathbb{R}^{d}\), chosen once as a function of \(t\) alone:
\[ \mathcal{L}(\theta) = \ell(\theta) - \int_0^{1} a^{\top}(t)\,\big[\dot x(t) - f_\theta\big(t, x(t)\big)\big]\,\mathrm{d}t . \]
The bracket is identically zero, because \(x\) solves the equation — for every \(\theta\).
So \(\mathcal{L} = \ell\) as functions of \(\theta\), and \(\dfrac{\mathrm{d}\mathcal{L}}{\mathrm{d}\theta} = \dfrac{\mathrm{d}\ell}{\mathrm{d}\theta}\), whatever \(a\) is. \(a\) is free. We will spend it.
\[ \int_0^{1} a^{\top}\dot x\,\mathrm{d}t = a^{\top}(1)\,x(1) - a^{\top}(0)\,x(0) - \int_0^{1} \dot a^{\top} x\,\mathrm{d}t . \]
Stated, not performed: boundary terms plus a sign flip. Check it — that is PS2.1(b). With it, \[ \mathcal{L}(\theta) = L\big(x(1)\big) - a^{\top}(1)\,x(1) + a^{\top}(0)\,x_0 + \int_0^{1} \Big[\dot a^{\top} x + a^{\top} f_\theta(t, x)\Big]\mathrm{d}t . \]
Write \(S(t) = \mathrm{d}x(t)/\mathrm{d}\theta \in \mathbb{R}^{d \times p}\) (exists and is continuous under Tier 2), with \(S(0) = 0\) because \(x_0\) does not depend on \(\theta\). Let \(A = \partial f_\theta/\partial x\), \(B = \partial f_\theta/\partial\theta\), both along the trajectory.
\[ \begin{aligned} \frac{\mathrm{d}\mathcal{L}}{\mathrm{d}\theta} &= \underbrace{\Big[\frac{\partial L}{\partial x}\big(x(1)\big) - a^{\top}(1)\Big] S(1)} _{\text{multiplies the unknown } S(1)} + \underbrace{\int_0^{1} \Big[\dot a^{\top} + a^{\top} A\Big] S\,\mathrm{d}t}_{\text{multiplies the unknown } S(t)} \\ &\quad + \underbrace{\int_0^{1} a^{\top} B\,\mathrm{d}t}_{\text{no sensitivity at all}} \end{aligned} \]
Why are we allowed to choose \(a\)? Because Step 1 holds for every fixed \(a\). So choose the one that annihilates both sensitivity groups:
\[ \dot a^{\top}(t) = -\,a^{\top}(t)\, \frac{\partial f_\theta}{\partial x}\big(t, x(t)\big), \qquad a^{\top}(1) = \frac{\partial L}{\partial x}\big(x(1)\big). \]
A linear final-value problem, solved backward from \(t = 1\); it exists, is unique and is \(C^{1}\) by Picard–Lindelöf (continuous coefficient matrix). With this \(a\), both unknown groups vanish whatever \(S\) is.
A free choice, spent wisely — the same proof taste as the projection Lemma’s session, and no formal connection claimed.
Under Tier 2, with \(x_0\) independent of \(\theta\) and \(\ell = L(x(1))\), \(L \in C^{1}\): \[ \begin{aligned} \frac{\mathrm{d}\ell}{\mathrm{d}\theta} &= \int_0^{1} a^{\top}(t)\, \frac{\partial f_\theta}{\partial \theta}\big(t, x(t)\big)\,\mathrm{d}t, \\ \dot a^{\top} &= -\,a^{\top}\,\frac{\partial f_\theta}{\partial x}, \qquad a^{\top}(1) = \frac{\partial L}{\partial x}\big(x(1)\big). \end{aligned} \] Moreover \(a^{\top}(t) = \mathrm{d}\ell/\mathrm{d}x(t)\): the sensitivity of the loss to the state at time \(t\) — the running VJP (Chen et al. 2018, App. B).
Named, boxed, and on the right board for the rest of the session. The full gap-free derivation is Box U2.T1-3 of the notes; the gaps are PS2.1.
Add one state, the parameter adjoint \(a_\theta(t) \in \mathbb{R}^{p}\): \[ \dot a_\theta^{\top} = -\,a^{\top}\,\frac{\partial f_\theta}{\partial\theta}\big(t, x(t)\big), \qquad a_\theta(1) = 0 . \]
Recipe (Chen et al. 2018, Alg. 1): solve \((x, a, a_\theta)\), dimension \(2d + p\), backward from \(t = 1\) to \(0\), from \(\big(x(1),\; \partial L/\partial x(x(1))^{\top},\; 0\big)\) with dynamics \(\big(f_\theta,\; -A^{\top} a,\; -B^{\top} a\big)\); read \[ \frac{\mathrm{d}\ell}{\mathrm{d}\theta} = a_\theta(0)^{\top}. \]
\(x(t)\) is reconstructed backward beside \(a\), not stored. Why \(a_\theta(0)\) equals the boxed integral is PS2.1(e).
\(f_\theta(t, x) = -\theta x\) on \(\mathbb{R}\), \(x(0) = x_0\), \(L(x) = \tfrac{1}{2} x^{2}\).
Directly. \(x(1) = x_0 e^{-\theta}\), so \(\ell = \tfrac{1}{2} x_0^{2} e^{-2\theta}\) and \(\mathrm{d}\ell/\mathrm{d}\theta = -x_0^{2} e^{-2\theta}\).
By the adjoint. \(\partial f/\partial x = -\theta\): \(\dot a = \theta a\), \(a(1) = x_0 e^{-\theta}\), so \(a(t) = x_0 e^{\theta(t-2)}\). And \(\partial f/\partial\theta = -x_0 e^{-\theta t}\): \[ \int_0^{1} a\,\frac{\partial f}{\partial\theta}\,\mathrm{d}t = -x_0^{2}\int_0^{1} e^{\theta(t-2)} e^{-\theta t}\,\mathrm{d}t = -x_0^{2} e^{-2\theta}. \quad\checkmark \]
And \(a(t) = \mathrm{d}\ell/\mathrm{d}x(t)\): \(\ell = \tfrac{1}{2} x(t)^{2} e^{-2\theta(1-t)}\) has derivative \(x(t) e^{-2\theta(1-t)} = x_0 e^{\theta(t-2)}\). The adjoint is the running sensitivity.
For a fixed number of requested output times, the continuous adjoint stores \(x(1)\), \(a\), \(a_\theta\) and the solver’s current step: \(O(1)\) state with respect to the number of solver steps. Direct backprop stores every intermediate state the solver produced.
The price, both halves:
For \(\ell = L(x(1)) + \int_0^{1} l(t, x(t), \theta)\,\mathrm{d}t\), \(l \in C^{1}\): \[ \dot a^{\top} = -\,a^{\top}\frac{\partial f_\theta}{\partial x} - \frac{\partial l}{\partial x}, \qquad \frac{\mathrm{d}\ell}{\mathrm{d}\theta} = \int_0^{1}\Big[a^{\top}\frac{\partial f_\theta}{\partial\theta} + \frac{\partial l}{\partial\theta}\Big]\mathrm{d}t . \]
Proposition 1 of Massaroli et al. (2020) proves the case \(l = l(t, x)\), with no explicit \(\theta\); the direct \(\partial l/\partial\theta\) term is what appears when the integrand depends on the parameters — a regularizer on the learned field itself (U2.T2 meets one). “Integral loss” is not merely an extra state derivative.
| Memory | Compute | Correctness | |
|---|---|---|---|
| Direct backprop through the solver (discretize \(\to\) optimize) | every stored solver state; grows with the steps | forward solve + one reverse sweep of VJPs | for a fixed-step solver: the exact gradient of the executed discrete map |
| Continuous adjoint (optimize \(\to\) discretize) | \(O(1)\) in the steps, at a fixed number of requested output times | a second solve, dimension \(2d + p\), each RHS call an \(f_\theta\) plus VJPs | an approximation of the exact-solution gradient; two discretizations; reconstruction can drift |
Discretize, then optimize. A fixed-step solver computes a specific composition of arithmetic; autodiff differentiates that. Exact for the function the computer evaluated — not for the exact solution. For an adaptive solver the step controller’s decisions are treated as constants: a statement about the executed trace, locally valid, not globally smooth.
Optimize, then discretize. Derive the gradient of the exact solution’s loss (the theorem), then discretize the adjoint equation. Close to the true gradient when both solves are accurate — and not the gradient of anything the forward solver computed.
Neither is “the correct one”: exact for the wrong function, or approximate for the right one. Which is better is empirical — U2.L1 asks it with a table.
RK4 is the fourth-order Runge–Kutta solver; \(\varepsilon = 10^{-4}\) is injected at \(t = 1\).
Libraries, stated carefully: torchdiffeq (Chen 2018) offers the continuous adjoint as odeint_adjoint. Diffrax (Kidger 2021) makes recursive checkpointing its default and offers the continuous adjoint as a contrast — the contrast U2.L1 uses.
None of these is a theorem. Each is an engineering choice with a bill. Beyond the course: (Kidger 2022, sec. 5.1).
In U2.L1 you produce the memory-against-NFE plot yourselves, on a small classifier where nothing hurts yet, and compare it to this schematic. The data is yours to make.
Setting: \(\dot x = f_\theta(t, x)\), \(x(0) = x_0\), \(\ell = L(x(1))\), \(f_\theta\) continuously differentiable, Lipschitz in \(x\).
| Left board | Right board | Top right |
|---|---|---|
| the two costs, v2 annotated: inverse resolved, runtime ODE solve / NFE, log-determinant ??? — circled | the adjoint sensitivity theorem, boxed; PS2.1 (a)–(g) with their G-numbers | What does \(\log\lvert\det J\rvert\) become in continuous time? — not erased |
We can now build continuous-depth invertible maps and differentiate them without storing every solver step. What we cannot yet do is account for their density change cheaply. The lab measures the numerical bill; U2.T2 finds out what \(\log\lvert\det J\rvert\) became.
| On the board | Status |
|---|---|
| Residual steps \(\to\) an ODE | Made precise, with the honest caveat |
| Existence, uniqueness | Yes, under a Lipschitz field — two tiers recorded |
| Invertibility | Structurally automatic; computationally an ODE solve — orientation preserved |
| Differentiating through a solver | The adjoint sensitivity theorem — gaps G1–G3 = PS2.1 |
| \(\log\lvert\det J\rvert\) in continuous time | Open. U2.T2 |
Next session: the lab (U2.L1), solvers and adjoints in practice. The theory session after it (U2.T2) opens on the circled cell.