Hi all,
I am trying to familiarise myself with Infer.Net with C# which I feel is a great tool. I have been looking at the tutorials, and in particular the GaussianMixture example. I've made a simplified version of it with two unidimensional Gaussians, instead of the
2 two-dimentional Gaussians in the original tutorial. However I'm facing some issues when doing so. I get the following exception (using the default inference engine):
"MessageTransform failed with 2 error(s) and 0 warning(s):
Error 0: The operator method requires a message to sample but there is no such message in
Factor.GaussianFromMeanAndVariance(means_k_, vars_k_)
Error 1: some arguments were not converted in
Factor.GaussianFromMeanAndVariance(means_k_, vars_k_)"
Setting any other inference engine result in exception being thrown, albeit with a different error message. The offensive line seams to be the line marked with (*) at the beginning (since when it is removed the exception does not trigger).
Any help would be appreciated.
public static void test()
{
Range k = new Range (2).Named ("k");
VariableArray<double> means = Variable.Array<double> (k).Named ("means");
means [k] = Variable.GaussianFromMeanAndVariance (0.0, 1.0).ForEach (k);
VariableArray<double> vars = Variable.Array<double> (k).Named ("vars");
vars [k] = Variable.GammaFromShapeAndScale(2.0, 0.5).ForEach (k);
Variable<Vector> weights = Variable.Dirichlet (k, new double[] { 1, 1 }).Named ("weights");
// Create a variable array which will hold the data
Range n = new Range (300).Named ("n");
VariableArray<double> x = Variable.Array<double> (n).Named ("x");
// Create latent indicator variable for each data point
VariableArray<int> z = Variable.Array<int> (n).Named ("z");
// The mixture of Gaussians model
using (Variable.ForEach (n))
{
z [n] = Variable.Discrete (weights);
using (Variable.Switch (z [n]))
{
(*) x [n] = Variable.GaussianFromMeanAndVariance (means [z [n]], vars [z [n]]);
}
}
// Attach some generated data
x.ObservedValue = GenerateData (n.SizeAsInt);
InferenceEngine ie = new InferenceEngine();
Console.WriteLine ("Dist over weights=" + ie.Infer (weights));
Console.WriteLine ("Dist over means=\n" + ie.Infer (means));
Console.WriteLine ("Dist over precisions=\n" + ie.Infer (vars));
}
private static double[] GenerateData(int nData)
{
Gaussian trueG1 = Gaussian.FromMeanAndVariance(2.0, 1.0);
Gaussian trueG2 = Gaussian.FromMeanAndVariance(7.0, 0.5);
Bernoulli trueB = new Bernoulli(0.6);
// Restart the infer.NET random number generator
Rand.Restart(12347);
double[] data = new double[nData];
for (int j = 0; j < nData; j++)
{
bool bSamp = trueB.Sample();
data[j] = bSamp ? trueG1.Sample() : trueG2.Sample();
}
return data;
}