Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Coupling ↔ diagonal equivalence

A zero-kernel coupling flow and a diagonal Gaussianization flow are the same function — verified element-wise — and training is exactly what breaks the equivalence

06 — Coupling ↔ diagonal equivalence

Notebook 05 showed empirically that fit_rbig_coupling initialises every conditioner’s final kernel to zero, so each coupling acts like a diagonal RBIG marginal. Here we make the claim exact and verify it numerically:

A zero-kernel coupling flow and a diagonal Gaussianization flow are the same function. If the conditioner’s final layer has kernel W=0W = 0, its output θ(xA)=Wϕ(xA)+c=c\theta(x_A) = W\phi(x_A) + c = c is constant in xAx_A — so the coupling’s bijector no longer depends on the passive half, which is precisely a diagonal per-coordinate marginal transform.

The diagonal flow is the parametric form of RBIG; the zero-kernel coupling is a reparameterisation of it — three names (RBIG, diagonal flow, zero-kernel coupling) for one map. We confirm they agree element-wise, then show training breaks the equivalence by switching on the kernel.

What you will see

1. Two flows, identical data

fit_rbig builds a diagonal Gaussianization flow; fit_rbig_coupling builds a coupling flow with the conditioner zero-initialised. Both greedily fit the same PCA rotations and per-dimension mixtures, so by construction they should encode the same map — even though the coupling carries two conditioner MLPs per block.

diagonal flow :    212 parameters
coupling flow :  46804 parameters  (220× more — all inert at init)

The coupling flow has hundreds of times more parameters — the conditioner MLPs — but at zero-kernel init that capacity is dormant. We check that the functions agree.

2. Element-wise equality

The forward (data → latent) map is bijection.inverse. We evaluate both flows on the whole dataset and compare the pushforwards z=f(x)z = f(x) and the log-densities, per sample.

pushforward error ||z_cpl - z_diag||:  median 1.46e-04, max 5.50e-01
log-prob error |Δ log p|:              median 1.32e-04, max 1.87e-03
conditioner kernels max|W| at init: ['0e+00', '0e+00', '0e+00', '0e+00', '0e+00', '0e+00', '0e+00', '0e+00']
  -> all exactly zero: the coupling is the diagonal flow, reparameterised
<Figure size 1150x500 with 2 Axes>

The two pushforwards are a single indistinguishable point cloud, the error vectors Δz\Delta z sit on the origin (to accumulated float drift through 4 blocks), and every conditioner kernel is exactly zero. The 200×-larger coupling flow computes the same function as the tiny diagonal flow — its extra parameters do nothing until something turns them on.

3. Training breaks the equivalence

That “something” is a gradient step. We train only the coupling flow (the diagonal flow stays frozen as the reference). The optimiser pushes the conditioner kernels off zero, the couplings stop being constant-in-xAx_A, and the pushforwards pull apart.

kernels  max|W|: init ['0e+00', '0e+00', '0e+00', '0e+00', '0e+00', '0e+00', '0e+00', '0e+00']
                 -> trained ['0.03', '0.05', '0.07', '0.04', '0.09', '0.04', '0.11', '0.05']
pushforward error ||z_cpl - z_diag||:  init median 1.5e-04  -> trained median 1.8e-01
<Figure size 1150x500 with 2 Axes>

The kernels grow from exactly 0 to O(0.1)O(0.1), the pushforward error jumps by orders of magnitude, and the trained coupling’s latent visibly differs from the frozen diagonal one — it has learnt cross-coordinate structure the diagonal flow cannot represent. The equivalence held only at init, and only because the conditioner was switched off.

Recap

claimevidence
zero-kernel coupling ≡\equiv diagonal flow∥zcpl−zdiag∥\lVert z_{\rm cpl}-z_{\rm diag}\rVert median ∼10−4\sim10^{-4} at init
the equivalence is exact, not approximateconditioner kernels are literally 0
extra coupling capacity is inert at init200× more parameters, identical function
training breaks itkernels 0→O(0.1)0 \to O(0.1); error jumps orders of magnitude

This closes the loop opened in Part 4: RBIG = diagonal Gaussianization flow = zero-kernel coupling flow — one function, three parameterisations — and a coupling flow is exactly “a diagonal flow plus a conditioner you can switch on.” It is also why the RBIG warm-start of notebook 05 is so natural: you initialise the coupling at the diagonal solution and let training add only what helps.

Next up. 07 — Depth, residual coupling & stability stacks coupling layers deep, where the gradient pathologies of very deep flows appear, and looks at residual coupling and the pre-conditioning (ActNorm, Part 2) that keeps deep stacks trainable.