VBMC
#
Note
The VBMC
class implements the Variational Bayesian Monte Carlo (VBMC) algorithm.
VBMC computes a variational approximation of the full posterior and a lower bound on the log normalization constant (log marginal likelhood or log model evidence) for a provided unnormalized log posterior.
To perform inference, first initialize a VBMC
object and then call vbmc.optimize()
on the instance.
By default VBMC assumes noiseless evaluations of the log posterior, but noisy likelihoods can also be handled. See PyVBMC Example 6: Noisy log-likelihood evaluations for more details.
See below for more details on the VBMC
class methods and interface. The primary entry-points for users are the VBMC
class, which initializes the algorithm, and the VariationalPosterior class, which represents the returned variational solution. The Basic options may also be useful.
- class pyvbmc.VBMC(log_density: callable, x0: ndarray = None, lower_bounds: ndarray = None, upper_bounds: ndarray = None, plausible_lower_bounds: ndarray = None, plausible_upper_bounds: ndarray = None, options: dict = None, options_path: PathLike | None = None, prior: Prior = None, log_prior: callable = None, sample_prior: callable = None)[source]#
Posterior and model inference via Variational Bayesian Monte Carlo (VBMC).
VBMC computes a variational approximation of the full posterior and a lower bound on the normalization constant (marginal likelhood or model evidence) for a provided unnormalized log posterior.
Initialize a
VBMC
object to set up the inference problem, then runoptimize()
. See the examples for more details.- Parameters:
- log_densitycallable
A given target log-posterior or log-likelihood. If
log_prior
isNone
,log_density
accepts inputx
and returns the value of the target log-joint, that is, the unnormalized log-posterior density atx
. Iflog_prior
is notNone
,log_density
should return the unnormalized log-likelihood. In either case, ifoptions["specify_target_noise"]
is true,log_density
should return a tuple where the first element is the noisy log-density, and the second is an estimate of the standard deviation of the noise.- x0np.ndarray, optional
Starting point for the inference. Ideally
x0
is a point in the proximity of the mode of the posterior. Default isNone
.- lower_bounds, upper_boundsnp.ndarray, optional
lower_bounds
(LB) andupper_bounds
(UB) define a set of strict lower and upper bounds for the coordinate vector, x, so that the posterior has support on LB < x < UB. If scalars, the bound is replicated in each dimension. UseNone
for LB and UB if no bounds exist. Set LB [i] = -inf
and UB [i] =inf
if the i-th coordinate is unbounded (while other coordinates may be bounded). Note that if LB and UB contain unbounded variables, the respective values of PLB and PUB need to be specified (see below), by defaultNone
.- plausible_lower_bounds, plausible_upper_boundsnp.ndarray, optional
Specifies a set of
plausible_lower_bounds
(PLB) andplausible_upper_bounds
(PUB) such that LB < PLB < PUB < UB. Both PLB and PUB need to be finite. PLB and PUB represent a “plausible” range, which should denote a region of high posterior probability mass. Among other things, the plausible box is used to draw initial samples and to set priors over hyperparameters of the algorithm. When in doubt, we found that setting PLB and PUB using the topmost ~68% percentile range of the prior (e.g, mean +/- 1 SD for a Gaussian prior) works well in many cases (but note that additional information might afford a better guess). Both are by default None.- optionsdict, optional
Additional options can be passed as a dict. Please refer to the VBMC options page for the default options. If no
options
are passed, the default options are used.- options_pathpathlike, optional
Additional options can also be specified by a .ini file. The
options
dict keyword takes precedence over options set in the .ini file.options_path
should be either absolute or relative to the pyvbmc/vbmc/ directory.- prior, optional
An optional separate prior. It can be a
pyvbmc.priors.Prior
subclass, an appropriatescipy.stats
distribution, or a list of one-dimensional PyVBMCPrior
and/or one-dimenional continuousscipy.stats
distributions. (see the documentation on priors for more details). Ifprior
is not None, the argumentlog_density
is assumed to represent the log-likelihood (otherwise it is assumed to represent the log-joint).- log_priorcallable, optional
An optional separate log-prior function, which should accept a single argument x and return the log-density of the prior at x. If
log_prior
is notNone
, the argumentlog_density
is assumed the log-joint).- sample_priorcallable, optional
An optional function which accepts a single argument n and returns an array of samples from the prior, of shape (n, D), where D is the problem dimension. Currently unused.
- Raises:
- ValueError
When neither x0 or (plausible_lower_bounds and plausible_upper_bounds) are specified.
- ValueError
When various checks for the bounds (LB, UB, PLB, PUB) of VBMC fail.
References
[1]Huggins, B., Li, C., Tobaben, M., Aarnos, M., & Acerbi, L. (2023). “PyVBMC: Efficient Bayesian inference in Python”. Journal of Open Source Software 8(86), 5428, https://doi.org/10.21105/joss.05428.
[2]Acerbi, L. (2018). “Variational Bayesian Monte Carlo”. In Advances in Neural Information Processing Systems 31 (NeurIPS 2018), pp. 8213-8223.
[3]Acerbi, L. (2020). “Variational Bayesian Monte Carlo with Noisy Likelihoods”. In Advances in Neural Information Processing Systems 33 (NeurIPS 2020).
Examples
For VBMC usage examples, please look up the Jupyter notebook tutorials in the PyVBMC documentation: https://acerbilab.github.io/pyvbmc/_examples/pyvbmc_example_1.html
- optimize(self)#
Run inference on an initialized
VBMC
object.VBMC computes a variational approximation of the full posterior and the ELBO (evidence lower bound), a lower bound on the log normalization constant (log marginal likelhood or log model evidence) for the provided unnormalized log posterior.
- Returns:
- vpVariationalPosterior
The
VariationalPosterior
computed by VBMC.- resultsdict
A dictionary with additional information about the VBMC run.
- save(self, file, overwrite=False)#
Save the VBMC instance to a file.
Note
Complex attributes of a VBMC instance (such as the stored
log_joint
callable) may not behave correctly if they have been saved and loaded by different minor versions of Python, due to differing dependency versions. Basic (static) data should remain legible across versions.- Parameters:
- filepath-like
The file name or path to write to. Default file extension .pkl will be added if no extension is specified.
- overwritebool
Whether to allow overwriting existing files. Default False.
- Raises:
- FileExistsError
If the file already exists and
overwrite
is False.- OSError
If the file cannot be opened for other reasons (e.g., the directory is not found, the disk is full, etc.).
- load(file, new_options=None, iteration=None, set_random_state=False)#
Load a VBMC instance from a file.
Note
Complex attributes of a VBMC instance (such as the stored
log_joint
callable) may not behave correctly if they have been saved and loaded by different minor versions of Python, due to differing dependency versions. Basic (static) data should remain legible across versions.- Parameters:
- filepath-like
The file name or path to write to.
- new_optionsdict or None
A dictionary of options to change when loading the stored VBMC instance. Useful, for example, to continue a previous run with a larger budget of function evaluations and/or iterations. See the documentation on PyVBMC’s options for more details.
- iterationint or None
The iteration at which to initialize the stored VBMC instance. Default is None, meaning initialize to the last recorded iteration.
- set_random_statebool
Whether to set the global random state to the stored random state of the VBMC object, for reprodicibility. Default False.
- Returns:
- vbmcVBMC
The loaded VBMC instance, initialized at the specified iteration.
- Raises:
- ValueError
If the specified
iteration
is less than zero or larger than the last stored iteration.- OSError
If the file cannot be found, or cannot be opened for other reasons.
- determine_best_vp(max_idx: int = None, safe_sd: float = 5, frac_back: float = 0.25, rank_criterion_flag: bool = False)[source]#
Return the best VariationalPosterior found during the optimization of VBMC as well as its ELBO, ELBO_SD and the index of the iteration.
- Parameters:
- max_idxint, optional
Check up to this iteration, by default None which means last iter.
- safe_sdfloat, optional
Penalization for uncertainty, by default 5.
- frac_backfloat, optional
If no past stable iteration, go back up to this fraction of iterations, by default 0.25.
- rank_criterion_flagbool, optional
If True use new ranking criterion method to pick best solution. It finds a solution that combines ELCBO, stability, and recency, by default False.
- Returns:
- vpVariationalPosterior
The VariationalPosterior found during the optimization of VBMC.
- elbofloat
The ELBO of the iteration with the best VariationalPosterior.
- elbo_sdfloat
The ELBO_SD of the iteration with the best VariationalPosterior.
- idx_bestint
The index of the iteration with the best VariationalPosterior.
- final_boost(vp: VariationalPosterior, gp: GP)[source]#
Perform a final boost of variational components.
- Parameters:
- vpVariationalPosterior
The VariationalPosterior that should be boosted.
- gpGaussianProcess
The corresponding GaussianProcess of the VariationalPosterior.
- Returns:
- vpVariationalPosterior
The VariationalPosterior resulting from the final boost.
- elboVariationalPosterior
The ELBO of the VariationalPosterior resulting from the final boost.
- elbo_sdVariationalPosterior
The ELBO_SD of the VariationalPosterior resulting from the final boost.
- changed_flagbool
Indicates if the final boost has taken place or not.
Additional functions#
- pyvbmc.vbmc.optimize_vp(options: Options, optim_state: dict, vp: VariationalPosterior, gp: GP, fast_opts_N: int, slow_opts_N: int, K: int = None)[source]#
Optimize variational posterior.
- Parameters:
- optionsOptions
Options from the VBMC instance we are calling this from.
- optim_statedict
Optimization state from the VBMC instance we are calling this from.
- vpVariationalPosterior
The variational posterior we want to optimize.
- gpgpyreg.GaussianProcess
The Gaussian process surrogate of the log-posterior, against which to optimize the VP.
- fast_opts_Nint
Number of fast optimizations.
- slow_opts_Nint
Number of slow optimizations.
- Kint, optional
Number of mixture components. If not given defaults to the number of mixture components the given VP has.
- Returns:
- vpVariationalPosterior
The optimized variational posterior.
- var_ssint
Estimated variance of the ELBO, due to variance of the expected log-joint, for each GP hyperparameter sample.
- prunedint
Number of pruned components.
- pyvbmc.vbmc.train_gp(hyp_dict: dict, optim_state: dict, function_logger: FunctionLogger, iteration_history: IterationHistory, options: Options, plb_tran: ndarray, pub_tran: ndarray)[source]#
Train Gaussian process model.
- Parameters:
- hyp_dictdict
Hyperparameter summary statistics dictionary. If it does not contain the appropriate keys they will be added automatically.
- optim_statedict
Optimization state from the VBMC instance we are calling this from.
- function_loggerFunctionLogger
Function logger from the VBMC instance which we are calling this from.
- iteration_historyIterationHistory
Iteration history from the VBMC instance we are calling this from.
- optionsOptions
Options from the VBMC instance we are calling this from.
- plb_tranndarray, shape (1, D)
Transformed lower plausible bounds, used to set GP hyperparameters.
- pub_tranndarray, shape (1, D)
Transformed upper plausible bounds, used to set GP hyperparameters.
- Returns:
- gpGP
The trained GP.
- gp_s_Nint
The number of samples for fitting.
- sn2_hpdfloat
An estimate of the GP noise variance at high posterior density.
- hyp_dictdict
The updated summary statistics.
- pyvbmc.vbmc.update_K(optim_state: dict, iteration_history: IterationHistory, options: Options)[source]#
Update number of variational mixture components.
- Parameters:
- optim_statedict
Optimization state from the VBMC instance we are calling this from.
- iteration_historyIterationHistory
Iteration history from the VBMC instance we are calling this from.
- optionsOptions
Options from the VBMC instance we are calling this from.
- Returns:
- K_newint
The new number of variational mixture components.