Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Expectation Propagation for non-conjugate GPs

Where Laplace fits a Gaussian to the mode of the posterior using local curvature, EP fits a Gaussian by matching moments against the tilted distribution per site. This is a fundamentally different approximation philosophy:

  • Laplace: q(f)=N(f^,(−∇2log⁡p(f^,y))−1)q(f) = \mathcal{N}(\hat f, (-\nabla^2 \log p(\hat f, y))^{-1}) — local, second-order Taylor at the mode.
  • EP: q(f)∝p(f)∏ntn(fn)q(f) \propto p(f) \prod_n t_n(f_n) where each site approximation tn(fn)=N(fn;μn,τn−1)t_n(f_n) = \mathcal{N}(f_n; \mu_n, \tau_n^{-1}) is iteratively chosen to match the first two moments of the tilted distribution
p^n(fn) ∝ q∖n(fn) p(yn∣fn)\hat p_n(f_n) \,\propto\, q^{\setminus n}(f_n) \, p(y_n \mid f_n)

where q∖nq^{\setminus n} is the cavity — the current posterior with site nn removed.

EP iteration (parallel, damped). All sites are updated simultaneously per outer iteration, then damped:

  1. For each nn, compute the cavity q∖n=N(mnc,vnc)q^{\setminus n} = \mathcal{N}(m^c_n, v^c_n) from the current posterior.
  2. Compute tilted moments E[f]E[f], E[f2]E[f^2] under p^n\hat p_n via Gauss-Hermite quadrature.
  3. Match: solve for new site naturals so the global posterior matches those tilted moments per site.
  4. Damp: ηnnew←(1−α)ηnold+αηnmatched\eta_n^{\text{new}} \leftarrow (1-\alpha)\eta_n^{\text{old}} + \alpha \eta_n^{\text{matched}}.

Damping is essential — without it parallel-EP can oscillate or diverge, especially when posterior precision is anisotropic across sites.

Why bother? EP captures more posterior mass than Laplace whenever the per-site likelihood is skewed — which is typical for Bernoulli (the logistic CDF is asymmetric near the decision boundary). Empirically EP gives more accurate predictive probabilities and (often) tighter calibration than Laplace on classification problems.

/home/azureuser/localfiles/pyrox/.venv/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Bernoulli classification — the canonical EP testbed

Same dataset as the Laplace / GN notebooks for direct comparison.

Laplace  iters=  6  conv=True  log_marg≈-25.691
EP       iters= 27  conv=True  log_marg≈-25.660
max |q_mean diff|: 1.691e-01
max |q_var  diff|: 2.202e-02

Reading the table: EP takes more iterations than Laplace (parallel moment matching needs damping) but reaches a different fixed point — the posterior mean is essentially the same as Laplace, but the variance can differ. Bernoulli’s per-site tilted distribution is moderately skewed near the decision boundary, so EP’s matched moments capture wider/narrower local mass than Laplace’s quadratic Taylor.

Damping — convergence speed, not stability (on this problem)

Folklore says “parallel EP needs damping or it diverges.” That’s true for some hard problems (heavy-tailed likelihoods, very anisotropic posteriors, large NN with strong correlations) but not for this one — Bernoulli on a smooth 1-D RBF prior is benign. Compare iteration counts across damping levels:

   damping  iters   converged    log_marg
       0.2     52         yes     -25.660
       0.4     27         yes     -25.660
       0.6     17         yes     -25.660
       0.8     12         yes     -25.660
       1.0      8         yes     -25.660

For this problem, full Newton-style EP (damping=1.0) converges fastest. The pyrox default of 0.5 is a conservative choice — it sacrifices ~5–10× iterations in exchange for robustness on harder problems where smaller updates avoid oscillation. If you find EP slow on a benign problem, bump damping up, don’t drop it.

Tilted moments — the heart of EP

The site-update math we just ran is:

  1. Cavity precision: τnc=1/vn−τnsite\tau^c_n = 1/v_n - \tau_n^{\text{site}}
  2. Cavity mean: μnc=vnc(mn/vn−μnsite)\mu^c_n = v^c_n (m_n / v_n - \mu_n^{\text{site}})
  3. Tilted distribution: p^n(f)∝N(f;μnc,vnc)⋅p(yn∣f)\hat p_n(f) \propto \mathcal{N}(f; \mu^c_n, v^c_n) \cdot p(y_n \mid f)
  4. Matched moments: mˉn=Ep^n[f]\bar m_n = E_{\hat p_n}[f], vˉn=Ep^n[f2]−mˉn2\bar v_n = E_{\hat p_n}[f^2] - \bar m_n^2
  5. New site precision: τnnew=1/vˉn−τnc\tau_n^{\text{new}} = 1/\bar v_n - \tau^c_n

Let’s plot the per-site tilted means and compare to the cavity means — the shift the data injects per observation.

<Figure size 880x385 with 1 Axes>

Each gray segment is the moment-matching shift contributed by site nn. Larger shifts at the boundary (where one observation provides more decision information) and smaller shifts in confidently-classified regions.

Predictive comparison — where Laplace and EP differ

<Figure size 1210x396 with 2 Axes>
<Figure size 880x330 with 1 Axes>

Reading the panels: posterior means track each other very closely on this problem (typical for log-concave likelihoods). The differences are concentrated in the standard deviation, especially near the decision boundary and in the data-sparse extrapolation regions. EP’s wider intervals reflect moment-matched (rather than Taylor-expanded) per-site uncertainty.

Summary

  • EP fits a different criterion than Laplace — moment matching against the tilted distribution per site, not Taylor at the mode. The result is typically wider posterior uncertainty on classification problems, often better calibrated.
  • Damping is a speed/robustness knob, not a correctness one — for benign problems. On smooth log-concave likelihoods (Bernoulli, Poisson) you can usually bump damping toward 1.0 for faster convergence. Drop to 0.2–0.4 only when you observe oscillation (heavy tails, very large NN, anisotropic posteriors).
  • Cost: more iterations than Laplace (typically 20–80 vs 5–10), each with a Gauss-Hermite integral per site. For small NN the constant factor is modest; for very large NN, Laplace remains cheaper.
  • When to pick EP: log-concave likelihoods where calibration matters (Bernoulli, Poisson) and you can afford the extra iterations. For mode-fitting where you only need point predictions, Laplace is fine.
cond = prior.condition_nongauss(BernoulliLikelihood(), y,
                                strategy=ExpectationPropagation(damping=0.4))
m, v = cond.predict(X_star)