Using a precompiled inference algorithm
Internally Infer.NET compiles a model into a C# class for performing inference on that model. By default, the source of the generated class is placed at: (Debug/Release)\bin\GeneratedSource\[ModelName].cs. and has a standard structure. This page describes how this compiled inference algorithm can be directly included in a C# project. This might be useful for one of the following reasons:
- To remove the dependence on the compiler For standalone applications that make heavy use of a specific inference algorithm it might be desired to remove the dependence on the compiler.
- To run multi-threaded inference Including the compiled algorithm directly allows different instances of the compiled algorithm to be used in each thread separately without recompilation.
- Speed-up Inclusion of the compiled algorithm avoids compilation on first time usage.
- To manually edit and alter the created output code For advanced usage of Infer.Net it might be desired to alter the generated code. This mainly applies when specific features are not available in Infer.Net and you want to use the compiler to get a starting point for your own implementation of inference algorithms. This is only recommended if you know what you are doing!
Example
In order to ensure that the output code can be used directly, without any further modification a few guidelines need to be obeyed.
- Use 'observed' variables rather than 'constant' variables for any values which are fixed for a given call to the inference algorithm, but which may change between invocations (see Creating Variables).
- Use the inline .Named("name") method for all variables you want to Infer or set as a given. Sensible choice of naming ensures a higher level of readability of the compiled output code.
|
// Initial Data double[] dataSet = new double[100]; for (int i = 0; i < dataSet.Length; i++) dataSet[i] = Rand.Normal(0, 1);
// Observed variables for data and data count Variable<int> dataCount = Variable.Observed(dataSet.Length).Named("dataCount"); Range N = new Range(dataCount); VariableArray<double> data = Variable.Observed<double>(dataSet, N).Named("data");
// Observations are assumed to be sampled from a Gaussian with unknown parameters Variable<double> mean = Variable.GaussianFromMeanAndVariance(0, 100).Named("mean"); Variable<double> precision = Variable.GammaFromShapeAndScale(1, 1).Named("precision"); data[N] = Variable.GaussianFromMeanAndPrecision(mean, precision).ForEach(N);
// Create an inference engine for VMP InferenceEngine engine = new InferenceEngine(new VariationalMessagePassing());
// Retrieve the posterior distributions Console.WriteLine("mean=" + engine.Infer(mean)); Console.WriteLine("prec=" + engine.Infer(precision)); |
Run this example, take the generated output code (it be named Model_VMP.cs unless you set the ModelName property on the engine) and add it to your project. This instance contains the compiled model class Model_VMP.
There are two ways to call the compiled inference algorithm from your code. The easiest way to use this class is to wrap an instance in a CompiledAlgorithm object and use the methods on CompiledAlgorithm to set the observations and execute inference. This is documented in the next section. Alternatively you can use the class directly as documented in the subsequent section.
Using the CompiledAlgorithm object
The CompiledAlgorithm object has a constructor which takes a compiled model class (such a class implements the IIterativeProcess interface) and an engine. You can then use the SetObservedValue and Execute methods on the CompiledAlgorithm instance. Note that you will need to use the SetObservedValue signature which takes a string rather than a Variable, as the variable will no longer be available in your stand-alone code.
|
// Run-time data double[] dataSet = new double[10000]; for (int i = 0; i < dataSet.Length; i++) dataSet[i] = Rand.Normal(0, 1);
InferenceEngine engine = new InferenceEngine(new VariationalMessagePassing()); // Instantiate the compiled algorithm Model_VMP model = new Model_VMP(); model.Reset(); CompiledAlgorithm ca = new CompiledAlgorithm(model, engine);
// Set the observed values and execute ca.SetObservedValue("dataCount", dataSet.Length); ca.SetObservedValue("data", dataSet); ca.Execute();
// Retrieve the posterior distributions Console.WriteLine("mean=" + ca.Marginal<Gaussian>("mean")); Console.WriteLine("prec=" + ca.Marginal<Gamma>("precision")); |
Calling the compiled model class directly
There are 6 general steps which are illustrated in the example code.
|
// Run-time data double[] dataSet = new double[10000]; for (int i = 0; i < dataSet.Length; i++) dataSet[i] = Rand.Normal(0, 1);
// 1) Create an instance of the class Model_VMP model = new Model_VMP();
// 2) Call the Reset() method model.Reset();
// 3) Set the value of any externally-set fields e.g. data, priors model.data = dataSet; model.dataCount = dataSet.Length;
// 4) Call the Initialise() method once model.Initialise();
// 5) Call the Update() method multiple times - each call performs // one iteration of inference for (int i=0; i < 20; i++) model.Update();
// 6) Use the XXXMarginal() methods to retrieve posterior marginals // for different variables. Gaussian inferredMean = model.MeanMarginal(); Gamma inferredPrec = model.PrecisionMarginal();
// Print out the results Console.WriteLine("mean=" + inferredMean); Console.WriteLine("prec=" + inferredPrec); |
Last modified at 8/4/2009 4:11 PM by Tom Minka
|
|