# The tracked parameters are not updated during Flux.training

I’m building an oscillator defined by ODE. The purpose is to use Flux training to optimize parameters in ODE, i.e. the R and C value of the oscillator, given loss function.

``````using Flux, DifferentialEquations, DiffEqSensitivity

# encapsule all parameters in VO struct
struct VO
Cth::Any
Rth::Any
end

Flux.@functor VO
Flux.trainable(device::VO) = (device.Rth, device.Cth)

# VO constructor
VO() = VO([1.63e-13], [4.0e5])

# 2nd order function of VO
function (device::VO)(Input_time_series)
tspan = (0.0, 1e-5)
u0 = vcat(repeat([1.0]; outer = ), repeat([300.0]; outer = ))
# single device paramters
p = [device.Cth, device.Rth]

function VO_system!(du, u, p, t)
Cth, Rth = p
V = u[1:10]
T = u[11:end]
du[1:10] = -V
@. du[11:end] = 1 / Cth * (V - T / Rth)
end

sol = concrete_solve(
ODEProblem(VO_system!, u0, tspan, p),
Tsit5();
u0 = u0,
p = p,
saveat = range(tspan, tspan, length = 500),
jac = true,
abstol = 1e-5,
reltol = 1e-5,
)

return sol
end

###############################################Training#########################

device = VO()

model = device

ps = params(model)

loss(x, y) = Flux.mse(model(x), y)

println("Tracked Parameters: ", ps)

gs = Flux.gradient(() -> loss(0, 0), ps)
@show gs[ps]
@show gs[ps]

``````

The problem I met is that, during training, while `Flux.params(model)` confirms that the parameters are already being tracked, these tracked parameters are not updated. I tested the gradient by `gs=Flux.gradient()` , and it returns nothing.
The output is like below:

Tracked Parameters: Params([[400000.0], [1.63e-13]])
gs[ps] = nothing
gs[ps] = nothing

I’d be grateful of any insights into it.

Hey,
Sorry it took a bit to get to this. The issue was that you were mixing an old deprecated syntax with a new one. What you wanted was:

``````    sol = solve(
ODEProblem(VO_system!, u0, tspan, p),
Tsit5();
u0 = u0,
p = p,
saveat = range(tspan, tspan, length = 500),
abstol = 1e-10,
reltol = 1e-10,
)
``````

i.e. use `solve` and keyword arguments for `u0` and `p`. A full example that double checks the values of the gradients with ForwardDiff is:

``````using Flux, OrdinaryDiffEq, DiffEqSensitivity

# encapsule all parameters in VO struct
struct VO
Cth::Any
Rth::Any
end

Flux.@functor VO
Flux.trainable(device::VO) = (device.Rth, device.Cth)

# VO constructor
VO() = VO([1.63e-13], [4.0e5])

# 2nd order function of VO
function (device::VO)(Input_time_series,p = [device.Cth, device.Rth])
tspan = (0.0, 1e-5)
u0 = vcat(repeat([1.0]; outer = ), repeat([300.0]; outer = ))
# single device paramters

function VO_system!(du, u, p, t)
Cth, Rth = p
V = u[1:10]
T = u[11:end]
du[1:10] = -V
@. du[11:end] = 1 / Cth * (V - T / Rth)
end

sol = solve(
ODEProblem(VO_system!, u0, tspan, p),
Tsit5();
u0 = u0,
p = p,
saveat = range(tspan, tspan, length = 500),
abstol = 1e-10,
reltol = 1e-10,
)

return sol
end

###############################################Training#########################

device = VO()
model = device
ps = Flux.params(model)
loss(x, y) = Flux.mse(model(x),y)

println("Tracked Parameters: ", ps)

gs = Flux.gradient(() -> loss(0, 0), ps)
@show gs[ps]
@show gs[ps]

using ForwardDiff
``````Tracked Parameters: Params([[400000.0], [1.63e-13]])