NRE_C#

class NRE_C(prior=None, classifier='resnet', device='cpu', logging_level='warning', summary_writer=None, tracker=None, show_progress_bars=True)[source]#

Bases: RatioEstimatorTrainer

Neural Ratio Estimation (NRE-C / CNRE) as in Miller et al. (2022) [1].

NRE-C generalizes NRE-A and NRE-B using a “multi-class sigmoid” loss that ensures the estimated ratio \(p(\theta,x)/p(\theta)p(x)\) is exact at optimum in the first round. This addresses the issue that NRE-B’s ratio is only defined up to an arbitrary function of \(x\). NRE-C provides more accurate ratio estimates while maintaining the benefits of contrastive learning.

[1] Contrastive Neural Ratio Estimation, Benjamin Kurt Miller, et al.,

NeurIPS 2022, https://arxiv.org/abs/2210.06170

Example:#

import torch
from sbi.inference import NRE_C
from sbi.utils import BoxUniform

# 1. Setup prior and simulate data
prior = BoxUniform(low=torch.zeros(3), high=torch.ones(3))
theta = prior.sample((100,))
x = theta + torch.randn_like(theta) * 0.1

# 2. Train ratio estimator
inference = NRE_C(prior=prior)
ratio_estimator = inference.append_simulations(theta, x).train(num_classes=5)

# 3. Build posterior
posterior = inference.build_posterior(ratio_estimator)

# 4. Sample from posterior
x_o = torch.randn(1, 3)
samples = posterior.sample((1000,), x=x_o)
train(num_classes=5, gamma=1.0, training_batch_size=200, learning_rate=0.0005, validation_fraction=0.1, stop_after_epochs=20, max_num_epochs=2147483647, clip_max_norm=5.0, resume_training=False, discard_prior_samples=False, retrain_from_scratch=False, show_train_summary=False, dataloader_kwargs=None)[source]#

Return classifier that approximates the ratio \(p(\theta,x)/p(\theta)p(x)\).

Parameters:
  • num_classes (int) – Number of theta to classify against, corresponds to \(K\) in _Contrastive Neural Ratio Estimation_. Minimum value is 1. Similar to num_atoms for SNRE_B except SNRE_C has an additional independently drawn sample. The total number of alternative parameters NRE-C “sees” is \(2K-1\) or 2 * num_classes - 1 divided between two loss terms.

  • gamma (float) – Determines the relative weight of the sum of all \(K\) dependently drawn classes against the marginally drawn one. Specifically, \(p(y=k) :=p_K\), \(p(y=0) := p_0\), \(p_0 = 1 - K p_K\), and finally \(\gamma := K p_K / p_0\).

  • training_batch_size (int) – Training batch size.

  • learning_rate (float) – Learning rate for Adam optimizer.

  • validation_fraction (float) – The fraction of data to use for validation.

  • stop_after_epochs (int) – The number of epochs to wait for improvement on the validation set before terminating training.

  • max_num_epochs (int) – Maximum number of epochs to run. If reached, we stop training even when the validation loss is still decreasing. Otherwise, we train until validation loss increases (see also stop_after_epochs).

  • clip_max_norm (float | None) – Value at which to clip the total gradient norm in order to prevent exploding gradients. Use None for no clipping.

  • exclude_invalid_x – Whether to exclude simulation outputs x=NaN or x=±∞ during training. Expect errors, silent or explicit, when False.

  • resume_training (bool) – Can be used in case training time is limited, e.g. on a cluster. If True, the split between train and validation set, the optimizer, the number of epochs, and the best validation log-prob will be restored from the last time .train() was called.

  • discard_prior_samples (bool) – Whether to discard samples simulated in round 1, i.e. from the prior. Training may be sped up by ignoring such less targeted samples.

  • retrain_from_scratch (bool) – Whether to retrain the conditional density estimator for the posterior from scratch each round.

  • show_train_summary (bool) – Whether to print the number of epochs and validation loss and leakage after the training.

  • dataloader_kwargs (Dict | None) – Additional or updated kwargs to be passed to the training and validation dataloaders (like, e.g., a collate_fn)

Returns:

Classifier that approximates the ratio \(p(\theta,x)/p(\theta)p(x)\).

Return type:

RatioEstimator

append_simulations(theta, x, exclude_invalid_x=False, from_round=0, algorithm='SNRE', data_device=None)#

Store parameters and simulation outputs to use them for later training.

Data are stored as entries in lists for each type of variable (parameter/data).

Stores \(\theta\), \(x\), prior_masks (indicating if simulations are coming from the prior or not) and an index indicating which round the batch of simulations came from.

Parameters:
  • theta (Tensor) – Parameter sets.

  • x (Tensor) – Simulation outputs.

  • exclude_invalid_x (bool) – Whether invalid simulations are discarded during training. If False, NRE raises an error when invalid simulations are found. If True, invalid simulations are discarded and training can proceed, but this gives systematically wrong results.

  • from_round (int) – Which round the data stemmed from. Round 0 means from the prior. With default settings, this is not used at all for NRE. Only when the user later on requests .train(discard_prior_samples=True), we use these indices to find which training data stemmed from the prior.

  • algorithm (str) – Which algorithm is used. This is used to give a more informative warning or error message when invalid simulations are found.

  • data_device (str | None) – Where to store the data, default is on the same device where the training is happening. If training a large dataset on a GPU with not much VRAM can set to ‘cpu’ to store data on system memory instead.

