dotnet / infer

Infer.NET is a framework for running Bayesian inference in graphical models
https://dotnet.github.io/infer/
MIT License
1.56k stars 228 forks source link

Microsoft.ML.Probabilistic.Compiler.CompilationFailedException: VariableTransform failed #477

Open francescomandruvs opened 2 weeks ago

francescomandruvs commented 2 weeks ago

Hi @tminka, I tried your suggestion from https://github.com/dotnet/infer/issues/434, in order to infer some parameters, adding: prec.InitialiseTo(Gamma.PointMass(1.0)), but I got the following issues (I'm using dotnet 8.0):

Compiling model...compilation failed.
Unhandled exception. Microsoft.ML.Probabilistic.Compiler.CompilationFailedException: VariableTransform failed with 3 error(s) and 0 warning(s):
Error 0: mean has PointEstimate but is not initialised in
mean = Factor.GaussianFromMeanAndVariance(0.0, 100.0)
Error 1: mean has PointEstimate but InitialisationAffectsSchedule is false in
mean = Factor.GaussianFromMeanAndVariance(0.0, 100.0)
Error 2: prec has PointEstimate but InitialisationAffectsSchedule is false in
prec = Factor.Random<double>(vGamma0)

I attach the code:

using Microsoft.ML.Probabilistic.Distributions;
using Microsoft.ML.Probabilistic.Models;
using Microsoft.ML.Probabilistic.Models.Attributes;
using Range = Microsoft.ML.Probabilistic.Models.Range;

internal static class Program
{
    static void Main()
    {
        var sampleData = GenerateGaussianData(10000, 1, 4);

        var mean = Variable.GaussianFromMeanAndVariance(0, 10 * 10).Named("mean").Attrib(new PointEstimate());
        var prec = Variable.Random(Gamma.Uniform()).InitialiseTo(Gamma.PointMass(1.0)).Named("prec")
            .Attrib(new PointEstimate());

        var numSamples = sampleData.Length;
        var number = new Range(numSamples);
        var data = Variable.Array<double>(number).Named("number");
        data[number] = Variable.GaussianFromMeanAndPrecision(mean, prec).ForEach(number);

        var inferenceEngine = new InferenceEngine();

        data.ObservedValue = sampleData;
        var inferredMean = inferenceEngine.Infer<Gaussian>(mean);
        var inferredPrec = inferenceEngine.Infer<Gamma>(prec);

        Console.WriteLine(inferredMean);
        Console.WriteLine(inferredPrec);
    }

    static double[] GenerateGaussianData(int nSamples, double mean, double prec)
    {
        var myGaussian = Gaussian.FromMeanAndPrecision(mean, prec);
        var data = new double[nSamples];

        for (int i = 0; i < nSamples; i++)
        {
            data[i] = myGaussian.Sample();
        }

        return data;
    }
}
tminka commented 2 weeks ago

When using PointEstimate, you must initialize the variable and you must set engine.Compiler.InitialisationAffectsSchedule to true. That's what the error message is saying.