-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Distributions Generative Functions #259
Comments
I agree this would simplify parts of the implementation, and I'm really glad you're bringing this up now. I considered this before decided not to at the time because in some previous probabilistic programming languages in the lab, there was some confusion about the distinction between return values of functions (which cannot in general be constrained, and therefore do not have addresses in Gen choice maps), and values that can be constrained. In this earlier language, the return value of a function had the empty address, and this made thinking about inference constructs more confusing. The other reason was to provide the ability to specialize to the special case of a Distribution (i.e. a generative function whose return value is constrainable) with no overhead. Using a subtype as you suggested in https://github.com/probcomp/Gen/issues/258 could allow for language implementation code to specialize to the case of the Distribution with little or no overhead (avoiding runtime checks), probably, so that issue might be moot. I think having uniformity here would be really nice; but I want to make sure we are able to clearly describe the different cases to users. I want to make sure they don't start trying to constrain the return value of generative functions, or expect these values to appear in choice maps (because choice maps are for constrainable choices only, and that's a central part of Gen's design that allows for choice maps to be the abstract representation for random variates that gets passed between proposals and models). I think we should iterate a bit on how this would be described to users. Here is a start. After describing generative functions and random choices and addresses (without talking about what a Distribution actually is), then we say: "Distributions are a special type of generative function that always have exactly one address in their choice map, and this address is the empty address. The value at this address is always equal to the return value." We would also need to:
|
I think a requirement for this change is that it doesn't introduce substantial performance regressions. |
The high-level takeway from my responses are that (i) we would want to make sure the conceptual model is explained well, and (ii) I think that to avoid performance regressions, there might not be as much code reduction as you are expecting. But it does seem awesome to be able to use distributions in all the ways that generative functoins can be used (e.g. Map), and then let implementers of different components to specialize to Distributions if they want. That could potentially expand coverage out of the box for various features as you mentioned. And I think this is definitely worth prototyping, benchmarking, and iterating on. There is probably a good way of at least reducing the redundant code without introducing performance regressions. |
I agree with all this, and will add that:
|
That's interesting. That sounds like it has something in common with Gen's SML, which also generates typed traces. I think I might be okay with some performance regression on DML if SML stayed fast (including recent performance gains due to @georgematheos, we are not losing those. :) ) |
Those two representations of a binomial sound like two different generative functions to me. I am going to be hesitant to agree to relaxing many of the design choices that make generative functions and traces easy to reason about statically (e.g. what address schema they use), until we have some work on an inference compiler. |
To be clear, I totally agree --- I just mean that you might like to write either, and that in the second case, you might want to be able to constrain the return value (if the GF supports it). Also agree about being conservative about relaxing design choices. |
Re formalisms: The way I’m thinking about the different objects in Gen is:
I agree with Alex that there are cases where it would be elegant to allow users to constrain the return value of a generative function. (Ie. Can I Practically speaking, I’m in favor of having some special Re Performance: Ie. If we write @inline get_score(tr::DistributionTrace{Dist}) where {Dist} = logpdf(Dist(), tr.val, tr.args...) I’m hoping that when we call That said, we should certainly run some tests on this; I’m not sure exactly how well optimized Julia is. For instance, if we have an inlined method which returns |
What if
Distribution
were a subtype ofGenerativeFunction
?This would simplify implementations of some combinators and DSLs. For example, instead of having separate code to handle
@trace
ing a distribution and generative function, we could only ever trace generative functions--and distributions just have the GFI implemented for them! Likewise, what if I want to have a generative function sample from a poisson 100 times? If we hadDistribution <: GenerativeFunction
, then we could simply useMap(poisson)
.We would need a trace type to store a value from the distribution, for instance
To implement
get_choices
it seems like we would need a choicemap which has no address, and a single value. I think changing the definition of a choicemap to support this is worth considering; I have opened issue #258 to discuss this. Following my proposal in this issue, we could defineI think implementing
generate
,simulate
,update
, andregenerate
would be pretty straightforward. The internal proposal distribution and the distribution for a Distribution generative function would be the same: the Distribution itself.The text was updated successfully, but these errors were encountered: