sbi
sbi copied to clipboard
The size of tensor mismatch when sample from posterior
Hi,
I am trying to sample from the posterior. I have 4 parameters in my model, when I try to sample from posterior, I got this error
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Input In [14], in <cell line: 1>()
----> 1 posterior_samples = posterior.sample((10000,),x = x_0)
File ~\anaconda3\lib\site-packages\sbi\inference\posteriors\mcmc_posterior.py:236, in MCMCPosterior.sample(self, sample_shape, x, method, thin, warmup_steps, num_chains, init_strategy, init_strategy_num_candidates, mcmc_parameters, mcmc_method, sample_with, num_workers, show_progress_bars)
231 init_strategy_num_candidates = _maybe_use_dict_entry(
232 init_strategy_num_candidates, "init_strategy_num_candidates", m_p
233 )
234 self.potential_ = self._prepare_potential(method) # type: ignore
--> 236 initial_params = self._get_initial_params(
237 init_strategy, num_chains, num_workers, show_progress_bars # type: ignore
238 )
239 num_samples = torch.Size(sample_shape).numel()
241 track_gradients = method in ("hmc", "nuts")
File ~\anaconda3\lib\site-packages\sbi\inference\posteriors\mcmc_posterior.py:363, in MCMCPosterior._get_initial_params(self, init_strategy, num_chains, num_workers, show_progress_bars)
356 initial_params = torch.cat(
357 Parallel(n_jobs=num_workers)(
358 delayed(seeded_init_fn)(seed) for seed in seeds
359 )
360 )
361 else:
362 initial_params = torch.cat(
--> 363 [init_fn() for _ in range(num_chains)] # type: ignore
364 )
366 return initial_params
File ~\anaconda3\lib\site-packages\sbi\inference\posteriors\mcmc_posterior.py:363, in <listcomp>(.0)
356 initial_params = torch.cat(
357 Parallel(n_jobs=num_workers)(
358 delayed(seeded_init_fn)(seed) for seed in seeds
359 )
360 )
361 else:
362 initial_params = torch.cat(
--> 363 [init_fn() for _ in range(num_chains)] # type: ignore
364 )
366 return initial_params
File ~\anaconda3\lib\site-packages\sbi\inference\posteriors\mcmc_posterior.py:301, in MCMCPosterior._build_mcmc_init_fn.<locals>.<lambda>()
299 return lambda: proposal_init(proposal, transform=transform, **kwargs)
300 elif init_strategy == "sir":
--> 301 return lambda: sir(proposal, potential_fn, transform=transform, **kwargs)
302 elif init_strategy == "latest_sample":
303 latest_sample = IterateParameters(self._mcmc_init_params, **kwargs)
File ~\anaconda3\lib\site-packages\sbi\samplers\mcmc\init_strategy.py:67, in sir(proposal, potential_fn, transform, sir_num_batches, sir_batch_size, **kwargs)
65 batch_draws = proposal.sample((sir_batch_size,)).detach()
66 init_param_candidates.append(batch_draws)
---> 67 log_weights.append(potential_fn(batch_draws).detach())
68 log_weights = torch.cat(log_weights)
69 init_param_candidates = torch.cat(init_param_candidates)
File ~\anaconda3\lib\site-packages\sbi\inference\potentials\likelihood_based_potential.py:94, in LikelihoodBasedPotential.__call__(self, theta, track_gradients)
86 # Calculate likelihood over trials and in one batch.
87 log_likelihood_trial_sum = _log_likelihoods_over_trials(
88 x=self.x_o,
89 theta=theta.to(self.device),
90 net=self.likelihood_estimator,
91 track_gradients=track_gradients,
92 )
---> 94 return log_likelihood_trial_sum + self.prior.log_prob(theta)
RuntimeError: The size of tensor a (1000) must match the size of tensor b (4) at non-singleton dimension 1
I know tensor a is like a number of particels. However, I am not sure why there is tensor b (4). Can you give me some help to debug this one? I have personalized prior and .sample() and .log_prob() work correctly for such prior.
the log_prob() in my prior like this
def log_prob(self, values):
log_probs = torch.ones(values.size()[0],values.size()[1])
length = values.size()[0]
if self.return_numpy:
values = torch.as_tensor(values)
for i in range(values.size()[0]):
log_probs[i][0] = self.dist2.log_prob(values[i][0])
log_probs[i][1] = self.dist3.log_prob(values[i][1])
log_probs[i][2] = torch.log(torch.exp(torch.log(self.loc1*torch.ones(1)) + 1/(torch.sqrt(2*math.pi*torch.ones(1)))*torch.exp(-0.5 * (values[i][2]-0)**2)))
log_probs[i][3] = torch.log(torch.exp(torch.log(self.loc2*torch.ones(1)) + 1/(torch.sqrt(2*math.pi*torch.ones(1)))*torch.exp(-0.5 * (values[i][3]-0)**2)))
return log_probs.numpy() if self.return_numpy else log_probs
it return size as (n,4). I undestand I need a size (n,), but the reshape method is not working here
I think you need to sum the log probs over the second dimension: your prior has four independent dimensions, but the final log prob should be the joint over all dimensions, e.g., return log_probs.sum(1)
btw, I am wondering why you are converting back and forth between torch
and numpy
? within sbi
it should be fine to only use torch
. We added the numpy
option for cases where the prior only returns numpy
, but yours seems to be sampling form torch
distributions.
Closing this due to inactivity. Feel free to re-open if concrete questions come up.