New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ZDM / GB heterogeneous input #374
ZDM / GB heterogeneous input #374
Conversation
I am now running into problems with the way I define the cord (we changed it to call it input_cord). We define it like this Will take a break and look at it later. Hopefully with fresh eyes. |
@KirillZubov as requested, an MWE for input_cord
|
It does not need to θ = gensym("θ")
interior_u_args = [:y, :x]
julia> input_cord = :(adapt((DiffEqBase.parameterless_type($θ)), vcat($(interior_u_args...))))
:(adapt(DiffEqBase.parameterless_type(var"##θ#347"), vcat(y, x))) julia> input_cord = :(vcat($(interior_u_args...)))
:(vcat(y, x)) also, I think I suggest this way: ex.args = if !(typeof(chain) <: AbstractVector)
[:($(Expr(:$, :u))), Symbol(:cord,num_depvar), :($θ), :phi]
else
[:($(Expr(:$, :u))), Symbol(:cord,num_depvar), Symbol(:($θ), num_depvar), Symbol(:phi, num_depvar)]
end so inner representation will look like this: (Expr[:((cord, var"##θ#338", phi, derivative, u, p)->begin
begin
(var"##θ#3381", var"##θ#3382") = (var"##θ#338"[1:61], var"##θ#338"[62:122])
(phi1, phi2,phi3, phi4) = (phi[1], phi[2], phi[3], phi[4])
let (x, y) = (cord[[1], :], cord[[2], :])
cord1 = vcat(x)
cord2 = vcat(y)
cord3 = vcat(x, y)
cord4 = vcat(y, x)
expression_of_equation(phi1(cord1,...), phi2(cord2,...), ... derivative(phi1, u, cord1,...))
end
end
end, ...
it's already done something similar for Quadrature NeuralPDE.jl/src/pinns_pde_solve.jl Line 455 in 5a881ff
and sym_prob output of this example NeuralPDE.jl/test/NNPDE_tests.jl Lines 223 to 257 in 5a881ff
|
in general, it is no longer necessary to store a cord in one multidimensional array, it is outdated. cord = rand(2,10)
(x, y) = (cord[[1], :],cord[[2], :])
julia> @benchmark (x, y) = (cord[[1], :],cord[[2], :])
BenchmarkTools.Trial: 10000 samples with 178 evaluations.
Range (min … max): 591.865 ns … 165.837 μs ┊ GC (min … max): 0.00% … 99.26%
Time (median): 626.309 ns ┊ GC (median): 0.00%
Time (mean ± σ): 795.487 ns ± 3.504 μs ┊ GC (mean ± σ): 9.79% ± 2.22%
cord = [rand(1,10),rand(1,10)]
@benchmark (x, y) = (cord[1],cord[2])
BenchmarkTools.Trial: 10000 samples with 973 evaluations.
Range (min … max): 72.491 ns … 29.747 μs ┊ GC (min … max): 0.00% … 99.58%
Time (median): 77.020 ns ┊ GC (median): 0.00%
Time (mean ± σ): 89.026 ns ± 297.478 ns ┊ GC (mean ± σ): 3.33% ± 1.00% |
Thanks! This explains a lot and cleans up a lot of the code. I have a question: in
I need to know which dependent variables are being used in each equation. How do you recommend I do that inside of build_symbolic_loss_function? I tried using |
draft function pair(eq, depvars,dict_depvars, dict_depvar_input)
expr = toexpr(eq)
pair_ = map(depvars) do depvar
if !isempty(find_thing_in_expr(expr, depvar))
dict_depvars[depvar] => dict_depvar_input[depvar]
end
end
Dict(filter(p -> p !==nothing , pair_))
end
julia> eq_pair = pair(eq, depvars,dict_depvars, dict_depvar_input)
Dict{Int64, Vector{Symbol}} with 4 entries:
4 => [:y, :x]
2 => [:y]
3 => [:x, :y]
1 => [:x]
julia> bcs_pair = map(bc ->pair(bc, depvars,dict_depvars, dict_depvar_input),bcs)
6-element Vector{Dict{Int64, Vector{Symbol}}}:
Dict(1 => [:x])
Dict(2 => [:y])
Dict(3 => [:x, :y])
Dict(3 => [:x, :y])
Dict(4 => [:y, :x])
Dict(4 => [:y, :x])
some_eq = Dx(p(x, y)) + Dy(s(y, x)) - Dy(s(0, x)) ~ p(0,0)
julia> some_eq_pair =pair(some_eq, depvars,dict_depvars, dict_depvar_input)
Dict{Int64, Vector{Symbol}} with 2 entries:
4 => [:y, :x]
1 => [:x]
|
eq_pair_expr =Expr[]
for i in keys(some_eq_pair)
push!(eq_pair_expr, :( $(Symbol(:cord, :($i))) = vcat($(some_eq_pair[i]...))))
end
julia> eq_pair_expr
2-element Vector{Expr}:
:(cord4 = vcat(y, x))
:(cord1 = vcat(x)) |
…Heterogeneous systems still throw a dimension mismatch
Thanks! I now have restructured build_symbolic_loss so it outputs this for a heterogeneous system
And for a normal system
The normal systems and tests are working now which is good. But the heterogeneous system is still throwing out an I think this might have something to do with EDIT: I had a typo. Both systems are working now! 😄 |
Ok so here is the current to do list before opening the PR:
I plan to open the PR tomorrow. |
@KirillZubov this is ready for a code review. Are there any good examples of heterogeneous systems we could use for the tests and the documentation? |
…b-zm-heterogeneous-input
An update: I cleaned up the white spaces. There are only 2 problems remaining now: Problem 1: I am getting a (Expr[:((cord, var"##θ#332", phi, derivative, integral, u, p)->begin
begin
let (x, y) = (cord[[1], :], cord[[2], :])
begin
cord1 = vcat(x, y)
end
u(cord1, var"##θ#332", phi) .- (*).(-1, (cos).(x), (cos).(y), (exp).((+).((*).(-1, (^).((+).(-3.141592653589793, x), 2)), (*).(-1, (^).((+).(-3.141592653589793, y), 2)))))
end
end
end)], Expr[:((cord, var"##θ#332", phi, derivative, integral, u, p)->begin
begin
let (x, y) = (cord[[1], :], cord[[2], :])
begin
cord1 = vcat(x, y)
end
u(cord1, var"##θ#332", phi) .- u(cord1, var"##θ#332", phi)
end
end
end)]) Problem 2: The way we discretize a Integro-DE is very different. From what I gathered from looking at # if eqs = nothing, this_eq_pair can't get the information it needs.
this_eq_pair = pair(eqs, depvars, dict_depvars, dict_depvar_input)
this_eq_indvars = sort(collect(Set(vcat(values(this_eq_pair)...))))
...
eq_pair_expr = Expr[]
for i in keys(this_eq_pair)
push!(eq_pair_expr, :( $(Symbol(:cord, :($i))) = vcat($(this_eq_pair[i]...))))
end
vcat_expr = Expr(:block, :($(eq_pair_expr...)))
vcat_expr_loss_functions = Expr(:block, vcat_expr, loss_function)
... (Expr[:((cord, var"##θ#331", phi, derivative, integral, u, p)->begin
begin
let (x,) = (cord[[1], :],)
integral(u, cord, phi, [1], RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:cord, Symbol("##θ#331"), :phi, :derivative, :integral, :u, :p), NeuralPDE.var"#_RGF_ModTag", NeuralPDE.var"#_RGF_ModTag", (0x1a7e437d, 0x633f4d2b, 0x0c12a9a0, 0xdba3679e, 0x4f5c1eae)}(quote
begin
let (x,) = (cord[[1], :],)
u(cord, var"##θ#331", phi)
end
end
end), Any[0], Any[RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:cord, Symbol("##θ#331"), :phi, :derivative, :integral, :u, :p), NeuralPDE.var"#_RGF_ModTag", NeuralPDE.var"#_RGF_ModTag", (0xece15f21, 0xdd268b8a, 0x3a6073e5, 0x93a3d03a, 0x3d656f4c)}(quote
begin
let (x,) = (cord[[1], :],)
x
end
end
end)], var"##θ#331") .- (*).(1//3, (^).(x, 3))
end
end
end)], Expr[:((cord, var"##θ#331", phi, derivative, integral, u, p)->begin
begin
let (x,) = (cord[[1], :],)
u(cord, var"##θ#331", phi) .- 0.0
end
end
end)]) I will be back at it tomorrow to try to figure this out. |
Ok I now fixed Problem 2 and IDEs work with the heterogeneous system. I am still getting the |
…ld format dep_vars = [Q, P, Z]
…ill figuring out SIR model
I know I said this before but – this is almost done now. I am training the Kermack–McKendrick model right now. This system is big and takes a while to train. It would be maybe a good idea to use another system to do a convergence test on just to improve developer experience. I may also just be training it wrong right now (it currently stops converging when the loss hits about 80). I did not spend too much time playing with this yet, so I will try to focus on it now as it seems like this is the current bottleneck. This PR is now 2 weeks old, so I am trying to wrap this up asap. I started writing some documentation for the feature. We can probably use the Kermack–McKendrick model there at least (as it is a pretty cool example). I would love to get some feedback on some questions I have regarding order:
|
Yes, let's wrap it off. It seems like this is getting side tracked. Get to a version you think is ready to merge, and then let's merge and follow up with the other issues.
I think that is expected. If it's |
Alright @ChrisRackauckas I pushed a version I think is ready to merge. It doesn't have a convergence test but I am still gonna try to get either this SIR model or another heterogeneous system to work. I will make another PR for that though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Note this will need a breaking release. |
NNPDE should be split. It doesn't make sense to have one test set be over an hour. |
I started working on @zoemcc's PR last weekend because 1. I really want us to support heterogeneous inputs and 2. I thought it would be a good learning opportunity given that Zoe has done such a great job thinking about the architecture of this. My goal was to bring this PR up to date with the code base and get rid of remaining bugs so we could merge.
At this point this is almost done and you can check out Zoe's PR for an explanation of how this works #298. This is mostly her work and I just opened a new branch because it was more pleasant to merge it bit-by-bit. I hope that is ok!
The PR is up to date with master, and I fixed a few bugs. The main bug that remains is that I still get a
LoadError: DimensionMismatch("A has dimensions (3,1) but B has dimensions (2,30)")
when I try to run a heterogeneous system. I am still not sure where this bug is coming from, but it probably has something to do with the fact that you need a array of chains of different input sizes to get heterogeneous systems to work and we didn't handle that correctly somewhere (probably in build_symbolic_function or discretize).