-
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
UpdateSpec rather than choicemap for update specifications #189
Comments
Another consideration is that if we use In other words, the current update interface is new_tr::Trace, weight::Float64, retdiff::Diff, discard::ChoiceMap = Gen.update(tr, args, argdiffs, constraints::ChoiceMap) but I perhaps we should change it to new_tr::Trace, weight::Float64, retdiff::Diff, reverse_spec::UpdateSpecification = Gen.update(tr, args, argdiffs, spec::UpdateSpecification) This is because, as far as I am aware, the only place we use the |
I want to give a sense of what it might look like to run MCMC inference with this new interface. In this example, say I am running "split/merge" MH updates on a trace. Say I have a custom generative function If I want to run MH, I can create a proposal distribution which will decide which objects to split and merge: @gen function splitmerge_proposal(tr)
if @trace(bernoulli(0.5), :do_split)
@trace(sample_one(tr[:object_set], :target)
else
@trace(sample_one(tr[:object_set]), :target1)
@trace(sample_one(tr[:object_set]), :target2)
end
end Then to use function involution(trace, fwd_choices::ChoiceMap, fwd_ret, _)
args = get_args(trace)
argdiffs = map(_ -> NoChange(), args)
if fwd_choices[:do_split]
new_tr, weight, retdiff, reverse_update_spec = update(trace, args, argdiffs, SplitUpdate(fwd_choices[:target]))
bwd_choices = choicemap((:do_split, false), (:target1, reverse_update_spec.target1), (:target2, reverse_update_spec.target2))
else
new_tr, weight, retdiff, reverse_update_spec = update(trace, args, argdiffs, MergeUpdate(fwd_choices[:target1], fwd_choices[:target2))
bwd_choices = choicemap((:do_split, true), (:target, reverse_update_spec.target))
end
return new_tr, bwd_choices, weight Then to run MH, we can call tr, acc = Gen.mh(tr, splitmerge_proposal, (), involution) The (If we wanted, we could actually implement a whole new version of |
I think it can sometimes make sense for custom generative functions to know how to perform special types of updates which are not simply of the form of of changing the value of one of the choices in the choicemap.
For instance, in some code I'm writing, we have a type of "split" update which splits a generated object into two generated objects with the same properties as the original. One hacky thing we can do now is have an update call along the lines of:
But I think that really the call signature for the update function should be something along the lines of
where we have a built-in
ChoicemapUpdateSpecification <: UpdateSpecification
that choicemaps can get cast to by default so the old form of the interface works.Then specifying a split update as in the example above could look like
or, if we wanted, we could even have some automatic way to convert
Pair
s into update specs, so we could have the interface simply look like(Really, I think that the update method interface should take a fifth optional
kwargs
argument, as I describe in https://github.com/probcomp/Gen/issues/182, but this is a separate issue.)The text was updated successfully, but these errors were encountered: