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 = [10]), repeat([300.0]; outer = [10]))
# single device paramters
p = [device.Cth[1], device.Rth[1]]
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[1], tspan[2], length = 500),
sensealg = QuadratureAdjoint(),
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[1]]
@show gs[ps[2]]
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[1]] = nothing
gs[ps[2]] = nothing
I’d be grateful of any insights into it.