示例#1
0
    def _set_maybe_z_scored_prior(self) -> None:
        r"""
        Compute and store potentially standardized prior (if z-scoring was requested).

        This function is highly similar to `SNPE_C._set_maybe_z_scored_prior()`.

        The proposal posterior is:
        $p(\theta|x) = 1/Z * q(\theta|x) * prop(\theta) / p(\theta)$

        Let's denote z-scored theta by `a`: a = (theta - mean) / std
        Then $p'(a|x) = 1/Z_2 * q'(a|x) * prop'(a) / p'(a)$

        The ' indicates that the evaluation occurs in standardized space. The constant
        scaling factor has been absorbed into $Z_2$.
        From the above equation, we see that we need to evaluate the prior **in
        standardized space**. We build the standardized prior in this function.

        The standardize transform that is applied to the samples theta does not use
        the exact prior mean and std (due to implementation issues). Hence, the z-scored
        prior will not be exactly have mean=0 and std=1.
        """
        if self.z_score_theta:
            # Default to cpu to avoid mismatch with prior (always on cpu) below.
            scale = self._neural_net._transform._transforms[0]._scale.cpu()
            shift = self._neural_net._transform._transforms[0]._shift.cpu()

            # Following the definition of the linear transform in
            # `standardizing_transform` in `sbiutils.py`:
            # shift=-mean / std
            # scale=1 / std
            # Solving these equations for mean and std:
            estim_prior_std = 1 / scale
            estim_prior_mean = -shift * estim_prior_std

            # Compute the discrepancy of the true prior mean and std and the mean and
            # std that was empirically estimated from samples.
            # N(theta|m,s) = N((theta-m_e)/s_e|(m-m_e)/s_e, s/s_e)
            # Above: m,s are true prior mean and std. m_e,s_e are estimated prior mean
            # and std (estimated from samples and used to build standardize transform).
            almost_zero_mean = (self._prior.mean -
                                estim_prior_mean) / estim_prior_std
            almost_one_std = torch.sqrt(self._prior.variance) / estim_prior_std

            if isinstance(self._prior, MultivariateNormal):
                self._maybe_z_scored_prior = MultivariateNormal(
                    almost_zero_mean, torch.diag(almost_one_std))
            else:
                range_ = torch.sqrt(almost_one_std * 3.0)
                self._maybe_z_scored_prior = utils.BoxUniform(
                    almost_zero_mean - range_, almost_zero_mean + range_)
        else:
            self._maybe_z_scored_prior = self._prior
示例#2
0
def test_snl_on_linearGaussian_based_on_mmd(num_dim: int, prior_str: str):
    """Test SNL on linear Gaussian, comparing to ground truth posterior via MMD.

    NOTE: The MMD threshold is calculated based on a number of test runs and taking the mean plus 2 stds. 
    
    Args:
        num_dim: parameter dimension of the gaussian model
        prior_str: one of "gaussian" or "uniform"
    """

    true_observation = torch.zeros((1, num_dim))
    num_samples = 200

    if prior_str == "gaussian":
        prior = distributions.MultivariateNormal(
            loc=torch.zeros(num_dim), covariance_matrix=torch.eye(num_dim))
        target_samples = get_true_posterior_samples_linear_gaussian_mvn_prior(
            true_observation, num_samples=num_samples)
    else:
        prior = utils.BoxUniform(-1.0 * torch.ones(num_dim),
                                 torch.ones(num_dim))
        target_samples = get_true_posterior_samples_linear_gaussian_uniform_prior(
            true_observation, num_samples=num_samples, prior=prior)

    neural_likelihood = utils.likelihood_nn(
        model="maf",
        prior=prior,
        context=true_observation,
    )

    infer = SNL(
        simulator=linear_gaussian,
        prior=prior,
        true_observation=true_observation,
        density_estimator=neural_likelihood,
        mcmc_method="slice-np",
    )

    posterior = infer(num_rounds=1, num_simulations_per_round=1000)

    samples = posterior.sample(num_samples=num_samples)

    # compute the mmd
    mmd = utils.unbiased_mmd_squared(target_samples, samples)

    # check if mmd is larger than expected
    # NOTE: the mmd is calculated based on a number of test runs
    max_mmd = 0.02

    assert (mmd < max_mmd
            ), f"MMD={mmd} is more than 2 stds above the average performance."
def test_inference_with_rejection_estimator(set_seed):

    # likelihood_mean will be likelihood_shift+theta
    num_dim = 3
    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.3 * eye(num_dim)
    x_o = zeros(1, num_dim)
    num_samples = 500
    num_simulations = 2000

    def linear_gaussian_nan(theta,
                            likelihood_shift=likelihood_shift,
                            likelihood_cov=likelihood_cov):
        condition = theta[:, 0] < 0.0
        x = linear_gaussian(theta, likelihood_shift, likelihood_cov)
        x[condition] = float("nan")

        return x

    prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))
    target_samples = samples_true_posterior_linear_gaussian_uniform_prior(
        x_o,
        likelihood_shift=likelihood_shift,
        likelihood_cov=likelihood_cov,
        num_samples=num_samples,
        prior=prior,
    )

    simulator, prior = prepare_for_sbi(linear_gaussian_nan, prior)
    rejection_estimator = RestrictionEstimator(prior=prior)
    proposals = [prior]
    num_rounds = 2

    for r in range(num_rounds):
        theta, x = simulate_for_sbi(simulator, proposals[-1], 500)
        rejection_estimator.append_simulations(theta, x)
        if r < num_rounds - 1:
            _ = rejection_estimator.train()
        proposals.append(rejection_estimator.restrict_prior())

    all_theta, all_x, _ = rejection_estimator.get_simulations()

    # Any method can be used in combination with the `RejectionEstimator`.
    inference = SNPE_C(prior=prior)
    _ = inference.append_simulations(all_theta, all_x).train()
    posterior = inference.build_posterior().set_default_x(x_o)

    samples = posterior.sample((num_samples, ))

    # Compute the c2st and assert it is near chance level of 0.5.
    check_c2st(samples, target_samples, alg=f"{SNPE_C}")
示例#4
0
def test_z_scoring_warning(snpe_method: type):

    # Create data with large variance.
    num_dim = 2
    theta = torch.ones(100, num_dim)
    x = torch.rand(100, num_dim)
    x[:50] += 1e7

    # Make sure a warning is raised because z-scoring will map these data to duplicate
    # data points.
    with pytest.warns(UserWarning, match="Z-scoring these simulation outputs"):
        snpe_method(utils.BoxUniform(zeros(num_dim),
                                     ones(num_dim))).append_simulations(
                                         theta, x).train(max_num_epochs=1)
示例#5
0
def test_api_snpe_c_posterior_correction(
    sample_with_mcmc, mcmc_method, prior_str, set_seed
):
    """Test that leakage correction applied to sampling works, with both MCMC and
    rejection.

    Args:
        set_seed: fixture for manual seeding
    """

    num_dim = 2
    x_o = zeros(1, num_dim)

    # likelihood_mean will be likelihood_shift+theta
    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.3 * eye(num_dim)

    if prior_str == "gaussian":
        prior_mean = zeros(num_dim)
        prior_cov = eye(num_dim)
        prior = MultivariateNormal(loc=prior_mean, covariance_matrix=prior_cov)
    else:
        prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))

    def simulator(theta):
        return linear_gaussian(theta, likelihood_shift, likelihood_cov)

    simulator, prior = prepare_for_sbi(simulator, prior)
    inference = SNPE_C(
        prior,
        density_estimator="maf",
        simulation_batch_size=50,
        sample_with_mcmc=sample_with_mcmc,
        mcmc_method=mcmc_method,
        show_progress_bars=False,
    )

    theta, x = simulate_for_sbi(simulator, prior, 1000)
    _ = inference.append_simulations(theta, x).train(max_num_epochs=5)
    posterior = inference.build_posterior()
    posterior = posterior.set_sample_with_mcmc(sample_with_mcmc).set_mcmc_method(
        mcmc_method
    )

    # Posterior should be corrected for leakage even if num_rounds just 1.
    samples = posterior.sample((10,), x=x_o)

    # Evaluate the samples to check correction factor.
    posterior.log_prob(samples, x=x_o)
def test_api_snl_sampling_methods(sampling_method: str, prior_str: str,
                                  set_seed):
    """Runs SNL on linear Gaussian and tests sampling from posterior via mcmc.

    Args:
        mcmc_method: which mcmc method to use for sampling
        prior_str: use gaussian or uniform prior
        set_seed: fixture for manual seeding
    """

    num_dim = 2
    num_samples = 10
    num_trials = 2
    # HMC with uniform prior needs good likelihood.
    num_simulations = 10000 if sampling_method == "hmc" else 1000
    x_o = zeros((num_trials, num_dim))
    # Test for multiple chains is cheap when vectorized.
    num_chains = 3 if sampling_method == "slice_np_vectorized" else 1
    if sampling_method == "rejection":
        sample_with = "rejection"
    else:
        sample_with = "mcmc"

    if prior_str == "gaussian":
        prior = MultivariateNormal(loc=zeros(num_dim),
                                   covariance_matrix=eye(num_dim))
    else:
        prior = utils.BoxUniform(-1.0 * ones(num_dim), ones(num_dim))

    simulator, prior = prepare_for_sbi(diagonal_linear_gaussian, prior)
    inference = SNL(prior, show_progress_bars=False)

    theta, x = simulate_for_sbi(simulator,
                                prior,
                                num_simulations,
                                simulation_batch_size=50)
    _ = inference.append_simulations(theta, x).train(max_num_epochs=5)
    posterior = inference.build_posterior(
        sample_with=sample_with,
        mcmc_method=sampling_method).set_default_x(x_o)

    posterior.sample(
        sample_shape=(num_samples, ),
        x=x_o,
        mcmc_parameters={
            "thin": 3,
            "num_chains": num_chains
        },
    )
示例#7
0
def get_simulator(N, g, K):
    _W_eigs = get_W_eigs_np(g, K)

    num_dim = 2 * N * RANK
    prior = utils.BoxUniform(low=-1.0 * torch.ones(num_dim),
                             high=1.0 * torch.ones(num_dim))

    def simulator(params):
        params = params.numpy()
        U = np.reshape(params[:(RANK * N)], (N, RANK))
        V = np.reshape(params[(RANK * N):], (N, RANK))
        x = _W_eigs(U, V)
        return x

    return simulator, prior
示例#8
0
def test_api_snpe_c_posterior_correction(sample_with, mcmc_method, prior_str):
    """Test that leakage correction applied to sampling works, with both MCMC and
    rejection.

    """

    num_dim = 2
    x_o = zeros(1, num_dim)

    # likelihood_mean will be likelihood_shift+theta
    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.3 * eye(num_dim)

    if prior_str == "gaussian":
        prior_mean = zeros(num_dim)
        prior_cov = eye(num_dim)
        prior = MultivariateNormal(loc=prior_mean, covariance_matrix=prior_cov)
    else:
        prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))

    simulator, prior = prepare_for_sbi(
        lambda theta: linear_gaussian(theta, likelihood_shift, likelihood_cov),
        prior)
    inference = SNPE_C(prior, show_progress_bars=False)

    theta, x = simulate_for_sbi(simulator, prior, 1000)
    posterior_estimator = inference.append_simulations(theta, x).train()
    potential_fn, theta_transform = posterior_estimator_based_potential(
        posterior_estimator, prior, x_o)
    if sample_with == "mcmc":
        posterior = MCMCPosterior(
            potential_fn=potential_fn,
            theta_transform=theta_transform,
            proposal=prior,
            method=mcmc_method,
        )
    elif sample_with == "rejection":
        posterior = RejectionPosterior(
            potential_fn=potential_fn,
            proposal=prior,
            theta_transform=theta_transform,
        )

    # Posterior should be corrected for leakage even if num_rounds just 1.
    samples = posterior.sample((10, ))

    # Evaluate the samples to check correction factor.
    _ = posterior.log_prob(samples)
