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.