-
-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DomainError: Starting point has non-finite density using DynamicHMC backend #195
Comments
I don't think I'll be getting to this any time soon, but maybe @tpapp would like to chime in if he has an idea. The initialization runs an MAP first so that could be something, but I don't see how that could get to such a bad starting point so I am pretty confused by this behavior as well. |
I will look into it. |
Do you have any update? I would be very interested to know. |
Apologies for the delay (I am working through a large backlog) and thanks for the ping. Conceptually, the variable_transformation = as(Vector, asℝ₊, length(variable_parameters_priors))
q0 = vcat(inverse(variable_transformation, 𝒫), fill(0.0, size(data', 1) ))
mcmc_kwargs = (initialization = (q = q0,),
warmup_stages = default_warmup_stages(; local_optimization = nothing))
bayesian_result_dynamic = dynamichmc_inference(problem, Tsit5(), t,data', variable_parameters_priors,
variable_transformation;
save_idxs = [4*4+1],
σ_priors = fill(InverseGamma(2, 3), size(data', 1)),
mcmc_kwargs = mcmc_kwargs) This skips the initial optimization, which fails. I imagine that this is happening because of a singularity that is far from the typical set, but breaks MAP. But this should be fine since we have an initial point. Let me know if I can help with anything else. |
Hello @tpapp , thanks for answering and sorry for replying so late.
I explain myself better in the following MWE ( partially taken from the first comment) that reproduces this behaviour. using DynamicHMC, Turing, DifferentialEquations, DiffEqBayes, RecursiveArrayTools, TransformVariables, Optim, DiffEqParamEstim, Plots
# 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
P = 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!,ℬ, 𝒯, P )
solution = solve(problem, Tsit5(), saveat = 1:20);
# build a faster problem
fast_problem = ODEProblem(modelingtoolkitize(problem),ℬ, 𝒯, P)
fast_solution = solve(problem, Tsit5(), saveat = 1:20);
# define priors
const variable_parameters_priors = [Uniform(0.0,1.0),Uniform(0.0,1.0),Uniform(0.0,1.0)]
# define transoformations
variable_transformation = as(Vector, asℝ₊, length(variable_parameters_priors))
# define initial values and kwargs
q0 = vcat(inverse(variable_transformation, P), fill(0.0, size(data', 1) ))
mcmc_kwargs = (initialization = (q = q0,),
warmup_stages = default_warmup_stages(; local_optimization = nothing))
# run DynamicHMC
bayesian_result_dynamic = dynamichmc_inference(fast_problem, Tsit5(), t,data', variable_parameters_priors,
variable_transformation;
save_idxs = [4*4+1],
σ_priors = fill(InverseGamma(2, 3), size(data', 1)),
mcmc_kwargs = mcmc_kwargs, num_samples = 100)
But if I then try to better initialize the parameters using Optim: # obtain optim-compatible data
const optim_data = convert(Array, VectorOfArray(data))
# define cost function
cost_function = build_loss_objective(fast_problem, Tsit5(), L2Loss(t, optim_data'), maxiters=1000000, verbose=true, save_idxs=[4*4+1])
# define bounds that mimic the priors above
const lower_bounds = [0.01, 0.01, 0.01]
const upper_bounds = [1.0, 1.0, 1.0]
# run optim
result_optim = Optim.optimize(cost_function, lower_bounds, upper_bounds, P, Optim.Fminbox(BFGS()))
# get the calibrated parameters
P_optim = result_optim.minimizer
# check that the parameters coming from optim correspond to a kind of good fit
calibrated_solution = solve(fast_problem, Tsit5(); saveat=t, u0=ℬ, p=P_optim)
total_predicted_deaths = [slice[end] for slice in calibrated_solution.u]
p = plot(calibrated_solution.t, total_predicted_deaths)
plot!(calibrated_solution.t, data,seriestype=:scatter)
p
# initilialize DynamicHMC with the parameters values coming from optim
q0 = vcat(inverse(variable_transformation, P_optim), fill(0.0, size(data', 1) ))
mcmc_kwargs = (initialization = (q = q0,),
warmup_stages = default_warmup_stages(; local_optimization = nothing))
I get: bayesian_result_dynamic = dynamichmc_inference(fast_problem, Tsit5(), t,data', variable_parameters_priors,
variable_transformation;
save_idxs = [4*4+1],
σ_priors = fill(InverseGamma(2, 3), size(data', 1)),
mcmc_kwargs = mcmc_kwargs, num_samples = 10000)
Increasing Thank you very much |
@ClaudMor: I am not an expert on this model family, but are you sure parameters near 1 actually make sense? For Also, a quick fix like q0 = vcat(inverse(variable_transformation, P_optim), fill(0.0, size(data', 1) )) .- 0.001 makes it work. Cf boundary values are problematic in the Stan manual. |
Incidentally, I recently removed local optimization from DynamicHMC.jl (tpapp/DynamicHMC.jl#146). It adds very little to well-behaved posteriors (the adaptation restarts multiple times anyway, so the starting point should not matter much), and often creates problems like this. |
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.
If I try to calibrate the three parameters using
dynamic_inference
, I get the following error: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:
I'm interested in using the DynamicHMC interface since it seems to allow for parameter initialization.
Thanks in advance
The text was updated successfully, but these errors were encountered: