NumPyro Documentation

repository·master·Indexed 25 days ago

https://github.com/pyro-ppl/numpyro

A lightweight probabilistic programming library powered by JAX, providing a NumPy backend for Pyro. It supports high-performance autograd and JIT compilation to CPU, GPU, and TPU. NumPyro includes various inference algorithms such as MCMC (NUTS, MixedHMC, HMCECS, BarkerMH, HMCGibbs, SA), Stochastic Variational Inference (SVI) with multiple ELBO implementations, and Nested Sampling via jaxns. It features a distribution API compatible with PyTorch and supports TensorFlow Probability (TFP) distributions.

Tokens
18.4K
Snippets
45
Records
109
Agent score
82%

What's inside NumPyro

  1. Overview of NumPyro

    master
    NumPyro is a lightweight probabilistic programming library that provides a NumPy backend for Pyro. It leverages JAX for automatic differentiation and JIT compilation to GPU, CPU, and TPU. It is designed to be a flexible substrate for probabilistic modeling, supporting Pyro primitives, various inference algorithms, and a distribution API compatible with PyTorch.
  2. Explore NumPyro model and inference examples

    master

    NumPyro provides various examples for different modeling and inference tasks. Key examples include:

    • Bayesian Regression: Covers model writing, MCMC API, effect handlers, and custom inference utilities.
    • Time Series Forecasting: Demonstrates converting for-loops to JAX's lax.scan for performance.
    • Discrete Latent Variables: Uses enumeration mechanisms for inference.
    • Hierarchical Models: Implementation of the Baseball example using NUTS.
    • Hidden Markov Models (HMM): Comparison with Stan implementations.
    • Variational Autoencoders (VAE): Using Variational Inference with neural networks.
    • Gaussian Processes: Using NUTS to sample posterior hyper-parameters.
    • Horseshoe Regression: Implementing GLMs with Horseshoe priors.
    • Statistical Rethinking: Translations of Richard McElreath's book to NumPyro.
  3. Use non-centered reparameterization to fix MCMC pathologies

    master

    If your MCMC chain shows high divergence counts or low effective sample size (n_eff), you can use non-centered reparameterization. This is achieved by using numpyro.handlers.reparam with a reparameterization configuration.

    For distributions with loc and scale parameters (like Normal, Cauchy, or StudentT), you can use LocScaleReparam(centered=0) to automatically handle the transformation.

  4. Choose an Automatic Guide for Variational Inference

    master

    NumPyro provides several AutoGuide classes to automatically generate variational distributions (guides) for your models. Use the following guide to select an appropriate one based on your needs:

    Basic Mean-Field Guides

    Best for starting with variational inference. They automatically handle non-Euclidean latent spaces (e.g., positivity constraints) using bijective transformations.

    • AutoNormal: Basic mean-field guide.
    • AutoDiagonalNormal: Basic mean-field guide.

    Multivariate Normal Guides

    These capture correlations in the posterior but may be difficult to fit in high-dimensional settings.

    • AutoMultivariateNormal: Full multivariate Normal distribution.
    • AutoLowRankMultivariateNormal: Low-rank multivariate Normal distribution.

    Normalizing Flow Guides

    Provide highly flexible variational distributions parameterized by normalizing flows.

    • AutoBNAFNormal: Uses BNAF flows.
    • AutoIAFNormal: Uses IAF (Inverse Autoregressive Flow) flows.

    Advanced HMC-based Guides

    Powerful algorithms that leverage HMC. Good for highly correlated posteriors but can be computationally expensive.

    • AutoDAIS: Standard DAIS algorithm.
    • AutoSurrogateLikelihoodDAIS: DAIS with support for data subsampling.
    • AutoSemiDAIS: Supports data subsampling by using a parametric guide for global latent variables while using DAIS-style approximations for local latent variables.

    Other Specialized Guides

    • AutoDelta: Used for computing point estimates via MAP (Maximum A Posteriori) estimation.
    • AutoLaplaceApproximation: Computes a Laplace approximation.
    • AutoGuideList: Used to combine multiple automatic guides.
  5. Migrate Pyro models to NumPyro

    master

    NumPyro supports most Pyro primitives (sample, param, plate, module, and effect handlers). To use a Pyro model in NumPyro, consider the following changes:

    • Replace Torch operations: Convert torch operations to jax.numpy operations.
    • Handle Randomness: Wrap pyro.sample statements outside of inference contexts in a seed handler.
    • Parameter Retrieval: Since there is no global parameter store, use SVI.get_params() to retrieve optimized values from SVI. numpyro.param works inside models via the substitute effect handler.
    • Neural Networks: Rewrite PyTorch modules using stax or flax.
    • Functional Style: JAX works best with functional code. If your model has side-effects that are not visible to the JAX tracer, rewrite it in a more functional style to leverage JIT compilation.
  6. Handle random number generation in NumPyro

    master

    Unlike Pyro, numpyro.sample requires an explicit random number generator key because JAX does not have a global random state. If you call numpyro.sample outside of an inference context, you have three options:

    1. Directly call the distribution and provide a PRNG key: dist.Normal(0, 1).sample(key)

    2. Provide the rng_key argument to numpyro.sample: numpyro.sample('x', dist.Normal(0, 1), rng_key=key)

    3. Use a seed handler as a context manager or a higher-order function to thread the key automatically.

    Using seed as a context manager:

    with handlers.seed(rng_seed=0):
        x = numpyro.sample("x", dist.Beta(1, 1))
        y = numpyro.sample("y", dist.Bernoulli(x))

    Using seed as a higher-order function:

    def fn():
        x = numpyro.sample("x", dist.Beta(1, 1))
        y = numpyro.sample("y", dist.Bernoulli(x))
        return y
    
    print(handlers.seed(fn, rng_seed=0)())
    with handlers.seed(rng_seed=0):
        x = numpyro.sample("x", dist.Beta(1, 1))
        y = numpyro.sample(
            "y", dist.Bernoulli(x)
        )
  7. Install NumPyro

    master

    You can install NumPyro using pip or conda.

    CPU Installation

    To install the latest CPU version of JAX and NumPyro:

    pip install numpyro

    If you encounter compatibility issues, force a known compatible CPU version:

    pip install 'numpyro[cpu]'

    GPU Installation

    To use NumPyro on a GPU, you must install CUDA first. Use the command corresponding to your CUDA version:

    For CUDA 12.x.y:

    pip install 'numpyro[cuda12]' -f https://storage.googleapis.com/jax_cuda_releases.html

    For CUDA 13.x.y:

    pip install 'numpyro[cuda13]' -f https://storage.googleapis.com/jax_cuda_releases.html

    Cloud TPU Installation

    1. Set up the TPU backend following the Cloud TPU VM JAX Quickstart Guide.
    2. Install NumPyro via pip install numpyro.

    Other Installation Methods

    Conda:

    conda install -c conda-forge numpyro

    From Source:

    git clone https://github.com/pyro-ppl/numpyro.git
    cd numpyro
    # install jax/jaxlib first for CUDA support
    pip install -e '.[dev]'
    pip install numpyro
  8. Use NumPyro optimization algorithms

    master

    NumPyro provides several optimizer classes that wrap JAX optimizers to work seamlessly with NumPyro inference algorithms (like SVI). These optimizers can be passed directly to inference objects.

    Available optimizers include:

    • Adam
    • ClippedAdam: Adam with gradient clipping between [-clip_norm, clip_norm].
    • Adagrad
    • Momentum
    • RMSProp
    • RMSPropMomentum
    • SGD
    • SM3
    • Minimize: A wrapper for jax.scipy.optimize.minimize (currently only supports the BFGS method). Note that Minimize is intended for use with static guides (e.g., MLE, MAP, or AutoLaplaceApproximation) and may be difficult to converge in stochastic settings.
  9. Use `condition` handler for forecasting models

    master

    When designing a model that needs to perform both inference on observed data and forecasting on unobserved future data, use the numpyro.handlers.condition handler instead of the obs= argument in sample().

    By using condition(data={'y': y}), you can provide observed values for the training period. When the model is later used for forecasting (where the sequence length exceeds the length of the conditioned data), NumPyro will automatically sample the unobserved values from the specified distribution rather than raising an index-out-of-bounds error.

  10. Run MCMC inference with NUTS

    master

    To perform Bayesian inference using the No-U-Turn Sampler (NUTS), follow these steps:

    1. Define your model as a Python callable using numpyro.sample primitives.
    2. Initialize the NUTS kernel with your model.
    3. Create an MCMC instance specifying the kernel, num_warmup, and num_samples.
    4. Execute the inference using mcmc.run(), providing a JAX PRNGKey and any necessary model arguments.

    Note: JAX requires explicit PRNG keys for all stochastic operations. Use jax.random.split to manage keys.

    Methods available on the MCMC object:

    • run(...): Runs warmup, adapts step size/mass matrix, and performs sampling.
    • print_summary(): Prints diagnostic information (quantiles, effective sample size, Gelman-Rubin diagnostic).
    • get_samples(): Retrieves the posterior distribution samples.
    • warmup(...): Performs only the warmup phase.
    from numpyro.infer import MCMC, NUTS
    from jax import random
    
    # Initialize kernel and MCMC
    kernel = NUTS(model)
    num_samples = 2000
    mcmc = MCMC(kernel, num_warmup=1000, num_samples=num_samples)
    
    # Run inference
    rng_key = random.key(0)
    rng_key, rng_key_ = random.split(rng_key)
    mcmc.run(
        rng_key_, 
        marriage=dset.MarriageScaled.values, 
        divorce=dset.DivorceScaled.values
    )
    
    # Retrieve results
    mcmc.print_summary()
    samples = mcmc.get_samples()