locked
Example of Sum-Product on a 5 node Markov Network (Migrated from community.research.microsoft.com) RRS feed

  • Question

  • amchiclet posted on 02-09-2010 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. 

    x1-x2-x3-x4-x5

    Our assumption of the original image is neighbor pixels tend to have the same color.

    Let the possible values of x1-x5 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 plug-in 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 07-01-2010 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 < numPixels-1; 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]));

    Friday, June 3, 2011 5:52 PM

All replies

  • minka replied on 02-10-2010 4:49 AM

    To use Infer.NET, you just specify the random variables and their dependencies.  Infer.NET will then run sum-product 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 02-10-2010 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 02-10-2010 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 02-10-2010 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 02-10-2010 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 02-10-2010 12:21 PM

    Thanks both Minka and John. You've been tremendously helpful!

    Friday, June 3, 2011 5:51 PM
  • alexjames replied on 06-21-2010 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 06-29-2010 11:46 AM

    Hi Alex. Which bit of code are you referring to?

    John

    Friday, June 3, 2011 5:52 PM
  • alexjames replied on 06-30-2010 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 sum-product 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 06-30-2010 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 sum-product 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 07-01-2010 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 < numPixels-1; 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]));

    Friday, June 3, 2011 5:52 PM