Frequently Asked Questions
Common questions and answers about the Infer.NET framework.
General

What is Infer.NET?
Infer.NET is a framework for running Bayesian inference in graphical models. If you don’t know what that means, but would like to, take a look at the Resources and References page. Infer.NET provides the stateoftheart messagepassing algorithms, graph algorithms, and linear algebra routines needed by modern machine learning applications (read more).

Who is behind Infer.NET?
Infer.NET is being developed in the Machine Learning and Perception group at Microsoft Research Cambridge. The framework was conceived and designed by Tom Minka and John Winn who remain technical leaders, principal researchers, and key developers on the project. Other contributors over the years include John Guiver, Anitha Kannan, David Knowles, Sam Webster, Yordan Zaykov, Boris Yangel, Alex Spengler, Dany Fabian, Martin Kukla, Pavel Myshkov, Sergey Berezin, Elena Pochernina, Dmitry Kats, Mikhail Nikolaev, and John Bronskill.

How do I cite Infer.NET?
Please cite using the following text:
T. Minka, J. Winn, J. Guiver, Y. Zaykov, D. Fabian, and J. Bronskill
Infer.NET 0.3, Microsoft Research Cambridge, 2018. http://dotnet.github.io/inferor using the following BibTeX:
@misc{InferNET18, author = "Minka, T. and Winn, J.M. and Guiver, J.P. and Zaykov, Y. and Fabian, D. and Bronskill, J.", title = {/{Infer.NET 0.3}}, year = 2018, note = {Microsoft Research Cambridge. http://dotnet.github.io/infer} }

Do I have to use C#?
No. You can use Infer.NET from any .NET language such as C#, C++/CLI, F#, IronPython, and others. Examples of using Infer.NET from several of these languages are included in the user guide.
The code generated by Infer.NET is in C#, but it can be invoked from any .NET language.

Do I have to use Microsoft Windows?
No. Infer.NET works great on Linux, macOS, or any platform that supports .NET Standard 2.0.

Can I use Infer.NET in a commercial application?
Yes. Please read the the MIT license for details.

Where can I learn about graphical models and Bayesian inference?
We have a list of resources relevant to Infer.NET here.

How to contribute?
Please read contributing guidelines here.
Running the examples

I get a Security Exception when running the example solutions.
This happens when the example solutions are on a network drive. The easiest solution is to copy the example folders to a local drive. Security exceptions can also be avoided by setting the compiler’s GenerateInMemory flag to true as described in Inference engine settings (this is the default setting).
Modelling

What models can Infer.NET handle?
Infer.NET can handle Bayesian networks and undirected models (Markov Random Fields) containing both discrete and continuous variables. A wide variety of distributions can be constructed by chaining together various primitives. For example, a variable with Student T distribution can be constructed by making a Gaussiandistributed variable whose precision is Gammadistributed. For more examples, see this forum thread.

What models can Infer.NET not handle?
 Nonparametric models such as Dirichlet processes are not supported. However, Gaussian Processes are supported.
 Infer.NET requires a model to be defined by a sampling process. It does not allow a model to be defined by a custom probability density function.
 Infer.NET does not support models that perform inference internally, i.e. nested inference. This limits its ability to automatically search over the space of models, as explained below.
Inference

What inference algorithms does Infer.NET support?
Infer.NET supports expectation propagation (including belief propagation as a special case), variational message passing (also known as variational Bayes), max product (for discrete models), and block Gibbs sampling.

How can I improve the speed/accuracy of inference with Infer.NET?
Read the section on improving the speed and accuracy of inference.

How can I change the inference schedule?
At present, the only supported mechanism for changing the automatically generated inference schedule is to provide initial values for particular messages which will then indirectly affect the schedule. If you have examples where the scheduler is giving a poor schedule, please let us know.
It is also possible to change the schedule manually by editing the generated code to reorder the message computations.
You can also affect the schedule by partitioning your model and using the concept of shared variables. The automatic schedule will run on each piece, but you have control over scheduling the submodels.
Finally, you can bypass the Infer.NET schedule altogether and call directly into the operator message methods.

Does Infer.NET scale to large models/data sets?
Infer.NET has been designed from the ground up to be computationally efficient. The compiler architecture means that the generated inference code often approaches the efficiency of handwritten code. Infer.NET also supports batchprocessing of large datasets by sharing variables between models and you can implement customised message operators to overcome particular performance bottlenecks. However, there will always be cases where handcoded solutions can exploit special cases to improve efficiency. If you have an example where Infer.NET generated code is significantly less efficient than handwritten code, please let us know.
Note that the model compiler is not itself particularly efficient. We have focused our efforts so far on making the generated code efficient, rather than the generation process itself. Hence you should ensure that you are only invoking the compiler once or, at most, a small number of times (i.e. not inside a loop). Methods for doing this are presented in the tutorials.

Does Infer.NET do structure learning?
Infer.NET can do limited forms of structure learning via gates. The idea is to add selector variables to your model that turn links on and off. For example, see Structural Expectation Propagation (SEP): Bayesian structure learning for networks with latent variables. Infer.NET does not do automatic structure learning of Bayesian networks, as you might find in a dedicated Bayes net package.

Can I learn the parameters of a Beta distribution, or the shape parameter of a Gamma distribution?
No. The inference algorithms in Infer.NET can theoretically learn these parameters, but only at great expense. Therefore Infer.NET doesn’t include these operations, in order to encourage people to use better modelling options that allow efficient inference. For modelling a number between zero and one, consider putting a Gaussian distribution through a logistic transformation. For modelling a number between zero and infinity, consider putting a Gaussian through an exponential transformation. These choices are not only better from the point of view of inference, but give more modelling options since the input Gaussian can have its own sophisticated model.
Troubleshooting

Inference is running very slowly
This is normally caused by the inference compiler running inside a loop. You can avoid recompilation using observed values as described in this tutorial. If this does not help, try reading the section on improving the speed and accuracy of inference.
Another common reason for slow inference is that you are hitting memory limits on your system. Refer to the earlier bullet on memory efficiency for strategies to deal with that.

OutOfMemoryException during inference
Infer.NET preallocates memory for all messages being passed during inference. This can be particularly severe when running models with large message types such as Dirichlet or Discrete messages, especially in cases where arrays of Discrete variables, each with a large value range, are used to switch on and off parts of a model  for example LDA models. All messages for all data instances for all values of the switch variable are stored, and the messages themselves are large, so such models quickly consume all available memory.
To reduce memory consumption, see the section on how to build scalable applications.

IndexOutOfRangeException during inference
The most common cause of this is setting the ObservedValue of an array variable to an array of the wrong length. If you attach names to your arrays and enable debugging of generated code, then the line in the generated code where the exception is raised will tell you which array is the wrong size.

ImproperMessageException during inference
To avoid this, depending on your model, use initialization (for an example of initialization, see the Mixture of Gaussians tutorial), try changing priors or reorder the data. If you attach names to your variables and enable debugging of generated code, then the line in the generated code where the exception is raised will tell you which message is improper.

AllZeroException during inference
A current limitation of Infer.NET is that this exception will be thrown if any branch in your model is impossible. For example, if your model has an If statement that makes x equal to true in one case and false in the other, and you observe that x is false, then you will get an AllZeroException when the first branch is visited. To work around this, avoid using point masses in your model definition. For example, the first branch can generate x from a Bernoulli(0.99999) distribution, which is effectively equivalent to true but avoids the exception.

Inferred marginals are far from exact, even for a simple model
All of the inference algorithms in Infer.NET will degrade if your model translates to a factor graph with a loop of strongly coupled variables, especially a deterministic loop. If your model contains such a loop, try to rewrite it using some of the other factors available in Infer.NET. See forum thread XOR Inference for an example. A related issue is that Gibbs sampling requires a certain amount of stochasticity in the model, even without loops. If the variables are too strongly coupled, then the sampler won’t mix.

Results are bad and I don’t know why
First determine if the problem is due to inference or modelling. Generate a dataset by sampling from the model and see if you can recover the generating parameters, as done in the examples. If you can recover them, then it is probably a modelling issue. If not, check the following:
 Is there enough data?
 Does the model have a strong enough link between the parameters and the data for them to be recovered? For example, is the noise level too high?
 Does the model have parameter symmetries, i.e. different settings of the parameters that produce the same data distribution? See the Recommender System example.
 Has the inference algorithm converged? You can determine this by running for different numbers of iterations.
 Try initializing the algorithm near the true values. If this helps, then the problem may have multiple solutions.
 Try a different inference algorithm.
 Try simplifying the model by observing some of the parameters to their true values.