sbi-dev / sbi

Simulation-based inference toolkit
https://sbi-dev.github.io/sbi/
Apache License 2.0
546 stars 133 forks source link

Expected value argument to be within the support but found invalid values #1145

Closed ManonRegamey closed 2 months ago

ManonRegamey commented 2 months ago

I'm encountering a perplexing issue with the sbi Python package in my code. I've been using it to train a model with multiple input parameters and corresponding output simulations. Initially, everything seems to be going smoothly—I've defined priors on the input parameters and successfully trained the model.

Here is how I implemented my prior:

class CustomDistribution(Distribution):
    def __init__(self, lower_bounds, upper_bounds, mean, std_dev):
        super(CustomDistribution, self).__init__()
        self.lower_bounds = torch.tensor(lower_bounds, dtype=torch.float32)
        self.upper_bounds = torch.tensor(upper_bounds, dtype=torch.float32)
        self.normal_dist = Normal(mean, std_dev)

    def sample(self, sample_shape=torch.Size()):
        uniform_samples = Uniform(self.lower_bounds, self.upper_bounds).sample(sample_shape)
        normal_sample = self.normal_dist.sample(sample_shape + torch.Size([1]))  # Adjusting shape
        return torch.cat((uniform_samples, normal_sample), dim=-1)

    def log_prob(self, value):
        uniform_log_probs = Uniform(self.lower_bounds, self.upper_bounds).log_prob(value[:, :5]).sum(dim=-1)
        normal_log_prob = self.normal_dist.log_prob(value[:, 5])
        return uniform_log_probs + normal_log_prob

lower_bounds = [0.155, 0.6, 0.5, -1., 0]
upper_bounds = [0.7, 1.2, 2., 1., 2]

mean = 70.0
std_dev = 3.0

prior = CustomDistribution(lower_bounds, upper_bounds, mean, std_dev)

However, the problem arises when I compare the model's predictions to my observed data: samples = model.sample((10000,), x= observed_data) Each time I perform this comparison, I encounter an error message stating that the expected values are not within the defined support range.

This error is confusing because I've been diligent in setting up these priors, expecting them to constrain the search space during both training and prediction phases. Yet somehow, the sbi search is still venturing outside these boundaries during the comparison process.

Sbi issue
michaeldeistler commented 2 months ago

Could you try with using MultipleIndependent to define your prior?

import torch
from sbi.utils import MultipleIndependent, BoxUniform
from torch.distributions import MultivariateNormal

prior = MultipleIndependent([
   BoxUniform(-torch.ones(1,), torch.ones(1,)),
   BoxUniform(-torch.ones(1,), torch.ones(1,)),
   MultivariateNormal(torch.zeros(1,), torch.eye(1)),
])
janfb commented 2 months ago

Hi @ManonRegamey , I have not looked at the error in detail but there might a quick fix. Instead of using your custom prior that seems to concatenate two uniform and one Gaussian parameters independently, you could just use the MultipleIndependent prior implemented in the sbi package.

from sbi.utils import BoxUniform
from sbi.utils.user_input_checks import process_prior
list_of_priors = [BoxUniform(lower_bounds, upper_bounds), Normal(loc, std)]
prior = process_prior(list_of_priors)
inference = SNPE(prior=prior, ...)

Does that help?

janfb commented 2 months ago

haha - let's hope at least one of the proposal work.

ManonRegamey commented 2 months ago

Hello! Thanks a lot for your proposals, it works! :)

michaeldeistler commented 2 months ago

Great, happy to hear that!