def test_inference_with_2d_x(embedding, method):

    num_dim = 2
    num_samples = 10
    num_simulations = 100

    prior = utils.BoxUniform(zeros(num_dim), torch.ones(num_dim))

    simulator, prior = prepare_for_sbi(simulator_2d, prior)

    theta_o = torch.ones(1, num_dim)

    if method == SNPE:
        net_provider = utils.posterior_nn(
            model="mdn",
            embedding_net=embedding(),
        )
        sample_kwargs = {"sample_with_mcmc": True}
        num_trials = 1
    elif method == SNLE:
        net_provider = utils.likelihood_nn(model="mdn",
                                           embedding_net=embedding())
        sample_kwargs = {}
        num_trials = 2
    else:
        net_provider = utils.classifier_nn(
            model="mlp",
            embedding_net_x=embedding(),
        )
        sample_kwargs = {
            "mcmc_method": "slice_np_vectorized",
            "mcmc_parameters": {
                "num_chains": 2
            },
        }
        num_trials = 2

    inference = method(prior, net_provider, show_progress_bars=False)
    theta, x = simulate_for_sbi(simulator, prior, num_simulations)
    _ = inference.append_simulations(theta, x).train(training_batch_size=100,
                                                     max_num_epochs=10)
    x_o = simulator(theta_o.repeat(num_trials, 1))
    posterior = inference.build_posterior(**sample_kwargs).set_default_x(x_o)

    posterior.log_prob(
        posterior.sample((num_samples, ), show_progress_bars=False))
示例#10
0
def test_inference_with_2d_x(embedding, method):

    num_dim = 2
    num_samples = 10
    num_simulations = 100

    prior = utils.BoxUniform(zeros(num_dim), torch.ones(num_dim))

    simulator, prior = prepare_for_sbi(simulator_2d, prior)

    theta_o = torch.ones(1, num_dim)
    x_o = simulator(theta_o)

    if method == SNPE:
        kwargs = dict(
            density_estimator=utils.posterior_nn(
                model="mdn",
                embedding_net=embedding(),
            ),
            sample_with_mcmc=True,
        )
    elif method == SNLE:
        kwargs = dict(density_estimator=utils.likelihood_nn(
            model="mdn", embedding_net=embedding()))
    else:
        kwargs = dict(density_estimator=utils.classifier_nn(
            model="mlp",
            embedding_net_x=embedding(),
        ))

    infer = method(
        simulator,
        prior,
        1,
        1,
        show_progress_bars=False,
        mcmc_method="slice_np",
        **kwargs,
    )

    posterior = infer(num_simulations=num_simulations,
                      training_batch_size=100,
                      max_num_epochs=10).set_default_x(x_o)

    posterior.log_prob(
        posterior.sample((num_samples, ), show_progress_bars=False))
示例#11
0
def test_apt_posterior_correction(sample_with_mcmc, mcmc_method, prior):
    """Test that leakage correction applied to sampling works, with both MCMC and rejection."""

    num_dim = 2

    if prior == "gaussian":
        prior = distributions.MultivariateNormal(
            loc=torch.zeros(num_dim), covariance_matrix=torch.eye(num_dim))
    else:
        prior = utils.BoxUniform(low=-1.0 * torch.ones(num_dim),
                                 high=torch.ones(num_dim))

    true_observation = torch.zeros((1, num_dim))

    neural_net = utils.posterior_nn(
        model="maf",
        prior=prior,
        context=true_observation,
    )

    infer = SnpeC(
        simulator=linear_gaussian,
        true_observation=true_observation,
        density_estimator=neural_net,
        prior=prior,
        num_atoms=-1,
        z_score_obs=True,
        simulation_batch_size=50,
        use_combined_loss=False,
        retrain_from_scratch_each_round=False,
        discard_prior_samples=False,
        sample_with_mcmc=sample_with_mcmc,
        mcmc_method=mcmc_method,
    )

    # Run inference.
    num_rounds, num_simulations_per_round = 1, 1000
    posterior = infer(num_rounds=num_rounds,
                      num_simulations_per_round=num_simulations_per_round)

    # Draw samples from posterior (should be corrected for leakage)
    # even if just num_rounds=1.
    samples = posterior.sample(10)

    # Evaluate the samples to check correction factor.
    posterior.log_prob(samples)
示例#12
0
    def flat_prior(self, low = None, high = None, log = True):
        """
        BoxUniform prior
        """


        if low == None:
            if log:
                low = torch.tensor([-7, .5])
            else:
                low = torch.tensor([1e-7, 10**.5])
        if high == None:
            if log:
                high = torch.tensor([-2.5, 20])
            else:
                high = torch.tensor([10**-2.5, 20])


        return utils.BoxUniform(low = low, high = high)
