dotnet / infer

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

Error when running inference using softmax observed values #101

Closed ahmadsalim closed 5 years ago

ahmadsalim commented 5 years ago

Hi!

I am trying to model observed softmax data using Infer.Net and I get an error no matter which algorithm I use. I have a more complicated model myself, but I have tried to reduce the issue to a simplified Gaussian-softmax example model below:

    class Program
    {
        static void Main(string[] args)
        {
            var testData = new Vector[]
            {
                Vector.FromArray(0.1, 0.3, 0.5, 0.1),
                Vector.FromArray(0.05, 0.5, 0.2, 0.25),
                Vector.FromArray(0.2, 0.4, 0.3, 0.1),
                Vector.FromArray(0.15, 0.2, 0.35, 0.3),
                Vector.FromArray(0.15, 0.3, 0.4, 0.15)
            };
            Model(testData);
            Console.ReadLine();
        }

        static void Model(Vector[] data)
        {
            var priorMean = Variable.VectorGaussianFromMeanAndPrecision(Vector.Constant(4, 0.0), PositiveDefiniteMatrix.Identity(4)).Named("priorMean");
            var priorCov = Variable.WishartFromShapeAndRate(4.0, PositiveDefiniteMatrix.Identity(4)).Named("priorCov");
            var prior = Variable.VectorGaussianFromMeanAndPrecision(priorMean, priorCov).Named("prior");
            var numDocs = Variable.New<int>().Named("numDocs");
            var docR = new Range(numDocs);
            var arrvals = Variable.Array<Vector>(docR).Named("arrvals");
            arrvals[docR] = Variable.Softmax(prior).ForEach(docR);

            // Observations
            numDocs.ObservedValue = data.Length;
            arrvals.ObservedValue = data;

            // var alg = new ExpectationPropagation(); 
            // var alg = new VariationalMessagePassing();
            var alg = new GibbsSampling();
            var ieng = new InferenceEngine(alg);
            var compAlg = ieng.GetCompiledInferenceAlgorithm(priorMean, priorCov);
            Console.WriteLine(compAlg.Marginal(priorMean.NameInGeneratedCode));
        }
    }

The errors I get for each individual algorithm are as follows. For expectation propagation and Gibbs sampling, I get that the model is unsupported because of MMath.Softmax. E.g., the exception for Gibbs sampling:

Error 0: This model is not supported with GibbsSampling due to MMath.Softmax(Vector softmax, IList<double> x). Try using a different algorithm or expressing the model differently Gibbs Sampling requires the conditionals to be conjugate in
MMath.Softmax(prior_rep_uses[0][index0])
Details: System.MissingMethodException: xAverageConditional not found in SoftmaxOp_Bouchard_Sparse,SoftmaxOp_Bouchard,SoftmaxOp_BL06_LBFGS,SoftmaxOp_Bohning,SoftmaxOp_Taylor,SoftmaxOp_KM11,SoftmaxOp_KM11_Sparse2,SoftmaxOp_KM11_Sparse,SoftmaxOp_BL06,VectorSoftmaxOp_KM11,SoftmaxOp_KM11_LBFGS,SoftmaxOp_KM11_LBFGS_Sparse,GammaSoftmaxOp using parameter types: [softmax] Vector,[x] PlaceHolder,[to_x] VectorGaussian,[result] VectorGaussian

For VMP, the model succesfully compiles, but I get a null-pointer exception:

Exception thrown: 'System.NullReferenceException' in Microsoft.ML.Probabilistic.dll
An unhandled exception of type 'System.NullReferenceException' occurred in Microsoft.ML.Probabilistic.dll
Object reference not set to an instance of an object.

Any idea of whether I am misspecifying something here, or there is a workaround to solve the issue?

Thank you very much in advance!

tminka commented 5 years ago

This happens because your observed values are null. See Controlling how inference is performed.

ahmadsalim commented 5 years ago

@tminka Thank you for responding.

I am providing the constant testData to the observed values, which is defined as a constant in Main and all values there are non-null. (I also tested the values under the debugger). The priors are also initialized correctly as far as I understand, so I am not sure where null is coming from.

tminka commented 5 years ago

My mistake. The null happens because you didn't run inference, as explained on the page I linked.

ahmadsalim commented 5 years ago

Right, sorry. I changed from Infer to GetCompiledInferenceAlgorithm before I posted the code and forgot. When running the inference with VMP, I now get:

Exception thrown: 'Microsoft.ML.Probabilistic.Math.PositiveDefiniteMatrixException' in Microsoft.ML.Probabilistic.dll
An unhandled exception of type 'Microsoft.ML.Probabilistic.Math.PositiveDefiniteMatrixException' occurred in Microsoft.ML.Probabilistic.dll
The matrix is not positive definite.

This is despite changing the covariance matrix to be scaled up or down (several orders of magnitude). Any idea, why that happens?

Thanks again

tminka commented 5 years ago

Doubling the shape of priorCov seems to work.

ahmadsalim commented 5 years ago

Awesome, thanks!

tminka commented 5 years ago

Unfortunately, when I look at the code for Softmax, it is not meant to work when the output is directly observed (as is the case for many factors under VMP). The code should be throwing an exception here. I will fix that. Meanwhile, you shouldn't trust the output of this program.