Exemplo n.º 1
0
def infer(
    simulator: Callable,
    prior: Distribution,
    method: str,
    num_simulations: int,
    num_workers: int = 1,
) -> NeuralPosterior:
    r"""Runs simulation-based inference and returns the posterior.

    This function provides a simple interface to run sbi. Inference is run for a single
    round and hence the returned posterior $p(\theta|x)$ can be sampled and evaluated
    for any $x$ (i.e. it is amortized).

    The scope of this function is limited to the most essential features of sbi. For
    more flexibility (e.g. multi-round inference, different density estimators) please
    use the flexible interface described here:
    https://www.mackelab.org/sbi/tutorial/02_flexible_interface/

    Args:
        simulator: A function that takes parameters $\theta$ and maps them to
            simulations, or observations, `x`, $\mathrm{sim}(\theta)\to x$. Any
            regular Python callable (i.e. function or class with `__call__` method)
            can be used.
        prior: A probability distribution that expresses prior knowledge about the
            parameters, e.g. which ranges are meaningful for them. Any
            object with `.log_prob()`and `.sample()` (for example, a PyTorch
            distribution) can be used.
        method: What inference method to use. Either of SNPE, SNLE or SNRE.
        num_simulations: Number of simulation calls. More simulations means a longer
            runtime, but a better posterior estimate.
        num_workers: Number of parallel workers to use for simulations.

    Returns: Posterior over parameters conditional on observations (amortized).
    """

    try:
        method_fun: Callable = getattr(sbi.inference, method.upper())
    except AttributeError:
        raise NameError(
            "Method not available. `method` must be one of 'SNPE', 'SNLE', 'SNRE'."
        )

    simulator, prior = prepare_for_sbi(simulator, prior)

    inference = method_fun(prior=prior)
    theta, x = simulate_for_sbi(
        simulator=simulator,
        proposal=prior,
        num_simulations=num_simulations,
        num_workers=num_workers,
    )
    _ = inference.append_simulations(theta, x).train()
    posterior = inference.build_posterior()

    return posterior
Exemplo n.º 2
0
    prior = sbi.utils.torchutils.BoxUniform(low=torch.as_tensor(prior_min),
                                            high=torch.as_tensor(prior_max))

    # Simulate samples from the prior distribution
    theta = prior.sample((10_000, ))
    print('Simulating samples from prior simulation... ', end='')
    stats = simulation_wrapper(theta.numpy())
    print('done.')

    # Train inference network
    density_estimator_build_fun = sbi.utils.posterior_nn(model='mdn')
    inference = sbi.inference.SNPE(
        prior, density_estimator=density_estimator_build_fun)
    print('Training inference network... ')
    inference.append_simulations(theta, stats).train()
    posterior = inference.build_posterior()

    # true parameters for real ground truth data
    true_params = np.array([[32., 1.]])
    true_data = simulate(true_params)
    t = true_data['t']
    I_inj = true_data['I_inj']
    v = true_data['v']
    xo = calculate_summary_statistics(true_data)
    print("The true summary statistics are:  ", xo)

    # Plot estimated posterior distribution
    samples = posterior.sample((1000, ), x=xo, show_progress_bars=False)
    labels_params = [r'$\overline{g}_{Na}$', r'$\overline{g}_{K}$']
    sbi.analysis.pairplot(samples,
                          limits=[[.5, 80], [1e-4, 15.]],