Skip to content

Important Distribution-to-RandomVariable logic changes #4463

Closed
@brandonwillard

Description

@brandonwillard

PyMC's Distribution classes are being converted to RandomVariables in the v4 branch. A lot of core changes have already been made but a handful of important logic changes are still required in order to reinstate multiple PyMC features. This issue lists some points in the codebase where these changes are needed.

First, for anyone who's interested in helping out with the v4 branch, searching for the string XXX: will generally reveal parts of the logic that have been disabled and need to be refactored.

Here is a potentially outdated list of those parts accompanied by short summaries of the problem(s) and the work involved:

  • pymc3.model.Model.register_rv
    • I don't know what the whole dict-as-observed-data thing is about, so I couldn't finish refactoring this.
    • Marking as stale
  • pymc3.distributions.transforms.TransformedDistribution
    • The forward_val methods use draw_values, which has been removed. I think these methods can be removed entirely, because they only appear to be used by pymc3.sampling.sample_prior_predictive and I don't think that logic is relevant any longer.
    • Marking as stale
  • pymc3.gp.gp.[Marginal, MarginalKron]
    • These also use draw_values, and I think they only need to be replaced by the creation and use of theano.function. For example, draw_values([mu, cov], point=point) roughly translates to something like theano.function([model[n] for n in point.keys()], [mu, cov])(*point.values()), but we wouldn't want to compile that function every time a sample is needed, so we would need to do self.mu_cov_fn = theano.function([model[n] for n in point.keys()], [mu, cov]) somewhere (e.g. the constructor) and reuse self.mu_cov_fn in those methods.
    • Addressed by PR v4 refactor for GP module #5055
  • pymc3.parallel_sampling._Process
    • The whole parallel sampling approach relies on a single set of fixed-shape shared memory arrays for each random variable, and the processes all appear to write to that set of memory. Unfortunately, that approach doesn't work when the random variables change shape during sampling. This doesn't need to be fixed immediately, but it is an unnecessary restriction caused by this specific approach to multi-processing.
    • Reminder issue: Allow step methods to work with variables that have dynamic sizes #5139
  • pymc3.variational.opvi.Group
    • The constructor for this class creates aDictToArrayBijection in a peculiar way and requires explicit shape information to do it. Just like all the other changes of this sort, we need to move the creation of the bijection(s) to the places where actual concrete samples are generated (and said bijection(s) are actually used/needed). I don't know enough about this code to do that, so someone who has worked on this should take a look.
    • Addressed by PR Make VI work on v4 #4582
  • pymc3.sampling.sample_posterior_predictive_w
  • pymc3.step_methods.elliptical_slice.EllipticalSlice.astep
  • pymc3.step_methods.metropolis
    • The first instance uses the old dsize field on the random variables to create a NumPy array that—in turn—is used to initialize the proposal distributions. Instead, we should use the initial sample values for each variable to do this, and perhaps update the proposal distributions when/if new samples are drawn that have new shapes.
    • As always, for all these cases we can assume that the sizes of the initial values are representative of all the future samples (i.e. shapes don't change), but we shouldn't if that assumption isn't necessary.
    • Besides the size/shape refactoring, there's also a draw_values that looks like it might be straightforward to fix.
    • Fixed in: 28fdda5
  • pymc3.step_methods.hmc.base_hmc.BaseHMC.__init__
  • pymc3.step_methods.gibbs.ElemwiseCategorical
    • Yet another use of the deprecated dshape property that can always be replaced by using the shapes of the initial sample point (but shouldn't, if avoidable).
    • Stepper was removed in #97dc4bd
  • pymc3.step_methods.sgmcmc.BaseStochasticGradient
  • pymc3.data
    • This code attempts to evaluate the shape, but I think the shape is necessarily for a (shared) constant variable, so it might not need to be changed, but it's weird nonetheless.
    • Marking as stale
  • pymc3.model_graph.ModelGraph
    • This is another use of dshape; however, this one might not need to be changed, since the whole class could be replaced by the sample-space graphs provided by a Model object. The only unique feature I can immediately see is the Graphviz plate notation. Theano graphs, like the sample-space graphs, can already be converted to Graphviz Digraphs using functionality that's been in Theano for a while, but the plate notation may be a new thing that requires changes/additions.
    • Refactored in Refactor ModelGraph for v4 #4818

Originally posted by @brandonwillard in #4440 (comment)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions