SciML / ModelingToolkitNeuralNets.jl

Symbolic-Numeric Universal Differential Equations for Automating Scientific Machine Learning (SciML)
MIT License
23 stars 1 forks source link

NeuralNetworkBlock errors with inputs/outputs to be 1 #16

Closed sathvikbhagavan closed 5 months ago

sathvikbhagavan commented 6 months ago

Describe the bug 🐞

NeuralNetworkBlock errors out if either of the inputs/outputs is 1

Expected behavior

It should not error.

Minimal Reproducible Example 👇

Error & Stacktrace ⚠️

julia> nn = NeuralNetworkBlock(1, 1)
ERROR: type Term has no field layer_1.
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] throw_no_field(::Val{:Term}, s::Symbol)
    @ Unityper ~/.julia/packages/Unityper/BiodR/src/compactify.jl:505
  [3] getproperty
    @ ~/.julia/packages/Unityper/BiodR/src/compactify.jl:310 [inlined]
  [4] macro expansion
    @ ~/.julia/packages/Lux/d6MXd/src/layers/containers.jl:0 [inlined]
  [5] applychain(layers::@NamedTuple{…}, x::Num, ps::SymbolicUtils.BasicSymbolic{…}, st::@NamedTuple{…})
    @ Lux ~/.julia/packages/Lux/d6MXd/src/layers/containers.jl:479
  [6] (::Chain{…})(x::Num, ps::SymbolicUtils.BasicSymbolic{…}, st::@NamedTuple{…})
    @ Lux ~/.julia/packages/Lux/d6MXd/src/layers/containers.jl:477
  [7] apply(model::Chain{…}, x::Num, ps::SymbolicUtils.BasicSymbolic{…}, st::@NamedTuple{…})
    @ LuxCore ~/.julia/packages/LuxCore/8lRV2/src/LuxCore.jl:180
  [8] stateless_apply(model::Chain{@NamedTuple{…}, Nothing}, x::Num, ps::SymbolicUtils.BasicSymbolic{AbstractVector{…}})
    @ LuxCore ~/.julia/packages/LuxCore/8lRV2/src/LuxCore.jl:190
  [9] NeuralNetworkBlock(n_input::Int64, n_output::Int64; chain::Chain{…}, rng::Random.Xoshiro, eltype::Type)
    @ UDEComponents ~/UDEComponents.jl/src/UDEComponents.jl:35
 [10] NeuralNetworkBlock(n_input::Int64, n_output::Int64)
    @ UDEComponents ~/UDEComponents.jl/src/UDEComponents.jl:22
 [11] top-level scope
    @ REPL[129]:1
Some type information was truncated. Use `show(err)` to see complete types.

julia> NeuralNetworkBlock(1, 2)
ERROR: type Term has no field layer_1.
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] throw_no_field(::Val{:Term}, s::Symbol)
    @ Unityper ~/.julia/packages/Unityper/BiodR/src/compactify.jl:505
  [3] getproperty
    @ ~/.julia/packages/Unityper/BiodR/src/compactify.jl:310 [inlined]
  [4] macro expansion
    @ ~/.julia/packages/Lux/d6MXd/src/layers/containers.jl:0 [inlined]
  [5] applychain(layers::@NamedTuple{…}, x::Num, ps::SymbolicUtils.BasicSymbolic{…}, st::@NamedTuple{…})
    @ Lux ~/.julia/packages/Lux/d6MXd/src/layers/containers.jl:479
  [6] (::Chain{…})(x::Num, ps::SymbolicUtils.BasicSymbolic{…}, st::@NamedTuple{…})
    @ Lux ~/.julia/packages/Lux/d6MXd/src/layers/containers.jl:477
  [7] apply(model::Chain{…}, x::Num, ps::SymbolicUtils.BasicSymbolic{…}, st::@NamedTuple{…})
    @ LuxCore ~/.julia/packages/LuxCore/8lRV2/src/LuxCore.jl:180
  [8] stateless_apply(model::Chain{@NamedTuple{…}, Nothing}, x::Num, ps::SymbolicUtils.BasicSymbolic{AbstractVector{…}})
    @ LuxCore ~/.julia/packages/LuxCore/8lRV2/src/LuxCore.jl:190
  [9] NeuralNetworkBlock(n_input::Int64, n_output::Int64; chain::Chain{…}, rng::Random.Xoshiro, eltype::Type)
    @ UDEComponents ~/UDEComponents.jl/src/UDEComponents.jl:35
 [10] NeuralNetworkBlock(n_input::Int64, n_output::Int64)
    @ UDEComponents ~/UDEComponents.jl/src/UDEComponents.jl:22
 [11] top-level scope
    @ REPL[135]:1
