Description
Consider a Bayesian model where the likelihood is a binomial distribution with probability parameter $p$. Let us consider an over-parameterized model where we write $p = p_1 p_2$. Assume that each $p_i$ has a uniform prior on the interval $[0, 1]$.
In summary:
\[\begin{aligned} p_1 &\sim \text{Unif}(0, 1) \\ p_2 &\sim \text{Unif}(0, 1) \\ y &\sim \text{Bin}(n, p_1 p_2) \end{aligned}\]
Here we use the values:
Parameter | Value |
---|---|
Number of trials $n$ | 100000 |
Number of successes $y$ | 50000 |
This is a toy example of an unidentifiable parameterization. In practice many popular Bayesian models are unidentifiable.
When there are many observations, the posterior of unidentifiable models concentrate on a sub-manifold, making sampling difficult, as shown in the following pair plots.
Pair plot
Diagonal entries show estimates of the marginal densities as well as the (0.16, 0.5, 0.84) quantiles (dotted lines). Off-diagonal entries show estimates of the pairwise densities.
Movie linked below (🍿) superimposes 100 iterations of MCMC.

Trace plots

Intervals
Nominal coverage requested: 0.95 (change via interval_probability
option which can be passed to report()
).
The credible interval (naive_left, naive_right)
is constructed using the quantiles of the posterior distribution. It is naive in the sense that it does not take into account additional uncertainty brought by the Monte Carlo approximation.
The radius of a Monte Carlo confidence interval with the same nominal coverage, constructed on each of the end points of the naive interval is shown in mcci_radius_left
and mcci_radius_left
.
Finally, (fused_left, fused_right)
is obtained by merging the two sources of uncertainty: statistical, captured by the credible interval, and computational, captured by the confidence intervals on the end points.
parameters | naive_left | naive_right | mcci_radius_left | mcci_radius_right | fused_left | fused_right |
---|---|---|---|---|---|---|
p1 | 0.505263 | 0.97405 | 0.00409735 | 0.0306463 | 0.501166 | 1.0047 |
p2 | 0.513555 | 0.99029 | 0.017401 | 0.00692447 | 0.496154 | 0.997214 |
log_density | -13.565 | -9.16351 | 0.969294 | 0.0158598 | -14.5343 | -9.14765 |
Moments, MCSE, ESS, etc
The ESS/MCSE/Rhat estimators use InferenceReports.safe_summarystats(chains)
, which are based on the truncated autocorrelation estimator (Geyer, 1992, sec 3.3) computed with FFT with no lag limit. As a result, these estimators should be safe to use in the low relative ESS regime, in contrast to the defaults used in MCMCChains, which lead to catastrophic ESS over-estimation in that regime.
parameters | mean | std | mcse | ess_bulk | ess_tail | rhat | ess_per_sec |
---|---|---|---|---|---|---|---|
p1 | 0.692481 | 0.148287 | 0.0209421 | 71.0811 | 203.673 | 1.01627 | missing |
p2 | 0.754933 | 0.155562 | 0.0210788 | 71.9976 | 203.673 | 1.00814 | missing |
log_density | -10.3602 | 1.12445 | 0.0694097 | 208.782 | 383.238 | 1.00259 | missing |
Cumulative traces
For each iteration $i$, shows the running average up to $i$, $\frac{1}{i} \sum_{n = 1}^{i} x_n$.

Local communication barrier
When the global communication barrier is large, many chains may be required to obtain tempered restarts.
The local communication barrier can be used to visualize the cause of a high global communication barrier. For example, if there is a sharp peak close to a reference constructed from the prior, it may be useful to switch to a variational approximation.

GCB estimation progress
Estimate of the Global Communication Barrier (GCB) as a function of the adaptation round.
The global communication barrier can be used to set the number of chains. The theoretical framework of Syed et al., 2021 yields that under simplifying assumptions, it is optimal to set the number of chains (the argument n_chains
in pigeons()
) to roughly 2Λ.
Last round estimate: $3.5147080542681985$

Evidence estimation progress
Estimate of the log normalization (computed using the stepping stone estimator) as a function of the adaptation round.
Last round estimate: $-11.768917526035043$

Round trips
Number of tempered restarts as a function of the adaptation round.
A tempered restart happens when a sample from the reference percolates to the target. When the reference supports iid sampling, tempered restarts can enable large jumps in the state space.

Swaps plot

Pigeons summary
round | n_scans | n_tempered_restarts | global_barrier | global_barrier_variational | last_round_max_time | last_round_max_allocation | stepping_stone |
---|---|---|---|---|---|---|---|
1 | 2 | 0 | 2.0006 | missing | 0.014732 | 2.18198e6 | -3538.08 |
2 | 4 | 0 | 2.34832 | missing | 0.00326135 | 3.08475e6 | -52.8968 |
3 | 8 | 0 | 3.19937 | missing | 0.00500756 | 4.78347e6 | -10.1343 |
4 | 16 | 0 | 3.93311 | missing | 0.00999964 | 1.01412e7 | -10.8158 |
5 | 32 | 0 | 3.50845 | missing | 0.0250476 | 2.07684e7 | -12.3277 |
6 | 64 | 2 | 3.32197 | missing | 0.0785468 | 4.01766e7 | -10.8109 |
7 | 128 | 6 | 3.45067 | missing | 0.0857237 | 8.03176e7 | -11.6315 |
8 | 256 | 17 | 3.49445 | missing | 0.214535 | 1.61059e8 | -11.675 |
9 | 512 | 41 | 3.48487 | missing | 0.407686 | 3.2128e8 | -11.667 |
10 | 1024 | 75 | 3.51471 | missing | 0.807255 | 6.37429e8 | -11.7689 |
Pigeons inputs
Keys | Values |
---|---|
extended_traces | false |
checked_round | 0 |
extractor | nothing |
record | Function[Pigeons.traces, Pigeons.round_trip, Pigeons.log_sum_ratio, Pigeons.timing_extrema, Pigeons.allocation_extrema] |
multithreaded | false |
show_report | true |
n_chains | 10 |
variational | nothing |
explorer | nothing |
n_chains_variational | 0 |
target | TuringLogPotential{...}(Model{typeof(PigeonsDynamicPPLExt.toy_turing_unid_model), (:n_trials, :n_successes), (), (), Tuple{Int64, Int64}, Tuple{}, DefaultContext}(PigeonsDynamicPPLExt.toy_turing_unid_model, (n_trials = 100000, n_successes = 50000), NamedTuple(), DefaultContext()), DefaultContext(), 2) |
n_rounds | 10 |
exec_folder | nothing |
reference | nothing |
checkpoint | false |
seed | 1 |
Reproducibility
run(`git clone https://github.com/Julia-Tempering/InferenceReport.jl`)
cd("InferenceReport.jl")
run(`git checkout 3e33eb00e251294cff0d7580793dc023f8f1525d`)
using Pkg
Pkg.activate(".")
Pkg.instantiate()
using Pigeons
inputs = Inputs(; target = Pigeons.toy_turing_unid_target(), n_rounds = 10, record = [traces; round_trip; record_default()])
pt = pigeons(inputs)