symbolic-pymc icon indicating copy to clipboard operation
symbolic-pymc copied to clipboard

Automatically convert PyMC3 `Distribution`s to `RandomVariable`s

Open brandonwillard opened this issue 5 years ago • 2 comments

We can create a function that constructs a RandomVariable class for a given PyMC3 Distribution class. The basic requirements are

  1. that #109 be in place and log_lik = Distribution.logp(out_var),
  2. Distribution.__init__ is utilized in RandomVariable.make_node and its signature is used to determine the signature of RandomVariable.make_node, as well (see the examples here),
  3. and Distribution.random is the backing implementation within RandomVariable.perform.

One complication that comes to mind involves requirement 3.; most implementations of Distribution.random use draw_values, which would be redundant within RandomVariable.perform, since pre-computed samples of all dependent terms already appear as arguments to RandomVariable.perform. We would have to override draw_values in that context so that it simply returns RandomVariable.perform arguments. It seems like we could use something like mock to accomplish that easily.

brandonwillard avatar Jun 06 '20 20:06 brandonwillard

Here's a prototype conversion function that does almost everything mentioned above.

There is a lot of room for error, especially when a Distribution demands test values or uses instance fields in Distribution.random that can't be converted to Theano objects. Both of these are poor practice in general, but the former is effectively required in some situations—I imagine.

@lucianopaz, this is a good starting point for considering class-level Distribution field additions—beyond support and parameter dimension sizes. For instance, while setting up that prototype, I realized that one of the biggest issues is the lack of information about distribution parameters in general. The connections between Distribution.__init__ signatures and the assignments to Distribution.__dict__ aren't strong enough to work with, so perhaps we could add more class-level information like that (e.g. names of essential parameters, or keep a list of said parameters within a class instance, etc.)

brandonwillard avatar Jun 07 '20 03:06 brandonwillard

This looks really promising!

twiecki avatar Jun 09 '20 08:06 twiecki