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

能否在Turing模型中嵌入JuMP优化问题?报错求助

能否在Turing模型中使用JuMP优化问题?

你的问题核心是Turing的自动微分(ForwardDiff)与JuMP求解器的类型不兼容:Turing在采样时会将参数θ转换为ForwardDiff的Dual类型以计算梯度,但JuMP的Ipopt求解器只能处理标准Float64类型,导致类型转换错误。

下面提供两种可行的解决方案:


方案一:用解析解替代JuMP优化(最简单,适合你的示例)

你的优化问题是二次函数最大化,可直接推导解析解,完全避免调用JuMP:

using Turing

# 替换原find_u函数为解析解
function find_u(θ)
    # 最大化θ*u - u²的解析解:u = θ/2
    return θ / 2
end

@model function turing_model(y)
    σ = 1e-3
    θ ~ Uniform(0, 2)
    for i in 1:length(y)
        y[i] ~ Normal(find_u(θ), σ)
    end
end

# 模拟数据
θs = 1
y = [find_u(θs) + rand(Normal(0, 1e-3)) for _ in 1:10]

# 推理
numberofsamples = 500
m_train = turing_model(y);
posterior_chain = sample(m_train, NUTS(100, 0.65), numberofsamples)

这个方案完全规避了类型问题,运行不会报错,且效率更高。


方案二:兼容自动微分的JuMP优化(适用于复杂无法解析的问题)

如果你的实际问题无法用解析解表达,需要保留JuMP优化,可以通过以下方式让函数兼容ForwardDiff的Dual类型:

方法1:改用支持自动微分的优化器(如Optim.jl)

Optim.jl的求解器原生支持ForwardDiff的Dual类型,可替代JuMP+Ipopt:

using Turing
using Optim

function find_u(θ)
    # 将最大化问题转为最小化(Optim默认求最小)
    f(u) = -(θ * u - u^2)
    # 用L-BFGS求解带边界的优化问题
    res = optimize(f, 0.0, 10.0, LBFGS())
    return Optim.minimizer(res)
end

@model function turing_model(y)
    σ = 1e-3
    θ ~ Uniform(0, 2)
    for i in 1:length(y)
        y[i] ~ Normal(find_u(θ), σ)
    end
end

# 模拟数据与推理部分同方案一
θs = 1
y = [find_u(θs) + rand(Normal(0, 1e-3)) for _ in 1:10]

numberofsamples = 500
m_train = turing_model(y);
posterior_chain = sample(m_train, NUTS(100, 0.65), numberofsamples)

方法2:用ImplicitDifferentiation.jl实现隐式微分

对于必须使用JuMP的场景,可借助ImplicitDifferentiation.jl通过KKT条件隐式计算优化问题对参数θ的导数,无需让JuMP直接处理Dual类型:

using Turing
using JuMP
import Ipopt
using ImplicitDifferentiation

# 原JuMP优化函数
function find_u(θ)
    model = Model(optimizer_with_attributes(Ipopt.Optimizer))
    set_silent(model)
    @variables(model, begin
        0 <= u <= 10
    end)
    @NLobjective(model, Max, θ * u - u^2)
    optimize!(model)
    return value(u)
end

# 定义优化问题的KKT条件(用于隐式微分)
function kkt(θ, u)
    # 一阶最优条件:d/du(θu - u²) = 0 → θ - 2u = 0
    # 因θ∈(0,2)时u=θ/2∈(0,1),边界约束无绑定,互补松弛项为0
    return [θ - 2u]
end

# 创建支持自动微分的隐式函数
implicit_find_u = ImplicitFunction(find_u, kkt)

@model function turing_model(y)
    σ = 1e-3
    θ ~ Uniform(0, 2)
    for i in 1:length(y)
        y[i] ~ Normal(implicit_find_u(θ), σ)
    end
end

# 模拟数据与推理部分同方案一
θs = 1
y = [find_u(θs) + rand(Normal(0, 1e-3)) for _ in 1:10]

numberofsamples = 500
m_train = turing_model(y);
posterior_chain = sample(m_train, NUTS(100, 0.65), numberofsamples)

内容的提问来源于stack exchange,提问作者Marco Tulio Angulo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:17:54