Learned data assimilation: what can be learned in the analysis
The taxonomy page took the model apart. This page takes the assimilation apart: the objective, its gradient, the solver, the output, and whether the answer is computed per window or learned across windows. Eleven ways to learn one of those pieces, on the same Gulf Stream QG example and the same 10-day window of SSH maps.
TL;DR
One analysis operator, eleven insides
Every type is box 2's operator: maps, masks, errors, background, covariates and forcing in; a state window and its uncertainty out. What changes is the inside, the training data it needs, and whether the output is a point, an ensemble or a density.
The training signal matters more than the network. Simulated truth (OSSE) learns the QG model's ocean; the ELBO and held-out observations learn the real one but never see unobserved scales.
Mean, mode or sample. 4D-Var returns a mode, an MSE-trained network a mean, VI a density. Benchmarks must compare the same statistic.
Teal types fail loudly: the classical cost or solver is still there to check the answer. Amber types fail silently: an unusual window gets a confident wrong field. Scoring any output with the classical 𝒥 and its innovations turns most silent failures into loud ones.
As on the other two pages. On this page \(\gvect{\nu}\) is the variational parameters; the QG viscosity does not appear. Losses \(\mathcal{L}\) are always minimised, so \(\mathcal{L}_\text{ELBO} = -\mathrm{ELBO}\).
background (prior mean of \(\vect{x}_0\)), covariates, forcing; the exogenous inputs are \(\vect{u}_k = (\vect{u}^\text{cov}, \vect{u}^\text{wind}_k)\)
weights of a learned model from the taxonomy page; weights of a learned piece of the analysis: prior, solver, gradient, initialiser, proposal, localisation
Weak-constraint 4D-Var over one window. With \(p(\vect{x} \mid \vect{y}) \propto \exp(-\mathcal{J}(\vect{x}))\), every type on this page edits this cost, its gradient, its solver, or replaces all three:
The classical solver iterates \(\vect{x}^{(i+1)} = \vect{x}^{(i)} - \gamma \mat{P} \nabla_{\vect{x}} \mathcal{J}(\vect{x}^{(i)})\) from \(\vect{x}^{(0)}\), with step size \(\gamma\), \(N \approx 50\)–\(100\) and \(\mat{P}\) built from \(\gmat{\Sigma}_x^{1/2}\). In code, the cost, the solver and the variational objective are three short functions. qg_day and QGParams are the ones defined on the taxonomy page:
Markers: today ships on main (checked 24 Oct 2026: finitevolX 831c69f, gaussx eeda235, somax 9cb19b3); today* ships, arguments sketched; user is defined on these pages; not pinned is a library whose API was not checked. Shape column letters are defined in the header.
No Gaussian variational family ships in gaussx or vardax, so LowRankGaussian is page-defined; gaussx supplies its covariance, samples and entropy.
Type
The edit
A1
an outer loop differentiates the evidence of many analyse calls with respect to the scales inside prior_cov, obs_var and model_err_var
A2
background_cost (and model_cost) → prior_net(phi, states), or qg_day → a hybrid model
A3
jax.grad(weak_4dvar_cost) → an emulator's gradient, an ensemble estimate, or gradient_net(phi, states, window)
A4
iterate body → states - solver_net(phi, gradient, memory); n_iterations=10; train through the scan
A5
initial_states = init_net(phi, window), or precondition → a learned positive-definite map
A6
analyse → analysis_net(psi, window)
A7
posterior = amortised_net(psi, window); minimise neg_elbo over many windows, or forward KL on OSSEs
A8
minimise neg_elbo over posterior for this window only
A9
start A8 from amortised_net, run a few steps
A10
replace analyse by an EnKF cycle with learned localisation and inflation
A11
alternate analyse per window with a gradient step on the weights inside qg_day through model_cost
Training signals
What a type can learn from decides where it can be used. Five signals, with what each needs and which statistic it returns:
OSSE-trained types learn the climate of the QG model: its eddy sizes, its energy, its errors. Observation-trained types learn the real ocean, but gridded SSH maps resolve little below roughly 100 km, so held-out-pixel losses cannot teach anything finer. The practical combination is to pretrain on OSSEs for the small scales and fine-tune with the ELBO or held-out observations for the large ones.
The eleven types
Each card gives the equation, the operator signature with what is learned and what it trains on, and attribute rows. The training signal is a row, as on the taxonomy page.
A1
Learned hyperparameters
replaces: hand-tuned α
Keep everything, and fit the numbers that shape \(\gmat{\Sigma}_x\), \(\gmat{\Sigma}_\eta\), \(\gmat{\Sigma}_\varepsilon\), localisation and inflation by maximising the evidence over many real windows \(w\):
The right-hand side is the Laplace approximation at the analysis \(\hat{\vect{x}}\). The cheaper alternative is to match the innovation statistics of the state-estimation page.
iny, m, σ_ε(time, height, width) ×3μ_x(height, width)α(hyper,)outx̂_0:T(time+1, height, width)learnedα(hyper,)trainreal windows, obs only(window, time, height, width) ×3
Replaces
manual tuning of Σ_x, Σ_η, Σ_ε scales, localisation radius, inflation
Signal
marginal likelihood, or innovation consistency; observations only
Output
the classical analysis with better weights
Failure
loud a bad α shows up in 2𝒥⋆/D_y and the innovations
Cost
an outer loop over many classical analyses
The DA counterpart of T1. Always worth doing first: every later type inherits α, and a learned piece trained with a wrong Σ_ε learns to compensate for it.
A2
Learned prior
replaces: the background and dynamics terms
The observation term stays; the regulariser becomes learned. Three forms, from least to most physical:
The first is a density (a flow or an energy model on windows). The second is a projection: \(g_\text{proj}\) maps a window to the nearest plausible one, as in 4DVarNet. The third is weak-constraint 4D-Var with any hybrid model from the taxonomy page as \(f(\cdot; \gvect{\theta}_\text{emu})\).
density fitting on simulated or reanalysis windows (no observations needed), or end to end with A4
Output
the minimiser of the new cost: a MAP under the learned prior
Failure
loud the cost is explicit and its value is checkable
Cost
as 4D-Var, plus the prior's gradient
The dynamical form is the important one: it keeps physics in the prior and makes every model on the taxonomy page a candidate. The projection form is expressive but carries no physics, and it is not a normalised density, so it cannot be sampled.
A3
Approximate gradient
replaces: the adjoint
Keep the cost and the solver; compute \(\nabla_{\vect{x}} \mathcal{J}\) more cheaply. With \(\mat{F}_k = \mat{J}_f(\vect{x}_{k-1})\) the tangent-linear model and \(\tilde{\mat{X}}_k \in \mathbb{R}^{D_x \times N_{\mathcal{E}}}\) ensemble anomalies:
Here \(\vect{z}_\text{ens} \in \mathbb{R}^{N_{\mathcal{E}}}\) has one entry per ensemble member and \(\mat{F}_{k \leftarrow 0}\) maps an initial perturbation to day \(k\).
emulator: step-1 trajectories with a Jacobian term; ensemble: none
Output
a point estimate, near the 4D-Var MAP if the gradient is right
Failure
silent a biased gradient converges to the wrong point and the iterations still look healthy
Cost
forward runs only (ensemble), or one network evaluation per iteration
The test for any approximate gradient: at the true minimiser it must vanish. Check it by evaluating the exact gradient once at the end; that single adjoint run turns a silent failure into a loud one.
A4
Learned solver (unrolled)
replaces: the optimiser
A network decides each update from the gradient and an internal memory \(\vect{z}_\text{mem}\). The loop is unrolled for a fixed \(N \approx 10\) iterations and trained end to end, usually together with a learned prior (A2):
MSE against simulated truth; or held-out observations on real data
Output
after end-to-end MSE training, an estimate of the posterior mean, not the minimiser of 𝒥_learned
Failure
silent the cost is no longer what is minimised, so its value does not certify the output
Cost
N ≈ 10 gradient evaluations, versus 50–100 classically
4DVarNet's core. The variational cost becomes an architecture: a good inductive bias for the network, not a probability model. Treat its output as a mean, and do not read its cost as a posterior.
A5
Warm start or learned preconditioner
replaces: the initial guess and the metric
The classical solver still decides the answer. The network only proposes where to start, or reshapes the space so fewer iterations are needed:
iny, m, σ_ε(time, height, width) ×3μ_x(height, width)α(hyper,)outx̂_0:T(time+1, height, width)learnedθ_DAinitialiser or preconditionertrain4D-Var analyses(window, time+1, height, width)
Replaces
x⁽⁰⁾ = μ_x and the plain Σ_x^{1/2} change of variables
Signal
the analyses of box 2 itself, or the iteration count
Output
the classical MAP, unchanged
Failure
loud a bad guess only costs iterations
Cost
fewer iterations; never more wrong
The safest learned DA. Its training targets are box 2 outputs, so no truth and no OSSE are needed, and its worst case is plain 4D-Var. The speed-up is bounded by how far the classical solve has to travel.
A6
Amortised point analysis
replaces: the whole solve
One forward pass from observations to state, trained across windows:
MSE on OSSEs; or held-out observations on real windows
Output
posterior mean, no uncertainty
Failure
silent an unusual window gets a confident, smooth, wrong field
Cost
one forward pass
The direct analysis of the state-estimation page. Its output can still be scored for free: evaluate the classical 𝒥 and the innovations on x̂. That check costs one model run and catches most silent failures.
A7
Amortised variational inference
replaces: the whole solve, with a density
A conditional density over the window, trained either on simulated truth (forward KL) or on real observations (ELBO):
forward KL on OSSEs (needs truth) or ELBO on real observations (needs the likelihood and a model-based prior, no truth)
Output
a density: mean and samples
Failure
silent forward KL tends to be well spread; ELBO tends to be under-dispersed
Cost
one forward pass per sample
The ELBO route is the one that trains on the real ocean without truth, because the model enters through log p(x). The Markov family is the natural choice here: it respects time and is a learned smoother.
A8
Per-window variational inference
replaces: the point estimate
Fit a Gaussian to each window's posterior directly. With \(\gvect{\xi} \sim \mathcal{N}(\vect{0}, \mat{I})\), samples are reparameterised, and the ELBO uses the classical cost because \(p(\vect{x} \mid \vect{y}) \propto \exp(-\mathcal{J}(\vect{x}))\):
As the rank grows, \(\gvect{\mu}_q\) approaches the posterior mean and \(\mat{L}_q \mat{L}_q^\top + \mat{D}_q\) the posterior covariance. With one sample at \(\gvect{\xi} = \vect{0}\), it collapses to 4D-Var.
4D-Var's point estimate and its Laplace covariance
Signal
this window's ELBO; no training set
Output
a Gaussian posterior for the window
Failure
loud the ELBO value is a direct check
Cost
4D-Var × samples per iteration
The honest reference for A7, and box 2 extended to give a density. With gaussx for the low-rank algebra and the somax adjoint, it is mostly a change of loss in code you already have.
A9
Semi-amortised inference
amortised proposal, per-window refinement
Start from an amortised answer, then take a few classical or variational steps on the actual window:
A related route is guided diffusion: learn the prior score \(g_\text{score}(\vect{x}, \tau; \gvect{\theta}_\text{DA}) \approx \nabla_{\vect{x}} \log p_\tau(\vect{x})\) from states alone, and at inference add \(\nabla_{\vect{x}} \log p(\vect{y} \mid \vect{x})\) with this window's masks to every denoising step.
proposal trained as A7; refinement uses each window's ELBO
Output
a density refined on the window
Failure
loud refinement steps that move far flag an out-of-distribution window
Cost
one pass plus N_refine ≪ N iterations
Closes the amortisation gap, and the size of the refinement is a built-in novelty detector. Guided diffusion has the same advantage for the observing system: masks change at inference without retraining.
A10
Learned filter pieces
sidebar: the sequential route
For the EnKF, keep the forecast–analysis cycle and learn its fragile parts: localisation \(\gmat{\rho}(\gvect{\theta}_\text{DA})\), inflation \(\alpha_\text{infl}(\gvect{\theta}_\text{DA})\), or the gain itself, and run the forecast with an emulator. Trained end to end through the cycle on a rollout loss:
iny, m, σ_ε(time, height, width) ×3μ_x(height, width)α(hyper,)outμ_q,0:T(time+1, height, width)learnedθ_emua model from the taxonomy pagetrainreal windows, obs only(window, time, height, width) ×3
Replaces
the need for a richer reference model
Signal
observations only; variational EM puts both steps in one ELBO
Output
a corrected model f(·; θ_emu) and analysed states
Failure
silent model and states can co-adapt: the model learns the analysis's errors
Cost
an analysis per window per EM iteration
The bridge between the two pages: it is how a correction-type hybrid (T1–T4, T7) is trained when no high-resolution truth exists. Fix Σ_η and α before starting, or the M-step can explain everything as model error.
Model type × assimilation type
Any model from the taxonomy page can sit inside any type that uses a model. A6 and A7 use a model only to make training data (OSSEs) or, for the ELBO, inside \(\log p(\vect{x})\).
● natural ◐ works, with a caveat ○ does not fit
Assimilation
Physical f
T1–T5 (classical integrator)
T6–T8 (step maps)
T9 rollout
T10 embedding
A1 hyperparameters
●
●
●
◐
◐
A2 dynamical prior
●
●
◐
○
◐
A3 approx. gradient
●
●
◐
◐
◐
A4 learned solver
●
●
◐
◐
◐
A5 warm start
●
●
●
●
●
A8 per-window VI
●
●
◐
◐
◐
A9 semi-amortised
●
●
◐
◐
◐
A10 learned filter
●
●
●
○
◐
A11 joint learning
◐
●
●
◐
◐
The caveats: T6–T8 need a trustworthy Jacobian wherever a gradient flows through them (A2–A4, A8, A9); T9 has no one-day step, so it cannot enter a weak-constraint dynamics term or cycle in a filter; T10 moves the whole problem into the embedding, with observations entering through the decoder. A11 with the physical model only calibrates θ, which is A1's job done the hard way.
What the structure implies
Score every output with the classical cost
Whatever produced \(\hat{\vect{x}}\), computing \(\mathcal{J}(\hat{\vect{x}})\), \(2 \mathcal{J}^\star / D_y\) and the innovations costs one model run. It is the cheapest guard against silent failure, and it makes the box-2 diagnostics of the state-estimation page apply to every learned type.
A learned cost is not a posterior
Once a cost is trained end to end for MSE (A2 with A4), its minimiser is no longer the point of interest and \(\exp(-\mathcal{J}_\text{learned})\) is not a calibrated density. Uncertainty then has to come from somewhere else: an ensemble of solvers, a VI head, or A8 run around the output.
The safe ladder
A1 → A5 → A8 → A9 keeps the classical machinery in charge at every step and adds learning only where it pays: tuning, speed, uncertainty, then amortisation with refinement. A4, A6 and A7 jump straight to amortisation and give up the checks; they are worth it when per-window cost is the binding constraint and the training distribution covers the windows you will see.
Learning the model needs the analysis
A11 is the only way to train a correction-type hybrid from observations alone. It inherits every weakness of its E-step, and it can let the model absorb analysis errors. Fix α first (A1), and keep the model's learned part structural (T1, T2, T4) so it cannot explain everything.
Where each type lives
Type
Hook in the stack
A1, A5, A8
the 4D-Var path (vardax) on a somax model, with gaussx for \(\gmat{\Sigma}_x^{1/2}\), low-rank covariances and log-determinants
A2
the dynamics term takes any somax model; a learned density from the flow and probabilistic libraries
A3, A10
ensemble machinery (filterax); emulators from the taxonomy page as forecast or gradient
A4, A6, A7, A9
a training loop over windows in pipekit, with the DA cycle supplying OSSE pairs
A11
an outer loop alternating the DA cycle with rollout_loss-style updates of the model's weights