Denoise a binary image with one belief: a pixel probably looks like its neighbors.
Write that as an energy, read the energy as a probability, and solve it with the cheapest approximate inference there is — mean field. No training set, no labels.
Ising / Boltzmann energy, then a Boltzmann distribution over configurations:
E(x)=−J(i,j)∑xixj−hi∑xiyi p(x)=Z1exp(−E(x))Z sums over 2576 configurations of a 24×24 grid — intractable. So we don't compute it.
Approximate the posterior with independent per-pixel coins, one mean μi each, and update each by the field pressing on it:
μi←tanh(Jj∈N(i)∑μj+hyi)Sweep it one pixel at a time to convergence. That minimizes the free energy:
F(μ)=Eq[E(x)]−H(q)=−logZ+KL(q∥p)Driving F down pushes the approximation toward the true posterior.
Top: the current mean-field estimate μ, sweep by sweep. Bottom: the free energy, sliding downhill and never rising.
Sequential (Gauss-Seidel) sweeps are coordinate descent on F — so it only ever goes down. Cousin to EM's monotone climb, pointing the other way.
−1009.6 → −1351.7, converged in 13 sweeps.
18% salt-and-pepper noise on a 24×24 "3". No sklearn twin — the honest baseline is a
3×3 median filter (majority vote). BernoulliRBM is a cousin, not a substitute (it
learns its couplings).
Iteration over the whole grid beats a one-shot local vote by ~4 dB.