示例#13
0
def test_inference_with_nan_simulator(method: type, exclude_invalid_x: bool,
                                      percent_nans: float, set_seed):

    # likelihood_mean will be likelihood_shift+theta
    num_dim = 3
    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.3 * eye(num_dim)
    x_o = zeros(1, num_dim)
    num_samples = 500
    num_simulations = 2000

    def linear_gaussian_nan(theta,
                            likelihood_shift=likelihood_shift,
                            likelihood_cov=likelihood_cov):
        x = linear_gaussian(theta, likelihood_shift, likelihood_cov)
        # Set nan randomly.
        x[torch.rand(x.shape) < (percent_nans * 1.0 /
                                 x.shape[1])] = float("nan")

        return x

    prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))
    target_samples = samples_true_posterior_linear_gaussian_uniform_prior(
        x_o,
        likelihood_shift=likelihood_shift,
        likelihood_cov=likelihood_cov,
        num_samples=num_samples,
        prior=prior,
    )

    simulator, prior = prepare_for_sbi(linear_gaussian_nan, prior)
    inference = method(prior)

    theta, x = simulate_for_sbi(simulator, prior, num_simulations)
    _ = inference.append_simulations(
        theta, x).train(exclude_invalid_x=exclude_invalid_x)

    posterior = inference.build_posterior().set_default_x(x_o)

    samples = posterior.sample((num_samples, ))

    # Compute the c2st and assert it is near chance level of 0.5.
    check_c2st(samples, target_samples, alg=f"{method}")
def test_restricted_prior_log_prob(prior):
    """Test whether the log-prob method of the restricted prior works appropriately."""
    def simulator(theta):
        perturbed_theta = theta + 0.5 * torch.randn(2)
        perturbed_theta[theta[:, 0] < 0.8] = torch.as_tensor(
            [float("nan"), float("nan")])
        return perturbed_theta

    if prior == "uniform":
        prior = utils.BoxUniform(-2 * torch.ones(2), 2 * torch.ones(2))
    else:
        prior = MultivariateNormal(torch.zeros(2), torch.eye(2))
    theta, x = simulate_for_sbi(simulator, prior, 1000)

    restriction_estimator = RestrictionEstimator(prior=prior)
    restriction_estimator.append_simulations(theta, x)
    _ = restriction_estimator.train(max_num_epochs=40)
    restricted_prior = restriction_estimator.restrict_prior()

    def integrate_grid(distribution):
        resolution = 500
        range_ = 4
        x = torch.linspace(-range_, range_, resolution)
        y = torch.linspace(-range_, range_, resolution)
        X, Y = torch.meshgrid(x, y)
        xy = torch.stack([X, Y])
        xy = torch.reshape(xy, (2, resolution**2)).T
        dist_on_grid = torch.exp(distribution.log_prob(xy))
        integral = torch.sum(dist_on_grid) / resolution**2 * (2 * range_)**2
        return integral

    integal_restricted = integrate_grid(restricted_prior)
    error = torch.abs(integal_restricted - torch.as_tensor(1.0))
    assert error < 0.01, "The restricted prior does not integrate to one."

    theta = prior.sample((10_000, ))
    restricted_prior_probs = torch.exp(restricted_prior.log_prob(theta))

    valid_thetas = restricted_prior.predict(theta).bool()
    assert torch.all(restricted_prior_probs[valid_thetas] > 0.0
                     ), "Accepted theta have zero probability."
    assert torch.all(restricted_prior_probs[torch.logical_not(valid_thetas)] ==
                     0.0), "Rejected theta has non-zero probablity."
示例#15
0
def test_embedding_net_api(method, num_dim: int, embedding_net: str):
    """Tests the API when using a preconfigured embedding net."""

    x_o = zeros(1, num_dim)

    # likelihood_mean will be likelihood_shift+theta
    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.3 * eye(num_dim)

    prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))

    theta = prior.sample((1000, ))
    x = linear_gaussian(theta, likelihood_shift, likelihood_cov)

    if embedding_net == "mlp":
        embedding = FCEmbedding(input_dim=num_dim)
    else:
        raise NameError

    if method == "SNPE":
        density_estimator = posterior_nn("maf", embedding_net=embedding)
        inference = SNPE(prior,
                         density_estimator=density_estimator,
                         show_progress_bars=False)
    elif method == "SNLE":
        density_estimator = likelihood_nn("maf", embedding_net=embedding)
        inference = SNLE(prior,
                         density_estimator=density_estimator,
                         show_progress_bars=False)
    elif method == "SNRE":
        classifier = classifier_nn("resnet", embedding_net_x=embedding)
        inference = SNRE(prior,
                         classifier=classifier,
                         show_progress_bars=False)
    else:
        raise NameError

    _ = inference.append_simulations(theta, x).train(max_num_epochs=5)
    posterior = inference.build_posterior().set_default_x(x_o)

    s = posterior.sample((1, ))
    _ = posterior.potential(s)
示例#16
0
def infer_and_save_posterior(device: str, simulator_type: str,
                             simulation_type: str, params: Dict) -> None:
    parameter_prior = sbi_utils.BoxUniform(
        low=torch.tensor([0.0, 0.0]).type(torch.FloatTensor),
        high=torch.tensor([4.0, 4.0]).type(torch.FloatTensor))
    inferrer = inference_class.TimeSeriesInference(
        parameter_prior=parameter_prior, device=device)
    inferrer.load_simulator(dirname=ARTIFACT_PATH,
                            simulator_type=simulator_type,
                            simulation_type=simulation_type)
    batch_size = params.pop("batch_size")
    learning_rate = params.pop("learning_rate")
    hidden_features = params.pop("hidden_features")
    num_transforms = params.pop("num_transforms")
    inferrer.infer_snpe_posterior(
        embedding_net_conf=params,
        batch_size=batch_size,
        learning_rate=learning_rate,
        hidden_features=hidden_features,
        num_transforms=num_transforms,
    )
    inferrer.save_inference(ARTIFACT_PATH)
