Compositional probabilistic inference algorithms.
Every method runs a probabilistic program as a savepoint handler: SMC
(foerster.smc) for the particle methods — smc-infer,
importance-sampling, pimh-infer, pgibbs-infer, pgas-infer, ipmcmc-infer,
bbvi-infer and kernel-infer with a PInferenceKernel — and replay plus
accept over traces (foerster.trace) for the Markov-chain kernels.
Pure inference (:world-policy :fresh, the default) runs in fresh worlds;
:world-policy :fork in canonical forks of the caller's world (see
in-canonical-worlds). Particle measures hold Samples (result, trace,
and a canonical particle's world descriptor).
All functions return Spin<EmpiricalMeasure> for composability; post-processing is measure-centric (query, predict).
Compositional probabilistic inference algorithms. Every method runs a probabilistic program as a savepoint handler: SMC (`foerster.smc`) for the particle methods — smc-infer, importance-sampling, pimh-infer, pgibbs-infer, pgas-infer, ipmcmc-infer, bbvi-infer and kernel-infer with a PInferenceKernel — and replay plus accept over traces (`foerster.trace`) for the Markov-chain kernels. Pure inference (`:world-policy :fresh`, the default) runs in fresh worlds; `:world-policy :fork` in canonical forks of the caller's world (see `in-canonical-worlds`). Particle measures hold `Sample`s (result, trace, and a canonical particle's world descriptor). All functions return Spin<EmpiricalMeasure> for composability; post-processing is measure-centric (query, predict).
(bbvi-infer model-task num-particles num-iterations & [opts])Black Box Variational Inference (Ranganath et al., AISTATS 2014).
Learns a mean-field q(z) = Π_addr q_addr by stochastic ascent on the ELBO
with the score-function estimator and control variates: num-iterations
updates, each from num-particles programs that sample latents from q
and weight by p(x, y)/q(x). Each site's q starts as the prior it has when
first reached and from then on moves by gradient only: mean-field, it
does not follow a prior that depends on other latents.
Args: model-task, num-particles, num-iterations opts: :base-lr (1.0) — step size at iteration t is base-lr / (t+1)^robbins-monro :robbins-monro (0.0) :adagrad (true) — true: AdaGrad, γ ∈ (0,1): RMSprop with decay γ, false: plain steps :executor
Returns: Spin<EmpiricalMeasure> — num-particles importance-weighted
samples from the final q (with 0 iterations: from the priors); the learned
q is under :variational-dists (see get-variational-dists).
Black Box Variational Inference (Ranganath et al., AISTATS 2014).
Learns a mean-field q(z) = Π_addr q_addr by stochastic ascent on the ELBO
with the score-function estimator and control variates: `num-iterations`
updates, each from `num-particles` programs that sample latents from q
and weight by p(x, y)/q(x). Each site's q starts as the prior it has when
first reached and from then on moves by gradient only: mean-field, it
does not follow a prior that depends on other latents.
Args:
model-task, num-particles, num-iterations
opts: :base-lr (1.0) — step size at iteration t is
base-lr / (t+1)^robbins-monro
:robbins-monro (0.0)
:adagrad (true) — true: AdaGrad, γ ∈ (0,1): RMSprop with decay γ,
false: plain steps
:executor
Returns: Spin<EmpiricalMeasure> — `num-particles` importance-weighted
samples from the final q (with 0 iterations: from the priors); the learned
q is under `:variational-dists` (see `get-variational-dists`).(conditional model opts)Nested inference: a spin resolving the posterior of model's value under
opts (as for infer) as a distribution — a categorical over the values
the inner inference found, weighted (Anglican's conditional). The outer
program samples from it, or observes against it:
(let [guess (await (infer/conditional (inner-model x) {:method :enumerate}))] (sample guess :id :their-guess))
The inner inference runs in fresh worlds of its own. Under exact
enumeration the distribution is exact; otherwise it is the inner measure,
so it has as many atoms as distinct values. Memoize it (process/mem) when
the outer program asks the same question repeatedly.
Nested inference: a spin resolving the posterior of `model`'s value under
`opts` (as for `infer`) as a distribution — a categorical over the values
the inner inference found, weighted (Anglican's `conditional`). The outer
program samples from it, or observes against it:
(let [guess (await (infer/conditional (inner-model x) {:method :enumerate}))]
(sample guess :id :their-guess))
The inner inference runs in fresh worlds of its own. Under exact
enumeration the distribution is exact; otherwise it is the inner measure,
so it has as many atoms as distinct values. Memoize it (`process/mem`) when
the outer program asks the same question repeatedly.(get-variational-dists measure)The learned {address -> distribution} of a bbvi-infer result.
The learned {address -> distribution} of a `bbvi-infer` result.
(importance-sampling model-task num-samples & [opts])Importance sampling: num-samples runs of model-task, each weighted by
its observations, never resampled (savepoint SMC with
:resample-threshold 0). Options and result as for smc-infer.
Importance sampling: `num-samples` runs of `model-task`, each weighted by its observations, never resampled (savepoint SMC with `:resample-threshold` 0). Options and result as for `smc-infer`.
(infer model
{:keys [method particles iterations chains burn step-size kernel]
:as opts})Run model under the inference method (:method opts) — one call shape
for every method, as Anglican's doquery:
(infer/infer (model) {:method :smc :particles 1000}) (infer/infer (model) {:method :mh :iterations 4000 :chains 4 :burn 1000}) (infer/infer (model) {:method :pmmh :particles 100 :iterations 2000 :params #{:drift}})
Methods and their sizes:
:enumerate (exact; finite supports only,
:max-branches)
:importance :smc :tempered :particles
:pimh :pgibbs :pgas :ipmcmc :bbvi :particles :iterations
:mh :rmh :nuts :iterations per chain, :chains (default
4), :burn, :step-size (:rmh); every
draw after :burn is kept; :nuts adapts
during :burn (block sites)
:kernel :kernel (a foerster.kernel kernel)
and :chains or :particles
:pmmh :particles per SMC, :iterations,
:params (and smc2/pmmh options)
The other options go to the method (see its function). Returns a spin
resolving the measure.
Run `model` under the inference method `(:method opts)` — one call shape
for every method, as Anglican's `doquery`:
(infer/infer (model) {:method :smc :particles 1000})
(infer/infer (model) {:method :mh :iterations 4000 :chains 4 :burn 1000})
(infer/infer (model) {:method :pmmh :particles 100 :iterations 2000
:params #{:drift}})
Methods and their sizes:
:enumerate (exact; finite supports only,
:max-branches)
:importance :smc :tempered :particles
:pimh :pgibbs :pgas :ipmcmc :bbvi :particles :iterations
:mh :rmh :nuts :iterations per chain, :chains (default
4), :burn, :step-size (:rmh); every
draw after :burn is kept; :nuts adapts
during :burn (block sites)
:kernel :kernel (a `foerster.kernel` kernel)
and :chains or :particles
:pmmh :particles per SMC, :iterations,
:params (and `smc2/pmmh` options)
The other options go to the method (see its function). Returns a spin
resolving the measure.(ipmcmc-infer model-task num-particles num-iterations & [opts])Interacting Particle MCMC inference.
Runs M nodes in parallel, where M_c nodes run conditional SMC (with retained particles) and M_s nodes run plain SMC. After each sweep, performs Gibbs updates on which nodes become CSMC based on marginal likelihood estimates.
This creates 'interaction' between parallel chains: nodes with higher log-Z are more likely to have their particles retained in future sweeps.
Algorithm:
Args: model-task - Spin representing probabilistic program num-particles - Number of particles per sweep (per node) num-iterations - Number of IPMCMC iterations opts - Optional map with: :num-nodes - Total number of nodes (default 8) :num-csmc-nodes - Number of CSMC nodes (default num-nodes/2) :executor - Shared executor :all-particles? - Return all particles or one per node (default true)
Returns: Spin<EmpiricalMeasure>
Reference: Rainforth et al., 'Interacting Particle Markov Chain Monte Carlo', ICML 2016
Interacting Particle MCMC inference.
Runs M nodes in parallel, where M_c nodes run conditional SMC (with retained
particles) and M_s nodes run plain SMC. After each sweep, performs Gibbs
updates on which nodes become CSMC based on marginal likelihood estimates.
This creates 'interaction' between parallel chains: nodes with higher log-Z
are more likely to have their particles retained in future sweeps.
Algorithm:
1. Initialize: Run SMC on all nodes
2. For each iteration:
a. Run CSMC on M_c nodes (with retained particles from previous sweep)
b. Run SMC on M_s nodes (fresh)
c. Collect log-Z estimates from each node
d. Gibbs update: sample which nodes become CSMC for next sweep
e. Extract retained particles for selected CSMC nodes
3. Output: Weighted samples from all nodes with Rao-Blackwellized weights
Args:
model-task - Spin representing probabilistic program
num-particles - Number of particles per sweep (per node)
num-iterations - Number of IPMCMC iterations
opts - Optional map with:
:num-nodes - Total number of nodes (default 8)
:num-csmc-nodes - Number of CSMC nodes (default num-nodes/2)
:executor - Shared executor
:all-particles? - Return all particles or one per node (default true)
Returns: Spin<EmpiricalMeasure>
Reference:
Rainforth et al., 'Interacting Particle Markov Chain Monte Carlo', ICML 2016(kernel-infer model-task kernel num-particles & [opts])Run inference with a kernel.
Markov-chain kernels (single-site-mh-kernel, random-walk-mh-kernel,
block-gibbs-kernel, hmc-kernel) run num-particles independent chains.
Any other PInferenceKernel runs savepoint SMC whose latent sites take the
value the kernel's step gives (the prior kernel: a draw from the prior).
Args:
Returns: Spin<EmpiricalMeasure>
Examples: ;; Importance sampling with prior kernel (spin (let [model (coin-flip-model) measure (await (kernel-infer model (prior-kernel) 100 {:barrier-policy :none}))] (query measure identity)))
Run inference with a kernel.
Markov-chain kernels (`single-site-mh-kernel`, `random-walk-mh-kernel`,
`block-gibbs-kernel`, `hmc-kernel`) run `num-particles` independent chains.
Any other PInferenceKernel runs savepoint SMC whose latent sites take the
value the kernel's `step` gives (the prior kernel: a draw from the prior).
Args:
- model-task: Spin (from model function) - Probabilistic program to infer
- kernel: a kernel (e.g., prior-kernel, single-site-mh-kernel)
- num-particles: Number of particles (chains)
- opts: Optional map with:
- :barrier-policy - :every-observe (default, SMC) | :none (importance
sampling)
- :resample-threshold - ESS threshold (default 0.5)
- :executor - Shared executor for all particles
- :world-policy - :fresh (default) for pure inference, or :fork to
execute each particle in a frozen canonical Yggdrasil world that is
discarded after the final particle values are captured
- :world-opts - Optional :systems/:rights/:snapshots policy forwarded to
canonical particle forks; lifecycle fields are owned by inference
Returns: Spin<EmpiricalMeasure>
Examples:
;; Importance sampling with prior kernel
(spin
(let [model (coin-flip-model)
measure (await (kernel-infer model (prior-kernel) 100
{:barrier-policy :none}))]
(query measure identity)))(pgas-infer model-task num-particles num-iterations & [opts])Particle Gibbs with Ancestor Sampling (Lindsten et al. 2014).
Like pgibbs-infer, but at every barrier the retained particle redraws
which particle's past it continues from, with weights
w_i · p(retained future | particle i's past) computed by re-running each
particle's future on the retained values. Improves mixing on state-space
models; costs a forward re-run per particle per barrier.
Returns: Spin<EmpiricalMeasure> of every sweep's particles, each sweep normalized to total weight one.
Particle Gibbs with Ancestor Sampling (Lindsten et al. 2014). Like `pgibbs-infer`, but at every barrier the retained particle redraws which particle's past it continues from, with weights w_i · p(retained future | particle i's past) computed by re-running each particle's future on the retained values. Improves mixing on state-space models; costs a forward re-run per particle per barrier. Returns: Spin<EmpiricalMeasure> of every sweep's particles, each sweep normalized to total weight one.
(pgibbs-infer model-task num-particles num-iterations & [opts])Particle Gibbs (conditional SMC, Andrieu et al. 2010).
Args: model-task, num-particles (per sweep, including the retained one), num-iterations (sweeps) opts: :executor
Returns: Spin<EmpiricalMeasure> of every sweep's particles, each sweep normalized to total weight one.
Particle Gibbs (conditional SMC, Andrieu et al. 2010). Args: model-task, num-particles (per sweep, including the retained one), num-iterations (sweeps) opts: :executor Returns: Spin<EmpiricalMeasure> of every sweep's particles, each sweep normalized to total weight one.
(pimh-infer model-task num-particles num-iterations & [opts])Particle Independent Metropolis-Hastings (Andrieu et al. 2010).
Each iteration proposes a fresh SMC sweep and accepts it with probability min(1, Ẑ_new / Ẑ_current); the current sweep's particles, normalized, are emitted every iteration.
Args: model-task, num-particles (per sweep), num-iterations opts: :executor, :resample-threshold
Returns: Spin<EmpiricalMeasure>
Particle Independent Metropolis-Hastings (Andrieu et al. 2010). Each iteration proposes a fresh SMC sweep and accepts it with probability min(1, Ẑ_new / Ẑ_current); the current sweep's particles, normalized, are emitted every iteration. Args: model-task, num-particles (per sweep), num-iterations opts: :executor, :resample-threshold Returns: Spin<EmpiricalMeasure>
(predict measure pred-fn num-samples)num-samples draws from measure, resampled by weight, each passed to
pred-fn — which gets the particle (a Sample, or a context), so
m/get-value reads its program value and m/get-trace its trace.
`num-samples` draws from `measure`, resampled by weight, each passed to `pred-fn` — which gets the particle (a `Sample`, or a context), so `m/get-value` reads its program value and `m/get-trace` its trace.
(predictive model measure n)n posterior predictive draws: particles of measure drawn by weight,
each replayed through model with its latent choices held and its
observed sites drawing fresh values instead of scoring the data. A prior
predictive draw is the same with model simply run (gfi/simulate).
Returns a spin resolving a vector of {:value v :observations {address x}}: the program's value and what each observed site drew.
`n` posterior predictive draws: particles of `measure` drawn by weight,
each replayed through `model` with its latent choices held and its
observed sites drawing fresh values instead of scoring the data. A prior
predictive draw is the same with `model` simply run (`gfi/simulate`).
Returns a spin resolving a vector of {:value v :observations {address x}}:
the program's value and what each observed site drew.(query measure query-fn)Weighted statistics of a numeric function of the program's value over
measure: query-fn is identity (the value itself), a keyword (a field
of a map value) or a function of the value.
Returns {:mean :variance :std-dev :quantiles :samples :weights :type};
:samples and :weights are the particles' values and normalized
weights.
Weighted statistics of a numeric function of the program's value over
`measure`: `query-fn` is `identity` (the value itself), a keyword (a field
of a map value) or a function of the value.
Returns {:mean :variance :std-dev :quantiles :samples :weights :type};
`:samples` and `:weights` are the particles' values and normalized
weights.(smc-infer model-task num-particles & [opts])Sequential Monte Carlo: num-particles particles run model-task (a
spin); at every observation the population is resampled when its
effective sample size falls below :resample-threshold·N. Runs on
savepoints (foerster.smc/smc); the measure holds Samples, and its
m/log-marginal estimates the evidence.
Options:
:resample-threshold ESS fraction below which to resample (default 0.5)
:world-policy :fresh (default): fresh worlds; :fork: canonical
forks of the caller's world (doc/worlds.md)
:world-opts fork options for :fork (:systems, :rights, :snapshots)
:authority, :grant a world.scope/PResourceAuthority and the budget the
inference draws from the caller's wallet (:fork)
:executor the executor the worlds run on (default: spindel's)
:policy a foerster.trace/policy deciding the sites
(constraints, interventions, proposals)
:anchors, :rejuvenate resample-move: after each resampling, MH moves
from anchored sites (foerster.smc/smc; :fresh only)
Returns a spin resolving the EmpiricalMeasure.
(sp/with-context world @(smc-infer (model) 1000)) ; at the REPL (spin (query (await (smc-infer (model) 1000)) identity))
Sequential Monte Carlo: `num-particles` particles run `model-task` (a
spin); at every observation the population is resampled when its
effective sample size falls below `:resample-threshold`·N. Runs on
savepoints (`foerster.smc/smc`); the measure holds `Sample`s, and its
`m/log-marginal` estimates the evidence.
Options:
:resample-threshold ESS fraction below which to resample (default 0.5)
:world-policy :fresh (default): fresh worlds; :fork: canonical
forks of the caller's world (doc/worlds.md)
:world-opts fork options for :fork (:systems, :rights, :snapshots)
:authority, :grant a world.scope/PResourceAuthority and the budget the
inference draws from the caller's wallet (:fork)
:executor the executor the worlds run on (default: spindel's)
:policy a `foerster.trace/policy` deciding the sites
(constraints, interventions, proposals)
:anchors, :rejuvenate resample-move: after each resampling, MH moves
from anchored sites (`foerster.smc/smc`; :fresh only)
Returns a spin resolving the EmpiricalMeasure.
(sp/with-context world @(smc-infer (model) 1000)) ; at the REPL
(spin (query (await (smc-infer (model) 1000)) identity))(tempered-infer model-task num-particles & [opts])Tempered SMC (foerster.tempering): num-particles complete runs of
model-task, moved from the prior to the posterior through the targets
p(x)·L(x)^β with an adaptive schedule of β. Explores posteriors whose
modes a Markov chain cannot cross, and estimates the evidence.
Options: :ess-target (0.5), :moves (single-site MH moves per particle
per step; default a sweep), :scale (2.38), :waste-free P, :max-steps,
:executor; fresh worlds only.
Returns a spin resolving the EmpiricalMeasure; :temperatures holds the
schedule.
Tempered SMC (`foerster.tempering`): `num-particles` complete runs of `model-task`, moved from the prior to the posterior through the targets p(x)·L(x)^β with an adaptive schedule of β. Explores posteriors whose modes a Markov chain cannot cross, and estimates the evidence. Options: `:ess-target` (0.5), `:moves` (single-site MH moves per particle per step; default a sweep), `:scale` (2.38), `:waste-free` P, `:max-steps`, `:executor`; fresh worlds only. Returns a spin resolving the EmpiricalMeasure; `:temperatures` holds the schedule.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |