Julia 如何训练神经ODE来预测朱莉娅的Lotka-Voltera时间序列?

Julia 如何训练神经ODE来预测朱莉娅的Lotka-Voltera时间序列?,julia,ode,differential-equations,julia-flux,Julia,Ode,Differential Equations,Julia Flux,我想将ODE与嵌入ODE中的神经网络解耦,ODE将从中生成时间序列数据,ODE将尝试学习数据的结构。换句话说,我想复制中提供的时间序列外推示例,但使用不同的底层函数,即我使用Lotka Voltera生成数据 我在Julia的工作流程如下(请注意,我对Julia还比较陌生,但我希望这一点很清楚): 然而,我可以观察到,我的神经网络学习不多,它停滞了,Euler和Tsit5的损失保持在155左右,RK4的表现更好一些(损失142) 如果有人指出我的实现中是否存在错误,或者这种行为是预期的,我将非常

我想将ODE与嵌入ODE中的神经网络解耦,ODE将从中生成时间序列数据,ODE将尝试学习数据的结构。换句话说,我想复制中提供的时间序列外推示例,但使用不同的底层函数,即我使用Lotka Voltera生成数据

我在Julia的工作流程如下(请注意,我对Julia还比较陌生,但我希望这一点很清楚):

然而,我可以观察到,我的神经网络学习不多,它停滞了,Euler和Tsit5的损失保持在155左右,RK4的表现更好一些(损失142)


如果有人指出我的实现中是否存在错误,或者这种行为是预期的,我将非常感激。

最大值=
的数量增加到300有助于实现更好的拟合,但是训练极不稳定。

将maxiters=的数量增加到300有助于获得更好的配合,但训练极不稳定。

这可能还不够大problem@Chris不过,请注意,在上面的设置中,我只选择时间序列的一个周期。。。我将进行更多的实验,但很高兴知道代码是可以的。这可能不是一个足够大的网络problem@Chris不过,请注意,在上面的设置中,我只选择时间序列的一个周期。。。我将进行更多的实验,但很高兴知道代码是好的。
train_size = 32
tspan_train = (0.0f0,4.00f0)

u0 = [1.0,1.0]
p = [1.5,1.0,3.0,1.0]

function lotka_volterra(du,u,p,t)
  x, y = u
  α, β, δ, γ = p
  du[1] = dx = α*x - β*x*y
  du[2] = dy = -δ*y + γ*x*y
end

t_train = range(tspan_train[1],tspan_train[2],length = train_size)

prob = ODEProblem(lotka_volterra, u0, tspan_train,p)
ode_data_train = Array(solve(prob, Tsit5(),saveat=t_train))

function create_neural_ode(solver, tspan, t_saveat)
    dudt = Chain(
            Dense(2,50,tanh),
            Dense(50,2))
    ps = Flux.params(dudt)   
    n_ode = NeuralODE(dudt, tspan, solver, saveat = t_saveat, reltol=1e-7, abstol=1e-9)           
    n_ode
end

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

n_ode = create_neural_ode(Tsit5(), tspan_train, t_train)

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

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

# Plot and save training results 
x = 1:100
plot_to_save = plot(x,losses,title=solver_name,label="loss")
plot(x,losses,title=solver_name, label="loss")
xlabel!("Epochs")