Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

A neural ODE is an ODE where a neural network defines its derivative function. u˙=NN(u)\dot{u} = NN(u)

From: https://docs.sciml.ai/DiffEqFlux/stable/examples/neural_ode/

Random.Xoshiro(0xdb2fa90498613fdf, 0x48d73dc42d195740, 0x8c49bc52dc8a77ea, 0x1911b814c02405e8, 0x22a21880af5dc689)

True solution: u3u^3 and multiplied by a matrix

trueODEfunc (generic function with 1 method)

Generate data from the true function

2×31 Matrix{Float64}: 2.0 1.94945 1.76453 1.29976 0.666819 … 1.40552 1.36871 1.29216 0.0 0.773425 1.42861 1.79063 1.8658 0.471329 0.738451 0.97313

Define a NeuralODE problem with a neural network from Lux.jl.

NeuralODE( model = Chain( layer_1 = WrappedFunction(#2), layer_2 = Dense(2 => 50, tanh), # 150 parameters layer_3 = Dense(50 => 2), # 102 parameters ), ) # Total: 252 parameters, # plus 0 states.

Predicted output

predict_neuralode (generic function with 1 method)

Loss function Optimization.jl v4 only accept a scalar output

loss_neuralode (generic function with 1 method)

Callback function

#6 (generic function with 1 method)

Try the callback function to see if it works.

119.82857445391798
false

Use https://github.com/SciML/Optimization.jl to solve the problem and https://github.com/FluxML/Zygote.jl for automatic differentiation (AD).

ADTypes.AutoZygote()

Define a function to optimize with AD.

SciMLBase.OptimizationFunction{true, ADTypes.AutoZygote, Main.var"##142".var"#9#10", Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}(Main.var"##142".var"#9#10"(), ADTypes.AutoZygote(), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, SciMLBase.DEFAULT_OBSERVED_NO_TIME, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing)

Define an OptimizationProblem

OptimizationProblem. In-place: true u0: ComponentVector{Float64}(layer_1 = Float64[], layer_2 = (weight = [-1.8019577264785767 1.509717345237732; -0.18273845314979553 -0.46764108538627625; … ; 0.37099915742874146 -0.27108314633369446; -0.34856587648391724 -0.6062840819358826], bias = [-0.5224840044975281, -0.6805992722511292, -0.21060703694820404, 0.5093754529953003, 0.336392879486084, 0.22010256350040436, -0.12450861930847168, 0.38843590021133423, 0.5799375176429749, 0.3984285593032837 … 0.10401319712400436, 0.009969078004360199, -0.460673987865448, 0.210310161113739, 0.5280858278274536, 0.7054404020309448, 0.0009628869011066854, 0.4056747257709503, 0.30830612778663635, 0.17590543627738953]), layer_3 = (weight = [0.22905384004116058 -0.23547108471393585 … 0.0332123264670372 0.13550478219985962; 0.22466984391212463 -0.148941770195961 … -0.1966829150915146 0.10960526019334793], bias = [-0.02694704197347164, -0.03700210154056549]))

Solve the OptimizationProblem using the ADAM optimizer first to get a rough estimate.

Loss is: 0.07475743652666186

Use another optimizer (BFGS) to refine the solution.

Loss is: 0.07475743652666186

Visualize the fitting process

[ Info: Saved animation to /tmp/jl_IpMzgZCJqD.mp4
Loading...
Plot{Plots.GRBackend() n=2}

This notebook was generated using Literate.jl.