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

We give a simple example of how to use the output code directly based on the Learning a Gaussian tutorial.

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 
©2009 Microsoft Corporation. All rights reserved.  Terms of Use | Trademarks | Privacy Statement