示例#17
0
def test_snl_posterior_correction(mcmc_method: str, prior_str: str):
    """Test SNL on linear Gaussian, comparing to ground truth posterior via MMD.

    NOTE: The mmd threshold is calculated based on a number of test runs and taking the mean plus 2 stds.

    Args:
        mcmc_method: which mcmc method to use for sampling
        prior_str: use gaussian or uniform prior
    """

    num_dim = 2
    num_samples = 30
    true_observation = torch.zeros((1, num_dim))

    if prior_str == "gaussian":
        prior = distributions.MultivariateNormal(
            loc=torch.zeros(num_dim), covariance_matrix=torch.eye(num_dim))
    else:
        prior = utils.BoxUniform(-1.0 * torch.ones(num_dim),
                                 torch.ones(num_dim))

    neural_likelihood = utils.likelihood_nn(
        model="maf",
        prior=prior,
        context=true_observation,
    )

    infer = SNL(
        simulator=linear_gaussian,
        prior=prior,
        true_observation=true_observation,
        density_estimator=neural_likelihood,
        simulation_batch_size=50,
        mcmc_method="slice-np",
    )

    posterior = infer(num_rounds=1, num_simulations_per_round=1000)

    posterior.sample(num_samples=num_samples)
示例#18
0
def test_api_snl_sampling_methods(mcmc_method: str, prior_str: str, set_seed):
    """Runs SNL on linear Gaussian and tests sampling from posterior via mcmc.

    Args:
        mcmc_method: which mcmc method to use for sampling
        prior_str: use gaussian or uniform prior
        set_seed: fixture for manual seeding
    """

    num_dim = 2
    num_samples = 10
    x_o = zeros((1, num_dim))

    if prior_str == "gaussian":
        prior = MultivariateNormal(loc=zeros(num_dim),
                                   covariance_matrix=eye(num_dim))
    else:
        prior = utils.BoxUniform(-1.0 * ones(num_dim), ones(num_dim))

    simulator, prior = prepare_for_sbi(diagonal_linear_gaussian, prior)
    inference = SNL(
        prior,
        show_progress_bars=False,
    )

    theta, x = simulate_for_sbi(simulator,
                                prior,
                                200,
                                simulation_batch_size=50)
    _ = inference.append_simulations(theta, x).train(max_num_epochs=5)
    posterior = inference.build_posterior(
        mcmc_method=mcmc_method).set_default_x(x_o)

    posterior.sample(sample_shape=(num_samples, ),
                     x=x_o,
                     mcmc_parameters={"thin": 3})
示例#19
0
def test_sre_posterior_correction(mcmc_method: str, prior_str: str):
    """Test leakage correction both for MCMC and rejection sampling.

    Args:
        mcmc_method: which mcmc method to use for sampling
        prior_str: one of "gaussian" or "uniform"
    """

    num_dim = 2
    if prior_str == "gaussian":
        prior = distributions.MultivariateNormal(
            loc=torch.zeros(num_dim), covariance_matrix=torch.eye(num_dim))
    else:
        prior = utils.BoxUniform(low=-1.0 * torch.ones(num_dim),
                                 high=torch.ones(num_dim))

    true_observation = torch.zeros(num_dim)

    classifier = utils.classifier_nn(
        "resnet",
        prior=prior,
        context=true_observation,
    )

    infer = SRE(
        simulator=linear_gaussian,
        prior=prior,
        true_observation=true_observation,
        classifier=classifier,
        simulation_batch_size=50,
        mcmc_method=mcmc_method,
    )

    posterior = infer(num_rounds=1, num_simulations_per_round=1000)

    samples = posterior.sample(num_samples=50)
示例#20
0
    def sample(self, sample_shape: torch.Size):
        """
        Return samples from the toy density.

        We first sample from a box uniform and then compute their L1-distance to a
        hyperplane in the 8D parameter space. We then accept with probability
        (1.-distance). If the distance is larger than 1.0, we never accept.
        """
        num_dim = 3
        all_samples = torch.empty(0, num_dim)
        num_accepted = 0
        while num_accepted < sample_shape[0]:
            proposed_samples = utils.BoxUniform(
                -2 * torch.ones(num_dim),
                2 * torch.ones(num_dim)).sample(sample_shape)
            vec_prior_samples = proposed_samples * self.normal_vec
            dist_to_zero = torch.abs(torch.sum(vec_prior_samples, dim=1))
            accept_or_not = (self.noise_factor * torch.rand(dist_to_zero.shape)
                             > dist_to_zero)
            accepted_samples = proposed_samples[accept_or_not]

            num_accepted += accepted_samples.shape[0]
            all_samples = torch.cat((all_samples, accepted_samples), dim=0)
        return all_samples
示例#21
0
def test_api_sre_sampling_methods(mcmc_method: str, prior_str: str, set_seed):
    """Test leakage correction both for MCMC and rejection sampling.

    Args:
        mcmc_method: which mcmc method to use for sampling
        prior_str: one of "gaussian" or "uniform"
        set_seed: fixture for manual seeding
    """

    num_dim = 2
    x_o = zeros(num_dim)
    if prior_str == "gaussian":
        prior = MultivariateNormal(loc=zeros(num_dim), covariance_matrix=eye(num_dim))
    else:
        prior = utils.BoxUniform(low=-1.0 * ones(num_dim), high=ones(num_dim))

    simulator, prior = prepare_for_sbi(diagonal_linear_gaussian, prior)
    inference = SRE(prior, classifier="resnet", show_progress_bars=False,)

    theta, x = simulate_for_sbi(simulator, prior, 200, simulation_batch_size=50)
    _ = inference.append_simulations(theta, x).train(max_num_epochs=5)
    posterior = inference.build_posterior(mcmc_method=mcmc_method)

    posterior.sample(sample_shape=(10,), x=x_o)
def main() -> None:
    # Parse command line arguments
    parser = argparse.ArgumentParser(description="CNN Tuning")
    parser.add_argument("--max_evals",
                        required=False,
                        type=int,
                        default=5,
                        help="Maximum number of sampled sets of parameters ")
    args, *_ = parser.parse_known_args()

    mlflow.set_experiment(f"snpe-fully-padded-cnn-timeseries-tuning")
    # Initialize the model and load context - needs to be done whether using local data or doing transforms
    print("\t Initialize inference object")
    parameter_prior = sbi_utils.BoxUniform(
        low=torch.tensor([0.0, 0.0]).type(torch.FloatTensor),
        high=torch.tensor([4.0, 4.0]).type(torch.FloatTensor))
    inferrer = TimeSeriesInference(parameter_prior=parameter_prior,
                                   device="gpu")
    inferrer.load_simulator(dirname=ARTIFACT_PATH,
                            simulator_type="double_rho",
                            simulation_type="timeseries")

    print("\t Tuning model")
    tuning(inferrer=inferrer, max_evals=args.max_evals)
示例#23
0
import torch
import pandas as pd
import sys
import csv

from vit_pytorch.efficient import ViT
from linformer import Linformer
from vit_pytorch import ViT as ViT_modified
from collections import Counter, OrderedDict
import torch.nn as nn

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

Prior= utils.BoxUniform(low=torch.tensor([0.1, -1.5, -6.0, -3.5, -3.5,  2.0, 0.7, 300.0, 0., 0., 0.,\
                                  1., 0. ]), \
                      high=torch.tensor([1.6, 1.5, 3.0, 4.5, 4.5, 5.5, 2.0, 2300.0, 1., 1., 1.,\
                                      2., 1. ]), device='cuda')


def build_den():
    class VisualTrans(nn.Module):
        def __init__(self, file_path):
            super(VisualTrans, self).__init__()

            self.file_path = file_path

            self.model = ViT_modified(
                n_classes=1,
                image_size=(1,
                            962),  # image size is a tuple of (height, width)
                patch_size=(1, 13),  # patch size is a tuple of (height, width)
示例#24
0
 def prior_(self):
     self.prior = utils.BoxUniform(low=self.sim.min, high=self.sim.max)
示例#25
0
def test_sample_conditional(set_seed):
    """
    Test whether sampling from the conditional gives the same results as evaluating.

    This compares samples that get smoothed with a Gaussian kde to evaluating the
    conditional log-probability with `eval_conditional_density`.

    `eval_conditional_density` is itself tested in `sbiutils_test.py`. Here, we use
    a bimodal posterior to test the conditional.
    """

    num_dim = 3
    dim_to_sample_1 = 0
    dim_to_sample_2 = 2

    x_o = zeros(1, num_dim)

    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.1 * eye(num_dim)

    prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))

    def simulator(theta):
        if torch.rand(1) > 0.5:
            return linear_gaussian(theta, likelihood_shift, likelihood_cov)
        else:
            return linear_gaussian(theta, -likelihood_shift, likelihood_cov)

    net = utils.posterior_nn("maf", hidden_features=20)

    simulator, prior = prepare_for_sbi(simulator, prior)
    inference = SNPE_C(
        prior,
        density_estimator=net,
        show_progress_bars=False,
    )

    # We need a pretty big dataset to properly model the bimodality.
    theta, x = simulate_for_sbi(simulator, prior, 10000)
    _ = inference.append_simulations(theta, x).train(max_num_epochs=50)
    posterior = inference.build_posterior().set_default_x(x_o)
    samples = posterior.sample((50, ))

    # Evaluate the conditional density be drawing samples and smoothing with a Gaussian
    # kde.
    cond_samples = posterior.sample_conditional(
        (500, ),
        condition=samples[0],
        dims_to_sample=[dim_to_sample_1, dim_to_sample_2])
    _ = utils.pairplot(
        cond_samples,
        limits=[[-2, 2], [-2, 2], [-2, 2]],
        fig_size=(2, 2),
        diag="kde",
        upper="kde",
    )

    limits = [[-2, 2], [-2, 2], [-2, 2]]

    density = gaussian_kde(cond_samples.numpy().T, bw_method="scott")

    X, Y = np.meshgrid(
        np.linspace(
            limits[0][0],
            limits[0][1],
            50,
        ),
        np.linspace(
            limits[1][0],
            limits[1][1],
            50,
        ),
    )
    positions = np.vstack([X.ravel(), Y.ravel()])
    sample_kde_grid = np.reshape(density(positions).T, X.shape)

    # Evaluate the conditional with eval_conditional_density.
    eval_grid = utils.eval_conditional_density(
        posterior,
        condition=samples[0],
        dim1=dim_to_sample_1,
        dim2=dim_to_sample_2,
        limits=torch.tensor([[-2, 2], [-2, 2], [-2, 2]]),
    )

    # Compare the two densities.
    sample_kde_grid = sample_kde_grid / np.sum(sample_kde_grid)
    eval_grid = eval_grid / torch.sum(eval_grid)

    error = np.abs(sample_kde_grid - eval_grid.numpy())

    max_err = np.max(error)
    assert max_err < 0.0025
