petitRADTRANS.sbi.flows.refinement#
Test-time, per-observation posterior refinement.
Free functions that sharpen the amortized posterior for one specific target
spectrum using the differentiable forward model: a flow-ELBO refinement
(refine_posterior_on_observation()) and a MAP + Laplace / Gaussian-VI
refinement (map_laplace_posterior_on_observation()). Each takes the trained
ConditionalFlowPosterior as its first
argument (posterior); the estimator exposes them as thin methods. Extracted
from flows.posterior to keep the estimator focused on amortized inference.
Functions#
|
Repeat a single (batch-1) prestacked observation |
Semi-amortized test-time refinement of the posterior for one |
|
Likelihood importance sampling on top of the amortized posterior. |
|
MAP + Laplace test-time inference for one observation (robust path). |
Module Contents#
- petitRADTRANS.sbi.flows.refinement._tile_prestacked_observation(observation: Any, n_tiles: int) Any#
Repeat a single (batch-1) prestacked observation
n_tilestimes.
- petitRADTRANS.sbi.flows.refinement.refine_posterior_on_observation(posterior, target_observation: Any, elbo_log_likelihood_fn: Callable[[jax.numpy.ndarray, Any], jax.numpy.ndarray], *, num_steps: int = 400, learning_rate: float = 0.0001, num_samples: int = 16, beta_start: float = 0.001, beta_anneal_fraction: float = 0.5, gradient_clip_norm: float = 1.0, gradient_clip_value: float = 1.0, seed: int = 0, verbose: bool = True) petitRADTRANS.sbi.flows.posterior.ConditionalFlowPosterior#
Semi-amortized test-time refinement of the posterior for one observation (flow-based ELBO variant).
Starting from the trained amortized model, optimize the single-observation tempered ELBO
- ELBO_beta(x_obs) = E_{q(theta|c)}[ beta * log p(x_obs|theta)
log q(theta|c) ]
adapting the flow while holding the encoder (hence the conditioning embedding
c = encoder(x_obs)) fixed.betais annealed soft -> 1 across the steps so the very small observational noise does not blow up the single-observation gradient early (which previously made this step diverge); a low learning rate and gradient clipping (both by global norm and by value) further stabilize it. The best beta=1 ELBO state seen during optimization is returned (not the last), so a late instability cannot degrade the result.Returns a shallow copy of this posterior whose flow is specialized to
target_observation; use it only for inference on that observation.See also
map_laplace_posterior_on_observation(), the more robust MAP + Laplace variant that sidesteps reverse-KL under-dispersion.
- petitRADTRANS.sbi.flows.refinement.importance_sampling_posterior_on_observation(posterior, target_observation: Any, standardized_residual_fn: Callable[[jax.numpy.ndarray], jax.numpy.ndarray], *, n_proposal_samples: int = 16384, forward_batch_size: int = 256, n_posterior_samples: int = 4096, seed: int = 0, verbose: bool = True) petitRADTRANS.sbi.flows.posterior.ConditionalFlowPosterior#
Likelihood importance sampling on top of the amortized posterior.
Draws proposal samples from the amortized flow conditioned on the target observation, evaluates the exact Gaussian likelihood of each through the differentiable forward model, and reweights by
log w = log L(theta) + log pi(theta) - log q(theta | x). This is the field-standard correction for amortized posteriors (Gebhard et al. 2025): unlike MAP+Laplace it cannot collapse to a degenerate covariance, and its sampling efficiencyeps = ESS / Nis a built-in trust diagnostic —epsnear 1 means the amortized posterior already matches the true one;epsnear 0 means the amortized posterior misses the true posterior mass and the importance estimate itself should not be trusted either.Weights are computed in the flow’s unconstrained (logit-of-cube) space, where the uniform-cube prior is the standard logistic density and the proposal density is the flow’s own
log_prob— both exact.Parameters#
- target_observation:
Batch-1 prestacked target observation (conditions the proposal).
- standardized_residual_fn:
Differentiable
theta_cube[param_dim] -> (n_wavelengths,)returning noise-standardized residuals(model(theta) - x_obs)/sigmafor the target; masked channels contribute 0.- n_proposal_samples:
Number of amortized proposal draws to weight.
- forward_batch_size:
Forward-model chunk size (vmapped); bounds device memory exactly like the ELBO per-batch forward passes did.
- n_posterior_samples:
Number of importance-resampled posterior draws stored on the returned estimator.
Returns#
- ConditionalFlowPosterior
A shallow copy of
posteriorwhose_fixed_cube_sampleshold the importance-resampled posterior, with the weighting diagnostics attached as_importance_sampling_diagnostics.
- petitRADTRANS.sbi.flows.refinement.map_laplace_posterior_on_observation(posterior, target_observation: Any, standardized_residual_fn: Callable[[jax.numpy.ndarray], jax.numpy.ndarray], *, num_steps: int = 600, learning_rate: float = 0.05, beta_start: float = 0.001, beta_anneal_fraction: float = 0.5, n_posterior_samples: int = 4096, gradient_clip_value: float = 10.0, eigenvalue_floor: float = 1e-06, covariance_method: str = 'laplace', vi_num_steps: int = 300, vi_learning_rate: float = 0.01, vi_num_samples: int = 32, vi_freeze_mean: bool = True, vi_beta: float = 1.0, seed: int = 0, verbose: bool = True) petitRADTRANS.sbi.flows.posterior.ConditionalFlowPosterior#
MAP + Laplace test-time inference for one observation (robust path).
Optimizes the (beta-annealed -> 1) log-posterior in the unconstrained logit space
u(theta_cube = sigmoid(u), uniform-cube prior -> logistic prior onu) to the MAP, initialized from the amortized posterior mean for the target, then forms a Gauss-Newton Laplace covariance from the forward-model Jacobian and the prior curvature:precision Lambda = J^T J + diag(2 c (1 - c)), J = d r / d u
where
rare the noise-standardized residuals. Posterior samples are drawn asu ~ N(u*, Lambda^-1)and mapped through the sigmoid. This gives the correct location (MAP) and correctly-scaled, per-direction local widths (tight where well-constrained, e.g. planet radius; moderate on degenerate directions), sidestepping the reverse-KL under-dispersion of the flow ELBO.Returns a shallow copy of this posterior carrying the Laplace cube samples; its
sample_posterior()returns those samples, so the existing inference/predictive pipeline can consume it unchanged. Use it only for inference ontarget_observation.Parameters#
- target_observation:
Batch-1 prestacked target observation (used only for the amortized MAP initialization via the encoder).
- standardized_residual_fn:
Differentiable
(theta_cube[param_dim]) -> (n_wavelengths,)returning noise-standardized residuals(model(theta) - x_obs)/sigmafor the target. Masked channels should contribute 0.