-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
log_prob fails for Restricted Prior when sampling with SIR #790
Comments
Thanks for creating this issue! I can not reproduce the error though. Two questions:
import torch
from torch import eye, ones, zeros
from torch.distributions import MultivariateNormal
from sbi.inference import SNPE, DirectPosterior
from sbi.utils import RestrictedPrior, get_density_thresholder, BoxUniform
num_dim = 2
x_o = zeros((1, num_dim))
prior = BoxUniform(-ones(num_dim), ones(num_dim))
theta = prior.sample((100,))
x = theta + torch.randn(theta.shape)
inference = SNPE(prior=prior)
_ = inference.append_simulations(theta, x).train()
posterior = inference.build_posterior().set_default_x(x_o)
accept_reject_fn = get_density_thresholder(posterior, quantile=1e-4)
proposal = RestrictedPrior(prior, accept_reject_fn, posterior=posterior, sample_with="sir")
theta = proposal.sample((1000,))
|
The code you gave me works perfectly. It is when I add: that the error is raised. 2.) Since the process_prior(prior,...) function checks if the prior can produce log_prob and I cannot seem to get the log_prob with the restricted prior when using SIR, the error occurs during process_prior. |
Got it, thanks! The quick solution for now is to not run from sbi.inference import SNPE
from sbi.utils import get_density_thresholder, RestrictedPrior
inference = SNPE(prior)
proposal = prior
for _ in range(rounds):
theta = proposal.sample((num_sims,))
x = simulator(theta)
_ = inference.append_simulations(theta, x).train(force_first_round_loss=True)
posterior = inference.build_posterior().set_default_x(x_o)
accept_reject_fn = get_density_thresholder(posterior, quantile=1e-4)
proposal = RestrictedPrior(prior, accept_reject_fn, sample_with="rejection") Note that the I'll think a bit more about whether we should remove the |
I was hoping to use the restrictedPrior as a proposal itself in the initialization of the SNPE(prior = RestrictedPrior) (which also checks if the prior has a log_prob) as I am trying to learn two different posterior distributions. The restrictedPrior would serve as a proposal for the second distribution. For now it works if I just use sample_with="rejection" since it returns a log_prob. Another issue with restrictedPrior I can raise separately, is there any way to pickle it ? Currently it cannot pickle the get_density_thresholder function so it raises an error. |
Thanks for clarifying! I agree that we should allow passing the RestrictedPrior to be passed at unit. I will fix this soon, but I don’t have time this week. Until then, you can very easily work around this: In SNPE, the prior passed at initialization is the prior, not the proposal. In TSNPE (and in single round NPE), the prior (passed at init) is not used during training at all (it is only used after training to reject samples from the approximate posterior that lie outside of the prior). Thus, you do not have to pass anything: inference = SNPE() or you simply pass the original prior: Inference = SNPE(prior=prior) The proposal is simply the distribution from the parameters theta are drawn. It does not require a log_prob method and you do not have to pass it at initialization. You will only lose the feature to reject samples from the approximate posterior that lie outside of the prior. |
That is only true for SNPE correct ? For SNLE/SNRE it requires the prior in order to calculate the posterior distribution, P(theta|X) = P(X|theta)P(theta) for SNLE and P(theta|X) = r(X,theta)P(theta) for SNRE |
Yes, that's only true for SNPE. |
For now, I recommend simply passing the original prior at initialization. I shouldn't make a big difference. I'll fix this next week. |
@michaeldeistler any chance we can get this fix in for the release? |
I think the problem here is that when calling One solution would be making Or change the wrapping in |
I am trying to use a restricted prior as a proposal and when creating it with the parameter SIR the process_prior function fails because it cannot calculate the log prob.
Also does this in general when simply doing:
It seems to be like there is no acceptance_rate analgous for SIR, whereas "rejection" has one explicitly defined. Is this intentional ? SIR provides a significant speed boost, so it would be nice to use. It looks like it would be possible to implement in the "sampling_importance_resampling" function.
The text was updated successfully, but these errors were encountered: