AdvancedMH.jl
AdvancedMH.jl copied to clipboard
AdvancedMH + Bijectors?
It is sometimes useful to perform MH in a reparametrised space, similar to HMC with its bijectors. This would effectively allow for non-stationary Gaussian proposals, among others. It does not seem like there is any support in AdvancedMH for this. I have some code for a ReparamProposal
that wraps another proposal, but this is very inelegant. Does anyone have any pointers or ideas for structuring this properly?
AdvancedMH was never intended to support explicit reparameterization, since the whole Turing universe prefers to wrap proposal distributions in bijections. We have a whole package for handling these kinds of tasks, Bijectors.jl. Additionally, we think of AdvancedMH as handling more of the inference side rather than the model side, and I think the general sense I've gotten from the team is that bijections are something of a model-side task.
There's a good little demo about working with multivariate bijections here. If you've got a demo you're working with we could try that as well.
Is it possible to wrap proposal distributions in bijections as of now? I haven't figured out a simple way to do that, any hints on that would be much appreciated!
Perhaps my use-case is different - I write custom models most of the time (not everything I work with is easy to do within Turing). In cases where people want to use AdvancedMH to do Metropolis-Hastings on a custom model it is often necessary to tweak things, and being able to reparametrise on the fly can be very useful. In my experience 95% of MH is figuring out the right proposal distribution anyway!
cc @torfjelde
Looks like I got a little confused as to where bijectors went in all these packages. I assumed that they were built into AdvancedHMC but I might have been relying on my personal modifications for that observations. If so, this might be a bigger change than anticipated. I do still think, however, that a simple-to-use reparametrisation layer would be quite convenient, one that Turing could also tap into. This would make the inference functionality in these packages more modular and users wouldn't be forced to make meaningless changes to their models (such as replacing parameters by log-parameters) just because their sampler of choice demands it. :)
To be clear, this is not built into AdvancedMH because it is a non-trivial task. A large part of DynamicPPL.jl, Turing's modelling language, is designed to explicitly handle just this unconstrained-to-constrained task.
If you need a lot of complicated bijections or whatever, you should not be using AdvancedMH.jl by itself. You can use the modelling suite in Turing with AdvancedMH built in.
We can try to work with your model though -- do you have an example of what you're trying to sample from?
It sort of depends on what you mean by "reparameterised" proposal.
If you're referring to usage of bijections, then the most natural way is to just give AMH.jl the log-density for the /transformed/ variables and define your proposal there instead of defining your proposal in the transformed space but the log-density in "un-transformed" space.
Does that make sense?
To be clear, this is not built into AdvancedMH because it is a non-trivial task. A large part of DynamicPPL.jl, Turing's modelling language, is designed to explicitly handle just this unconstrained-to-constrained task.
I see, this might explain why I didn't manage to do it in a few lines. My code is highly WIP and I'm trying to fit multiple models at times, which is why a nice interface for reparametrisation seemed desirable. I'll see if I can clean it up and share whatever I have once it's up and running.
If you're referring to usage of bijections, then the most natural way is to just give AMH.jl the log-density for the /transformed/ variables and define your proposal there instead of defining your proposal in the transformed space but the log-density in "un-transformed" space.
This is precisely it. If we cannot find a simple enough way to incorporate this into AMH.jl I should probably stick to doing it manually for now... :)