Homepage

# Mean Field Demo¶

## Background¶

In this interactive demo we introduce the Mean field method to solve the foreground/background segmentation problem.

First, we review the dynamical system models of neurons in the chapter. A neuron is described by two variables: a continuous valued variable $u_i \in \{-\infty, \infty\}$, and a continuous variable $q_i \in \{0, 1\}$. Roughly speaking, $u_i$ represents the input to the cell body and $q_i$ describes the probability that the cell will fire an action potential. These variables are related by the quations $u_i = \log(\frac{q_i}{1 - q_i})$.

The dynamics of the neuron is given by:

$$\frac{d u_i}{d t} = - u_i + \sum_j W_{ij} I_{j} + \sum_k \theta_{ik} q_k$$

$\sum_j w_{ij}I_j + \sum_k \theta_{ik}q_k$ represent the direct input and the input from the other neurons.

The definition of free energy is

$$F(q) = - \sum_{ij} W_{ij} I_{j} q_{i} - \frac{1}{2} \sum_{ij} \theta_{ij} q_i q_j + \sum_i { q_i \log q_i + (1 - q_i) log (1 - q_i)}$$

The update rule of $u_i$ can continually decreases the mean field free energy $F(q)$, see the chapter for more detail.

In the image segmentation problem, we use $q_i$ to represent the belief for foreground/background. Mean field algorithm is used to solve $q_i$.

## Initialization¶

At the beginning, we need to initialize this demo by loading a few python libraries

In [119]:
# Initiialization code
%matplotlib inline
import numpy as np
import numpy.random
import matplotlib.pyplot as plt
import skimage.color, skimage.transform


Then we load the image from a file, normalize it to be in range (-1, 1)

In [120]:
# im = plt.imread('../data/gibbs/gibbs_demo.jpg')
im = plt.imread('../data/gibbs/moon.jpg'); im = skimage.transform.rescale(im, 0.1)

plt.imshow(im)
grayim = skimage.color.rgb2gray(im)

# Linear map the data to -1, 1
scale = grayim.max() - grayim.min()
I = 2 * (grayim -grayim.min()) / scale - 1
# I = (grayim - grayim.min()) / scale

print 'original range:', grayim.min(), grayim.max()
print 'remaped range:', I.min(), I.max()

original range: 0.00561378787879 0.770716255013
remaped range: -1.0 1.0


## Run MFT algorithm¶

In [122]:
# Define a function to compute mean field free energy
def F(Q, I, W, Theta):
E = 0
E += - np.sum(W * I * Q)
E += - 1/2 * Theta * (np.sum(np.roll(Q, 1, axis=0) * Q + np.roll(Q, -1, axis=0) * Q +
np.roll(Q, 1, axis=1) * Q + np.roll(Q, -1, axis=1) * Q))
E += np.sum(Q * np.log(Q) + (1-Q) * np.log(1-Q))
return E

# Define logistic function
def logit(x):
y = 1 / (1 + np.exp(-x))
return y

In [129]:
U = numpy.random.random(I.shape) # Initialize the state of neurons
Q = logit(U)

Theta = 1 # smoothness
W = 5 # data term

# plt.figure(); plt.imshow(Q); plt.xlabel('Initial state of Q')
energy = [F(Q,I,W,Theta)]
for i in np.arange(20):
neighbor = np.roll(Q, 1, axis=0) + np.roll(Q, -1, axis=0)
np.roll(Q, 1, axis=1) + np.roll(Q, -1, axis=1)
dU = - U + neighbor * Theta + I * W
U = dU + U  # Update U
Q = logit(U)

# plt.imshow(Q)
energy.append(F(Q, I, W, Theta))

plt.figure(); plt.imshow(Q); plt.xlabel('Final state of Q, Belief for foreground and background')
plt.figure(); plt.plot(energy); plt.ylabel('Mean field free energy'); plt.xlabel('Iteration')

Out[129]:
<matplotlib.text.Text at 0x10e936b50>
In [127]:
mask = Q>0.5
fg = im.copy()
for i in np.arange(3):
fg[:,:,i] = fg[:,:,i] * (Q>0.5)
plt.imshow(fg); plt.xlabel('Segmented foreground')

Out[127]:
<matplotlib.text.Text at 0x10eca7bd0>