locked
Wet Grass/Sprinkler/Rain Model with Infer.NET 2.3 and Unity? RRS feed

  • Question

  • Hi

    I'm currently using Infer.NET 2.3 because I need to link it with Unity 4 and it's not possible with Infer.NET 2.5. I tried to run the Wet Grass/Sprinkler/Rain Model provided in the Example Browser of Infer.NET 2.5.

    However I got this error message:   Cannot convert to type Discrete[] from type DistributionRefArray<Discrete,int>.

    Related to this line code: var rainPosterior = Engine.Infer<Discrete[]>(Rain);

    Where Rain is a VariableArray<int>

    I'm sure the problem is the old version I'm using because I run it with Visual Studio and it works perfectly.

    Question:

    How can I make the same example work for the Infer.Net 2.3 version? I've already searched in google but I can't find the way.

    Thank you.

    Regards,

    Mike



    • Edited by Mike Bowie Saturday, May 25, 2013 3:13 PM
    Saturday, May 25, 2013 2:25 PM

Answers

  • Change the type argument of Infer to match the type that the error message is looking for.  In this case, use

    var rainPosterior = Engine.Infer<DistributionRefArray<Discrete,int>>(Rain);

    • Marked as answer by Mike Bowie Tuesday, May 28, 2013 3:10 PM
    Tuesday, May 28, 2013 11:02 AM
    Owner

All replies

  • Hi, Could anybody help me here? I'm really desperate. I didn't mention I've just started using Infer.NET, that's why it is difficult to me to find another way to do it for Infer.NET 2.3. There has to be a way for avoiding this problem...

    Actually here's the link for the Wet Grass/Sprinkler/Rain example: http://research.microsoft.com/en-us/um/cambridge/projects/infernet/docs/Discrete%20Bayesian%20network.aspx

    I'd really appreciate any clue about this.

    Tuesday, May 28, 2013 8:07 AM
  • Change the type argument of Infer to match the type that the error message is looking for.  In this case, use

    var rainPosterior = Engine.Infer<DistributionRefArray<Discrete,int>>(Rain);

    • Marked as answer by Mike Bowie Tuesday, May 28, 2013 3:10 PM
    Tuesday, May 28, 2013 11:02 AM
    Owner
  • Hi Tom,

    In the example, they predict the variable Rain (with one parent) in the following way:

    var rainPosterior = Engine.Infer<DistributionRefArray<Discrete,int>>(Rain);

    I would like to know how can I adapt it to infer the variable Wetgrass (with two parents). I tried the following:

    var wetgrassPosterior = Engine.Infer<DistributionRefArray<DistributionRefArray<Discrete,int>,int[]>>(WetGrass); but it's giving me the following error: IndexOutOfRangeException: Array index is out of range.

    I suppose that is because the cpt of Rain is Dirichlet[] cptRainPrior and the cpt of Wet Grass is Dirichlet[][] cptWetGrassPrior, but I'm not quite sure.

    I'd really appreciate your help,

    Regards.

    Monday, June 3, 2013 11:26 AM
  • Can you send the full stack trace printed with the exception?
    Monday, June 3, 2013 11:53 AM
    Owner
  • Actually I modified the method that returns the probability in order to return the whole vector of probabilities. However, if I make the inference the same way as Rain (var rainPosterior = Engine.Infer<DistributionRefArray<Discrete,int>>(Rain);) it onli brings me the first index of the vector.

    These are my methods to calculate de probability vector:       

         public Vector ProbWetGrass(
                int? cloudy,
                int? sprinkler,
                int? rain,
                Dirichlet probCloudyPrior,
                Dirichlet[] cptSprinklerPrior,
                Dirichlet[] cptRainPrior,
                Dirichlet[][] cptWetGrassPrior
            )
            {
                NumberOfExamples.ObservedValue = 1;
                if (cloudy.HasValue)
                    Cloudy.ObservedValue = new int[] { cloudy.Value };
                else
                    Cloudy.ClearObservedValue();
                if (sprinkler.HasValue)
                    Sprinkler.ObservedValue = new int[] { sprinkler.Value };
                else
                    Sprinkler.ClearObservedValue();
                if (rain.HasValue)
                    Rain.ObservedValue = new int[] { rain.Value };
                else
                    Rain.ClearObservedValue();
                WetGrass.ClearObservedValue();

                ProbCloudyPrior.ObservedValue = probCloudyPrior;
                CPTSprinklerPrior.ObservedValue = cptSprinklerPrior;
                CPTRainPrior.ObservedValue = cptRainPrior;
                CPTWetGrassPrior.ObservedValue = cptWetGrassPrior;

                // Inference        

                var wetPosterior = Engine.Infer<DistributionRefArray<Discrete,int>>(WetGrass);
            
                Vector VectorProbabilites = wetPosterior[0].GetProbs();  // It works with index 0, not with index 1
                Debug.Log(VectorProbabilites);    ///
                return VectorProbabilites;
            }


            public Vector ProbWetGrass(
                int? cloudy,
                int? sprinkler,
                int? rain,
                Vector probCloudy,
                Vector[] cptSprinkler,
                Vector[] cptRain,
                Vector[][] cptWetGrass
            )
            {
                var probCloudyPrior = Dirichlet.PointMass(probCloudy);
                var cptSprinklerPrior = cptSprinkler.Select(v => Dirichlet.PointMass(v)).ToArray();
                var cptRainPrior = cptRain.Select(v => Dirichlet.PointMass(v)).ToArray();
                var cptWetGrassPrior = cptWetGrass.Select(va => va.Select(v => Dirichlet.PointMass(v)).ToArray()).ToArray();
                return ProbWetGrass(cloudy, sprinkler, rain,/* wet,*/ probCloudyPrior, cptSprinklerPrior, cptRainPrior, cptWetGrassPrior);
            }

    It only works when I ask for the element 0 of the vector (the result is: 0.9162   0.0838)

    When I ask for the element 1 of the vector, it gives me the following error:

    IndexOutOfRangeException: Array index is out of range.
    MicrosoftResearch.Infer.Collections.ArrayBase`1[MicrosoftResearch.Infer.Distributions.Discrete].get_Item (Int32 index)
    WetGlassSprinklerRainModel.ProbWetGrass (Nullable`1 cloudy, Nullable`1 sprinkler, Nullable`1 rain, MicrosoftResearch.Infer.Distributions.Dirichlet probCloudyPrior, MicrosoftResearch.Infer.Distributions.Dirichlet[] cptSprinklerPrior, MicrosoftResearch.Infer.Distributions.Dirichlet[] cptRainPrior, MicrosoftResearch.Infer.Distributions.Dirichlet[][] cptWetGrassPrior) (at Assets/JeuBoule2/Scripts/BayNet.cs:270)
    WetGlassSprinklerRainModel.ProbWetGrass (Nullable`1 cloudy, Nullable`1 sprinkler, Nullable`1 rain, MicrosoftResearch.Infer.Maths.Vector probCloudy, MicrosoftResearch.Infer.Maths.Vector[] cptSprinkler, MicrosoftResearch.Infer.Maths.Vector[] cptRain, MicrosoftResearch.Infer.Maths.Vector[][] cptWetGrass) (at Assets/JeuBoule2/Scripts/BayNet.cs:304)

    I suppose it is because of the way that I make the inference: var wetPosterior = Engine.Infer<DistributionRefArray<Discrete,int>>(WetGrass); but I don't know how should I adapt it knowing that my cptWetGrass is defined as follows:

                Vector[][] cptWetGrass = new Vector[][]
                {
                    new Vector[] { Vector.FromArray(0.99, 0.01) /* rain */,  Vector.FromArray(0.9, 0.1) /* not rain */}, // Sprinkler
                    new Vector[] { Vector.FromArray(0.9, 0.1) /* rain */, Vector.FromArray(0.0, 1.0) /* not rain */}  // Not sprinkler
                };

    I hope I made myself clear. Thank your for your help.

    Monday, June 3, 2013 3:08 PM
  • The resulting array only has one element because NumberOfExamples.ObservedValue = 1.  Perhaps you meant to infer the CPT, not WetGrass itself?
    Monday, June 3, 2013 4:05 PM
    Owner