From b06c958516a5afa30c58b65cd7a43a40e6e59f27 Mon Sep 17 00:00:00 2001 From: Qingyu Qu <2283984853@qq.com> Date: Wed, 2 Apr 2025 00:25:39 +0800 Subject: [PATCH 1/4] Better documentation --- README.md | 285 ------------------------------------ docs/Project.toml | 6 + docs/make.jl | 24 ++- docs/src/api.md | 84 +++++++++-- docs/src/assets/favicon.ico | Bin 0 -> 201951 bytes docs/src/autodiff.md | 5 + docs/src/changelog.md | 19 +++ docs/src/get_started.md | 202 +++++++++++++++++++++++++ docs/src/index.md | 67 ++++++++- docs/src/references.md | 4 + docs/src/refs.bib | 48 ++++++ 11 files changed, 440 insertions(+), 304 deletions(-) create mode 100644 docs/src/assets/favicon.ico create mode 100644 docs/src/autodiff.md create mode 100644 docs/src/changelog.md create mode 100644 docs/src/get_started.md mode change 120000 => 100644 docs/src/index.md create mode 100644 docs/src/references.md create mode 100644 docs/src/refs.bib diff --git a/README.md b/README.md index 77bef9564..7a40193a3 100644 --- a/README.md +++ b/README.md @@ -39,285 +39,6 @@ If you are interested in using AdvancedHMC.jl through a probabilistic programmin + `Slice` -> `SliceTS` - [v0.2.0] The gradient function passed to `Hamiltonian` is supposed to return a value-gradient tuple now. -## A minimal example - sampling from a multivariate Gaussian using NUTS - -This section demonstrates a minimal example of sampling from a multivariate Gaussian (10-dimensional) using the no U-turn sampler (NUTS). Below we describe the major components of the Hamiltonian system which are essential to sample using this approach: - - - **Metric**: In many sampling problems the sample space is associated with a metric that allows us to measure the distance between any two points, and other similar quantities. In the example in this section, we use a special metric called the **Euclidean Metric**, represented with a `D × D` matrix from which we can compute distances.[^1] - - - **Leapfrog integration**: Leapfrog integration is a second-order numerical method for integrating differential equations (In this case they are equations of motion for the relative position of one particle with respect to the other). The order of this integration signifies its rate of convergence. Any algorithm with a finite time step size will have numerical errors, and the order is related to this error. For a second-order algorithm, this error scales as the second power of the time step, hence, the name second-order. High-order integrators are usually complex to code and have a limited region of convergence; hence they do not allow arbitrarily large time steps. A second-order integrator is suitable for our purpose. Hence we opt for the leapfrog integrator. It is called `leapfrog` due to the ways this algorithm is written, where the positions and velocities of particles "leap over" each other.[^2] - - **Kernel for trajectories (static or dynamic)**: Different kernels, which may be static or dynamic, can be used. At each iteration of any variant of the HMC algorithm, there are two main steps - the first step changes the momentum and the second step may change both the position and the momentum of a particle.[^3] - -```julia -using AdvancedHMC, ForwardDiff -using LogDensityProblems -using LinearAlgebra - -# Define the target distribution using the `LogDensityProblem` interface -struct LogTargetDensity - dim::Int -end -LogDensityProblems.logdensity(p::LogTargetDensity, θ) = -sum(abs2, θ) / 2 # standard multivariate normal -LogDensityProblems.dimension(p::LogTargetDensity) = p.dim -function LogDensityProblems.capabilities(::Type{LogTargetDensity}) - return LogDensityProblems.LogDensityOrder{0}() -end - -# Choose parameter dimensionality and initial parameter value -D = 10; -initial_θ = rand(D); -ℓπ = LogTargetDensity(D) - -# Set the number of samples to draw and warmup iterations -n_samples, n_adapts = 2_000, 1_000 - -# Define a Hamiltonian system -metric = DiagEuclideanMetric(D) -hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) - -# Define a leapfrog solver, with the initial step size chosen heuristically -initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) -integrator = Leapfrog(initial_ϵ) - -# Define an HMC sampler with the following components -# - multinomial sampling scheme, -# - generalised No-U-Turn criteria, and -# - windowed adaption for step-size and diagonal mass matrix -kernel = HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn())) -adaptor = StanHMCAdaptor(MassMatrixAdaptor(metric), StepSizeAdaptor(0.8, integrator)) - -# Run the sampler to draw samples from the specified Gaussian, where -# - `samples` will store the samples -# - `stats` will store diagnostic statistics for each sample -samples, stats = sample( - hamiltonian, kernel, initial_θ, n_samples, adaptor, n_adapts; progress=true -) -``` - -### Parallel sampling - -AdvancedHMC enables parallel sampling (either distributed or multi-thread) via Julia's [parallel computing functions](https://docs.julialang.org/en/v1/manual/parallel-computing/). -It also supports vectorized sampling for static HMC. - -The below example utilizes the `@threads` macro to sample 4 chains across 4 threads. - -```julia -# Ensure that Julia was launched with an appropriate number of threads -println(Threads.nthreads()) - -# Number of chains to sample -nchains = 4 - -# Cache to store the chains -chains = Vector{Any}(undef, nchains) - -# The `samples` from each parallel chain is stored in the `chains` vector -# Adjust the `verbose` flag as per need -Threads.@threads for i in 1:nchains - samples, stats = sample( - hamiltonian, kernel, initial_θ, n_samples, adaptor, n_adapts; verbose=false - ) - chains[i] = samples -end -``` - -### Using the `AbstractMCMC` interface - -Users can also use the `AbstractMCMC` interface to sample, which is also used in Turing.jl. -In order to show how this is done let us start from our previous example where we defined a `LogTargetDensity`, `ℓπ`. - -```julia -using AbstractMCMC, LogDensityProblemsAD -# Wrap the previous LogTargetDensity as LogDensityModel -# where ℓπ::LogTargetDensity -model = AdvancedHMC.LogDensityModel(LogDensityProblemsAD.ADgradient(Val(:ForwardDiff), ℓπ)) - -# Wrap the previous sampler as a HMCSampler <: AbstractMCMC.AbstractSampler -D = 10; -initial_θ = rand(D); -n_samples, n_adapts, δ = 1_000, 2_000, 0.8 -sampler = HMCSampler(kernel, metric, adaptor) - -# Now sample -samples = AbstractMCMC.sample( - model, sampler, n_adapts + n_samples; n_adapts=n_adapts, initial_params=initial_θ -) -``` - -### Convenience Constructors - -In the previous examples, we built the sampler by manually specifying the integrator, metric, kernel, and adaptor to build our own sampler. However, in many cases, users might want to initialize a standard NUTS sampler. In such cases having to define each of these aspects manually is tedious and error-prone. For these reasons `AdvancedHMC` also provides users with a series of convenience constructors for standard samplers. We will now show how to use them. - - - HMC: - - ```julia - # HMC Sampler - # step size, number of leapfrog steps - n_leapfrog, ϵ = 25, 0.1 - hmc = HMC(ϵ, n_leapfrog) - ``` - - Equivalent to: - - ```julia - metric = DiagEuclideanMetric(D) - hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) - integrator = Leapfrog(0.1) - kernel = HMCKernel(Trajectory{EndPointTS}(integrator, FixedNSteps(n_leapfrog))) - adaptor = NoAdaptation() - hmc = HMCSampler(kernel, metric, adaptor) - ``` - - - NUTS: - - ```julia - # NUTS Sampler - # adaptation steps, target acceptance probability, - δ = 0.8 - nuts = NUTS(δ) - ``` - - Equivalent to: - - ```julia - metric = DiagEuclideanMetric(D) - hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) - initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) - integrator = Leapfrog(initial_ϵ) - kernel = HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn())) - adaptor = StanHMCAdaptor(MassMatrixAdaptor(metric), StepSizeAdaptor(δ, integrator)) - nuts = HMCSampler(kernel, metric, adaptor) - ``` - - HMCDA: - - ```julia - #HMCDA (dual averaging) - # adaptation steps, target acceptance probability, target trajectory length - δ, λ = 0.8, 1.0 - hmcda = HMCDA(δ, λ) - ``` - - Equivalent to: - - ```julia - metric = DiagEuclideanMetric(D) - hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) - initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) - integrator = Leapfrog(initial_ϵ) - kernel = HMCKernel(Trajectory{EndPointTS}(integrator, FixedIntegrationTime(λ))) - adaptor = StepSizeAdaptor(δ, initial_ϵ) - hmcda = HMCSampler(kernel, metric, adaptor) - ``` - -Moreover, there's some flexibility in how these samplers can be initialized. -For example, a user can initialize a NUTS (HMC and HMCDA) sampler with their own metrics and integrators. -This can be done as follows: - -```julia -nuts = NUTS(δ; metric=:diagonal) #metric = DiagEuclideanMetric(D) (Default!) -nuts = NUTS(δ; metric=:unit) #metric = UnitEuclideanMetric(D) -nuts = NUTS(δ; metric=:dense) #metric = DenseEuclideanMetric(D) -# Provide your own AbstractMetric -metric = DiagEuclideanMetric(10) -nuts = NUTS(δ; metric=metric) - -nuts = NUTS(δ; integrator=:leapfrog) #integrator = Leapfrog(ϵ) (Default!) -nuts = NUTS(δ; integrator=:jitteredleapfrog) #integrator = JitteredLeapfrog(ϵ, 0.1ϵ) -nuts = NUTS(δ; integrator=:temperedleapfrog) #integrator = TemperedLeapfrog(ϵ, 1.0) - -# Provide your own AbstractIntegrator -integrator = JitteredLeapfrog(0.1, 0.2) -nuts = NUTS(δ; integrator=integrator) -``` - -### GPU Sampling with CUDA - -There is experimental support for running static HMC on the GPU using CUDA. -To do so, the user needs to have [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl) installed, ensure the logdensity of the `Hamiltonian` can be executed on the GPU and that the initial points are a `CuArray`. -A small working example can be found at `test/cuda.jl`. - -## API and supported HMC algorithms - -An important design goal of AdvancedHMC.jl is modularity; we would like to support algorithmic research on HMC. -This modularity means that different HMC variants can be easily constructed by composing various components, such as preconditioning metric (i.e., mass matrix), leapfrog integrators, trajectories (static or dynamic), adaption schemes, etc. -The minimal example above can be modified to suit particular inference problems by picking components from the list below. - -### Hamiltonian mass matrix (`metric`) - - - Unit metric: `UnitEuclideanMetric(dim)` - - Diagonal metric: `DiagEuclideanMetric(dim)` - - Dense metric: `DenseEuclideanMetric(dim)` - -where `dim` is the dimensionality of the sampling space. - -### Integrator (`integrator`) - - - Ordinary leapfrog integrator: `Leapfrog(ϵ)` - - Jittered leapfrog integrator with jitter rate `n`: `JitteredLeapfrog(ϵ, n)` - - Tempered leapfrog integrator with tempering rate `a`: `TemperedLeapfrog(ϵ, a)` - -where `ϵ` is the step size of leapfrog integration. - -### Kernel (`kernel`) - - - Static HMC with a fixed number of steps (`n_steps`) (Neal, R. M. (2011)): `HMCKernel(Trajectory{EndPointTS}(integrator, FixedNSteps(integrator)))` - - HMC with a fixed total trajectory length (`trajectory_length`) (Neal, R. M. (2011)): `HMCKernel(Trajectory{EndPointTS}(integrator, FixedIntegrationTime(trajectory_length)))` - - Original NUTS with slice sampling (Hoffman, M. D., & Gelman, A. (2014)): `HMCKernel(Trajectory{SliceTS}(integrator, ClassicNoUTurn()))` - - Generalised NUTS with slice sampling (Betancourt, M. (2017)): `HMCKernel(Trajectory{SliceTS}(integrator, GeneralisedNoUTurn()))` - - Original NUTS with multinomial sampling (Betancourt, M. (2017)): `HMCKernel(Trajectory{MultinomialTS}(integrator, ClassicNoUTurn()))` - - Generalised NUTS with multinomial sampling (Betancourt, M. (2017)): `HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn()))` - -### Adaptor (`adaptor`) - - - Adapt the mass matrix `metric` of the Hamiltonian dynamics: `mma = MassMatrixAdaptor(metric)` - - + This is lowered to `UnitMassMatrix`, `WelfordVar` or `WelfordCov` based on the type of the mass matrix `metric` - - - Adapt the step size of the leapfrog integrator `integrator`: `ssa = StepSizeAdaptor(δ, integrator)` - - + It uses Nesterov's dual averaging with `δ` as the target acceptance rate. - - Combine the two above *naively*: `NaiveHMCAdaptor(mma, ssa)` - - Combine the first two using Stan's windowed adaptation: `StanHMCAdaptor(mma, ssa)` - -### Gradients - -`AdvancedHMC` supports AD-based using [`LogDensityProblemsAD`](https://github.com/tpapp/LogDensityProblemsAD.jl) and user-specified gradients. In order to use user-specified gradients, please replace `ForwardDiff` with `ℓπ_grad` in the `Hamiltonian` constructor, where the gradient function `ℓπ_grad` should return a tuple containing both the log-posterior and its gradient. - -All the combinations are tested in [this file](https://github.com/TuringLang/AdvancedHMC.jl/blob/main/test/sampler.jl) except for using tempered leapfrog integrator together with adaptation, which we found unstable empirically. - -## The `sample` function signature in detail - -```julia -sample( - rng::Union{AbstractRNG,AbstractVector{<:AbstractRNG}}, - h::Hamiltonian, - κ::HMCKernel, - θ::AbstractVector{<:AbstractFloat}, - n_samples::Int; - adaptor::AbstractAdaptor=NoAdaptation(), - n_adapts::Int=min(div(n_samples, 10), 1_000), - drop_warmup=false, - verbose::Bool=true, - progress::Bool=false, -) -``` - -Draw `n_samples` samples using the kernel `κ` under the Hamiltonian system `h` - - - The randomness is controlled by `rng`. - - + If `rng` is not provided, the default random number generator (`Random.default_rng()`) will be used. - - - The initial point is given by `θ`. - - The adaptor is set by `adaptor`, for which the default is no adaptation. - - + It will perform `n_adapts` steps of adaptation, for which the default is `1_000` or 10% of `n_samples`, whichever is lower. - - `drop_warmup` specifies whether to drop samples. - - `verbose` controls the verbosity. - - `progress` controls whether to show the progress meter or not. - -Note that the function signature of the `sample` function exported by `AdvancedHMC.jl` differs from the [`sample`](https://turinglang.org/dev/docs/using-turing/guide#modelling-syntax-explained) function used by `Turing.jl`. We refer to the documentation of `Turing.jl` for more details on the latter. - ## Citing AdvancedHMC.jl If you use AdvancedHMC.jl for your own research, please consider citing the following publication: @@ -363,9 +84,3 @@ with the following BibTeX entry: 4. Betancourt, M. J., Byrne, S., & Girolami, M. (2014). Optimizing the integrator step size for Hamiltonian Monte Carlo. [arXiv preprint arXiv:1411.6669](https://arxiv.org/pdf/1411.6669). 5. Betancourt, M. (2016). Identifying the optimal integration time in Hamiltonian Monte Carlo. [arXiv preprint arXiv:1601.00225](https://arxiv.org/abs/1601.00225). 6. Hoffman, M. D., & Gelman, A. (2014). The No-U-Turn Sampler: adaptively setting path lengths in Hamiltonian Monte Carlo. Journal of Machine Learning Research, 15(1), 1593-1623. ([arXiv](http://arxiv.org/abs/1111.4246)) - -## Footnotes - -[^1]: The Euclidean metric is also known as the mass matrix in the physical perspective. See [Hamiltonian mass matrix](#Hamiltonian-mass-matrix-(metric)) for available metrics. -[^2]: About the leapfrog integration scheme: Suppose ${\bf x}$ and ${\bf v}$ are the position and velocity of an individual particle respectively; $i$ and $i+1$ are the indices for time values $t_i$ and $t_{i+1}$ respectively; $dt = t_{i+1} - t_i$ is the time step size (constant and regularly spaced intervals), and ${\bf a}$ is the acceleration induced on a particle by the forces of all other particles. Furthermore, suppose positions are defined at times $t_i, t_{i+1}, t_{i+2}, \dots $, spaced at constant intervals $dt$, the velocities are defined at halfway times in between, denoted by $t_{i-1/2}, t_{i+1/2}, t_{i+3/2}, \dots $, where $t_{i+1} - t_{i + 1/2} = t_{i + 1/2} - t_i = dt / 2$, and the accelerations ${\bf a}$ are defined only on integer times, just like the positions. Then the leapfrog integration scheme is given as: $x_{i} = x_{i-1} + v_{i-1/2} dt; \quad v_{i+1/2} = v_{i-1/2} + a_i dt$. For available integrators refer to [Integrator](#Integrator-(integrator)). -[^3]: On kernels: In the classical HMC approach, during the first step, new values for the momentum variables are randomly drawn from their Gaussian distribution, independently of the current values of the position variables. A Metropolis update is performed during the second step, using Hamiltonian dynamics to provide a new state. For available kernels refer to [Kernel](#Kernel-(kernel)). diff --git a/docs/Project.toml b/docs/Project.toml index 5bcf63503..7c50d9393 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,3 +1,9 @@ [deps] AdvancedHMC = "0bf59076-c3b1-5ca4-86bd-e02cd72cde3d" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" + +[compat] +AdvancedHMC = "0.7" +Documenter = "1" +DocumenterCitations = "1" \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index 7c690521b..948a58ad1 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,8 +1,26 @@ using Pkg -using Documenter +using Documenter, DocumenterCitations using AdvancedHMC -# cp(joinpath(@__DIR__, "../README.md"), joinpath(@__DIR__, "src/index.md")) +bib = CitationBibliography(joinpath(@__DIR__, "src", "refs.bib")) -makedocs(; sitename="AdvancedHMC", format=Documenter.HTML(), warnonly=[:cross_references]) +makedocs(; + sitename="AdvancedHMC", + format=Documenter.HTML(; + assets=["assets/favicon.ico"], + canonical="https://turinglang.org/AdvancedHMC.jl/stable/", + ), + warnonly=[:cross_references], + plugins=[bib], + pages=[ + "AdvancedHMC.jl" => "index.md", + "Get Started" => "get_started.md", + "Automatic Differentiation Backends" => "autodiff.md", + "Detailed API" => "api.md", + "Change Log" => "changelog.md", + "References" => "references.md", + ], +) + +deploydocs(; repo="github.com/TuringLang/AdvancedHMC.jl.git", push_preview=true) diff --git a/docs/src/api.md b/docs/src/api.md index 03109615b..d49f87d62 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -1,26 +1,80 @@ -# AdvancedHMC.jl +# Detailed API for AdvancedHMC.jl -Documentation for AdvancedHMC.jl +An important design goal of AdvancedHMC.jl is modularity; we would like to support algorithmic research on HMC. +This modularity means that different HMC variants can be easily constructed by composing various components, such as preconditioning metric (i.e., mass matrix), leapfrog integrators, trajectories (static or dynamic), adaption schemes, etc. In this documentation, we will explain the detailed usage of different modules in AdancedHMC.jl to provide a comprehensive udnerstanding of how AdvancedHMC.jl can achieve both modularity and efficiency. -```@contents -``` +### [Hamiltonian mass matrix (`metric`)](@id hamiltonian_mm) -## Types + - Unit metric: `UnitEuclideanMetric(dim)` + - Diagonal metric: `DiagEuclideanMetric(dim)` + - Dense metric: `DenseEuclideanMetric(dim)` -```@docs -ClassicNoUTurn -HMCSampler -HMC -NUTS -HMCDA -``` +where `dim` is the dimensionality of the sampling space. + +### [Integrator (`integrator`)](@id integrator) + + - Ordinary leapfrog integrator: `Leapfrog(ϵ)` + - Jittered leapfrog integrator with jitter rate `n`: `JitteredLeapfrog(ϵ, n)` + - Tempered leapfrog integrator with tempering rate `a`: `TemperedLeapfrog(ϵ, a)` + +where `ϵ` is the step size of leapfrog integration. + +### [Kernel (`kernel`)](@id kernel) + + - Static HMC with a fixed number of steps (`n_steps`) from [neal2011mcmc](@Citet): `HMCKernel(Trajectory{EndPointTS}(integrator, FixedNSteps(integrator)))` + - HMC with a fixed total trajectory length (`trajectory_length`) from [neal2011mcmc](@Citet): `HMCKernel(Trajectory{EndPointTS}(integrator, FixedIntegrationTime(trajectory_length)))` + - Original NUTS with slice sampling from [hoffman2014no](@Citet): `HMCKernel(Trajectory{SliceTS}(integrator, ClassicNoUTurn()))` + - Generalised NUTS with slice sampling from [betancourt2017conceptual](@Citet): `HMCKernel(Trajectory{SliceTS}(integrator, GeneralisedNoUTurn()))` + - Original NUTS with multinomial sampling from [betancourt2017conceptual](@Citet): `HMCKernel(Trajectory{MultinomialTS}(integrator, ClassicNoUTurn()))` + - Generalised NUTS with multinomial sampling from [betancourt2017conceptual](@Citet): `HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn()))` + +### Adaptor (`adaptor`) -## Functions + - Adapt the mass matrix `metric` of the Hamiltonian dynamics: `mma = MassMatrixAdaptor(metric)` + + + This is lowered to `UnitMassMatrix`, `WelfordVar` or `WelfordCov` based on the type of the mass matrix `metric` -```@docs -sample + - Adapt the step size of the leapfrog integrator `integrator`: `ssa = StepSizeAdaptor(δ, integrator)` + + + It uses Nesterov's dual averaging with `δ` as the target acceptance rate. + - Combine the two above *naively*: `NaiveHMCAdaptor(mma, ssa)` + - Combine the first two using Stan's windowed adaptation: `StanHMCAdaptor(mma, ssa)` + +## The `sample` functions + +```julia +sample( + rng::Union{AbstractRNG,AbstractVector{<:AbstractRNG}}, + h::Hamiltonian, + κ::HMCKernel, + θ::AbstractVector{<:AbstractFloat}, + n_samples::Int; + adaptor::AbstractAdaptor=NoAdaptation(), + n_adapts::Int=min(div(n_samples, 10), 1_000), + drop_warmup=false, + verbose::Bool=true, + progress::Bool=false, +) ``` +Draw `n_samples` samples using the kernel `κ` under the Hamiltonian system `h` + + - The randomness is controlled by `rng`. + + + If `rng` is not provided, the default random number generator (`Random.default_rng()`) will be used. + + - The initial point is given by `θ`. + - The adaptor is set by `adaptor`, for which the default is no adaptation. + + + It will perform `n_adapts` steps of adaptation, for which the default is `1_000` or 10% of `n_samples`, whichever is lower. + - `drop_warmup` specifies whether to drop samples. + - `verbose` controls the verbosity. + - `progress` controls whether to show the progress meter or not. + +Note that the function signature of the `sample` function exported by `AdvancedHMC.jl` differs from the [`sample`](https://turinglang.org/dev/docs/using-turing/guide#modelling-syntax-explained) function used by `Turing.jl`. We refer to the documentation of `Turing.jl` for more details on the latter. + +Note that the function signature of the `sample` function exported by `AdvancedHMC.jl` differs from the [`sample`](https://turinglang.org/dev/docs/using-turing/guide#modelling-syntax-explained) function used by `Turing.jl`. We refer to the documentation of `Turing.jl` for more details on the latter. + ## More types ```@autodocs; canonical=false diff --git a/docs/src/assets/favicon.ico b/docs/src/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3074916ebe87019080e163aab3c160c40a6d341c GIT binary patch literal 201951 zcmeEv1zc2F`~QQe*r=f7G%z$XLt}uAO4{AEcDDl3V0Y`QXf`atl9a|G!X-gCwYyna-!cv1iZ;$`4I5E{n`;jWVk|;!sq|h&cyZ&TGEiaeTMKdENH) z9Xh$UNz=s^)s?BL>WWxp4cU@LjqGO!t#=DqcRbkT9n12_j3Ib;`kP_L?ZajTyE!B) zlU%}=_0)M6E-i~Z6pz1kDC~An1iW;*iWJFmk}olLw;w({Z$iu5Ef>0EPAmxDUt_|= zp(Ib14^YK;bn*0fW42CL=28}sX@mC@FfNOd$PCI4-$$}U8P#7ywcY0gZt30T@VUgG zJjvqFJ*0?N)KsKM=ekBN?ChyMH^s_oES>9;MR-3PW!S~8M`=&HCA2$a1<_fePIFr? zZ5y`!w42M@8kg{;q)1dq6seNgTA#d;XuGYaXBm}5q@!fi!~1cikr@gUu8%(Gl&6Rr zJ^85fka6qK*8$E0W{@ID(M%cZGTu{jey&beVy)8^i|zB=;GH%olYbj}jdr(PVRRwl z$mE#OlO`x;wo2A%&&}&af)V=O(_wt~F`gb5XKJ;1#v08TI@oTlIKPUe)DN>7yD z=OVKvdd6sMl=13Voljnzr`si4#UiV*u3eL+d1@~7_4GVPT=*)D$Q1jGzBj_VBT
MR_)}i}55sziW>^TIF|nEbur^ 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�Ly^V?a~mtFS|LQ|85xo3+%L` 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 WL&-d8S|b2HhpeQMM75Yn!2bZx(K3zz literal 0 HcmV?d00001 diff --git a/docs/src/autodiff.md b/docs/src/autodiff.md new file mode 100644 index 000000000..aeebc2267 --- /dev/null +++ b/docs/src/autodiff.md @@ -0,0 +1,5 @@ +# Gradient in AdvancedHMC.jl + +AdvancedHMC.jl supports automatic differentiation using [`LogDensityProblemsAD`](https://github.com/tpapp/LogDensityProblemsAD.jl) and user-specified gradients. While the default AD backend for AdvancedHMC.jl is ForwardDiff.jl, we can seamlessly change to other backend like Zygote.jl using various syntax like `Hamiltonian(metric, ℓπ, Zygote)`, `Hamiltonian(metric, ℓπ, Val(:Zygote))` or via ADTypes.jl `Hamiltonian(metric, ℓπ, AutoZygote())`. + +In order to use user-specified gradients, please replace ForwardDiff.jl with `ℓπ_grad` in the `Hamiltonian` constructor, where the gradient function `ℓπ_grad` should return a tuple containing both the log-posterior and its gradient. diff --git a/docs/src/changelog.md b/docs/src/changelog.md new file mode 100644 index 000000000..5974088ad --- /dev/null +++ b/docs/src/changelog.md @@ -0,0 +1,19 @@ +**CHANGELOG** + + - [v0.5.0] **Breaking!** Convenience constructors for common samplers changed to: + + + `HMC(leapfrog_stepsize::Real, n_leapfrog::Int)` + + `NUTS(target_acceptance::Real)` + + `HMCDA(target_acceptance::Real, integration_time::Real)` + + - [v0.2.22] Three functions are renamed. + + + `Preconditioner(metric::AbstractMetric)` -> `MassMatrixAdaptor(metric)` and + + `NesterovDualAveraging(δ, integrator::AbstractIntegrator)` -> `StepSizeAdaptor(δ, integrator)` + + `find_good_eps` -> `find_good_stepsize` + - [v0.2.15] `n_adapts` is no longer needed to construct `StanHMCAdaptor`; the old constructor is deprecated. + - [v0.2.8] Two Hamiltonian trajectory sampling methods are renamed to avoid a name clash with Distributions. + + + `Multinomial` -> `MultinomialTS` + + `Slice` -> `SliceTS` + - [v0.2.0] The gradient function passed to `Hamiltonian` is supposed to return a value-gradient tuple now. diff --git a/docs/src/get_started.md b/docs/src/get_started.md new file mode 100644 index 000000000..482355c91 --- /dev/null +++ b/docs/src/get_started.md @@ -0,0 +1,202 @@ +# Sampling from a multivariate Gaussian using NUTS + +In this get-start section, we demonstrate a minimal example of sampling from a multivariate Gaussian (10-dimensional) using the no U-turn sampler (NUTS). Below we describe the major components of the Hamiltonian system which are essential to sample using this approach: + + - **Metric**: In many sampling problems the sample space is associated with a metric that allows us to measure the distance between any two points, and other similar quantities. In the example in this section, we use a special metric called the **Euclidean Metric**, represented with a `D × D` matrix from which we can compute distances.[^1] + + - **Leapfrog integration**: Leapfrog integration is a second-order numerical method for integrating differential equations (In this case they are equations of motion for the relative position of one particle with respect to the other). The order of this integration signifies its rate of convergence. Any algorithm with a finite time step size will have numerical errors, and the order is related to this error. For a second-order algorithm, this error scales as the second power of the time step, hence, the name second-order. High-order integrators are usually complex to code and have a limited region of convergence; hence they do not allow arbitrarily large time steps. A second-order integrator is suitable for our purpose. Hence we opt for the leapfrog integrator. It is called `leapfrog` due to the ways this algorithm is written, where the positions and velocities of particles "leap over" each other.[^2] + - **Kernel for trajectories (static or dynamic)**: Different kernels, which may be static or dynamic, can be used. At each iteration of any variant of the HMC algorithm, there are two main steps - the first step changes the momentum and the second step may change both the position and the momentum of a particle.[^3] + +```julia +using AdvancedHMC, ForwardDiff +using LogDensityProblems +using LinearAlgebra + +# Define the target distribution using the `LogDensityProblem` interface +struct LogTargetDensity + dim::Int +end +LogDensityProblems.logdensity(p::LogTargetDensity, θ) = -sum(abs2, θ) / 2 # standard multivariate normal +LogDensityProblems.dimension(p::LogTargetDensity) = p.dim +function LogDensityProblems.capabilities(::Type{LogTargetDensity}) + return LogDensityProblems.LogDensityOrder{0}() +end + +# Choose parameter dimensionality and initial parameter value +D = 10; +initial_θ = rand(D); +ℓπ = LogTargetDensity(D) + +# Set the number of samples to draw and warmup iterations +n_samples, n_adapts = 2_000, 1_000 + +# Define a Hamiltonian system +metric = DiagEuclideanMetric(D) +hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) + +# Define a leapfrog solver, with the initial step size chosen heuristically +initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) +integrator = Leapfrog(initial_ϵ) + +# Define an HMC sampler with the following components +# - multinomial sampling scheme, +# - generalised No-U-Turn criteria, and +# - windowed adaption for step-size and diagonal mass matrix +kernel = HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn())) +adaptor = StanHMCAdaptor(MassMatrixAdaptor(metric), StepSizeAdaptor(0.8, integrator)) + +# Run the sampler to draw samples from the specified Gaussian, where +# - `samples` will store the samples +# - `stats` will store diagnostic statistics for each sample +samples, stats = sample( + hamiltonian, kernel, initial_θ, n_samples, adaptor, n_adapts; progress=true +) +``` + +## Parallel sampling + +AdvancedHMC enables parallel sampling (either distributed or multi-thread) via Julia's [parallel computing functions](https://docs.julialang.org/en/v1/manual/parallel-computing/). +It also supports vectorized sampling for static HMC. + +The below example utilizes the `@threads` macro to sample 4 chains across 4 threads. + +```julia +# Ensure that Julia was launched with an appropriate number of threads +println(Threads.nthreads()) + +# Number of chains to sample +nchains = 4 + +# Cache to store the chains +chains = Vector{Any}(undef, nchains) + +# The `samples` from each parallel chain is stored in the `chains` vector +# Adjust the `verbose` flag as per need +Threads.@threads for i in 1:nchains + samples, stats = sample( + hamiltonian, kernel, initial_θ, n_samples, adaptor, n_adapts; verbose=false + ) + chains[i] = samples +end +``` + +## Using the `AbstractMCMC` interface + +Users can also use the `AbstractMCMC` interface to sample, which is also used in Turing.jl. +In order to show how this is done let us start from our previous example where we defined a `LogTargetDensity`, `ℓπ`. + +```julia +using AbstractMCMC, LogDensityProblemsAD +# Wrap the previous LogTargetDensity as LogDensityModel +# where ℓπ::LogTargetDensity +model = AdvancedHMC.LogDensityModel(LogDensityProblemsAD.ADgradient(Val(:ForwardDiff), ℓπ)) + +# Wrap the previous sampler as a HMCSampler <: AbstractMCMC.AbstractSampler +D = 10; +initial_θ = rand(D); +n_samples, n_adapts, δ = 1_000, 2_000, 0.8 +sampler = HMCSampler(kernel, metric, adaptor) + +# Now sample +samples = AbstractMCMC.sample( + model, sampler, n_adapts + n_samples; n_adapts=n_adapts, initial_params=initial_θ +) +``` + +## Convenience Constructors + +In the previous examples, we built the sampler by manually specifying the integrator, metric, kernel, and adaptor to build our own sampler. However, in many cases, users might want to initialize a standard NUTS sampler. In such cases having to define each of these aspects manually is tedious and error-prone. For these reasons `AdvancedHMC` also provides users with a series of convenience constructors for standard samplers. We will now show how to use them. + + - HMC: + + ```julia + # HMC Sampler + # step size, number of leapfrog steps + n_leapfrog, ϵ = 25, 0.1 + hmc = HMC(ϵ, n_leapfrog) + ``` + + Equivalent to: + + ```julia + metric = DiagEuclideanMetric(D) + hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) + integrator = Leapfrog(0.1) + kernel = HMCKernel(Trajectory{EndPointTS}(integrator, FixedNSteps(n_leapfrog))) + adaptor = NoAdaptation() + hmc = HMCSampler(kernel, metric, adaptor) + ``` + + - NUTS: + + ```julia + # NUTS Sampler + # adaptation steps, target acceptance probability, + δ = 0.8 + nuts = NUTS(δ) + ``` + + Equivalent to: + + ```julia + metric = DiagEuclideanMetric(D) + hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) + initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) + integrator = Leapfrog(initial_ϵ) + kernel = HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn())) + adaptor = StanHMCAdaptor(MassMatrixAdaptor(metric), StepSizeAdaptor(δ, integrator)) + nuts = HMCSampler(kernel, metric, adaptor) + ``` + - HMCDA: + + ```julia + #HMCDA (dual averaging) + # adaptation steps, target acceptance probability, target trajectory length + δ, λ = 0.8, 1.0 + hmcda = HMCDA(δ, λ) + ``` + + Equivalent to: + + ```julia + metric = DiagEuclideanMetric(D) + hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) + initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) + integrator = Leapfrog(initial_ϵ) + kernel = HMCKernel(Trajectory{EndPointTS}(integrator, FixedIntegrationTime(λ))) + adaptor = StepSizeAdaptor(δ, initial_ϵ) + hmcda = HMCSampler(kernel, metric, adaptor) + ``` + +Moreover, there's some flexibility in how these samplers can be initialized. +For example, a user can initialize a NUTS (HMC and HMCDA) sampler with their own metrics and integrators. +This can be done as follows: + +```julia +nuts = NUTS(δ; metric=:diagonal) #metric = DiagEuclideanMetric(D) (Default!) +nuts = NUTS(δ; metric=:unit) #metric = UnitEuclideanMetric(D) +nuts = NUTS(δ; metric=:dense) #metric = DenseEuclideanMetric(D) +# Provide your own AbstractMetric +metric = DiagEuclideanMetric(10) +nuts = NUTS(δ; metric=metric) + +nuts = NUTS(δ; integrator=:leapfrog) #integrator = Leapfrog(ϵ) (Default!) +nuts = NUTS(δ; integrator=:jitteredleapfrog) #integrator = JitteredLeapfrog(ϵ, 0.1ϵ) +nuts = NUTS(δ; integrator=:temperedleapfrog) #integrator = TemperedLeapfrog(ϵ, 1.0) + +# Provide your own AbstractIntegrator +integrator = JitteredLeapfrog(0.1, 0.2) +nuts = NUTS(δ; integrator=integrator) +``` + +## GPU Sampling with CUDA + +There is experimental support for running static HMC on the GPU using CUDA. +To do so, the user needs to have [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl) installed, ensure the logdensity of the `Hamiltonian` can be executed on the GPU and that the initial points are a `CuArray`. +A small working example can be found at `test/cuda.jl`. + +## Footnotes + +[^1]: The Euclidean metric is also known as the mass matrix in the physical perspective. See [Hamiltonian mass matrix](@ref hamiltonian-mm) for available metrics. +[^2]: About the leapfrog integration scheme: Suppose ${\bf x}$ and ${\bf v}$ are the position and velocity of an individual particle respectively; $i$ and $i+1$ are the indices for time values $t_i$ and $t_{i+1}$ respectively; $dt = t_{i+1} - t_i$ is the time step size (constant and regularly spaced intervals), and ${\bf a}$ is the acceleration induced on a particle by the forces of all other particles. Furthermore, suppose positions are defined at times $t_i, t_{i+1}, t_{i+2}, \dots $, spaced at constant intervals $dt$, the velocities are defined at halfway times in between, denoted by $t_{i-1/2}, t_{i+1/2}, t_{i+3/2}, \dots $, where $t_{i+1} - t_{i + 1/2} = t_{i + 1/2} - t_i = dt / 2$, and the accelerations ${\bf a}$ are defined only on integer times, just like the positions. Then the leapfrog integration scheme is given as: $x_{i} = x_{i-1} + v_{i-1/2} dt; \quad v_{i+1/2} = v_{i-1/2} + a_i dt$. For available integrators refer to [Integrator](@ref integrator). +[^3]: On kernels: In the classical HMC approach, during the first step, new values for the momentum variables are randomly drawn from their Gaussian distribution, independently of the current values of the position variables. A Metropolis update is performed during the second step, using Hamiltonian dynamics to provide a new state. For available kernels refer to [Kernel](@ref kernel). diff --git a/docs/src/index.md b/docs/src/index.md deleted file mode 120000 index fe8400541..000000000 --- a/docs/src/index.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 000000000..550fd6a5f --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,66 @@ +# AdvancedHMC.jl + +[![CI](https://github.com/TuringLang/AdvancedHMC.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/TuringLang/AdvancedHMC.jl/actions/workflows/CI.yml) +[![DOI](https://zenodo.org/badge/72657907.svg)](https://zenodo.org/badge/latestdoi/72657907) +[![Coverage Status](https://coveralls.io/repos/github/TuringLang/AdvancedHMC.jl/badge.svg?branch=kx%2Fbug-fix)](https://coveralls.io/github/TuringLang/AdvancedHMC.jl?branch=kx%2Fbug-fix) +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://turinglang.github.io/AdvancedHMC.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://turinglang.github.io/AdvancedHMC.jl/dev/) +[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) + +AdvancedHMC.jl provides a robust, modular, and efficient implementation of advanced HMC algorithms. An illustrative example of AdvancedHMC's usage is given below. AdvancedHMC.jl is part of [Turing.jl](https://github.com/TuringLang/Turing.jl), a probabilistic programming library in Julia. +If you are interested in using AdvancedHMC.jl through a probabilistic programming language, please check it out! + +**Interfaces** + + - [`IMP.hmc`](https://github.com/salilab/hmc): an experimental Python module for the Integrative Modeling Platform, which uses AdvancedHMC in its backend to sample protein structures. + +**NEWS** + + - We presented a paper for AdvancedHMC.jl at [AABI](http://approximateinference.org/) in 2019 in Vancouver, Canada. ([abs](http://proceedings.mlr.press/v118/xu20a.html), [pdf](http://proceedings.mlr.press/v118/xu20a/xu20a.pdf), [OpenReview](https://openreview.net/forum?id=rJgzckn4tH)) + - We presented a poster for AdvancedHMC.jl at [StanCon 2019](https://mc-stan.org/events/stancon2019Cambridge/) in Cambridge, UK. ([pdf](https://github.com/TuringLang/AdvancedHMC.jl/files/3730367/StanCon-AHMC.pdf)) + +## Citing AdvancedHMC.jl + +If you use AdvancedHMC.jl for your own research, please consider citing the following publication: + +Kai Xu, Hong Ge, Will Tebbutt, Mohamed Tarek, Martin Trapp, Zoubin Ghahramani: "AdvancedHMC.jl: A robust, modular and efficient implementation of advanced HMC algorithms.", *Symposium on Advances in Approximate Bayesian Inference*, 2020. ([abs](http://proceedings.mlr.press/v118/xu20a.html), [pdf](http://proceedings.mlr.press/v118/xu20a/xu20a.pdf)) + +with the following BibTeX entry: + +``` +@inproceedings{xu2020advancedhmc, + title={AdvancedHMC. jl: A robust, modular and efficient implementation of advanced HMC algorithms}, + author={Xu, Kai and Ge, Hong and Tebbutt, Will and Tarek, Mohamed and Trapp, Martin and Ghahramani, Zoubin}, + booktitle={Symposium on Advances in Approximate Bayesian Inference}, + pages={1--10}, + year={2020}, + organization={PMLR} +} +``` + +If you using AdvancedHMC.jl directly through Turing.jl, please consider citing the following publication: + +Hong Ge, Kai Xu, and Zoubin Ghahramani: "Turing: a language for flexible probabilistic inference.", *International Conference on Artificial Intelligence and Statistics*, 2018. ([abs](http://proceedings.mlr.press/v84/ge18b.html), [pdf](http://proceedings.mlr.press/v84/ge18b/ge18b.pdf)) + +with the following BibTeX entry: + +``` +@inproceedings{ge2018turing, + title={Turing: A language for flexible probabilistic inference}, + author={Ge, Hong and Xu, Kai and Ghahramani, Zoubin}, + booktitle={International Conference on Artificial Intelligence and Statistics}, + pages={1682--1690}, + year={2018}, + organization={PMLR} +} +``` + +## References + + 1. Neal, R. M. (2011). MCMC using Hamiltonian dynamics. Handbook of Markov chain Monte Carlo, 2(11), 2. ([arXiv](https://arxiv.org/pdf/1206.1901)) + + 2. Betancourt, M. (2017). A Conceptual Introduction to Hamiltonian Monte Carlo. [arXiv preprint arXiv:1701.02434](https://arxiv.org/abs/1701.02434). + 3. Girolami, M., & Calderhead, B. (2011). Riemann manifold Langevin and Hamiltonian Monte Carlo methods. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 73(2), 123-214. ([arXiv](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/j.1467-9868.2010.00765.x)) + 4. Betancourt, M. J., Byrne, S., & Girolami, M. (2014). Optimizing the integrator step size for Hamiltonian Monte Carlo. [arXiv preprint arXiv:1411.6669](https://arxiv.org/pdf/1411.6669). + 5. Betancourt, M. (2016). Identifying the optimal integration time in Hamiltonian Monte Carlo. [arXiv preprint arXiv:1601.00225](https://arxiv.org/abs/1601.00225). + 6. Hoffman, M. D., & Gelman, A. (2014). The No-U-Turn Sampler: adaptively setting path lengths in Hamiltonian Monte Carlo. Journal of Machine Learning Research, 15(1), 1593-1623. ([arXiv](http://arxiv.org/abs/1111.4246)) diff --git a/docs/src/references.md b/docs/src/references.md new file mode 100644 index 000000000..78f29bc41 --- /dev/null +++ b/docs/src/references.md @@ -0,0 +1,4 @@ +# References + +```@bibliography +``` diff --git a/docs/src/refs.bib b/docs/src/refs.bib new file mode 100644 index 000000000..927eb00fe --- /dev/null +++ b/docs/src/refs.bib @@ -0,0 +1,48 @@ +@article{neal2011mcmc, + title={Mcmc using hamiltonian dynamics (handbook of markov chain monte carlo) ed s brooks et al}, + author={Neal, R MCMC}, + journal={A Gelman, G Jones XL Meng}, + year={2011} +} + +@article{betancourt2017conceptual, + title={A conceptual introduction to Hamiltonian Monte Carlo}, + author={Betancourt, Michael}, + journal={arXiv preprint arXiv:1701.02434}, + year={2017} +} + +@article{girolami2011riemann, + title={Riemann manifold langevin and hamiltonian monte carlo methods}, + author={Girolami, Mark and Calderhead, Ben}, + journal={Journal of the Royal Statistical Society Series B: Statistical Methodology}, + volume={73}, + number={2}, + pages={123--214}, + year={2011}, + publisher={Oxford University Press} +} + +@article{betancourt2014optimizing, + title={Optimizing the integrator step size for Hamiltonian Monte Carlo}, + author={Betancourt, MJ and Byrne, Simon and Girolami, Mark}, + journal={arXiv preprint arXiv:1411.6669}, + year={2014} +} + +@article{betancourt2016identifying, + title={Identifying the optimal integration time in Hamiltonian Monte Carlo}, + author={Betancourt, Michael}, + journal={arXiv preprint arXiv:1601.00225}, + year={2016} +} + +@article{hoffman2014no, + title={The No-U-Turn sampler: adaptively setting path lengths in Hamiltonian Monte Carlo.}, + author={Hoffman, Matthew D and Gelman, Andrew and others}, + journal={J. Mach. Learn. Res.}, + volume={15}, + number={1}, + pages={1593--1623}, + year={2014} +} \ No newline at end of file From 8c00d8ffdc1e3a8d600a0c6180bec31ba4feb896 Mon Sep 17 00:00:00 2001 From: Qingyu Qu <2283984853@qq.com> Date: Fri, 4 Apr 2025 02:32:16 +0800 Subject: [PATCH 2/4] Apply reviews --- README.md | 74 +++++++++++++++++++++++++---------------- docs/make.jl | 2 ++ docs/src/api.md | 6 ++-- docs/src/autodiff.md | 4 +-- docs/src/get_started.md | 4 +-- docs/src/index.md | 11 +----- docs/src/interfaces.md | 3 ++ docs/src/news.md | 4 +++ docs/src/refs.bib | 4 +-- 9 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 docs/src/interfaces.md create mode 100644 docs/src/news.md diff --git a/README.md b/README.md index 7a40193a3..532aa252e 100644 --- a/README.md +++ b/README.md @@ -10,34 +10,52 @@ AdvancedHMC.jl provides a robust, modular, and efficient implementation of advanced HMC algorithms. An illustrative example of AdvancedHMC's usage is given below. AdvancedHMC.jl is part of [Turing.jl](https://github.com/TuringLang/Turing.jl), a probabilistic programming library in Julia. If you are interested in using AdvancedHMC.jl through a probabilistic programming language, please check it out! -**Interfaces** - - - [`IMP.hmc`](https://github.com/salilab/hmc): an experimental Python module for the Integrative Modeling Platform, which uses AdvancedHMC in its backend to sample protein structures. - -**NEWS** - - - We presented a paper for AdvancedHMC.jl at [AABI](http://approximateinference.org/) in 2019 in Vancouver, Canada. ([abs](http://proceedings.mlr.press/v118/xu20a.html), [pdf](http://proceedings.mlr.press/v118/xu20a/xu20a.pdf), [OpenReview](https://openreview.net/forum?id=rJgzckn4tH)) - - We presented a poster for AdvancedHMC.jl at [StanCon 2019](https://mc-stan.org/events/stancon2019Cambridge/) in Cambridge, UK. ([pdf](https://github.com/TuringLang/AdvancedHMC.jl/files/3730367/StanCon-AHMC.pdf)) - -**API CHANGES** - - - [v0.5.0] **Breaking!** Convenience constructors for common samplers changed to: - - + `HMC(leapfrog_stepsize::Real, n_leapfrog::Int)` - + `NUTS(target_acceptance::Real)` - + `HMCDA(target_acceptance::Real, integration_time::Real)` - - - [v0.2.22] Three functions are renamed. - - + `Preconditioner(metric::AbstractMetric)` -> `MassMatrixAdaptor(metric)` and - + `NesterovDualAveraging(δ, integrator::AbstractIntegrator)` -> `StepSizeAdaptor(δ, integrator)` - + `find_good_eps` -> `find_good_stepsize` - - [v0.2.15] `n_adapts` is no longer needed to construct `StanHMCAdaptor`; the old constructor is deprecated. - - [v0.2.8] Two Hamiltonian trajectory sampling methods are renamed to avoid a name clash with Distributions. - - + `Multinomial` -> `MultinomialTS` - + `Slice` -> `SliceTS` - - [v0.2.0] The gradient function passed to `Hamiltonian` is supposed to return a value-gradient tuple now. +## Hands on AdvancedHMC.jl + +Let's see how to sample a Hamiltonian using AdvanedHMC.jl + +```julia +using AdvancedHMC, LogDensityProblems, ForwardDiff +# Define the target distribution using the `LogDensityProblem` interface +struct LogTargetDensity + dim::Int +end +# standard multivariate normal distribution +LogDensityProblems.logdensity(p::LogTargetDensity, θ) = -sum(abs2, θ) / 2 +LogDensityProblems.dimension(p::LogTargetDensity) = p.dim +function LogDensityProblems.capabilities(::Type{LogTargetDensity}) + return LogDensityProblems.LogDensityOrder{0}() +end + +D = 10; # parameter dimensionality +initial_θ = rand(D); # initial parameter value +ℓπ = LogTargetDensity(D) + +# Set the number of samples to draw and warmup iterations +n_samples, n_adapts = 2_000, 1_000 + +# Define a Hamiltonian system +metric = DiagEuclideanMetric(D) +hamiltonian = Hamiltonian(metric, ℓπ, ForwardDiff) + +# Define a leapfrog solver, with the initial step size chosen heuristically +initial_ϵ = find_good_stepsize(hamiltonian, initial_θ) +integrator = Leapfrog(initial_ϵ) + +# Define an HMC sampler with the following components +# - multinomial sampling scheme, +# - generalised No-U-Turn criteria, and +# - windowed adaption for step-size and diagonal mass matrix +kernel = HMCKernel(Trajectory{MultinomialTS}(integrator, GeneralisedNoUTurn())) +adaptor = StanHMCAdaptor(MassMatrixAdaptor(metric), StepSizeAdaptor(0.8, integrator)) + +# Run the sampler to draw samples from the specified Gaussian, where +# - `samples` will store the samples +# - `stats` will store diagnostic statistics for each sample +samples, stats = sample( + hamiltonian, kernel, initial_θ, n_samples, adaptor, n_adapts; progress=true +) +``` ## Citing AdvancedHMC.jl diff --git a/docs/make.jl b/docs/make.jl index 948a58ad1..41410a009 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -18,6 +18,8 @@ makedocs(; "Get Started" => "get_started.md", "Automatic Differentiation Backends" => "autodiff.md", "Detailed API" => "api.md", + "Interfaces" => "interfaces.md", + "News" => "news.md", "Change Log" => "changelog.md", "References" => "references.md", ], diff --git a/docs/src/api.md b/docs/src/api.md index d49f87d62..54b5939dc 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -1,7 +1,7 @@ # Detailed API for AdvancedHMC.jl An important design goal of AdvancedHMC.jl is modularity; we would like to support algorithmic research on HMC. -This modularity means that different HMC variants can be easily constructed by composing various components, such as preconditioning metric (i.e., mass matrix), leapfrog integrators, trajectories (static or dynamic), adaption schemes, etc. In this documentation, we will explain the detailed usage of different modules in AdancedHMC.jl to provide a comprehensive udnerstanding of how AdvancedHMC.jl can achieve both modularity and efficiency. +This modularity means that different HMC variants can be easily constructed by composing various components, such as preconditioning metric (i.e., mass matrix), leapfrog integrators, trajectories (static or dynamic), adaption schemes, etc. In this section, we will explain the detailed usage of different modules in AdancedHMC.jl to provide a comprehensive udnerstanding of how AdvancedHMC.jl can achieve both modularity and efficiency. The section highlights the key components of AdvancedHMC.jl, with a complete documentation provided at the end. ### [Hamiltonian mass matrix (`metric`)](@id hamiltonian_mm) @@ -73,9 +73,7 @@ Draw `n_samples` samples using the kernel `κ` under the Hamiltonian system `h` Note that the function signature of the `sample` function exported by `AdvancedHMC.jl` differs from the [`sample`](https://turinglang.org/dev/docs/using-turing/guide#modelling-syntax-explained) function used by `Turing.jl`. We refer to the documentation of `Turing.jl` for more details on the latter. -Note that the function signature of the `sample` function exported by `AdvancedHMC.jl` differs from the [`sample`](https://turinglang.org/dev/docs/using-turing/guide#modelling-syntax-explained) function used by `Turing.jl`. We refer to the documentation of `Turing.jl` for more details on the latter. - -## More types +## Full documentation of APIs in AdvancedHMC.jl ```@autodocs; canonical=false Modules = [AdvancedHMC, AdvancedHMC.Adaptation] diff --git a/docs/src/autodiff.md b/docs/src/autodiff.md index aeebc2267..def57d0a2 100644 --- a/docs/src/autodiff.md +++ b/docs/src/autodiff.md @@ -1,5 +1,5 @@ # Gradient in AdvancedHMC.jl -AdvancedHMC.jl supports automatic differentiation using [`LogDensityProblemsAD`](https://github.com/tpapp/LogDensityProblemsAD.jl) and user-specified gradients. While the default AD backend for AdvancedHMC.jl is ForwardDiff.jl, we can seamlessly change to other backend like Zygote.jl using various syntax like `Hamiltonian(metric, ℓπ, Zygote)`, `Hamiltonian(metric, ℓπ, Val(:Zygote))` or via ADTypes.jl `Hamiltonian(metric, ℓπ, AutoZygote())`. +AdvancedHMC.jl supports automatic differentiation using [`LogDensityProblemsAD`](https://github.com/tpapp/LogDensityProblemsAD.jl) across various AD backends and allows user-specified gradients. While the default AD backend for AdvancedHMC.jl is ForwardDiff.jl, we can seamlessly change to other backend like Mooncake.jl using various syntax like `Hamiltonian(metric, ℓπ, AutoZygote())`. Different AD backend can also be pluged in using `Hamiltonian(metric, ℓπ, Zygote)`, `Hamiltonian(metric, ℓπ, Val(:Zygote))` but we recommend using ADTypes since that would allow you to have more freedom for specifying the AD backend. -In order to use user-specified gradients, please replace ForwardDiff.jl with `ℓπ_grad` in the `Hamiltonian` constructor, where the gradient function `ℓπ_grad` should return a tuple containing both the log-posterior and its gradient. +In order to use user-specified gradients, please replace ForwardDiff.jl with `ℓπ_grad` in the `Hamiltonian` constructor as `Hamiltonian(metric, ℓπ, ℓπ_grad)`, where the gradient function `ℓπ_grad` should return a tuple containing both the log-posterior and its gradient, for example `ℓπ_grad(x) = (log_posterior, grad)`. diff --git a/docs/src/get_started.md b/docs/src/get_started.md index 482355c91..eb8d4097e 100644 --- a/docs/src/get_started.md +++ b/docs/src/get_started.md @@ -1,10 +1,10 @@ # Sampling from a multivariate Gaussian using NUTS -In this get-start section, we demonstrate a minimal example of sampling from a multivariate Gaussian (10-dimensional) using the no U-turn sampler (NUTS). Below we describe the major components of the Hamiltonian system which are essential to sample using this approach: +In this section, we demonstrate a minimal example of sampling from a multivariate Gaussian (10-dimensional) using the No U-Turn Sampler (NUTS). Below we describe the major components of the Hamiltonian system which are essential to sample using this approach: - **Metric**: In many sampling problems the sample space is associated with a metric that allows us to measure the distance between any two points, and other similar quantities. In the example in this section, we use a special metric called the **Euclidean Metric**, represented with a `D × D` matrix from which we can compute distances.[^1] - - **Leapfrog integration**: Leapfrog integration is a second-order numerical method for integrating differential equations (In this case they are equations of motion for the relative position of one particle with respect to the other). The order of this integration signifies its rate of convergence. Any algorithm with a finite time step size will have numerical errors, and the order is related to this error. For a second-order algorithm, this error scales as the second power of the time step, hence, the name second-order. High-order integrators are usually complex to code and have a limited region of convergence; hence they do not allow arbitrarily large time steps. A second-order integrator is suitable for our purpose. Hence we opt for the leapfrog integrator. It is called `leapfrog` due to the ways this algorithm is written, where the positions and velocities of particles "leap over" each other.[^2] + - **Leapfrog integration**: Leapfrog integration is a second-order numerical method for integrating differential equations (In this case they are equations of motion for the relative position of one particle with respect to the other). The order of this integration signifies its rate of convergence. Any algorithm with a finite time step size will have numerical errors, and the order is related to this error. For a second-order algorithm, this error scales as the second power of the time step, hence the name. High-order integrators are usually complex to code and have a limited region of convergence; thus they do not allow arbitrarily large time steps. A second-order integrator is suitable for our purpose. Hence we opt for the leapfrog integrator. It is called `leapfrog` due to the ways this algorithm is written, where the positions and velocities of particles "leap over" each other.[^2] - **Kernel for trajectories (static or dynamic)**: Different kernels, which may be static or dynamic, can be used. At each iteration of any variant of the HMC algorithm, there are two main steps - the first step changes the momentum and the second step may change both the position and the momentum of a particle.[^3] ```julia diff --git a/docs/src/index.md b/docs/src/index.md index 550fd6a5f..e4645d62a 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -7,18 +7,9 @@ [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://turinglang.github.io/AdvancedHMC.jl/dev/) [![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) -AdvancedHMC.jl provides a robust, modular, and efficient implementation of advanced HMC algorithms. An illustrative example of AdvancedHMC's usage is given below. AdvancedHMC.jl is part of [Turing.jl](https://github.com/TuringLang/Turing.jl), a probabilistic programming library in Julia. +AdvancedHMC.jl provides a robust, modular, and efficient implementation of advanced Hamiltonian Monte Carlo(HMC) algorithms. AdvancedHMC.jl is part of [Turing.jl](https://github.com/TuringLang/Turing.jl), a probabilistic programming library in Julia. If you are interested in using AdvancedHMC.jl through a probabilistic programming language, please check it out! -**Interfaces** - - - [`IMP.hmc`](https://github.com/salilab/hmc): an experimental Python module for the Integrative Modeling Platform, which uses AdvancedHMC in its backend to sample protein structures. - -**NEWS** - - - We presented a paper for AdvancedHMC.jl at [AABI](http://approximateinference.org/) in 2019 in Vancouver, Canada. ([abs](http://proceedings.mlr.press/v118/xu20a.html), [pdf](http://proceedings.mlr.press/v118/xu20a/xu20a.pdf), [OpenReview](https://openreview.net/forum?id=rJgzckn4tH)) - - We presented a poster for AdvancedHMC.jl at [StanCon 2019](https://mc-stan.org/events/stancon2019Cambridge/) in Cambridge, UK. ([pdf](https://github.com/TuringLang/AdvancedHMC.jl/files/3730367/StanCon-AHMC.pdf)) - ## Citing AdvancedHMC.jl If you use AdvancedHMC.jl for your own research, please consider citing the following publication: diff --git a/docs/src/interfaces.md b/docs/src/interfaces.md new file mode 100644 index 000000000..fe31bb45e --- /dev/null +++ b/docs/src/interfaces.md @@ -0,0 +1,3 @@ +# Interfaces + + - [`IMP.hmc`](https://github.com/salilab/hmc): an experimental Python module for the Integrative Modeling Platform, which uses AdvancedHMC in its backend to sample protein structures. diff --git a/docs/src/news.md b/docs/src/news.md new file mode 100644 index 000000000..de7ca1f7c --- /dev/null +++ b/docs/src/news.md @@ -0,0 +1,4 @@ +# NEWS + + - We presented a paper for AdvancedHMC.jl at [AABI](http://approximateinference.org/) in 2019 in Vancouver, Canada. ([abs](http://proceedings.mlr.press/v118/xu20a.html), [pdf](http://proceedings.mlr.press/v118/xu20a/xu20a.pdf), [OpenReview](https://openreview.net/forum?id=rJgzckn4tH)) + - We presented a poster for AdvancedHMC.jl at [StanCon 2019](https://mc-stan.org/events/stancon2019Cambridge/) in Cambridge, UK. ([pdf](https://github.com/TuringLang/AdvancedHMC.jl/files/3730367/StanCon-AHMC.pdf)) diff --git a/docs/src/refs.bib b/docs/src/refs.bib index 927eb00fe..81bef6f7e 100644 --- a/docs/src/refs.bib +++ b/docs/src/refs.bib @@ -1,5 +1,5 @@ @article{neal2011mcmc, - title={Mcmc using hamiltonian dynamics (handbook of markov chain monte carlo) ed s brooks et al}, + title={Mcmc using Hamiltonian dynamics (handbook of Markov Chain Monte Carlo)}, author={Neal, R MCMC}, journal={A Gelman, G Jones XL Meng}, year={2011} @@ -13,7 +13,7 @@ @article{betancourt2017conceptual } @article{girolami2011riemann, - title={Riemann manifold langevin and hamiltonian monte carlo methods}, + title={Riemann manifold Langevin and Hamiltonian Monte Carlo methods}, author={Girolami, Mark and Calderhead, Ben}, journal={Journal of the Royal Statistical Society Series B: Statistical Methodology}, volume={73}, From e23c7a06af9a0188e71327413b237a954245e3e0 Mon Sep 17 00:00:00 2001 From: Qingyu Qu <2283984853@qq.com> Date: Fri, 4 Apr 2025 19:56:19 +0800 Subject: [PATCH 3/4] Fix some typos --- docs/src/get_started.md | 11 ++++++----- docs/src/index.md | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/src/get_started.md b/docs/src/get_started.md index eb8d4097e..6629aa52c 100644 --- a/docs/src/get_started.md +++ b/docs/src/get_started.md @@ -53,7 +53,7 @@ samples, stats = sample( ) ``` -## Parallel sampling +## Parallel Sampling AdvancedHMC enables parallel sampling (either distributed or multi-thread) via Julia's [parallel computing functions](https://docs.julialang.org/en/v1/manual/parallel-computing/). It also supports vectorized sampling for static HMC. @@ -80,13 +80,14 @@ Threads.@threads for i in 1:nchains end ``` -## Using the `AbstractMCMC` interface +## Using the `AbstractMCMC` Interface Users can also use the `AbstractMCMC` interface to sample, which is also used in Turing.jl. In order to show how this is done let us start from our previous example where we defined a `LogTargetDensity`, `ℓπ`. ```julia using AbstractMCMC, LogDensityProblemsAD + # Wrap the previous LogTargetDensity as LogDensityModel # where ℓπ::LogTargetDensity model = AdvancedHMC.LogDensityModel(LogDensityProblemsAD.ADgradient(Val(:ForwardDiff), ℓπ)) @@ -116,7 +117,7 @@ In the previous examples, we built the sampler by manually specifying the integr hmc = HMC(ϵ, n_leapfrog) ``` - Equivalent to: + is equivalent to: ```julia metric = DiagEuclideanMetric(D) @@ -136,7 +137,7 @@ In the previous examples, we built the sampler by manually specifying the integr nuts = NUTS(δ) ``` - Equivalent to: + is equivalent to: ```julia metric = DiagEuclideanMetric(D) @@ -156,7 +157,7 @@ In the previous examples, we built the sampler by manually specifying the integr hmcda = HMCDA(δ, λ) ``` - Equivalent to: + is equivalent to: ```julia metric = DiagEuclideanMetric(D) diff --git a/docs/src/index.md b/docs/src/index.md index e4645d62a..bb80c7bed 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -50,8 +50,9 @@ with the following BibTeX entry: 1. Neal, R. M. (2011). MCMC using Hamiltonian dynamics. Handbook of Markov chain Monte Carlo, 2(11), 2. ([arXiv](https://arxiv.org/pdf/1206.1901)) - 2. Betancourt, M. (2017). A Conceptual Introduction to Hamiltonian Monte Carlo. [arXiv preprint arXiv:1701.02434](https://arxiv.org/abs/1701.02434). - 3. Girolami, M., & Calderhead, B. (2011). Riemann manifold Langevin and Hamiltonian Monte Carlo methods. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 73(2), 123-214. ([arXiv](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/j.1467-9868.2010.00765.x)) - 4. Betancourt, M. J., Byrne, S., & Girolami, M. (2014). Optimizing the integrator step size for Hamiltonian Monte Carlo. [arXiv preprint arXiv:1411.6669](https://arxiv.org/pdf/1411.6669). - 5. Betancourt, M. (2016). Identifying the optimal integration time in Hamiltonian Monte Carlo. [arXiv preprint arXiv:1601.00225](https://arxiv.org/abs/1601.00225). - 6. Hoffman, M. D., & Gelman, A. (2014). The No-U-Turn Sampler: adaptively setting path lengths in Hamiltonian Monte Carlo. Journal of Machine Learning Research, 15(1), 1593-1623. ([arXiv](http://arxiv.org/abs/1111.4246)) + 2. Hoffman, M. D., & Gelman, A. (2014). The No-U-Turn Sampler: adaptively setting path lengths in Hamiltonian Monte Carlo. Journal of Machine Learning Research, 15(1), 1593-1623. ([arXiv](http://arxiv.org/abs/1111.4246)) + 3. Betancourt, M. (2017). A Conceptual Introduction to Hamiltonian Monte Carlo. [arXiv preprint arXiv:1701.02434](https://arxiv.org/abs/1701.02434). + 4. Girolami, M., & Calderhead, B. (2011). Riemann manifold Langevin and Hamiltonian Monte Carlo methods. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 73(2), 123-214. ([arXiv](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/j.1467-9868.2010.00765.x)) + 5. Betancourt, M. J., Byrne, S., & Girolami, M. (2014). Optimizing the integrator step size for Hamiltonian Monte Carlo. [arXiv preprint arXiv:1411.6669](https://arxiv.org/pdf/1411.6669). + 6. Betancourt, M. (2016). Identifying the optimal integration time in Hamiltonian Monte Carlo. [arXiv preprint arXiv:1601.00225](https://arxiv.org/abs/1601.00225). + 7. From 952c144790e374cfc1892e1f0f0605966fceb187 Mon Sep 17 00:00:00 2001 From: Qingyu Qu <2283984853@qq.com> Date: Fri, 4 Apr 2025 23:10:10 +0800 Subject: [PATCH 4/4] Fix typo --- docs/src/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/index.md b/docs/src/index.md index bb80c7bed..c638de167 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -55,4 +55,3 @@ with the following BibTeX entry: 4. Girolami, M., & Calderhead, B. (2011). Riemann manifold Langevin and Hamiltonian Monte Carlo methods. Journal of the Royal Statistical Society: Series B (Statistical Methodology), 73(2), 123-214. ([arXiv](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/j.1467-9868.2010.00765.x)) 5. Betancourt, M. J., Byrne, S., & Girolami, M. (2014). Optimizing the integrator step size for Hamiltonian Monte Carlo. [arXiv preprint arXiv:1411.6669](https://arxiv.org/pdf/1411.6669). 6. Betancourt, M. (2016). Identifying the optimal integration time in Hamiltonian Monte Carlo. [arXiv preprint arXiv:1601.00225](https://arxiv.org/abs/1601.00225). - 7.