我如何在Julia中访问神经ODE的训练参数?

我如何在Julia中访问神经ODE的训练参数?,julia,ode,differential-equations,julia-flux,Julia,Ode,Differential Equations,Julia Flux,我在试着用朱莉娅的DifferenceQflux把一首神经颂歌和一个时间序列结合起来。这是我的代码: u0 = Float32[2.;0] train_size = 15 tspan_train = (0.0f0,0.75f0) function trueODEfunc(du,u,p,t) true_A = [-0.1 2.0; -2.0 -0.1] du .= ((u.^3)'true_A)' end t_train = range(tspan_train[1],tspan

我在试着用朱莉娅的DifferenceQflux把一首神经颂歌和一个时间序列结合起来。这是我的代码:

u0 = Float32[2.;0]
train_size = 15
tspan_train = (0.0f0,0.75f0)

function trueODEfunc(du,u,p,t)
    true_A = [-0.1 2.0; -2.0 -0.1]
    du .= ((u.^3)'true_A)'
end

t_train = range(tspan_train[1],tspan_train[2],length = train_size)
prob = ODEProblem(trueODEfunc, u0, tspan_train)
ode_data_train = Array(solve(prob, Tsit5(),saveat=t_train))

dudt = Chain(
            Dense(2,50,tanh),
            Dense(50,2))
ps = Flux.params(dudt)
n_ode = NeuralODE(dudt, tspan_train, Tsit5(), saveat = t_train, reltol=1e-7, abstol=1e-9)

**n_ode.p**

function predict_n_ode(p)
    n_ode(u0,p)
end
function loss_n_ode(p)
    pred = predict_n_ode(p)
    loss = sum(abs2, ode_data_train .- pred)
    loss,pred
end

final_p = []
losses = []
cb = function(p,l,pred)
    display(l)
    display(p)
    push!(final_p, p)
    push!(losses,l)
    pl = scatter(t_train, ode_data_train[1,:],label="data")
    scatter!(pl,t_train,pred[1,:],label="prediction")
    display(plot(pl))
end

DiffEqFlux.sciml_train!(loss_n_ode, n_ode.p, ADAM(0.05), cb = cb, maxiters = 100)

**n_ode.p**
问题是在train函数前后调用n_ode.p或Flux.paramsdudt会返回保存值。我希望从培训中获得最新的更新值。这就是为什么我创建了一个数组来收集训练期间的所有参数值,然后访问它以获取更新的参数

我是不是在代码中做错了什么?列车功能是否自动更新参数?如果没有,如何执行


提前谢谢

结果是一个拥有最佳参数的对象。下面是一个完整的示例:

using DiffEqFlux, OrdinaryDiffEq, Flux, Optim, Plots

u0 = Float32[2.; 0.]
datasize = 30
tspan = (0.0f0,1.5f0)

function trueODEfunc(du,u,p,t)
    true_A = [-0.1 2.0; -2.0 -0.1]
    du .= ((u.^3)'true_A)'
end
t = range(tspan[1],tspan[2],length=datasize)
prob = ODEProblem(trueODEfunc,u0,tspan)
ode_data = Array(solve(prob,Tsit5(),saveat=t))

dudt2 = FastChain((x,p) -> x.^3,
            FastDense(2,50,tanh),
            FastDense(50,2))
n_ode = NeuralODE(dudt2,tspan,Tsit5(),saveat=t)

function predict_n_ode(p)
  n_ode(u0,p)
end

function loss_n_ode(p)
    pred = predict_n_ode(p)
    loss = sum(abs2,ode_data .- pred)
    loss,pred
end

loss_n_ode(n_ode.p) # n_ode.p stores the initial parameters of the neural ODE

cb = function (p,l,pred;doplot=false) #callback function to observe training
  display(l)
  # plot current prediction against data
  if doplot
    pl = scatter(t,ode_data[1,:],label="data")
    scatter!(pl,t,pred[1,:],label="prediction")
    display(plot(pl))
  end
  return false
end

# Display the ODE with the initial parameter values.
cb(n_ode.p,loss_n_ode(n_ode.p)...)

res1 = DiffEqFlux.sciml_train(loss_n_ode, n_ode.p, ADAM(0.05), cb = cb, maxiters = 300)
cb(res1.minimizer,loss_n_ode(res1.minimizer)...;doplot=true)
res2 = DiffEqFlux.sciml_train(loss_n_ode, res1.minimizer, LBFGS(), cb = cb)
cb(res2.minimizer,loss_n_ode(res2.minimizer)...;doplot=true)

# result is res2 as an Optim.jl object
# res2.minimizer are the best parameters
# res2.minimum is the best loss

最后,sciml_train函数返回一个result对象,该对象保存有关优化的信息,包括作为.minimizer的最终参数。

感谢您的澄清!还有一个小问题-在网络的定义中,我不明白为什么我们需要先用x,p->x转换输入。^3。我认为网络不应该有任何关于原始颂歌的知识?这个例子的目的是展示当你利用你对原始颂歌的任何知识时,事情会做得更好。我们最近的预印本将这一想法进一步推广。就我个人而言,我认为这是使用ODE形式的主要原因。顺便说一句,我注意到.minimizer确实给出了最后的参数,但不是最好的参数,即不是达到最小损失的参数。它与Optim优化器一起提供,但与Flux优化器不同。我们可以手动解决这个问题。请打开issueIssue以跟踪此问题: