tpapp / DynamicHMC.jl

Implementation of robust dynamic Hamiltonian Monte Carlo methods (NUTS) in Julia.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

preparing for release 2.0

tpapp opened this issue · comments

@zenna, @goedman, @cscherrer

DynamicHMC is nearing a new release. Many things are improved, but this is a breaking change in the API. I am pinging you because you are using this package in your own packages.

  1. At the very least, you should provide version bounds in Project.toml, along the lines
[compat]
DynamicHMC = "^1"

This should prevent problems when I release the new version, which I plan to do on Sep 1, 2019 if testing does not reveal any bugs.

  1. The new interface is documented at https://tamaspapp.eu/DynamicHMC.jl/latest/worked_example/ . Unless you are tweaking the adaptation, you would just use it as
results = mcmc_with_warmup(Random.GLOBAL_RNG, ∇P, 1000)

Note that LogDensityProblems also had an API change, 0.9.x is a bit different. If you are using the TransformedLogDensity constructor, not much changed, but if you are creating log densities directly, you need to use the new API (the changes are trivial).

  1. If you have tests which you can run with the new interface before I release, feedback and bug reports are appreciated. This code should be more solid than the previous release (I added tests and reworked a lot of internals), but one never knows.

  2. Finally, please ask questions here, and if you think that something you need is not addressed by the new API, let me know.

TODO before release

  • fix #67 edit: will fix later as Documenter.jl catches up
  • run more sample correctness tests

TODO after release

Nice! Thanks for the ping, and for the thorough documentation.

My current wrapper looks like this:

struct NUTS_result{T}
    chain::Vector{NUTS_Transition{Vector{Float64},Float64}}
    transformation
    samples::Vector{T}
    tuning
end

function nuts(m :: Model; kwargs...)
    ℓ = makeLogdensity(m)

    result = NUTS_result{}
    t = xform(m; data...)
    P = TransformedLogDensity(t, ℓ)
    ∇P = ADgradient(:ForwardDiff, P)
    chain, tuning = NUTS_init_tune_mcmc(∇P, 1000);
    samples = TransformVariables.transform.(Ref(parent(∇P).transformation), get_position.(chain));
    NUTS_result(chain, t, samples, tuning)
end

I'd like to better understand to what extent there's flexibility in the transforms (Can other approaches be used?) and the gradients (Can I write my own? Can I use Zygote?)

Maybe these are addressed in the API description - I'll find time to go through it, hopefully this evening.

That would be modified as something like

function nuts(rng, m :: Model; kwargs...)
    ℓ = makeLogdensity(m)
    result = NUTS_result{}
    t = xform(m; data...)
    P = TransformedLogDensity(t, ℓ)
    ∇P = ADgradient(:ForwardDiff, P)
    results = mcmc_and_warmup(rng, ∇P, 1000);
    samples = TransformVariables.transform.(parent(∇P).transformation, results.chain)
    # ... here you may want to return: samples, results.chain, results.tree_statistics,
    #     results.κ, results.ϵ in your container type
end

where

  1. results.chain is just a vector of (untransformed) vectors,
  2. results.tree_statistics is a vector of tree statistics (see DynamicHMC.Diagnostics),
  3. the κ and the ϵ used to live in tuning

Regarding providing your own gradients: see https://tamaspapp.eu/LogDensityProblems.jl/dev/#log-density-api-1, it basically amounts to defining a logdensity_and_gradient for whatever object you have. But that's an orthogonal change.

Finally, I would now (tentatively) recommend Flux instead of ForwardDiff for nontrivial problems --- more benchmarking is needed, but I think I solved all the type instability issues with a wrapper. Zygote is WIP, but when it is done you just swap that single argument.

Thanks Tamas, I’ve set aside next week to update the other models in DynamicHMCModels so this fits nicely with your planning and using Julia projects. StatisticalRethinking (using DynamicHMC and ideally Soss for the earlier chapters) and MCMCBenchmark will be later in September so I will add bounds in Project.toml. I’m very excited to have a world class implementation of HMC in pure Julia!

Off topic: I’ve made good progress with updating the Stan... family and testing it (and that includes a test using the 2nd release candidate of Stanc3 using StanRun). Currently working on the docs.

@goedman: sorry I did not get back to you (yet) about the Stan... family, I am following changes but all my spare time is consumed now by updating DynamicHMC. Will do it later.

2.0.0 is now released. 🎉

All items are covered now, closing the issue.