Problems on Flux.destructure()


As the figure shown above, I build a LSTM using the code "Chain(LSTM(1,1),LSTM(1,1)) "
Then I want to build the network with specific parameters p.
code re(p) but it failed and showed above.
How to deal with this issue?

My guess would be that p4 has element type Any?

So to deal with it try to make sure that p4 has the element type you want (probably Float32).

How to convert from Any to Float32?
I try to use convert but it showed below:

Hi @Louis612 ,

could you maybe provide a minimum example, so we can reproduce the error?
That is, in addition to the model (Chain(LSTM(1,1),LSTM(1,1))), how you use destructure and what kind of object you feed into re().

Please use triple backticks ``` to create copy-pasteable code blocks. Don’t just post screenshots. This makes it easier to help you.

convert(Vector{Float32}, b)

The best would probably be to not convert, but to use the proper array from the start. Using an array with Any type can be very inefficient.

To make sure you have the correct type from the start you can do something like

p4 = Float32[...]

when initially creating the vector, but if you prefer converting you can either use convert as suggested above or what I find easier is to use broadcasting Float32.(p4).

At first ,the vector’s type is Float64. But when I run the code, it becomes Any, which is very puzzling

(you can edit your post)
Please read through the suggestions here: Please read: make it easier to help you

It is hard to search through what is relevant if you just dump all your code like that.
Please

  • properly format your code
  • try to provide only as much as is relevant to the problem/error you observe.

Boiling down the problem to what is relevant will make it easiser to help you (and in the process you might even figure it out yourself)

It might be something with how differentialequations treat parameters? Try doing ODEProblem(QSIR, u0, tspan, (p3,)) and then do p3 = p[1] in QSIR function to see if that keeps the type?

using Plots
using Measures
using Flux
using DifferentialEquations
using DiffEqFlux
using LaTeXStrings
#导入数据
vars = matread("/Users/louislee/Desktop/北卡科研/COVID-19-ML-Quarantine-Control-Model-master/Hubei_Track.mat")
Infected = vars["Hubei_Infected_All"]
Recovered = vars["Hubei_Recovered_All"]
Dead = vars["Hubei_Dead_All"]
Time = vars["Hubei_Time"]
#构建网络
n=2
rnn = Chain(LSTM(4,n),LSTM(n,n),LSTM(n,1))
p1,re = Flux.destructure(rnn)
p2 = Float64[0.02, 0.01]
p3 = [p1; p2]
ps = Flux.params(p3)
m=size(p1)[1]
p3
#解方程
function QSIR(du, u, p, t)
    β = abs(p[m+1])
    γ = abs(p[m+2])
    du[1]=  - β*u[1]*(u[2])/u0[1]
    du[2] = β*u[1]*(u[2])/u0[1] - γ*u[2] - abs(re(p[1:m])(u)[1])*u[2]/u0[1]
    du[3] = γ*u[2]
    du[4] =  + abs(re(p[1:m])(u)[1])*u[2]/u0[1]
end


u0 = Float64[11000000.0, 500 ,10, 10]
tspan = (0, 39.0)
datasize = 39;

prob = ODEProblem(QSIR, u0, tspan, p3)
t = range(tspan[1],tspan[2],length=datasize)

sol = Array(concrete_solve(prob, Rosenbrock23(autodiff = false),u0, p3, saveat=t))
function predict_adjoint() # Our 1-layer neural network
  Array(concrete_solve(prob,Rosenbrock23(autodiff = false),u0,p3,saveat=t))
end

I = Infected[1, :];
R = Recovered[1,:];
D = Dead[1, :];
#误差函数
function loss_adjoint()
 prediction = predict_adjoint()
 loss = sum(abs2, log.(abs.(I[1:39])) .- log.(abs.(prediction[2, :]))) + sum(abs2, log.(abs.(R[1:39] + D[1:39]) .+ 1) .- log.(abs.(prediction[3, :] .+ 1)))
end


Loss = []
P1 = []
P2 = []
P3 = []

using DiffEqFlux
datan = Iterators.repeated((), 1000)
opt = ADAM(1)
cb = function()
  global Loss = append!(Loss, loss_adjoint())
  global P1 = append!(P1, p3[m+1])
  global P2 = append!(P2, p3[m+2])
  global P3 = append!(P3, p3)
end
function predict_adjoint() # Our 1-layer neural network
  Array(concrete_solve(prob,Rosenbrock23(autodiff = false),u0,p3,saveat=t))
end

I = Infected[1, :];
R = Recovered[1,:];
D = Dead[1, :];
#误差函数
function loss_adjoint()
 prediction = predict_adjoint()
 loss = sum(abs2, log.(abs.(I[1:39])) .- log.(abs.(prediction[2, :]))) + sum(abs2, log.(abs.(R[1:39] + D[1:39]) .+ 1) .- log.(abs.(prediction[3, :] .+ 1)))
end


Loss = []
P1 = []
P2 = []
P3 = []

using DiffEqFlux
datan = Iterators.repeated((), 1000)
opt = ADAM(1)
cb = function()
  global Loss = append!(Loss, loss_adjoint())
  global P1 = append!(P1, p3[m+1])
  global P2 = append!(P2, p3[m+2])
  global P3 = append!(P3, p3)
end
Flux.train!(loss_adjoint, ps, datan, opt, cb = cb)
#找误差最小值
L = findmin(Loss)
idx = L[2]
idx1 = (idx-1)*(m+2) +1
idx2 = idx*(m+2)
global p3 = P3[idx1: idx2]
prediction=  Array(concrete_solve(prob,Rosenbrock23(autodiff = false),u0,p3,saveat=t))
S_NN_all_loss = prediction[1, :]
I_NN_all_loss = prediction[2, :]
R_NN_all_loss = prediction[3, :]
T_NN_all_loss = prediction[4, :]
#Q(t)
Q_parameter = zeros(Float64, length(S_NN_all_loss), 1)

for i = 1:length(S_NN_all_loss)
  Q_parameter[i] = abs(re(p3[1:m])([S_NN_all_loss[i],I_NN_all_loss[i], R_NN_all_loss[i], T_NN_all_loss[i]])[1])
end

But the solve of ODEs remains Float64 which is the same as p3 at first

sry, I’m new here.lol

This creates an array of type Any:

julia> typeof(P3)
Vector{Any} (alias for Array{Any, 1})

Do this instead:

P3 = Float32[]

Hope that solves your problem.

But again

please read these suggestions carefully, they’re worth it. No need to rush it through. Take your time to formulate a question/response :slight_smile:

The code can run completely if I use ANN( Chain(Dense(,),Dense(,))

OK, thank you very much for your help. I’ll try it.