Skip to content

Gibbs does not use initialisation strategies for component samplers #2693

@penelopeysm

Description

@penelopeysm

Minimal working example

using Turing, Bijectors

dist = Beta(1, 1)
binv = Bijectors.inverse(bijector(dist))

@model function f()
    h ~ dist
    m ~ dist
end

spl = Gibbs(@varname(h) => HMC(0.1, 5), @varname(m) => MH())

chn = sample(f(), spl, MCMCThreads(), 1, 100)
all(h -> binv(-2) < h < binv(2), chn[:h]) # false

chn2 = sample(f(), spl, MCMCThreads(), 1, 100; initial_params=fill(InitFromUniform(), 100))
all(h -> binv(-2) < h < binv(2), chn2[:h]) # true

Description

The Gibbs sampler does not make use of initialisation strategies for component samplers. That's because it uses Turing.Inference.init_strategy(::Gibbs) which resolves to InitFromPrior, and init_strategy(::HMC) is never called.

In the above example the HMC variable should always be initialised to (binv(-2), binv(2)) but it isn't as can be seen from the check.

The solution to this is to write a custom AbstractInitStrategy for Gibbs which, I think, maps varnames to init strategies of the component samplers: so this would wrap @varname(h) => InitFromUniform(), @varname(m) => InitFromPrior(). Then inside DynamicPPL.init it would check the varname and dispatch to the appropriate strategy.

Julia version info

1.11.7

Manifest

0.41.0 (currently using #2689)

Note the same is true on previous versions as the first call to all(...) also returns false on 0.40.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions