<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://community.research.microsoft.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Infer.NET Team Blog</title><subtitle type="html">Infer.NET is a .NET framework for machine learning. It provides state-of-the-art algorithms for probabilistic inference from data.  Various Bayesian models such as Bayes Point Machine classifiers, TrueSkill matchmaking, hidden Markov models, and Bayesian networks can be implemented using Infer.NET.
</subtitle><id>http://community.research.microsoft.com/blogs/infernet_team_blog/atom.aspx</id><link rel="alternate" type="text/html" href="http://community.research.microsoft.com/blogs/infernet_team_blog/default.aspx" /><link rel="self" type="application/atom+xml" href="http://community.research.microsoft.com/blogs/infernet_team_blog/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2008-12-09T04:33:00Z</updated><entry><title>Infer.NET team at PDC09</title><link rel="alternate" type="text/html" href="/blogs/infernet_team_blog/archive/2009/11/12/infer-net-team-at-pdc09.aspx" /><id>/blogs/infernet_team_blog/archive/2009/11/12/infer-net-team-at-pdc09.aspx</id><published>2009-11-12T23:10:00Z</published><updated>2009-11-12T23:10:00Z</updated><content type="html">&lt;p&gt;Some lucky members of the Infer.NET team are&amp;nbsp;being let loose from the lab to attend &lt;a href="http://microsoftpdc.com/"&gt;PDC09&lt;/a&gt; and talk about the fun&amp;nbsp;stuff you&amp;nbsp;can do with Infer.NET.&lt;a href="http://community.research.microsoft.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/infernet_5F00_team_5F00_blog/PDC09Bling_5F00_Speaker_5F00_ImA_5F00_240.jpg"&gt;&lt;img src="http://community.research.microsoft.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/infernet_5F00_team_5F00_blog/PDC09Bling_5F00_Speaker_5F00_ImA_5F00_240.jpg" alt="I&amp;#39;m a PDC09 speaker" border="0" style="border:0;float:right;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can find out &lt;a href="http://microsoftpdc.com/Sessions/VTL03"&gt;full details of our session&lt;/a&gt;&amp;nbsp;which is called &amp;#39;&lt;a href="http://microsoftpdc.com/Sessions/VTL03"&gt;Infer.NET: Building Software with&amp;nbsp;Intelligence&lt;/a&gt;&amp;#39;.&amp;nbsp;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Update: &lt;/strong&gt;the video for our session is now up - so you can &lt;/em&gt;&lt;a href="http://microsoftpdc.com/Sessions/VTL03"&gt;&lt;em&gt;watch it here&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;nbsp;if you missed it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the blurb:&lt;/p&gt;
&lt;p style="PADDING-LEFT:30px;"&gt;&lt;em&gt;Would you like to write software that can adapt to the user, learn from examples or work with uncertain information? Infer.NET is a machine learning framework that lets you build these capabilities directly into your .NET application. The framework allows you to combine detailed domain knowledge with the latest machine learning algorithms to generate tailored code to solve your problem. An API based on random variables lets you call Infer.NET code from within your application. We provide examples of using Infer.NET in search and gaming.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re attending PDC, please do come along - we&amp;#39;ll also be at the &amp;#39;Ask the Experts&amp;#39; event to handle any particular questions you have about Infer.NET.&lt;/p&gt;
&lt;p&gt;See you in LA!&lt;/p&gt;
&lt;p&gt;The Infer.NET team&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://community.research.microsoft.com/aggbug.aspx?PostID=7343" width="1" height="1"&gt;</content><author><name>jwinn</name><uri>http://community.research.microsoft.com/members/jwinn/default.aspx</uri></author></entry><entry><title>Parallel inference in Infer.NET 2.3</title><link rel="alternate" type="text/html" href="/blogs/infernet_team_blog/archive/2009/08/13/parallel-inference-in-infer-net-2-3.aspx" /><id>/blogs/infernet_team_blog/archive/2009/08/13/parallel-inference-in-infer-net-2-3.aspx</id><published>2009-08-13T13:55:00Z</published><updated>2009-08-13T13:55:00Z</updated><content type="html">&lt;p&gt;Hello Infernauts!!&lt;/p&gt;
&lt;p&gt;One of the many changes we made in the recently released Infer.NET 2.3 beta was allowing parallel inference on multiple cores.&amp;nbsp; We are keen to make Infer.NET scale to ever larger datasets and supporting parallelism has always been an important part of that goal.&amp;nbsp; Here I&amp;#39;ll show how to use multi-core parallelism to speed up inference - of course, you&amp;#39;ll only see the speedup on a multi-core machine.&lt;/p&gt;
&lt;p&gt;The first thing you need to do is to install the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD-593D-4B3C-B055-694C50D2B0F3&amp;amp;displaylang=en"&gt;Microsoft Parallel Extensions CTP&lt;/a&gt;.&amp;nbsp; This is the library that Infer.NET uses to do multi-core parallelism.&amp;nbsp; We have chosen to work with the CTP for the time being - the Parallel Extensions library is planned to be part of version 4.0 of the Microsoft .NET framework and we will move to using that version at a future date. You can read more about current and forthcoming Microsoft parallelism technologies at the &lt;a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"&gt;MSDN Parallel Computing Developer Center&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;OK, so you&amp;#39;ve installed the CTP.&amp;nbsp; Now pick a model you want to parallelise. I&amp;#39;ll use the &lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/docs/Click%20model%20example.aspx"&gt;click model&lt;/a&gt; which you can run from inside the &lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/docs/The%20examples%20browser.aspx"&gt;Infer.NET examples browser&lt;/a&gt;, under &amp;#39;Applications&amp;#39;. Make sure that inference on your model is working as you would expect.&amp;nbsp; Now you can configure your inference engine to use parallel loops by adding the following line:&lt;/p&gt;
&lt;div&gt;
&lt;table cellpadding="5" cellspacing="5"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="BACKGROUND-COLOR:#eeeeee;"&gt;&lt;code&gt;&lt;span style="color:#000000;font-size:x-small;"&gt;
&lt;p&gt;engine.Compiler.&lt;span style="font-size:x-small;"&gt;UseParallelForLoops &lt;/span&gt;= &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;The click model uses two engines, one for training and one for test so I added this line in both cases. You must configure the inference engine before any calls to &lt;strong&gt;Infer() &lt;/strong&gt;for this to have an effect. The result of this change is that certain for loops in the generated inference code will be replaced with &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.parallel.for(VS.100).aspx"&gt;Parallel.For&lt;/a&gt; loops. To see how this affects the speed of inference, you can use the handy built-in ability to see timings for various stages of inference:
&lt;div&gt;
&lt;table cellpadding="5" cellspacing="5"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="BACKGROUND-COLOR:#eeeeee;"&gt;&lt;code&gt;&lt;span style="color:#000000;font-size:x-small;"&gt;
&lt;p&gt;engine.ShowTimings = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Typical results looks on my 8-core machine are shown in the table below.&amp;nbsp; For comparison, I have also shown results for running a Hidden Markov Model on a large data set.&lt;br /&gt;
&lt;table cellspacing="0" style="width:100%;" class="style1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style3"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="style3"&gt;&lt;strong&gt;Time per iteration - Normal&lt;/strong&gt;&lt;/td&gt;
&lt;td class="style3"&gt;&lt;strong&gt;Time per iteration - Parallel For&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style3"&gt;&lt;strong&gt;Click Model Training&lt;/strong&gt;&lt;/td&gt;
&lt;td class="style3"&gt;218ms&lt;/td&gt;
&lt;td class="style3"&gt;177ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style3"&gt;&lt;strong&gt;Click Model Test&lt;/strong&gt;&lt;/td&gt;
&lt;td class="style3"&gt;22ms&lt;/td&gt;
&lt;td class="style3"&gt;30ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style3"&gt;&lt;strong&gt;Hidden Markov Model&lt;/strong&gt;&lt;/td&gt;
&lt;td class="style3"&gt;5341ms&lt;/td&gt;
&lt;td class="style3"&gt;1352ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;These results may be unexpected.&amp;nbsp; The speed up for click model training is about 20% using parallel for loops but for click model testing, using parallel for loops actually slows things down.&amp;nbsp; This is because parallel for loops introduce additional overhead compared to ordinary for loops, and so you will only get a benefit if the loop is large and a reasonable amount of work is being done inside the loop.&amp;nbsp; In the test case, the iterations are quick and the time is dominated by the parallel overhead. This point is illustrated by the Hidden Markov Model results, where an almost 4x speedup is achieved using parallel for loops - quite a significant improvement for one line of code!!&lt;/p&gt;
&lt;p&gt;So, in summary, parallel for loops &lt;em&gt;can &lt;/em&gt;speed up inference, especially in larger models, and &lt;em&gt;may&lt;/em&gt; speed it up considerably.&amp;nbsp; The exact speedup you will get depends on your hardware, model and inference algorithm.&amp;nbsp; The easiest way to determine it is just to try it out and see.&lt;/p&gt;
&lt;p&gt;Whilst this post has discussed multi-core parallelism, it is also possible to distribute Infer.NET inference across a cluster, by dividing your model into chunks using &lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/docs/Sharing%20variables%20between%20models.aspx"&gt;shared variables&lt;/a&gt;. At the moment, you have to wire together together the chunks manually e.g. using &lt;a href="http://en.wikipedia.org/wiki/Message_Passing_Interface"&gt;MPI&lt;/a&gt;. We will be looking how to make this more automatic in a future version of Infer.NET and we&amp;#39;ll be sure to blog about it when we do!&lt;/p&gt;
&lt;p&gt;John W.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://community.research.microsoft.com/aggbug.aspx?PostID=6668" width="1" height="1"&gt;</content><author><name>jwinn</name><uri>http://community.research.microsoft.com/members/jwinn/default.aspx</uri></author><category term="Infer.NET" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/Infer.NET/default.aspx" /><category term="inference" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/inference/default.aspx" /><category term="parallel" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/parallel/default.aspx" /><category term="speed up" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/speed+up/default.aspx" /></entry><entry><title>Infer.NET 2.3 Beta 1 released</title><link rel="alternate" type="text/html" href="/blogs/infernet_team_blog/archive/2009/08/11/infer-net-2-3-beta-1-released.aspx" /><id>/blogs/infernet_team_blog/archive/2009/08/11/infer-net-2-3-beta-1-released.aspx</id><published>2009-08-11T18:03:00Z</published><updated>2009-08-11T18:03:00Z</updated><content type="html">&lt;p&gt;This &lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/download.aspx"&gt;new release&lt;/a&gt; is the first we have done since the January 2.2 Beta release; the version number change reflects the fact that an initial version of Gibbs sampling is now available. Just as importantly, there have been many practical improvements, particularly with respect to indexing and jagged arrays, which enable a larger class of models to be built. Also, some new factors are available including a logistic factor, and there are wrappers to make syntax a bit more natural for F# and for Iron Python. Finally, we have looked into what was preventing Infer.NET running on Linux under Mono (this was a combination of a bug in Mono, and some obfuscation issues), and we have worked around these; we have verified that the examples, at least, now run under Mono - let us know how you get along. There have been one or two minor API changes, but your models should mainly work without change, unless you have been using the &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;InferAll&lt;/span&gt;&lt;/span&gt; method - more on this later.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://research.microsoft.com/infernet/docs/Release%20change%20history.aspx"&gt;The list of changes&lt;/a&gt; can be found in &lt;a href="http://research.microsoft.com/infernet/docs/default.aspx"&gt;in the User Guide&lt;/a&gt;, and I will pick out and expand on a few of the changes below.&lt;/p&gt;
&lt;h3&gt;Gibbs Sampling&lt;/h3&gt;
&lt;p&gt;This represents the first release of Gibbs sampling within the Infer.NET framework. &lt;a href="http://en.wikipedia.org/wiki/Gibbs_sampling"&gt;Gibbs sampling&lt;/a&gt; is a very different algorithm from Expectation Propagation and Variational Message Passing (which are approximate deterministic algorithms); it generates a chain of samples from the posterior distribution, and marginal distributions can estimated from the samples lists. Block Gibbs sampling is also supported as part of the implementation.&amp;nbsp; This allows more efficient sampling for highly correlated variables, and is also required for dealing with deterministic factors and constraints. &lt;/p&gt;
&lt;p&gt;In Infer.NET, you specify a model in a way that is completely independent of the inference algorithm; it is only when you want to run inference that you specify the algorithm, and your model code is then compiled for that algorithm. The examples browser installed with Infer.NET allows you to choose which algorithm to run on a given model (however, note that not all algorithms support all factors so you will get an error message for certain combinations of model and algorithm). As an example, take a look at the &amp;#39;Learning a Gaussian with Ranges&amp;#39; example in the tutorial browser; you can run the same model with all three algorithms and compare results.&lt;/p&gt;
&lt;p&gt;Here is a very simple example of Gibbs sampling where we infer the mean and precision of a Gaussian. Note how we can recover both the marginal and the chain of samples.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#008000;"&gt;// The model&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Variable&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt; mean = &lt;span style="color:#2b91af;"&gt;Variable&lt;/span&gt;.GaussianFromMeanAndVariance(0, 100);&lt;span style="color:#2b91af;"&gt;&lt;br /&gt;Variable&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt; prec = &lt;span style="color:#2b91af;"&gt;Variable&lt;/span&gt;.GammaFromShapeAndScale(1, 1);&lt;span style="color:#2b91af;"&gt;&lt;br /&gt;Range&lt;/span&gt; i = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Range&lt;/span&gt;(2);&lt;span style="color:#2b91af;"&gt;&lt;br /&gt;VariableArray&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt; data = &lt;span style="color:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt;(i);&lt;br /&gt;data[ i ] = &lt;span style="color:#2b91af;"&gt;Variable&lt;/span&gt;.GaussianFromMeanAndPrecision(mean, prec).ForEach(i);&lt;span style="color:#008000;"&gt;&lt;br /&gt;// The observations&lt;br /&gt;&lt;/span&gt;data.ObservedValue = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;[ ] { 5.0, 7.0 };&lt;span style="color:#008000;"&gt;&lt;br /&gt;// The model&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;&lt;br /&gt;InferenceEngine&lt;/span&gt; engine = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;InferenceEngine&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;GibbsSampling&lt;/span&gt;());&lt;span style="color:#0000ff;"&gt;&lt;br /&gt;var&lt;/span&gt; meanMarg = engine.Infer&amp;lt;&lt;span style="color:#2b91af;"&gt;Gaussian&lt;/span&gt;&amp;gt;(mean);&lt;span style="color:#0000ff;"&gt;&lt;br /&gt;var&lt;/span&gt; meanSamples = engine.Infer&amp;lt;&lt;span style="color:#2b91af;"&gt;SampleList&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt;&amp;gt;(mean, &lt;span style="color:#2b91af;"&gt;QueryTypes&lt;/span&gt;.Samples);&lt;span style="color:#0000ff;"&gt;&lt;br /&gt;var&lt;/span&gt; precMarg = engine.Infer&amp;lt;&lt;span style="color:#2b91af;"&gt;Gamma&lt;/span&gt;&amp;gt;(prec);&lt;span style="color:#0000ff;"&gt;&lt;br /&gt;var&lt;/span&gt; precSamples = engine.Infer&amp;lt;&lt;span style="color:#2b91af;"&gt;SampleList&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt;&amp;gt;(prec, &lt;span style="color:#2b91af;"&gt;QueryTypes&lt;/span&gt;.Samples);&lt;/p&gt;
&lt;p&gt;Note that Gibbs sampling is a work in progress, and some factors are not yet supported. In particular, Gates are not yet handled, so you will not be able to use &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;Variable.Switch statements&lt;/span&gt;&lt;/span&gt; or &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;Variable.If&lt;/span&gt;&lt;/span&gt; statements. Also, factors which take an array argument such as &amp;#39;&lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;Sum&lt;/span&gt;&lt;/span&gt;&amp;#39; are not yet supported. Also on our to-do list are some speed improvements in the generated code, especially with respect to array variables.&lt;/p&gt;
&lt;h3&gt;Improvements in jagged arrays and indexing&lt;/h3&gt;
&lt;p&gt;Most real world problems have complex and irregular dependencies between variables. Support for such problems is now greatly improved, the generated code is more efficient, and several bugs have been fixed.&lt;/p&gt;
&lt;p&gt;As an example, consider a social network. We might have various observations about the individuals in the social network, and the goal is to infer something about the link between two individuals. Variable ranges, which were available in Infer.NET 2.2 can be used to encode the graph structure - so we can range over all users, and for each user range over that user&amp;#39;s friends. Improvements now allow edge indexing to be encoded via a 2D observed index array, and allow switching based on that edge index so that you can encode latent variables on the edges of the social network.&lt;/p&gt;
&lt;p&gt;A later blog will look at these types of model in more detail.&lt;/p&gt;
&lt;h3&gt;API changes&lt;/h3&gt;
&lt;p&gt;API changes have occurred in two areas. First within the &lt;span class="style6"&gt;&lt;span style="font-family:Courier New;"&gt;Infer&lt;/span&gt;&lt;/span&gt; and &lt;span class="style6"&gt;&lt;span style="font-family:Courier New;"&gt;InferAll&lt;/span&gt;&lt;/span&gt; methods, and secondly in the evidence operators. You won&amp;#39;t need to worry about the latter unless you&amp;#39;ve been writing your own factors and operators, so I&amp;#39;ll concentrate on the former.&lt;/p&gt;
&lt;p&gt;The &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;Infer&lt;/span&gt;&lt;/span&gt; function (a method on the &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;InferenceEngine&lt;/span&gt;&lt;/span&gt;) was previously a bit tricky to use with variable arrays (especially complex arrays such as jagged arrays of 2D arrays). The return types in these case were (and still are) quite difficult to understand and work with; each return type is a form of &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;DistributionArray&lt;/span&gt;&lt;/span&gt; which can be thought of as a distribution over an array domain. It is more natural and less confusing to work with .NET arrays of distributions over non-array domains, and this is now the recommended usage (though the old will still work).&lt;/p&gt;
&lt;p&gt;For example, suppose you have a jagged variable array of type&lt;/p&gt;
&lt;p class="style3"&gt;&lt;span class="style1"&gt;&lt;span style="color:#2b91af;font-family:Courier New;"&gt;VariableArray&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class="style1"&gt;&lt;span style="color:#2b91af;font-family:Courier New;"&gt;VariableArray&lt;/span&gt;&lt;/span&gt;&amp;lt;&lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&amp;gt;, &lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;[][]&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;where the individual items are drawn from &lt;span class="style1"&gt;&lt;span class="style5"&gt;&lt;span style="color:#2b91af;font-family:Courier New;"&gt;Gaussian&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;s. You can now get the inference results as a jagged array of &lt;span class="style1"&gt;&lt;span class="style5"&gt;&lt;span style="color:#2b91af;font-family:Courier New;"&gt;Gaussian&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;s&lt;span class="style1"&gt;&lt;span class="style5"&gt;&lt;span style="color:#2b91af;font-family:Courier New;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;as follows:&lt;/p&gt;
&lt;p class="style3"&gt;&lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span class="style5"&gt;&lt;span style="color:#2b91af;"&gt;Gaussian&lt;/span&gt;&lt;/span&gt;[][] posterior = engine.Infer&amp;lt;&lt;span class="style5"&gt;&lt;span style="color:#2b91af;"&gt;Gaussian&lt;/span&gt;&lt;/span&gt;[][]&amp;gt;(w);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As part of the overhaul of the inference methods, the &lt;span class="style6"&gt;&lt;span style="font-family:Courier New;"&gt;InferAll&lt;/span&gt;&lt;/span&gt; method no longer returns anything. You can call it as before, and it will have the same behaviour as before, and run the inference for the specified variables, but you will not be able to assign the results. To retrieve the results, just call individual &lt;span class="style6"&gt;&lt;span style="font-family:Courier New;"&gt;Infer&lt;/span&gt;&lt;/span&gt;s for each variable you are interested in; if this variable was specified in a previous call to &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;InferAll&lt;/span&gt;&lt;/span&gt;, the marginal will be returned immediately without further computation.&lt;/p&gt;
&lt;h3&gt;Language Wrappers&lt;/h3&gt;
&lt;p&gt;The extensive use of generic methods in Infer.NET can make calling it from F# a bit cumbersome and unintuitive. A set of wrapper types for distribution arrays (for example &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;GaussianArrayOfArray&lt;/span&gt;&lt;/span&gt;) and variable arrays (for example &lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;VariableGaussianArrayOfArray&lt;/span&gt;&lt;/span&gt;) are provided for commonly-used distributions and domain types.&amp;nbsp; Also, the wrapper provides alternative operators for cases where Infer.NET operator overloads are not recognised; for example the &amp;quot;&lt;span class="style1"&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&amp;quot; operator (though supported in Infer.NET for creating a boolean variable from two real variables) is not recognised when calling from F# - the wrapper provides &amp;quot;&amp;lt;&amp;lt;&amp;quot; as an alternative. Another part of the wrapper provides more F#-like syntax for working with Infer.NET if blocks and switch blocks. &lt;a href="http://research.microsoft.com/infernet/docs/FSharp%20Wrapper.aspx"&gt;The F# wrapper&lt;/a&gt; is documented in the User Guide, and distributed as a DLL (Infer.FSharp.dll) and as a source file (FSharpWrapper.fs) - these can be found under the bin and source folders respectively in the installation folder.&lt;/p&gt;
&lt;p&gt;There is also a wrapper for &lt;a href="http://research.microsoft.com/infernet/Calling%20Infer.NET%20from%20IronPython.aspx"&gt;IronPython&lt;/a&gt;, which is distributed as IronPythonWrapper.py under the source folder under the installation folder. This wrapper is only useful/tested for IronPython 2.6 Beta 2 and above.&lt;/p&gt;
&lt;p&gt;Well, that&amp;#39;s a summary of some of the more visible changes. There have, of course, been many changes under the hood, fixing bugs, and making things more efficient. We plan to do some more focussed blogs on individual areas in the coming weeks, so stay tuned.&lt;/p&gt;
&lt;p&gt;John G. and the Infer.NET team.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://community.research.microsoft.com/aggbug.aspx?PostID=6647" width="1" height="1"&gt;</content><author><name>John Guiver</name><uri>http://community.research.microsoft.com/members/John-Guiver/default.aspx</uri></author><category term="Gibbs Sampling" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/Gibbs+Sampling/default.aspx" /><category term="Infer.NET" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/Infer.NET/default.aspx" /></entry><entry><title>Bayesian PCA</title><link rel="alternate" type="text/html" href="/blogs/infernet_team_blog/archive/2009/02/03/bayesian-pca.aspx" /><id>/blogs/infernet_team_blog/archive/2009/02/03/bayesian-pca.aspx</id><published>2009-02-03T18:33:00Z</published><updated>2009-02-03T18:33:00Z</updated><content type="html">&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3" face="Calibri"&gt;It’s been a couple of months now since we’ve released Infer.NET to the outside world, and a blog is overdue. I hope those of you have downloaded it are enjoying it and have had a chance at least to go through some of the tutorials to see the scope of what we’re providing. In the process of doing this release, one point of discussion has been the question of to what level we should provide and/or support standard black box models.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Here I’m talking about the likes of Bayesian factor analysis, Bayesian PCA, HMMs, Bayesian neural nets, and the Bayes point machine. We have been reluctant to provide these as stock models because we have been keen that Infer.NET should be applied in a more customised way than just throwing data at a generic model. The &lt;/font&gt;&lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/docs/Click%20through%20model%20sample.aspx"&gt;&lt;font color="#0000ff" size="3" face="Calibri"&gt;click through &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;model&lt;/font&gt;&lt;/a&gt;&lt;font size="3" face="Calibri"&gt; &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;is an excellent example of a thoughtful customised model which tries to capture the behaviour of a user interacting with a page of results returned by a search engine.&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;That said, it is often useful in the early stages for a user to look at and employ some standard models just to get started. With the release, we have already provided a set of multi-class &lt;/font&gt;&lt;/font&gt;&lt;a href="http://research.microsoft.com/infernet/docs/Multi-class%20classification.aspx"&gt;&lt;font color="#0000ff" size="3" face="Calibri"&gt;Bayes point machine examples&lt;/font&gt;&lt;/a&gt;&lt;font size="3" face="Calibri"&gt; &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;which can be used for a variety of classification problems. In this blog I will look at Bayesian principal components analysis&lt;span style="mso-spacerun:yes;"&gt; &lt;/span&gt;– see Chris Bishop’s &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;book &lt;/font&gt;&lt;a href="http://research.microsoft.com/en-us/um/people/cmbishop/PRML/index.htm"&gt;&lt;font color="#0000ff" size="3" face="Calibri"&gt;Pattern Recognition and Machine Learning&lt;/font&gt;&lt;/a&gt;&lt;font size="3" face="Calibri"&gt; for example. Most of you will be familiar with standard &lt;/font&gt;&lt;a href="http://en.wikipedia.org/wiki/Principal_components_analysis"&gt;&lt;font size="3" face="Calibri"&gt;Principal Component Analysis&lt;/font&gt;&lt;/a&gt;&lt;font size="3" face="Calibri"&gt; which is a widely used technique for dimensionality reduction.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;Given an observation space of dimension &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;D&lt;/span&gt;&lt;/i&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; &lt;/span&gt;we would like to find a latent space of lower dimension &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;M&lt;/span&gt;&lt;/i&gt; (the ‘principal space’) which captures most of the data. The mapping from principal space to observation space is via a linear mapping represented by a mixing matrix &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;W&lt;/span&gt;&lt;/i&gt;. PCA can be formulated in probabilistic way (‘probabilistic PCA’) and this in itself gives many benefits as itemised in Bishop. If in addition we adopt a Bayesian approach to inferring W, we can also determine the optimal value for M using ‘automatic relevance determination’ (ARD). &lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3" face="Calibri"&gt;A fully Bayesian treatment of probabilistic PCA (including ARD) is quite complex and it might take several weeks of work to implement an efficient deterministic inference algorithm. In Infer.NET, defining the model is 20 to 25 lines of code and a few hours’ work. &lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3" face="Calibri"&gt;I am going to plunge straight in and show the factor graph for Bayesian PCA. Factor graphs are a great representation for probabilistic models, and especially useful if you are going to build models in Infer.NET. If you can draw a factor graph, you should be able to code up the model in&lt;img style="WIDTH:380px;HEIGHT:400px;" border="2" hspace="10" alt="Factor graph for Bayesian PCA" align="left" src="http://research.microsoft.com/infernet/images/bayesianpca.jpg" width="400" height="300" /&gt; Infer.NET (subject to the currently available distributions, factors, and message operators). &lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;I’ll jointly explain aspects of the factor graph and Bayesian PCA as I go along. As a reminder, the first thing to note is that the variables in the problem are represented as circles/ovals, and the factors (functions, distributions, or constraints) are represented as squares/rectangles. Each factor is only ever attached to its variables and each variable is only ever attached to its factors. The big enclosing rectangles represent ‘plates’ and show replications of variables and factors across arrays. Factor graphs are important both because they provide a clarifying visualisation of complex probabilistic models and because of the close relationship with the underlying inference and sampling algorithms (particularly those based on local message passing). &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3" face="Calibri"&gt;The accompanying factor graph shows PCA as a generative model for randomly generating the &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;N&lt;/span&gt;&lt;/i&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; &lt;/span&gt;observations – these observations can be represented as an &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;NxD&lt;/span&gt;&lt;/i&gt; array, and so are represented in the factor graph in the intersection of two plates of size &lt;i style="mso-bidi-font-style:normal;"&gt;N&lt;/i&gt; and &lt;i style="mso-bidi-font-style:normal;"&gt;D&lt;/i&gt; respectively. I have explicitly shown all indices in the factor graph to make the comparison with the code clearer. The generative process starts at the top left where, for each observation and for each component in latent space, we sample from a standard Gaussian to give an &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;NxM&lt;/span&gt;&lt;/i&gt; array &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;Z&lt;/span&gt;&lt;/i&gt; (with elements &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;z&lt;sub&gt;nm&lt;/sub&gt;&lt;/span&gt;&lt;/i&gt;).&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;In the top right we have the matrix variable &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;W&lt;/span&gt;&lt;/i&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; &lt;/span&gt;(elements &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;w&lt;sub&gt;nm&lt;/sub&gt;&lt;/span&gt;&lt;/i&gt;) which maps latent space to observation space – so this will be an &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;MxD&lt;/span&gt;&lt;/i&gt; matrix which will post-multiply &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;Z&lt;/span&gt;&lt;/i&gt;. We have specified a maximum &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;M&lt;/span&gt;&lt;/i&gt; in advance, but what we really want to do is learn the ‘true’ number of components that explain the data, and we do this by drawing the rows of &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;W&lt;/span&gt;&lt;/i&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; &lt;/span&gt;from a zero-mean Gaussian whose precisions&lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; a&lt;/span&gt;&lt;font face="Calibri"&gt; &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;(elements &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;a&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;sub&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; m&lt;/span&gt;&lt;/sub&gt;&lt;/i&gt;) we are going to learn. If the precision on a certain row becomes very large (i.e. the variance becomes very small) then the row has negligible effect on the mapping and the effective dimension of the principal space is reduced by the number of such rows. The elements of &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;a&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;are drawn from a common Gamma prior.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;The MatrixMultiply factor multiplies the &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;Z&lt;/span&gt;&lt;/i&gt; with &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;W&lt;/span&gt;&lt;/i&gt;; as this factor takes two double arrays of variables, it sits outside the plates. The result of this factor is an &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;NxM&lt;/span&gt;&lt;/i&gt; matrix variable &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;T&lt;/span&gt;&lt;/i&gt; (elements &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;t&lt;sub&gt;nm&lt;/sub&gt;&lt;/span&gt;&lt;/i&gt;).&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;We then add a bias vector variable &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;m&lt;/span&gt;&lt;font face="Calibri"&gt; (elements &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;m&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;sub&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; d&lt;/span&gt;&lt;/sub&gt;&lt;/i&gt; &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;drawn from a common Gaussian prior) to each row of &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;T&lt;/span&gt;&lt;/i&gt; to give matrix variable &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;U&lt;/span&gt;&lt;/i&gt; (elements u&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;sub&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;nm&lt;/span&gt;&lt;/sub&gt;&lt;/i&gt;). Finally, the matrix &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;X&lt;/span&gt;&lt;/i&gt; of observations vector is generated by drawing from Gaussians with mean U and precision given by the vector variable &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;p&lt;/span&gt;&lt;font face="Calibri"&gt; (elements &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;p&lt;/span&gt;&lt;font face="Calibri"&gt;&lt;i style="mso-bidi-font-style:normal;"&gt;&lt;sub&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt; d&lt;/span&gt;&lt;/sub&gt;&lt;/i&gt; drawn from a common Gamma prior). The elements in this final array of Gaussian factors are the likelihood factors and represent the likelihood of the observations conditional on the parameters of the model. These parameters are W, &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;m&lt;/span&gt;&lt;font face="Calibri"&gt; and &lt;/font&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:Symbol;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;p&lt;/span&gt;&lt;font face="Calibri"&gt; which we want to infer.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font size="3" face="Calibri"&gt;This model is captured in the following few lines of C# code which, as you can hopefully see, directly matches the factor graph (I have omitted the variable and range declarations as these don’t add further insight, but the full code can be found &lt;/font&gt;&lt;a href="http://research.microsoft.com/infernet/blogs/bayesianpca.aspx"&gt;&lt;font color="#0000ff" size="3" face="Calibri"&gt;here&lt;/font&gt;&lt;/a&gt;&lt;font size="3" face="Calibri"&gt;):&lt;/font&gt;&lt;/p&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:green;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;// Mixing matrix&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vAlpha = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;&amp;gt;(rM).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Alpha&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vW = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;&amp;gt;(rM, rD).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;W&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vAlpha[rM] = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Random&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;, &lt;span style="COLOR:#2b91af;"&gt;Gamma&lt;/span&gt;&amp;gt;(priorAlpha).ForEach(rM);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vW[rM, rD] = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.GaussianFromMeanAndPrecision(0, vAlpha[rM]).ForEach(rD);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:green;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;// Latent variables are drawn from a standard Gaussian&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vZ = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;&amp;gt;(rN, rM).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Z&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vZ[rN, rM] = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.GaussianFromMeanAndPrecision(0.0, 1.0).ForEach(rN, rM);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:green;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;// Multiply the latent variables with the mixing matrix...&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vT = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.MatrixMultiply(vZ, vW).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;T&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:green;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;// ... add in a bias ...&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vMu = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;&amp;gt;(rD).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;mu&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vMu[rD] = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Random&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;, &lt;span style="COLOR:#2b91af;"&gt;Gaussian&lt;/span&gt;&amp;gt;(priorMu).ForEach(rD);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vU = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;&amp;gt;(rN, rD).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;U&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vU[rN, rD] = vT[rN, rD] + vMu[rD];&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:green;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;// ... and add in some observation noise ...&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vPi = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Array&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;&amp;gt;(rD).Named(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;pi&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vPi[rD] = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.Random&amp;lt;&lt;span style="COLOR:blue;"&gt;double&lt;/span&gt;, &lt;span style="COLOR:#2b91af;"&gt;Gamma&lt;/span&gt;&amp;gt;(priorPi).ForEach(rD);&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:green;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;// ... to give the likelihood of observing the data&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;mso-no-proof:yes;"&gt;vData[rN, rD] = &lt;span style="COLOR:#2b91af;"&gt;Variable&lt;/span&gt;.GaussianFromMeanAndPrecision(vU[rN, rD], vPi[rD]);&lt;/span&gt; 
&lt;p&gt;&lt;font size="3" face="Calibri"&gt;In order to test out this model, I generated 1000 data points from a model with &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;M=3&lt;/span&gt;&lt;/i&gt;, &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;D= 10&lt;/span&gt;&lt;/i&gt;. However, when doing inference, I gave it &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;M=6&lt;/span&gt;&lt;/i&gt; to see if the inference could correctly determine the number of components. Here is the print-out from a run. As you can see, as expected, only three of the rows of &lt;i style="mso-bidi-font-style:normal;"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-SIZE:12pt;mso-bidi-font-size:11.0pt;"&gt;W&lt;/span&gt;&lt;/i&gt; have significant non-zero entries, and the bias and noise vectors are successfully inferred.&lt;/font&gt;&lt;/p&gt;&lt;span style="LINE-HEIGHT:150%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;"&gt;Mean absolute means of rows of W: 0.05&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.24&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.20&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.02&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.21 &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;0.01&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;"&gt;True bias:&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;-0.95&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.75 -0.20&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.20&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.30 -0.35&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.65&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.20&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.25&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.40&lt;br /&gt;&lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;"&gt;Inferred bias: -0.90&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.70 -0.22&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.22&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.31 -0.37&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.65&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.17&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.25&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;0.42&lt;br /&gt;&lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;"&gt;True noise:&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;4.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;1.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;3.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;4.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.00&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;1.00&lt;br /&gt;&lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:9pt;"&gt;Inferred noise: 0.98 &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;1.99&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;4.09&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.00 &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;1.08&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.00 &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;2.70 &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;3.51&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;2.16 &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;1.01&lt;/span&gt; 
&lt;p&gt;&lt;font size="3" face="Calibri"&gt;The full C# code for this example can be found &lt;/font&gt;&lt;a href="http://research.microsoft.com/infernet/blogs/bayesianpca.aspx"&gt;&lt;font color="#0000ff" size="3" face="Calibri"&gt;here&lt;/font&gt;&lt;/a&gt;&lt;font size="3" face="Calibri"&gt;. This code provides a class (BayesianPCA)&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;for constructing&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;a general Bayesian PCA model for which we can specify priors and data at inference time. There is also some example code for running inference and extracting marginals. One important aspect of running inference on this model is that we initially need to break symmetries in the model by initialising the W marginals to random values using the InitialiseTo() method – for another example of this see the &lt;/font&gt;&lt;a href="http://research.microsoft.com/infernet/docs/Mixture%20of%20Gaussians%20tutorial.aspx"&gt;&lt;font color="#0000ff" size="3" face="Calibri"&gt;Mixture of Gaussians tutorial&lt;/font&gt;&lt;/a&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="3" face="Calibri"&gt;I hope this provides a useful addition to your Infer.NET toolbox and also provides some insight into building models with Infer.NET. Keep the feedback and comments coming.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="3" face="Calibri"&gt;John Guiver and the Infer.NET team.&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://community.research.microsoft.com/aggbug.aspx?PostID=4396" width="1" height="1"&gt;</content><author><name>John Guiver</name><uri>http://community.research.microsoft.com/members/John-Guiver/default.aspx</uri></author><category term="Bayesian PCA" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/Bayesian+PCA/default.aspx" /><category term="Factor Analysis" scheme="http://community.research.microsoft.com/blogs/infernet_team_blog/archive/tags/Factor+Analysis/default.aspx" /></entry><entry><title>Infer.NET released!!</title><link rel="alternate" type="text/html" href="/blogs/infernet_team_blog/archive/2008/12/09/infer-net-released.aspx" /><id>/blogs/infernet_team_blog/archive/2008/12/09/infer-net-released.aspx</id><published>2008-12-09T02:33:00Z</published><updated>2008-12-09T02:33:00Z</updated><content type="html">&lt;p&gt;It&amp;#39;s a very exciting week for the Infer.NET team as we go live with our first public release, which &lt;a href="http://research.microsoft.com/infernet/"&gt;you can get hold of right now!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This release represents many years of work and we believe it is a significant step forward in how automatic inference is performed. Here&amp;#39;s a quick summary of what you get:&lt;span class="ms-sitemapdirectional"&gt; &lt;ul&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 12pt;"&gt;&lt;b&gt;Rich modelling language: &lt;/b&gt;support
for univariate and multivariate variables, both continuous and
discrete. Models can be constructed from a broad range of factors
including arithmetic operations, linear algebra, range and positivity
constraints, Boolean operators, Dirichlet-Discrete, Gaussian,and mixtures or hierachical mixtures of any of these. &lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 12pt;"&gt;&lt;b&gt;Multiple inference algorithms: &lt;/b&gt;built-in algorithms include expectation propagation, belief propagation (a special case of EP) and variational message passing (variational Bayes).&lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 12pt;"&gt;&lt;b&gt;Designed for large scale inference: &lt;/b&gt;Infer.NET is architected as a compiler allowing for very efficient inference through generated code.&lt;span class="ms-sitemapdirectional"&gt; In addition, the generated code can
be viewed, stepped through, profiled or modified as needed, using
standard development tools. &lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style="margin:0cm 0cm 12pt;"&gt;&lt;b&gt;User-extendable:&lt;/b&gt;&lt;span class="ms-sitemapdirectional"&gt; a plug-in architecture which
makes Infer.NET open-ended and adaptable. &lt;/span&gt;Probability
distributions, factors, message-passing operations and inference algorithms can
all be added by the user.&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;We have written a lot of &lt;a href="http://research.microsoft.com/infernet/docs/default.aspx"&gt;documentation&lt;/a&gt; on how the framework works and how you can add your own components to it.&amp;nbsp; There are also &lt;a href="http://research.microsoft.com/infernet/docs/Infer.NET%20tutorials%20and%20examples.aspx"&gt;lots of examples&lt;/a&gt; - ranging from simple explanatory tutorials to full applications - which should help you get into Infer.NET and then gain a deeper understanding of how it works. &lt;/p&gt;&lt;p&gt;Although we have spent many months of testing Infer.NET internally, it is inevitable that there will be some teething problems, with the system being used in ways which we have not anticipated.&amp;nbsp; For this reason, we are initially releasing the system as a &amp;#39;beta&amp;#39; and we are looking for lots of feedback from the community (i.e. you!) on how well it is working and what you are using it for.&amp;nbsp; If you do encounter a problem, please raise it on &lt;a href="http://community.research.microsoft.com/forums/116.aspx"&gt;the forum&lt;/a&gt; and we will aim to respond as quickly as we can.&lt;/p&gt;&lt;p&gt;We really hope that Infer.NET will prove to be a valuable platform for machine learning researchers and practitioners. Your comments and feedback will help us to make Infer.NET the machine learning solution of choice!&lt;/p&gt;&lt;p&gt;Thanks! &lt;br /&gt;&lt;/p&gt;&lt;p&gt;The Infer.NET team&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://community.research.microsoft.com/aggbug.aspx?PostID=3640" width="1" height="1"&gt;</content><author><name>jwinn</name><uri>http://community.research.microsoft.com/members/jwinn/default.aspx</uri></author></entry></feed>