Some type information was truncated. Use `show(err)` to see complete types.

julia> NeuralNetworkBlock(2, 1)
ERROR: ArgumentError: Cannot equate an array of different sizes. Got () and (1,).
Stacktrace:
 [1] ~(lhs::Num, rhs::Symbolics.Arr{Num, 1})
   @ Symbolics ~/.julia/packages/Symbolics/HIg7O/src/equations.jl:180
 [2] NeuralNetworkBlock(n_input::Int64, n_output::Int64; chain::Chain{…}, rng::Random.Xoshiro, eltype::Type)
   @ UDEComponents ~/UDEComponents.jl/src/UDEComponents.jl:37
 [3] NeuralNetworkBlock(n_input::Int64, n_output::Int64)
   @ UDEComponents ~/UDEComponents.jl/src/UDEComponents.jl:22
 [4] top-level scope
   @ REPL[136]:1
Some type information was truncated. Use `show(err)` to see complete types.

julia> NeuralNetworkBlock(2, 2) # this works
Model ude_comp with 1 equations
Unknowns (4):
  (input₊u(t))[1] [defaults to 0.0]: Inner variable in RealInput input
  (input₊u(t))[2] [defaults to 0.0]: Inner variable in RealInput input
  (output₊u(t))[1] [defaults to 0.0]: Inner variable in RealOutput output
  (output₊u(t))[2] [defaults to 0.0]: Inner variable in RealOutput output
Parameters (2):
  p [defaults to [-0.0263502, -0.174611, -0.893525, -0.798898, -0.555466, 0.670555, -0.424534, -0.766633, -0.356533, 0.299249  …  0.676001, -0.195723, -0.506862, -0.798457, -0.608183, 0.245349, 0.236982, -0.844565, 0.0, 0.0]]
  T [defaults to Arr{Num, 1}]
sathvikbhagavan commented 5 months ago

After investigating, this is happening because -

julia> @named input = RealInput(nin = 1)
Model input with 0 (1) equations
Unknowns (1):
  u(t) [defaults to 0.0]: Inner variable in RealInput input
Parameters (0):

julia> @named input = RealInput(nin = 2)
Model input with 0 (2) equations
Unknowns (2):
  (u(t))[1] [defaults to 0.0]: Inner variable in RealInput input
  (u(t))[2] [defaults to 0.0]: Inner variable in RealInput input
Parameters (0):

with nin = 1, the unknown is a scalar and not a vector and stateless_apply expects a vector.

sathvikbhagavan commented 5 months ago

looking at the source code for RealInput:

@connector function RealInput(; name, nin = 1, u_start = nin > 1 ? zeros(nin) : 0.0)
    if nin == 1
        @variables u(t)=u_start [
            input = true,
            description = "Inner variable in RealInput $name"
        ]
    else
        @variables u(t)[1:nin]=u_start [
            input = true,
            description = "Inner variable in RealInput $name"
        ]
        u = collect(u)
    end
    ODESystem(Equation[], t, [u...], []; name = name)
end

@ChrisRackauckas, does it make sense to have a keyword argument isarray which we can use such that we can have a array with nin = 1?

ChrisRackauckas commented 5 months ago

Yes

sathvikbhagavan commented 5 months ago

Fixed in https://github.com/SciML/ModelingToolkitStandardLibrary.jl/pull/283