示例#26
0
def test_c2st_snpe_on_linearGaussian(
    num_dim: int,
    prior_str: str,
    set_seed,
):
    """Test whether SNPE C infers well a simple example with available ground truth.

    Args:
        set_seed: fixture for manual seeding
    """

    x_o = zeros(1, num_dim)
    num_samples = 1000

    # likelihood_mean will be likelihood_shift+theta
    likelihood_shift = -1.0 * ones(num_dim)
    likelihood_cov = 0.3 * eye(num_dim)

    if prior_str == "gaussian":
        prior_mean = zeros(num_dim)
        prior_cov = eye(num_dim)
        prior = MultivariateNormal(loc=prior_mean, covariance_matrix=prior_cov)
        gt_posterior = true_posterior_linear_gaussian_mvn_prior(
            x_o[0], likelihood_shift, likelihood_cov, prior_mean, prior_cov)
        target_samples = gt_posterior.sample((num_samples, ))
    else:
        prior = utils.BoxUniform(-2.0 * ones(num_dim), 2.0 * ones(num_dim))
        target_samples = samples_true_posterior_linear_gaussian_uniform_prior(
            x_o,
            likelihood_shift,
            likelihood_cov,
            prior=prior,
            num_samples=num_samples)

    def simulator(theta):
        return linear_gaussian(theta, likelihood_shift, likelihood_cov)

    simulator, prior = prepare_for_sbi(simulator, prior)
    inference = SNPE_C(
        prior,
        show_progress_bars=False,
    )

    theta, x = simulate_for_sbi(simulator,
                                prior,
                                2000,
                                simulation_batch_size=1000)
    _ = inference.append_simulations(theta, x).train(training_batch_size=100)
    posterior = inference.build_posterior().set_default_x(x_o)
    samples = posterior.sample((num_samples, ))

    # Compute the c2st and assert it is near chance level of 0.5.
    check_c2st(samples, target_samples, alg="snpe_c")

    # Checks for log_prob()
    if prior_str == "gaussian":
        # For the Gaussian prior, we compute the KLd between ground truth and posterior.
        dkl = get_dkl_gaussian_prior(posterior, x_o[0], likelihood_shift,
                                     likelihood_cov, prior_mean, prior_cov)

        max_dkl = 0.15

        assert (
            dkl < max_dkl
        ), f"D-KL={dkl} is more than 2 stds above the average performance."

    elif prior_str == "uniform":
        # Check whether the returned probability outside of the support is zero.
        posterior_prob = get_prob_outside_uniform_prior(posterior, num_dim)
        assert (
            posterior_prob == 0.0
        ), "The posterior probability outside of the prior support is not zero"

        # Check whether normalization (i.e. scaling up the density due
        # to leakage into regions without prior support) scales up the density by the
        # correct factor.
        (
            posterior_likelihood_unnorm,
            posterior_likelihood_norm,
            acceptance_prob,
        ) = get_normalization_uniform_prior(posterior, prior, x_o)
        # The acceptance probability should be *exactly* the ratio of the unnormalized
        # and the normalized likelihood. However, we allow for an error margin of 1%,
        # since the estimation of the acceptance probability is random (based on
        # rejection sampling).
        assert (
            acceptance_prob * 0.99 < posterior_likelihood_unnorm /
            posterior_likelihood_norm < acceptance_prob * 1.01
        ), "Normalizing the posterior density using the acceptance probability failed."
示例#27
0
    #     5: "joint_6_dryfriction",
    #     6: "joint_7_dryfriction",
    # }
    # dp_mapping = create_damping_dryfriction_domain_param_map_wamjsc()

    # Behavioral policy
    policy_hparam = dict()
    policy = TimePolicy(env_real.spec, wam_jsp_7dof_sin, env_real.dt)

    # Prior
    dp_nom = env_sim.get_nominal_domain_param()
    prior_hparam = dict(
        low=to.tensor([dp_nom[name] * 0.5 for name in dp_mapping.values()]),
        high=to.tensor([dp_nom[name] * 1.5 for name in dp_mapping.values()]),
    )
    prior = sbiutils.BoxUniform(**prior_hparam)

    # Time series embedding
    embedding_hparam = dict(
        downsampling_factor=1,
        # len_rollouts=env_sim.max_steps,
        # recurrent_network_type=nn.RNN,
        # only_last_output=True,
        # hidden_size=20,
        # num_recurrent_layers=1,
        # output_size=1,
    )
    embedding = create_embedding(BayesSimEmbedding.name, env_sim.spec,
                                 **embedding_hparam)

    # Posterior (normalizing flow)
示例#28
0
    % (N, num_sims, num_batch, num_transforms, num_atoms, g, K, rs))

save_path = os.path.join(base_path, save_dir)
if not os.path.exists(save_path):
    os.makedirs(save_path)

if os.path.exists(os.path.join(base_path, save_dir, "optim.pkl")):
    print("SNPE optimization already run. Exitting.")
    exit()

_W_eigs = get_W_eigs_np(g, K)

M = 1000
RANK = 2
num_dim = 2 * N * RANK
prior = utils.BoxUniform(low=-1.0 * torch.ones(num_dim),
                         high=1.0 * torch.ones(num_dim))


def simulator(params):
    params = params.numpy()
    U = np.reshape(params[:(RANK * N)], (N, RANK))
    V = np.reshape(params[(RANK * N):], (N, RANK))
    x = _W_eigs(U, V)
    return x


simulator, prior = prepare_for_sbi(simulator, prior)
density_estimator_build_fun = posterior_nn(
    model="maf",
    hidden_features=50,
    num_transforms=num_transforms,
示例#29
0
文件: run_sbi.py 项目: Wrede/BNN-LFI
def run_snpe(total_runs=10, num_generation=6, seed=46):

    theta_true = np.log([1.0, 0.005, 1.0])

    torch.manual_seed(seed)
    num_workers = 16  #for parallel execution of simulations
    Ndata = 1000
    use_embedding_net = True
    use_mcmc = False  #becomes very slow, but can handle leakage
    result_posterior = []
    store_time = []

    a0, b0 = np.log(0.002), np.log(2)
    prior = utils.BoxUniform(low=torch.tensor([a0, a0, a0]),
                             high=torch.tensor([b0, b0, b0]))

    simulator_sbi, prior = prepare_for_sbi(wrapper, prior)

    x_o = np.load("target_original_shape_ts.npy")
    x_o = torch.tensor(x_o)
    #x_o = torch.flatten(x_o)#.flatten()reshape((2,51))

    #NN for summary statistic
    embedding_net = SummaryNet_large()

    try:
        for run in range(total_runs):
            print(f"starting run {run}")

            theta_store = []
            time_ticks = []
            posteriors = []
            proposal = prior

            if use_embedding_net:
                neural_posterior = utils.posterior_nn(
                    model='maf',
                    embedding_net=embedding_net,
                    hidden_features=10,
                    num_transforms=2)
            else:
                neural_posterior = utils.posterior_nn(model='maf',
                                                      hidden_features=10,
                                                      num_transforms=2)

            inference = SNPE_C(prior=prior, density_estimator=neural_posterior)

            for i in range(num_generation):
                print(f"starting round {i}")
                time_begin = time.time()
                theta, x = simulate_for_sbi(simulator_sbi,
                                            proposal,
                                            num_simulations=Ndata,
                                            num_workers=num_workers)

                mask = torch.tensor(np.invert(np.isnan(x.numpy())[:, 0, 0]))
                x = x[mask, :, :]
                theta = theta[mask, :]

                density_estimator = inference.append_simulations(
                    theta, x, proposal=proposal).train()
                posterior = inference.build_posterior(
                    density_estimator, sample_with_mcmc=use_mcmc)
                print("building post done")
                posteriors.append(posterior)
                proposal = posterior.set_default_x(x_o)

                posterior_samples = posterior.sample((Ndata, ), x=x_o).numpy()
                print("Post samples done")
                theta_store.append(posterior_samples)
                time_ticks.append(time.time() - time_begin)

            result_posterior.append(theta_store)
            store_time.append(time_ticks)
    except KeyboardInterrupt:
        return np.asarray(result_posterior), np.asarray(store_time), posteriors
    return np.asarray(result_posterior), np.asarray(store_time), posteriors
示例#30
0
def test_apt_on_linearGaussian_based_on_mmd(num_dim: int, prior_str: str,
                                            algorithm_str: str,
                                            simulation_batch_size: int):
    """Test whether APT infers well a simple example where ground truth is available."""

    true_observation = torch.zeros(num_dim)
    num_samples = 100

    if prior_str == "gaussian":
        prior = distributions.MultivariateNormal(
            loc=torch.zeros(num_dim), covariance_matrix=torch.eye(num_dim))
        target_samples = get_true_posterior_samples_linear_gaussian_mvn_prior(
            true_observation, num_samples=num_samples)
    else:
        prior = utils.BoxUniform(-1.0 * torch.ones(num_dim),
                                 torch.ones(num_dim))
        target_samples = get_true_posterior_samples_linear_gaussian_uniform_prior(
            true_observation, num_samples=num_samples, prior=prior)

    neural_net = utils.posterior_nn(model="maf",
                                    prior=prior,
                                    context=true_observation)

    snpe_common_args = dict(
        simulator=linear_gaussian,
        true_observation=true_observation,
        density_estimator=neural_net,
        prior=prior,
        z_score_obs=True,
        simulation_batch_size=simulation_batch_size,
        use_combined_loss=False,
        retrain_from_scratch_each_round=False,
        discard_prior_samples=False,
    )

    if algorithm_str == "snpe_b":
        infer = SnpeB(**snpe_common_args)
    elif algorithm_str == "snpe_c":
        infer = SnpeC(num_atoms=-1, sample_with_mcmc=False, **snpe_common_args)

    # Run inference.
    num_rounds, num_simulations_per_round = 1, 1000
    posterior = infer(
        num_rounds=num_rounds,
        num_simulations_per_round=num_simulations_per_round,
    )

    # Draw from posterior.
    samples = posterior.sample(num_samples)

    # Compute the mmd, and check if larger than expected
    mmd = utils.unbiased_mmd_squared(target_samples, samples)
    max_mmd = 0.03

    print(f"mmd for {algorithm_str} is {mmd}.")

    assert (mmd < max_mmd
            ), f"MMD={mmd} is more than 2 stds above the average performance."

    # Checks for log_prob()
    if prior_str == "gaussian":
        # For the Gaussian prior, we compute the KLd between ground truth and posterior.
        dkl = test_utils.get_dkl_gaussian_prior(posterior, true_observation,
                                                num_dim)

        max_dkl = 0.05 if num_dim == 1 else 0.8

        assert (
            dkl < max_dkl
        ), f"D-KL={dkl} is more than 2 stds above the average performance."

    elif prior_str == "uniform":
        # Check whether the returned probability outside of the support is zero.
        posterior_prob = test_utils.get_prob_outside_uniform_prior(
            posterior, num_dim)
        assert (
            posterior_prob == 0.0
        ), "The posterior probability outside of the prior support is not zero"

        # Check whether normalization (i.e. scaling up the density due
        # to leakage into regions without prior support) scales up the density by the
        # correct factor.
        (
            posterior_likelihood_unnorm,
            posterior_likelihood_norm,
            acceptance_prob,
        ) = test_utils.get_normalization_uniform_prior(posterior, prior,
                                                       true_observation)
        # The acceptance probability should be *exactly* the ratio of the unnormalized
        # and the normalized likelihood. However, we allow for an error margin of 1%,
        # since the estimation of the acceptance probability is random (based on
        # rejection sampling).
        assert (
            acceptance_prob * 0.99 < posterior_likelihood_unnorm /
            posterior_likelihood_norm < acceptance_prob * 1.01
        ), "Normalizing the posterior density using the acceptance probability failed."