Examples#

The repository ships with runnable scripts that demonstrate typical Aspire workflows. Execute them from the examples directory after installing the relevant extras.

Sequential Monte Carlo (MiniPCN)#

examples/smc_example.py (excerpt)#
 1"""Example using sequential posterior inference with SMC.
 2
 3This examples is slightly contrived, using a mixture of two Gaussians in 4D
 4as the target distribution. The goal is to demonstrate the ability of SMC to
 5explore multi-modal distributions, even when the initial samples deviate
 6significantly from the true modes.
 7
 8In practice, one would ideally use more informative initial samples.
 9"""
10
11from pathlib import Path
12
13import numpy as np
14
15from aspire import Aspire
16from aspire.plot import plot_comparison
17from aspire.samples import Samples
18from aspire.utils import AspireFile, configure_logger
19
20# RNG for generating initial samples
21rng = np.random.default_rng(42)
22
23# Output directory
24outdir = Path("outdir") / "smc_example"
25outdir.mkdir(parents=True, exist_ok=True)
26
27# Configure logger to show INFO level messages
28configure_logger()
29
30# Number of dimensions
31dims = 4
32
33# Means and covariances of the two Gaussian components
34mu1 = 2 * np.ones(dims)
35mu2 = -2 * np.ones(dims)
36cov1 = 0.5 * np.eye(dims)
37cov2 = np.eye(dims)
38
39
40def log_likelihood(samples):
41    """Log-likelihood of a mixture of two Gaussians"""
42    x = samples.x
43    comp1 = (
44        -0.5 * ((x - mu1) @ np.linalg.inv(cov1) * (x - mu1)).sum(axis=-1)
45        - 0.5 * dims * np.log(2 * np.pi)
46        - 0.5 * np.linalg.slogdet(cov1)[1]
47    )
48    comp2 = (
49        -0.5 * ((x - mu2) @ np.linalg.inv(cov2) * (x - mu2)).sum(axis=-1)
50        - 0.5 * dims * np.log(2 * np.pi)
51        - 0.5 * np.linalg.slogdet(cov2)[1]
52    )
53    return np.logaddexp(comp1, comp2)  # Log-sum-exp for numerical stability
54
55
56def log_prior(samples):
57    """Standard normal prior"""
58    return -0.5 * (samples.x**2).sum(axis=-1) - dims * 0.5 * np.log(2 * np.pi)
59
60
61# Generate prior samples for comparison, these are not used in SMC
62prior_samples = Samples(rng.normal(0, 1, size=(5000, dims)))
63
64# We draw initial samples from two Gaussians centered away from the true modes
65# to demonstrate the ability of SMC to explore the posterior
66offset_1 = rng.uniform(-3, 3, size=(dims,))
67offset_2 = rng.uniform(-3, 3, size=(dims,))
68initial_samples = np.concatenate(
69    [
70        rng.normal(mu1 - offset_1, 1, size=(2500, dims)),
71        rng.normal(mu2 - offset_2, 1, size=(2500, dims)),
72    ],
73    axis=0,
74)
75initial_samples = Samples(initial_samples)
76
77# Initialize Aspire with the log-likelihood and log-prior
78aspire = Aspire(
79    log_likelihood=log_likelihood,
80    log_prior=log_prior,

Run the full example:

$ python smc_example.py

The script demonstrates how to:

  • Build contrived mixtures of Gaussians for testing,

  • Fit a Neural Spline Flow to biased initial samples,

  • Run adaptive MiniPCN-SMC via aspire.Aspire.sample_posterior(),

  • Plot diagnostics (loss curves, beta schedule, corner plots).