UBC-Stat-ML / bayonet

Probabilistic inference utils
BSD 2-Clause "Simplified" License
4 stars 4 forks source link

Samplers + processors: design and implementation #8

Open jewellsean opened 10 years ago

jewellsean commented 10 years ago

I've recently been thinking about the implementation details for both @Samplers and @Processors. In particular, under the current framework, each type of node, for example: RealVariable, UnrootedTree, CRPState, is assigned both a list of samplers and processors. These assignments are determined through declarations within each type's class. At runtime, an MCMC model is built by using those declarations to assign each stochastic and unobserved node samplers and processors.

Concretely, suppose we have a model p(x, t) = p(x | t) p(t) where t and x are real variables and x is observed. The MCMC model would create a node for t, and associate with it a real valued MH move and a real valued processor. Currently, the default sampler is a Peskun type move and the default processor records the output and generates CODA plots.

Another strategy for assigning samplers/processors would be in the model definition. There are conceivably times when one sampler/processor is ill-suited for a task and should not be included. For example, consider the real variable distribution tests. These tests use the processor only for the purpose of recording data, and not the CODA plots. For another example, in my implementation of the DPMM with Blang the Peskun type sampler does not work correctly for reasons mentioned in #6, but the RealVariableMHProposal works well. These are both scenarios where defining samplers/processors in the model file would be more flexible than within type classes.

Along these same lines is the decision to use a sampler based on type alone (without regard to the connected factor). In the earlier example, where p(x, t) = p(x | t) p(t), suppose p(t) is easy to sample. In these types of scenarios, it seems the sampler should sample from the factor not via a proposal, but through the generative factor's generate method.

jewellsean commented 10 years ago

I should also note that some of this functionality can be modified via add/excludeNodeProcessor/Move but this requires (?) a priori knowledge of all default assigned samplers/processors.

alexandrebouchard commented 10 years ago

Agreed. There is a similar facility exists for samplers, via MCMCFactory.excludeNodeMove, but I agree it can be limiting, and is somewhat buried right now.

At the same time, it is generally better to include as many samplers as possible, as this often mix better than any individual one. This is especially true once we add some adaptation on the frequency at which each sampler is used. For example, if one of the sampler is a bad idea for one given node, the hope is that adaptation would just make the algorithm pick that sampler infrequently.

At the same time, I am definitely open to better mechanisms for move set specification.