我试图建立一个神经网络,它将接受ODE系统的解,并预测系统的参数。我使用的是朱莉娅,特别是DiffEqFlux包。网络的结构是几个简单的Dense层,它们可以预测一些中间参数(在这种情况下,是一些化学反应自由能),然后输入一些确定性的(未经训练的)层,将这些参数转换成进入方程组的参数(在这种情况下,是反应速率常数)。我在这里尝试过两种不同的方法:
但是,在这两种情况下,我都不能让Flux.train!实际运行。
下面是第一个选项的一个愚蠢的小例子,它提供了与我所得到的错误相同的错误(我已经尝试让尽可能多的事情与我的实际情况并行,即求解器等等,尽管我确实省略了中间的确定性层,因为它们似乎并没有起到作用)如下。
using Flux, DiffEqFlux, DifferentialEquations
# let's use Chris' favorite example, Lotka-Volterra
function lotka_volterra(du,u,p,t)
x, y = u
α, β, δ, γ = p
du[1] = dx = α*x - β*x*y
du[2] = dy = -δ*y + γ*x*y
end
u0 = [1.0,1.0]
tspan = (0.0,10.0)
# generate a couple sets of solutions to train on
training_params = [[1.5,1.0,3.0,1.0], [1.4,1.1,3.1,0.9]]
training_sols = [solve(ODEProblem(lotka_volterra, u0, tspan, tp)).u[end] for tp in training_params]
model = Chain(Dense(2,3), Dense(3,4), p -> diffeq_adjoint(p, ODEProblem(lotka_volterra, u0, tspan, p), Rodas4())[:,end])
# in this case we just want outputs to match inputs
# (actual parameters we're after are outputs of next-to-last layer)
training_data = zip(training_sols, training_sols)
# mean squared error loss
loss(x,y) = Flux.mse(model(x), y)
p = Flux.params(model[1:2])
Flux.train!(loss, p, training_data, ADAM(0.001))
# gives TypeError: in typeassert, expected Float64, got ForwardDiff.Dual{Nothing, Float64, 8}我已经尝试了所有三个解决程序层,diffeq_adjoint、diffeq_rd和diffeq_fd,它们都不起作用,但都会产生不同的错误,我在解析过程中遇到了困难。
对于另一个选项(实际上我更喜欢这一选项,但这两种方法都可以工作),只需将模型和损失函数定义替换为:
model = Chain(Dense(2,3), Dense(3,4))
function loss(x,y)
p = model(x)
sol = diffeq_adjoint(p, ODEProblem(lotka_volterra, u0, tspan, p), Rodas4())[:,end]
Flux.mse(sol, y)
end引发的错误与上述相同。
我已经黑了一个多星期了,完全不知所措,有什么想法吗?
发布于 2019-10-16 23:56:35
您正在遇到https://github.com/JuliaDiffEq/DiffEqFlux.jl/issues/31,即Jacobian的前向模式AD现在对Flux.jl不太好。要解决这个问题,请使用Rodas4(autodiff=false)。
https://stackoverflow.com/questions/58420907
复制相似问题