You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Turing.jl执行MCMC时遭遇MethodError错误求助

问题

参考Turing.jl的贝叶斯ODE示例构建ice系统ODE模型进行贝叶斯推理,代码如下:

ODE系统定义

function ice(du, u, p, t)
    εₘ, εₖ, σ, F, d, ε = u
    Aₘ, Qₘ, n, pₘ, R, T, Eₖ, Eₘ, η, dₛₛ, Fₛₛ, ε₁, ε₂, S  = p
    
    du[1] = Aₘ * (σ/F)^n * d^(-pₘ) * ℯ^(-Qₘ/(R*T))
    du[2] = (σ - Eₖ*εₖ)/η
    du[3] = Eₘ*(S - ((σ - Eₖ*εₖ)/η) - (Aₘ * (σ/F)^n * d^(-pₘ) * ℯ^(-Qₘ/(R*T))))
    du[4] = S*(Fₛₛ - F)/ε₁
    du[5] = S*(dₛₛ - d)/ε₂
    du[6] = S
end

参数、初始条件与数据生成

p = [0.7, 70.0, 3.5, 0.35, 8.315, 265.0, 4.0e9, 9.0e9, 1.0e11, 0.00025, 0.6, 1.0, 1.0, 1.0e-6];
u_0 = [0.0, 0.0, 0.0, 1.0, 0.001, 0.0];
tspan = (0,1000);
prob = ODEProblem(ice, u_0, tspan , p)

# 生成带噪声的观测数据
sol = solve(prob, Rosenbrock23(); saveat=0.15);
p1 = Array(sol[3,:]) + 0.8 * randn(size(Array(sol[3,:])));
p2 = Array(sol[6,:]) + 0.8 * randn(size(Array(sol[6,:])));
odedata = [reduce(hcat, p1); reduce(hcat, p2)];

贝叶斯模型定义

@model function fit_ice(data::AbstractMatrix, prob)
    # Prior distributions
    σₑᵣ ~ InverseGamma(2, 3)
    Aₘ ~ Uniform(0.0,10)
    Qₘ ~ Uniform(10,1e4)
    n ~ Uniform(0.5,5.0)
    pₘ ~ Uniform(0.0,1.0)
    Eₖ ~ Uniform(1e9,9e9)
    Eₘ ~ Uniform(1e9,9e9)
    η ~ Uniform(1e9,1e12)
    dₛₛ ~ Uniform(1e-5,1e-3)
    Fₛₛ ~ Uniform(0.0,1.0)
    ε₁ ~ Uniform(0.01,1.0)
    ε₂ ~ Uniform(0.01,1.0)
    S = 1e-4
    R = 8.3145
    T = 263

    # Simulate the model but save only σ and ε
    p = [Aₘ, Qₘ, n, pₘ, R, T, Eₖ, Eₘ, η, dₛₛ, Fₛₛ, ε₁, ε₂, S]
    predicted = solve(prob, Rosenbrock23(); p=p, saveat=0.15, save_idxs=[3,6])

    # Observations
     for i in 1:length(predicted)
        data[:, i] ~ MvNormal(predicted[i], σₑᵣ^2 * I)
    end

    return nothing
end
model2 = fit_ice(odedata, prob)

执行MCMC采样时:

chain2 = sample(model2, NUTS(0.45), MCMCSerial(), 50, 2; progress=true)

出现错误:

MethodError: ^(::Irrational{:ℯ}, ::ForwardDiff.Dual{ForwardDiff.Tag{Turing.TuringTag, Float64}, Float64, 12}) is ambiguous.

推测问题出在ODE系统的指数项,但数值积分器能正常求解该系统,寻求修复方法。


解决方案

问题根源是**ℯ作为无理数类型,与ForwardDiff的Dual类型进行幂运算时存在方法歧义**,数值积分时用的是普通浮点数,因此不会触发错误。修复方法如下:

将ODE定义中所有的ℯ^x替换为exp(x)——exp()是Julia专门的指数函数,对自动微分的Dual类型有完善的支持,可消除方法歧义。

修改后的ODE系统代码:

function ice(du, u, p, t)
    εₘ, εₖ, σ, F, d, ε = u
    Aₘ, Qₘ, n, pₘ, R, T, Eₖ, Eₘ, η, dₛₛ, Fₛₛ, ε₁, ε₂, S  = p
    
    # 替换ℯ^为exp(),提取公共计算项减少重复
    exp_term = exp(-Qₘ/(R*T))
    du[1] = Aₘ * (σ/F)^n * d^(-pₘ) * exp_term
    du[2] = (σ - Eₖ*εₖ)/η
    du[3] = Eₘ*(S - ((σ - Eₖ*εₖ)/η) - (Aₘ * (σ/F)^n * d^(-pₘ) * exp_term))
    du[4] = S*(Fₛₛ - F)/ε₁
    du[5] = S*(dₛₛ - d)/ε₂
    du[6] = S
end

修改后重新运行整个流程(重新定义prob、生成数据、构建模型、采样),即可解决该方法歧义错误。


内容的提问来源于stack exchange,提问作者ValientProcess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:24:54