Answered by:
Example of SumProduct on a 5 node Markov Network (Migrated from community.research.microsoft.com)
Question

amchiclet posted on 02092010 9:57 PM
Hi,
I posted a question here a while ago about belief propagation but I didn't have enough knowledge to ask the right question. I hope now I am specific enough.
Can anyone maybe give an example or guide me on doing the following with Infer.NET?
I have an image with only 5 pixels. They are just one line and they are a chain of nodes.
x1x2x3x4x5
Our assumption of the original image is neighbor pixels tend to have the same color.
Let the possible values of x1x5 be 0 and 1 (for white and black).
Let the original image be a white image 00000.
Let the observed image be 01010.
Can you show me how I can use a Markov Network and the Sum Product algorithm to denoise the image, please?
If I missed out any information (maybe the likelihood function), feel free to plugin something that you think is sensible.
Let me know if you want me to be more specific in any area.
Thank you so much. I think this example would help me understand Infer.NET a lot better.
Friday, June 3, 2011 5:51 PM
Answers

John Guiver replied on 07012010 5:44 AM
int numPixels = 5;
double probXEqualX = 0.8;
double probYEqualX = 0.7;
var x = new Variable<bool>[numPixels];
var y = new Variable<bool>[numPixels];
for (int i = 0; i < numPixels; i++ )
{
x[i] = Variable.Bernoulli(0.5);
y[i] = Variable.New<bool>();
Variable.ConstrainEqualRandom(x[i] == y[i], new Bernoulli(probYEqualX));
}
for (int i = 0; i < numPixels1; i++)
Variable.ConstrainEqualRandom(x[i] == x[i+1], new Bernoulli(probXEqualX));
InferenceEngine engine = new InferenceEngine();
bool[] obsImage = new bool[] { false, true, false, true, false };
for (int i = 0; i < numPixels; i++)
y[i].ObservedValue = obsImage[i];
for (int i = 0; i < numPixels; i++)
Console.WriteLine(engine.Infer<Bernoulli>(x[i])); Marked as answer by Microsoft Research Friday, June 3, 2011 5:52 PM
Friday, June 3, 2011 5:52 PM
All replies

minka replied on 02102010 4:49 AM
To use Infer.NET, you just specify the random variables and their dependencies. Infer.NET will then run sumproduct automatically. You can specify the variables in this order:
1. Create 5 boolean variables for the original image pixels, using Variable.Bernoulli.
2. For each pair of neighboring pixels, constrain them to be equal with some probability, call it probXEqualX. This can be done with: Variable.ConstrainEqualRandom(x[i] == x[i+1], new Bernoulli(probXEqualX));
3. Create 5 boolean variables for the observed image pixels. I assume that each observed pixel y[i] is a noisy version of the original pixel x[i]. The observed pixel matches the original pixel with probability probYEqualX. This can be done with: y[i] = (x[i] == Variable.Bernoulli(probYEqualX));
4. Set the ObservedValue property of the observed pixels to match the observed image.
5. Create an InferenceEngine and infer the original pixels.
Friday, June 3, 2011 5:51 PM 
amchiclet replied on 02102010 9:55 AM
Thanks. I have a follow up questions.
Suppose I come up with a new message passing algorithm for this example. Is there any way I can define them? What are the common APIs used for this?
Friday, June 3, 2011 5:51 PM 
minka replied on 02102010 10:43 AM
Infer.NET does not provide an API for defining arbitrary new inference algorithms. At most you can change the message updates used for particular factors.
Friday, June 3, 2011 5:51 PM 
amchiclet replied on 02102010 10:59 AM
minka:At most you can change the message updates used for particular factors.
Could you point me to some APIs, please?
Friday, June 3, 2011 5:51 PM 
John Guiver replied on 02102010 11:26 AM
http://research.microsoft.com/infernet/docs/How%20to%20add%20a%20new%20factor%20and%20message%20operators.aspx describes the general naming mechanisms for message update methods.
APIs for existing message updates are shown in the MicrosoftResearch.Infer.Factors Namespace at http://research.microsoft.com/infernet/codedoc/Index.html.
Source for many message operators are provided as part of the installed release
John G.
Friday, June 3, 2011 5:51 PM 
amchiclet replied on 02102010 12:21 PM
Thanks both Minka and John. You've been tremendously helpful!
Friday, June 3, 2011 5:51 PM 
alexjames replied on 06212010 5:51 AM
Hello, could you possibly post your code for this example?
best
alex
Friday, June 3, 2011 5:52 PM 
John Guiver replied on 06292010 11:46 AM
Hi Alex. Which bit of code are you referring to?
John
Friday, June 3, 2011 5:52 PM 
alexjames replied on 06302010 10:49 AM
Hello John
I was referring to the code I assume was implemented successfully on th basis of Tom's pseudocode; looks to me to be a good learning example:
To use Infer.NET, you just specify the random variables and their dependencies. Infer.NET will then run sumproduct automatically. You can specify the variables in this order:
1. Create 5 boolean variables for the original image pixels, using Variable.Bernoulli.
2. For each pair of neighboring pixels, constrain them to be equal with some probability, call it probXEqualX. This can be done with: Variable.ConstrainEqualRandom(x[i] == x[i+1], new Bernoulli(probXEqualX));
3. Create 5 boolean variables for the observed image pixels. I assume that each observed pixel y[i] is a noisy version of the original pixel x[i]. The observed pixel matches the original pixel with probability probYEqualX. This can be done with: y[i] = (x[i] == Variable.Bernoulli(probYEqualX));
4. Set the ObservedValue property of the observed pixels to match the observed image.
5. Create an InferenceEngine and infer the original pixels.
best
alex
Friday, June 3, 2011 5:52 PM 
alexjames replied on 06302010 10:52 AM
Hello john
I was referring to Tom's pseudocode above (
To use Infer.NET, you just specify the random variables and their dependencies. Infer.NET will then run sumproduct automatically. You can specify the variables in this order:
1. Create 5 boolean variables for the original image pixels, using Variable.Bernoulli.
2. For each pair of neighboring pixels, constrain them to be equal with some probability, call it probXEqualX. This can be done with: Variable.ConstrainEqualRandom(x[i] == x[i+1], new Bernoulli(probXEqualX));
3. Create 5 boolean variables for the observed image pixels. I assume that each observed pixel y[i] is a noisy version of the original pixel x[i]. The observed pixel matches the original pixel with probability probYEqualX. This can be done with: y[i] = (x[i] == Variable.Bernoulli(probYEqualX));
4. Set the ObservedValue property of the observed pixels to match the observed image.
5. Create an InferenceEngine and infer the original pixels.)
best
alex
Friday, June 3, 2011 5:52 PM 
John Guiver replied on 07012010 5:44 AM
int numPixels = 5;
double probXEqualX = 0.8;
double probYEqualX = 0.7;
var x = new Variable<bool>[numPixels];
var y = new Variable<bool>[numPixels];
for (int i = 0; i < numPixels; i++ )
{
x[i] = Variable.Bernoulli(0.5);
y[i] = Variable.New<bool>();
Variable.ConstrainEqualRandom(x[i] == y[i], new Bernoulli(probYEqualX));
}
for (int i = 0; i < numPixels1; i++)
Variable.ConstrainEqualRandom(x[i] == x[i+1], new Bernoulli(probXEqualX));
InferenceEngine engine = new InferenceEngine();
bool[] obsImage = new bool[] { false, true, false, true, false };
for (int i = 0; i < numPixels; i++)
y[i].ObservedValue = obsImage[i];
for (int i = 0; i < numPixels; i++)
Console.WriteLine(engine.Infer<Bernoulli>(x[i])); Marked as answer by Microsoft Research Friday, June 3, 2011 5:52 PM
Friday, June 3, 2011 5:52 PM