Returns:

NeuralInference object (returned so that this function is chainable).

Return type:

Self

build_posterior(density_estimator=None, prior=None, sample_with='mcmc', mcmc_method='slice_np_vectorized', vi_method='rKL', mcmc_parameters=None, vi_parameters=None, rejection_sampling_parameters=None, importance_sampling_parameters=None, posterior_parameters=None)#

Build posterior from the neural density estimator.

SNRE trains a neural network to approximate likelihood ratios. The posterior wraps the trained network such that one can directly evaluate the unnormalized posterior log probability \(p(\theta|x) \propto p(x|\theta) \cdot p(\theta)\) and draw samples from the posterior with MCMC or rejection sampling. Note that, in the case of single-round SNRE_A / AALR, it is possible to evaluate the log-probability of the normalized posterior, but sampling still requires MCMC (or rejection sampling).

Parameters:
  • density_estimator (RatioEstimator | None) – The density estimator that the posterior is based on. If None, use the latest neural density estimator that was trained.

  • prior (Distribution | None) – Prior distribution.

  • sample_with (Literal['mcmc', 'rejection', 'vi', 'importance']) – Method to use for sampling from the posterior. Must be one of [mcmc | rejection | vi | importance].

  • mcmc_method (Literal['slice_np', 'slice_np_vectorized', 'hmc_pyro', 'nuts_pyro', 'slice_pymc', 'hmc_pymc', 'nuts_pymc']) – Method used for MCMC sampling, one of slice_np, slice_np_vectorized, hmc_pyro, nuts_pyro, slice_pymc, hmc_pymc, nuts_pymc. slice_np is a custom numpy implementation of slice sampling. slice_np_vectorized is identical to slice_np, but if num_chains>1, the chains are vectorized for slice_np_vectorized whereas they are run sequentially for slice_np. The samplers ending on _pyro are using Pyro, and likewise the samplers ending on _pymc are using PyMC.

  • vi_method (Literal['rKL', 'fKL', 'IW', 'alpha']) – Method used for VI, one of [rKL, fKL, IW, alpha]. Note that some of the methods admit a mode seeking property (e.g. rKL) whereas some admit a mass covering one (e.g fKL).

  • mcmc_parameters (Dict[str, Any] | None) – Additional kwargs passed to MCMCPosterior.

  • vi_parameters (Dict[str, Any] | None) – Additional kwargs passed to VIPosterior.

  • rejection_sampling_parameters (Dict[str, Any] | None) – Additional kwargs passed to RejectionPosterior.

  • importance_sampling_parameters (Dict[str, Any] | None) – Additional kwargs passed to ImportanceSamplingPosterior.

  • posterior_parameters (MCMCPosteriorParameters | VIPosteriorParameters | RejectionPosteriorParameters | ImportanceSamplingPosteriorParameters | None) – Configuration passed to the init method for the posterior. Must be one of the following: - VIPosteriorParameters - ImportanceSamplingPosteriorParameters - MCMCPosteriorParameters - RejectionPosteriorParameters

Returns:

Posterior \(p(\theta|x)\) with .sample() and .log_prob() methods (the returned log-probability is unnormalized).

Return type:

NeuralPosterior

get_dataloaders(starting_round=0, training_batch_size=200, validation_fraction=0.1, resume_training=False, dataloader_kwargs=None)#

Return dataloaders for training and validation.

Parameters:
  • dataset – holding all theta and x, optionally masks.

  • training_batch_size (int) – training arg of inference methods.

  • resume_training (bool) – Whether the current call is resuming training so that no new training and validation indices into the dataset have to be created.

  • dataloader_kwargs (dict | None) – Additional or updated kwargs to be passed to the training and validation dataloaders (like, e.g., a collate_fn).

  • starting_round (int)

  • validation_fraction (float)

Returns:

Tuple of dataloaders for training and validation.

Return type:

Tuple[DataLoader, DataLoader]

get_simulations(starting_round=0)#

Returns all \(\theta\), \(x\), and prior_masks from rounds >= starting_round.

If requested, do not return invalid data.

Parameters:
  • starting_round (int) – The earliest round to return samples from (we start counting from zero).

  • warn_on_invalid – Whether to give out a warning if invalid simulations were found.

Return type:

Tuple[Tensor, Tensor, Tensor]

Returns: Parameters, simulation outputs, prior masks.

property summary#
Parameters:
  • prior (Distribution | None)

  • classifier (str | ConditionalEstimatorBuilder[RatioEstimator])

  • device (str)

  • logging_level (int | str)

  • summary_writer (SummaryWriter | None)

  • tracker (Tracker | None)

  • show_progress_bars (bool)