sbi-dev / sbi

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

maximum value of postorior distributions #583

Closed Ziaeemehr closed 2 years ago

Ziaeemehr commented 2 years ago

Hi, Is there any function that extracts the maximum values of posteriors from samples.

f

I just want values of maximum in histograms, a normal way would be a histogram from posteriors for each dimension, applying KDE to smooth the histogram calculate the index of maximum and find the corresponding values. These are done with use_pairplot functions, but no direct access to the processed histogram.

janfb commented 2 years ago

hi, you can use posterior.map() to obtain the maximum a posteriori estimate of the posterior: https://github.com/mackelab/sbi/blob/b8551d03373544f089797afcac9a22717cd4773a/sbi/inference/posteriors/base_posterior.py#L157-L167

Ziaeemehr commented 2 years ago

There are two points: map is using steepest descent and if we have a multimodal distribution, probably can be stuck in local min right? I already sample the posterior (with a large number of parameters it takes several hours ), so it would be better to use available distributions and just process the histograms, I may lose some precision but still be fine and extremely quick.

michaeldeistler commented 2 years ago

.map does the following: 1) Sample from the proposal. If you pass "posterior" it will sample from the posterior. 2) Pick the 100 samples that had the highest log_prob(). 3) Run gradient ascent on those 100 samples. 4) Return the very best sample after the gradient steps.

Because it starts with 100 samples it should be relatively robust to local optima.

Ziaeemehr commented 2 years ago

Thank you for your quick reply! now it makes sense, I still don't understand if it picks 100 samples why does it need to set an initial set_x?

ValueError: Context `x` needed when a default has not been set.If you'd like to have a default, use the `.set_default_x()` method.

it needs an initial x shape [1 x number of parameters], and it is not an optional parameter. or maybe I am using it incorrectly.

inference = inference.append_simulations(theta, x)
 _density_estimator = inference.train()
posterior = inference.build_posterior(_density_estimator)
samples = posterior.sample((num_samples,), x=obse_stats)
# posterior.set_default_x(obse_stats)
map_ = posterior.map(init_method="posterior")