Multi-round NPE targeting a single observation x_obs. Single-round npe()
spends its simulation budget across the whole prior; when only one
observation matters, most of those simulations land in regions the posterior
never visits. npe_sequential() implements truncated sequential NPE (TSNPE,
Deistler et al. 2022): after each round the prior is truncated to the
highest-probability region of the current posterior estimate, and the next
round's parameters are drawn from that truncated prior. Because every
proposal is proportional to the prior on its support, the standard NPE loss
stays valid – no importance-weight or atomic correction is needed, which is
what makes TSNPE the simplest correct sequential scheme.
Usage
npe_sequential(
prior,
simulator,
x_obs,
n_rounds = 2L,
n_simulations = 1000L,
density_estimator = c("maf", "mdn", "nsf", "linear_gaussian"),
epsilon = 1e-04,
n_truncation_samples = 5000L,
max_proposal_batches = 200L,
seed = NULL,
verbose = FALSE,
chunk_size = NULL,
...
)Arguments
- prior
An
nsbi_prior(seeprior_uniform(),prior_normal()).- simulator
A function mapping an
n x dimmatrix of parameters to ann x dmatrix of simulated data.- x_obs
The observation to target. Sequential inference concentrates simulations around the posterior for this observation.
- n_rounds
Number of rounds. Round 1 is ordinary single-round NPE.
- n_simulations
Simulation budget per round; either a scalar or a vector of length
n_rounds.- density_estimator
Passed to
npe()each round.- epsilon
Mass cut for the truncation: the proposal region is the
1 - epsilonhighest-probability region of the current posterior.- n_truncation_samples
Posterior draws used to locate the truncation threshold each round.
- max_proposal_batches
Cap on rejection-sampling batches per round.
- seed
Optional integer seed for reproducibility.
- verbose
Print per-round progress.
- chunk_size
Rows per simulator call; see nsbi_parallel. Each round's simulations run across
futureworkers when a plan is set.- ...
Passed to
npe()(estimator and training settings).
Value
An object of class c("nsbi_snpe", "nsbi_npe") with a rounds
field recording per-round budgets, acceptance rates, and thresholds.
Details
The rounds accumulate: each round's estimator is trained on all simulations
so far. The final fit is returned as an nsbi_npe (subclass nsbi_snpe)
and works with posterior(), sample() and the diagnostics, but unlike
single-round NPE it is not amortized: it is only trustworthy at (or very
near) x_obs.
Proposal draws are obtained by rejection: prior candidates are kept when
their posterior log-density clears the epsilon-quantile threshold of the
current posterior's own draws. If the posterior is much narrower than the
prior the acceptance rate falls; the round then stops after
max_proposal_batches batches and continues with the draws it has,
with a warning.
References
Deistler, Goncalves & Macke (2022), "Truncated proposals for scalable and hassle-free simulation-based inference", NeurIPS. doi:10.48550/arXiv.2210.04815
Examples
prior <- prior_normal(mean = c(0, 0), sd = 1)
simulator <- function(theta) theta + matrix(rnorm(length(theta), sd = 0.3),
nrow = nrow(theta))
fit <- npe_sequential(prior, simulator, x_obs = c(0.5, -0.5),
n_rounds = 2, n_simulations = 1000,
density_estimator = "linear_gaussian")
post <- posterior(fit, x_obs = c(0.5, -0.5))
draws <- sample(post, 1000)
