Incorporating the ode within my neural network

Good morning everyone, I am working on using neural ode for household consumption prediction using Rc models. Once I have created my solution and array. How can I make sure to incorporate the ode within the neural network? I clarify that my goal is not to incorporate the solution but the PROBLEM ODE within my chain. in diffeqflux the chain is used and then the neural ode to minimize the difference from the solution of the ode then incorporating the physics only in the loss calculation. my goal now is to incorporate the physics directly within the chain, is this possible?

Yeah, it’s just a differentiable function. You can do anything you want with it. What did you try?

Hi chris, I haven’t solved the problem yet. I’m working on using Neural Ode to predict an RC model. Do you have documentation or code examples to suggest for adding physical losses to the total loss? can it be done for neural odes? another approach could be to use my problem ode within the chain but I don’t really know how to do it

using DifferentialEquations, Plots, Flux,Optim, DiffEqFlux, DataInterpolations,Random, ComponentArrays, Lux
using Optimization, OptimizationOptimisers, OptimizationOptimJL,OptimizationNLopt
rng = Random.default_rng()
using CSV
using DataFrames
using Plots
using Flux
using Statistics: mean
using DiffEqFlux, Optimization, OptimizationOptimJL,Plots
using ComponentArrays, Lux, DiffEqFlux, Optimization, OptimizationPolyalgorithms, DifferentialEquations, Plots
using DiffEqFlux: group_ranges
# Load the data
df ="/Users/marco/OneDrive/Desktop/Tesi/Julia_files/measured_data_ex_00.csv", DataFrame)
df=repeat(df, outer=10)

registered_gas_flow = df[:, :2]
Registered_Temperature = df[:, 3]
sec_Temp = [mean(Registered_Temperature[i:i+59]) for i in 1:60:length(Registered_Temperature)-59]
sec_gas = [mean(registered_gas_flow[i:i+59]) for i in 1:60:length(registered_gas_flow)-59]
#create a 3600 time vector
function RC!(du,u,p,t)
    Rv, Ci,Rv2,Ci2 = p
    Text = ext_Temp(t)
    P= ext_power(t)
    P2= ext_power2(t)
    du[1] = 1/(Rv*Ci) .* (Text .- u[1]) .+ P/Ci

u0= [20.0]

tspan= (0.0f0, 3000.0f0)
datasize = 3000
tsteps= range(tspan[1], tspan[2], length = datasize)
p= [10000, 10, 10000, 10]

Ext_temperature = LinearInterpolation(sec_Temp,tsteps);
power = LinearInterpolation(sec_gas,tsteps);
power2= LinearInterpolation(sec_gas,tsteps);
function ext_Temp(tsteps)
return Ext_temperature(tsteps)
function ext_power(tsteps)
return power(tsteps)

function ext_power2(tsteps)
return power2(tsteps)

prob= ODEProblem(RC!, u0, tspan, p)
sol= solve(prob, Tsit5(), saveat=tsteps)[1,:]

# Verify ODE solution
ode_data =Array(solve(prob, Tsit5(), saveat=tsteps))

plot(tsteps, ode_data[1,:], label = "data")

#resize ode data 

plot(tsteps, ode_data[1,:], label = "data")

tspan= (0.0f0, 50.0f0)
tsteps= range(tspan[1], tspan[2], length = 50)

plot(ode_data_test[1,:], label = "data")

anim = Plots.Animation()

# Define the Neural Network
nn = Lux.Chain(
                Lux.Dense(1, 84, tanh),
                Lux.Dense(84, 44, tanh),
p_init, st = Lux.setup(rng, nn)

neuralode = NeuralODE(nn, tspan, Tsit5(), saveat = tsteps)
prob_node = ODEProblem((u,p,t)->nn(u,p,st)[1], u0, tspan, ComponentArray(p_init))

function plot_multiple_shoot(plt, preds, group_size)
	step = group_size-1
	ranges = group_ranges(datasize, group_size)

	for (i, rg) in enumerate(ranges)
		plot!(plt, tsteps[rg], preds[i][1,:], markershape=:circle)

# Animate training, cannot make animation on CI server
# anim = Plots.Animation()
iter = 0
callback = function (p, l, preds; doplot = true)
  global iter
  iter += 1
  if doplot && iter%1 == 0
    # plot the original data
    plt = scatter(tsteps, ode_data_train[1,:], label = "Data")

    # plot the different predictions for individual shoot
    plot_multiple_shoot(plt, preds, group_size)

  return false

# Define parameters for Multiple Shooting
group_size = 4
continuity_term = 100

function loss_function(data, pred)
	return sum(abs2, data - pred)

function loss_multiple_shooting(p)
    return multiple_shoot(p, ode_data_train, tsteps, prob_node, loss_function, Tsit5(),
                          group_size; continuity_term)

adtype = Optimization.AutoZygote()
optf = Optimization.OptimizationFunction((x,p) -> loss_multiple_shooting(x), adtype)
optprob = Optimization.OptimizationProblem(optf, ComponentArray(p_init))
res_ms = Optimization.solve(optprob, PolyOpt(), callback = callback)

gif(anim, "multiple_shooting.gif", fps=15)

optimized_params= res_ms.u

u1 = Float32[ode_data_train[1,end]]
tspan1=(50.0f0, 100.0f0)
tsteps1=range(tspan1[1], tspan1[2], length = datasize)

prob_neuralode2 = NeuralODE(nn, tspan1, Tsit5(), saveat = tsteps1)

function predict_neuralode2(p)
  Array(prob_neuralode2(u1, p, st)[1])
tstepsfinal=range(0.0f0, 100.0f0, length = 100)

plot(tstepsfinal, ode_data[1,:], label = "data")
plot!(tsteps1,ode_data_test[1,:], label = "data to check prediction")
scatter!(tsteps1, prediction[1,:], label = "prediction to check prediction")