dotnet / infer

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

SchedulingTransform Error when inferring Gamma.Uniform as Point Estimate #434

Closed fvisintini1 closed 1 year ago

fvisintini1 commented 1 year ago

Hi Tom, I want to infer parameters of a model without prior knowledge. Setting their priors as uniform seems conceptually the right thing to do. However compilation fails due to scheduling constrains not satisfied.

I was able to reduce the code to the minimal working example. The problem arises when I use Gamma.Uniform. Setting the Gaussian to uniform works just fine. I can work around this (setting a very large variance on the Gamma), but maybe there is a better way?

using System;
using Microsoft.ML.Probabilistic.Distributions;
using Microsoft.ML.Probabilistic.Models;
using Microsoft.ML.Probabilistic.Models.Attributes;

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()).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 1 year ago

The problem is that it doesn't know how to initialise prec, but it can figure out how to initialise mean. Try adding this:

            prec.InitialiseTo(Gamma.PointMass(1.0));
fvisintini1 commented 1 year ago

Thanks, that solves it.