Skip to content

DomainError: Starting point has non-finite density using DynamicHMC backend #195

@ClaudMor

Description

@ClaudMor

Hello,

I'm using DynamicHMC through DiffEqBayes.jl, but I'm experiencing an error I'm not able to overcome.
This issue is similar to this and this, and as such it could be related more to DynamicHMC.jl than to DiffEqBayes.jl, so I'll be happy to move it if necessary.

So my goal is to calibrate an epidemiological model using MCMC samplers. Here is a simplified version of the model.

using DynamicHMC, Turing, DifferentialEquations, DiffEqBayes, RecursiveArrayTools, TransformVariables

# Model parameters

β = 0.01# infection rate
λ_R = 0.05 # inverse of transition time from  infected to recovered
λ_D = 0.83 # inverse of transition time from  infected to dead

𝒫 = vcat([β, λ_R, λ_D]...)


# regional contact matrix and regional population

## regional contact matrix
regional_all_contact_matrix = [3.45536   0.485314  0.506389  0.123002 ; 0.597721  2.11738   0.911374  0.323385 ; 0.906231  1.35041   1.60756   0.67411 ; 0.237902  0.432631  0.726488  0.979258] # 4x4 contact matrix

## regional population stratified by age
N= [723208 , 874150, 1330993, 1411928] # array of 4 elements, each of which representing the absolute amount of population in the corresponding age class.

# model fixed parameters ( transitions)
δ₁, δ₂, δ₃, δ₄ = [0.003/100, 0.004/100, (0.015+0.030+0.064+0.213+0.718)/(5*100), (2.384+8.466+12.497+1.117)/(4*100)]
δ = vcat(repeat([δ₁],1),repeat([δ₂],1),repeat([δ₃],1),repeat([δ₄],4-1-1-1))


# Initial conditions 
i₀ = 0.075 # fraction of initial infected people in every age class
I₀ = repeat([i₀],4)
S₀ = N.-I₀
R₀ = [0.0 for n in 1:length(N)]
D₀ = [0.0 for n in 1:length(N)]
D_tot₀ = [0.0]
ℬ = vcat([S₀, I₀, R₀, D₀, D_tot₀]...) 

# Time 
final_time = 20
𝒯 = (1.0,final_time); 
t  = collect(1.0:20.0)

# data used for calibration
data = [0,2,4,5,5,13,17,21,26,46,59,81,111,133,154,175,209,238,283,315]


function SIRD!(du,u,p,t)  
    # Parameters to be calibrated
    β, λ_R, λ_D = p

    # initialize this parameter (death probability stratified by age, taken from literature)
    



    C = regional_all_contact_matrix 

    
    # State variables
    S = @view u[4*0+1:4*1]
    I = @view u[4*1+1:4*2]
    R = @view u[4*2+1:4*3]
    D = @view u[4*3+1:4*4]
    D_tot = @view u[4*4+1]

    # Differentials
    dS = @view du[4*0+1:4*1]
    dI = @view du[4*1+1:4*2]
   dR = @view du[4*2+1:4*3]
    dD = @view du[4*3+1:4*4]
    dD_tot = @view du[4*4+1]
    
    # Force of infection
    Λ = β*[sum([C[i,j]*I[j]/N[j] for j in 1:size(C)[1]]) for i in 1:size(C)[2]] 
    
    # System of equations
    @. dS = -Λ*S
    @. dI = Λ*S - ((1-δ)*λ_R + δ*λ_D)*I
    @. dR = λ_R*(1-δ)*I 
    @. dD = λ_D*δ*I
    @. dD_tot = dD[1]+dD[2]+dD[3]+dD[4]
    

end;
# the problem builds and solves correctly
problem = ODEProblem(SIRD!,ℬ, 𝒯, 𝒫  )
solution = solve(problem, saveat = 1:20);

If I try to calibrate the three parameters using dynamic_inference, I get the following error:

# define priors
variable_parameters_priors = [Uniform(0.0,1.0),Uniform(0.0,1.0),Uniform(0.0,1.0)]

bayesian_result_dynamic = dynamichmc_inference(problem, Tsit5(), t,data', variable_parameters_priors,
                                                as( Vector, asℝ₊, length(variable_parameters_priors)); 
                                                save_idxs = [4*4+1],
                                                σ_priors = fill(InverseGamma(2, 3), size(data', 1)),
                                                mcmc_kwargs = (initialization = (q = vcat(𝒫, repeat([0.0], size(data', 1) )), ),),)
┌ Info: finding initial optimum
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:81
DomainError with [-0.38685, -1.12035, 0.612873, 1.07036]:
Starting point has non-finite density.

Stacktrace:
 [1] local_acceptance_ratio at C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\stepsize.jl:180 [inlined]
 [2] warmup at C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\mcmc.jl:162 [inlined]
 [3] #36 at C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\mcmc.jl:446 [inlined]
 [4] BottomRF at .\reduce.jl:81 [inlined]
 [5] afoldl at .\operators.jl:526 [inlined] (repeats 2 times)
 [6] _foldl_impl at .\tuple.jl:207 [inlined]
 [7] foldl_impl at .\reduce.jl:48 [inlined]
 [8] mapfoldl_impl at .\reduce.jl:44 [inlined]
 [9] #mapfoldl#204 at .\reduce.jl:160 [inlined]
 [10] #foldl#205 at .\reduce.jl:178 [inlined]
 [11] _warmup at C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\mcmc.jl:444 [inlined]
 [12] #mcmc_keep_warmup#38 at C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\mcmc.jl:520 [inlined]
 [13] macro expansion at C:\Users\claud\.julia\packages\UnPack\EkESO\src\UnPack.jl:100 [inlined]
 [14] #mcmc_with_warmup#39 at C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\mcmc.jl:578 [inlined]
 [15] dynamichmc_inference(::ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,Array{Float64,1},ODEFunction{true,typeof(SIRD!),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}, ::Tsit5, ::Array{Float64,1}, ::LinearAlgebra.Adjoint{Int64,Array{Int64,1}}, ::Array{Uniform{Float64},1}, ::TransformVariables.ArrayTransform{TransformVariables.ShiftedExp{true,Float64},1}; σ_priors::Array{InverseGamma{Float64},1}, sample_u0::Bool, rng::Random._GLOBAL_RNG, num_samples::Int64, AD_gradient_kind::Val{:ForwardDiff}, save_idxs::Array{Int64,1}, solve_kwargs::Tuple{}, mcmc_kwargs::NamedTuple{(:initialization,),Tuple{NamedTuple{(:q,),Tuple{Array{Float64,1}}}}}) at C:\Users\claud\.julia\packages\DiffEqBayes\DNrGu\src\dynamichmc_inference.jl:105
 [16] top-level scope at In[32]:1
 [17] include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1091

I don't understand why does DynamicHMC use negative starting point, when the trasformations and the priors require that they are positive.

Curiously, if I use DynamicHMC via Turing via DiffEqBayes, it properly works:

bayesian_result = @time turing_inference(problem, Tsit5(), t, data', variable_parameters_priors; 
                    likelihood_dist_priors = [InverseGamma(2, 3)], 
                    likelihood = (u,p,t,σ) -> MvNormal(u, σ[1]*ones(length(u))),
                    num_samples=1000, sampler = Turing.DynamicNUTS( ),
                    syms = [Turing.@varname(theta[i]) for i in 1:length(variable_parameters_priors)],
                    sample_u0 = false, save_idxs = [4*4+1], progress = false)
┌ Info: finding initial optimum
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:81
┌ Warning: Automatic dt set the starting dt as NaN, causing instability.
└ @ OrdinaryDiffEq C:\Users\claud\.julia\packages\OrdinaryDiffEq\OK16j\src\solve.jl:482
┌ Warning: NaN dt detected. Likely a NaN value in the state, parameters, or derivative value caused this outcome.
└ @ DiffEqBase C:\Users\claud\.julia\packages\DiffEqBase\BcprQ\src\integrator_interface.jl:322
┌ Warning: Automatic dt set the starting dt as NaN, causing instability.
└ @ OrdinaryDiffEq C:\Users\claud\.julia\packages\OrdinaryDiffEq\OK16j\src\solve.jl:482
┌ Warning: NaN dt detected. Likely a NaN value in the state, parameters, or derivative value caused this outcome.
└ @ DiffEqBase C:\Users\claud\.julia\packages\DiffEqBase\BcprQ\src\integrator_interface.jl:322
┌ Warning: Automatic dt set the starting dt as NaN, causing instability.
└ @ OrdinaryDiffEq C:\Users\claud\.julia\packages\OrdinaryDiffEq\OK16j\src\solve.jl:482
┌ Warning: NaN dt detected. Likely a NaN value in the state, parameters, or derivative value caused this outcome.
└ @ DiffEqBase C:\Users\claud\.julia\packages\DiffEqBase\BcprQ\src\integrator_interface.jl:322
┌ Warning: Automatic dt set the starting dt as NaN, causing instability.
└ @ OrdinaryDiffEq C:\Users\claud\.julia\packages\OrdinaryDiffEq\OK16j\src\solve.jl:482
┌ Warning: NaN dt detected. Likely a NaN value in the state, parameters, or derivative value caused this outcome.
└ @ DiffEqBase C:\Users\claud\.julia\packages\DiffEqBase\BcprQ\src\integrator_interface.jl:322
┌ Info: found initial stepsize
│   ϵ = 0.188
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:81
┌ Info: Starting MCMC
│   total_steps = 75
│   tuning = stepsize
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.0038
│   estimated_seconds_left = 0.28
│   ϵ = 0.188
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: Starting MCMC
│   total_steps = 25
│   tuning = stepsize and LinearAlgebra.Diagonal metric
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.013
│   estimated_seconds_left = 0.32
│   ϵ = 0.0185
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: adaptation finished
│   adapted_kinetic_energy = Gaussian kinetic energy (Diagonal), √diag(M⁻¹): [0.10260070201710987, 0.3571388924637585, 0.08644880409307552, 0.22561617504798276]
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:107
┌ Info: Starting MCMC
│   total_steps = 50
│   tuning = stepsize and LinearAlgebra.Diagonal metric
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.17
│   estimated_seconds_left = 8.5
│   ϵ = 0.0149
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: adaptation finished
│   adapted_kinetic_energy = Gaussian kinetic energy (Diagonal), √diag(M⁻¹): [0.10781336743515858, 1.3797565011999835, 0.09975860313638406, 0.17923365650618753]
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:107
┌ Info: Starting MCMC
│   total_steps = 100
│   tuning = stepsize and LinearAlgebra.Diagonal metric
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.027
│   estimated_seconds_left = 2.7
│   ϵ = 0.169
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: adaptation finished
│   adapted_kinetic_energy = Gaussian kinetic energy (Diagonal), √diag(M⁻¹): [0.09091724910691205, 1.1149705850457625, 0.07812076795706102, 0.14441581425602598]
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:107
┌ Info: Starting MCMC
│   total_steps = 200
│   tuning = stepsize and LinearAlgebra.Diagonal metric
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.0054
│   estimated_seconds_left = 1.1
│   ϵ = 0.14
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 101
│   seconds_per_step = 0.085
│   estimated_seconds_left = 8.4
│   ϵ = 0.209
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: adaptation finished
│   adapted_kinetic_energy = Gaussian kinetic energy (Diagonal), √diag(M⁻¹): [0.09459000674764693, 0.9130219147836826, 0.05878469020872842, 0.16351282352710864]
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:107
┌ Info: Starting MCMC
│   total_steps = 400
│   tuning = stepsize and LinearAlgebra.Diagonal metric
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.035
│   estimated_seconds_left = 14.0
│   ϵ = 0.221
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 101
│   seconds_per_step = 0.081
│   estimated_seconds_left = 24.0
│   ϵ = 0.329
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 201
│   seconds_per_step = 0.06
│   estimated_seconds_left = 12.0
│   ϵ = 0.301
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 301
│   seconds_per_step = 0.057
│   estimated_seconds_left = 5.6
│   ϵ = 0.284
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: adaptation finished
│   adapted_kinetic_energy = Gaussian kinetic energy (Diagonal), √diag(M⁻¹): [0.09846607900835572, 1.359824677788105, 0.06657162402149377, 0.19551892156767317]
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:107
┌ Info: Starting MCMC
│   total_steps = 50
│   tuning = stepsize
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.027
│   estimated_seconds_left = 1.3
│   ϵ = 0.261
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: Starting MCMC
│   total_steps = 1000
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:112
┌ Info: MCMC progress
│   step = 1
│   seconds_per_step = 0.025
│   estimated_seconds_left = 24.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 101
│   seconds_per_step = 0.081
│   estimated_seconds_left = 73.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 201
│   seconds_per_step = 0.077
│   estimated_seconds_left = 62.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 301
│   seconds_per_step = 0.086
│   estimated_seconds_left = 60.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 401
│   seconds_per_step = 0.077
│   estimated_seconds_left = 46.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 501
│   seconds_per_step = 0.081
│   estimated_seconds_left = 41.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 601
│   seconds_per_step = 0.077
│   estimated_seconds_left = 31.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 701
│   seconds_per_step = 0.083
│   estimated_seconds_left = 25.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 801
│   seconds_per_step = 0.086
│   estimated_seconds_left = 17.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
┌ Info: MCMC progress
│   step = 901
│   seconds_per_step = 0.08
│   estimated_seconds_left = 8.0
└ @ DynamicHMC C:\Users\claud\.julia\packages\DynamicHMC\n1LsS\src\reporting.jl:130
170.734104 seconds (1.21 G allocations: 68.304 GiB, 5.46% gc time)
Object of type Chains, with data of type 1000×5×1 Array{Float64,3}

Iterations        = 1:1000
Thinning interval = 1
Chains            = 1
Samples per chain = 1000
internals         = lp
parameters        = theta[1], theta[2], theta[3], σ[1]

2-element Array{ChainDataFrame,1}

Summary Statistics
  parameters     mean     std  naive_se    mcse       ess   r_hat
  ──────────  ───────  ──────  ────────  ──────  ────────  ──────
    theta[1]   0.5326  0.0213    0.0007  0.0009  379.0684  0.9990
    theta[2]   0.0103  0.0103    0.0003  0.0004  305.5189  0.9991
    theta[3]   0.0003  0.0000    0.0000  0.0000  259.6280  0.9991
        σ[1]  11.5355  2.0806    0.0658  0.0953  384.7776  0.9997

Quantiles
  parameters    2.5%    25.0%    50.0%    75.0%    97.5%
  ──────────  ──────  ───────  ───────  ───────  ───────
    theta[1]  0.4930   0.5182   0.5311   0.5473   0.5759
    theta[2]  0.0003   0.0030   0.0072   0.0138   0.0392
    theta[3]  0.0003   0.0003   0.0003   0.0003   0.0004
        σ[1]  8.1851  10.0855  11.2343  12.7214  16.4303

I'm interested in using the DynamicHMC interface since it seems to allow for parameter initialization.

Thanks in advance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions