MilesCranmer / SymbolicRegression.jl

Distributed High-Performance Symbolic Regression in Julia
https://ai.damtp.cam.ac.uk/symbolicregression/
Apache License 2.0
645 stars 87 forks source link

[BUG] Domain errors #71

Closed MilesCranmer closed 2 years ago

MilesCranmer commented 2 years ago

Cross post with https://github.com/MilesCranmer/PySR/issues/116

It seems like there are some very rare edge cases where a domain error will occur. For the vast majority of instances, an Inf or Nan will be caught at the source, and the evaluation function immediately quit. However, it looks like sometimes this doesn't happen. Here is the traceback:

    nested task error: TaskFailedException
    Stacktrace:
     [1] wait
       @ ./task.jl:334 [inlined]
     [2] fetch
       @ ./task.jl:349 [inlined]
     [3] (::SymbolicRegression.var"#60#98"{Vector{Vector{Task}}, Int64, Int64})()
       @ SymbolicRegression ./task.jl:423

        nested task error: DomainError with Inf:
        cos(x) is only defined for finite x.
        Stacktrace:
          [1] cos_domain_error(x::Float32)
            @ Base.Math ./special/trig.jl:97
          [2] cos(x::Float32)
            @ Base.Math ./special/trig.jl:108
          [3] deg1_l1_ll0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{1}, #unused#::Val{2}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:175
          [4] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:31
          [5] deg2_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{4}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:66
          [6] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:49
          [7] deg2_r0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{2}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:271
          [8] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:47
          [9] deg2_l0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{2}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:245
         [10] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:45
         [11] deg2_r0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{1}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:271
         [12] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:47
         [13] deg2_r0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{4}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:271
         [14] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:47
         [15] deg2_r0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{1}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:271
         [16] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:47
         [17] deg2_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{4}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:68
         [18] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:49
         [19] deg2_r0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{1}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:271
         [20] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:47
         [21] deg1_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{1}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:84
         [22] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:33
         [23] deg2_r0_eval(tree::Node, cX::Matrix{Float32}, #unused#::Val{4}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:271
         [24] evalTreeArray(tree::Node, cX::Matrix{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss})
            @ SymbolicRegression.../EvaluateEquation.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/EvaluateEquation.jl:47
         [25] EvalLoss(tree::Node, dataset::SymbolicRegression.../Dataset.jl.Dataset{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss}; allow_diff::Bool)
            @ SymbolicRegression.../LossFunctions.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/LossFunctions.jl:28
         [26] scoreFunc(dataset::SymbolicRegression.../Dataset.jl.Dataset{Float32}, baseline::Float32, tree::Node, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss}; allow_diff::Bool)
            @ SymbolicRegression.../LossFunctions.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/LossFunctions.jl:47
         [27] scoreFunc
            @ ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/LossFunctions.jl:47 [inlined]
         [28] nextGeneration(dataset::SymbolicRegression.../Dataset.jl.Dataset{Float32}, baseline::Float32, member::PopMember{Float32}, temperature::Float32, curmaxsize::Int64, frequencyComplexity::Vector{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss}; tmp_recorder::Dict{String, Any})
            @ SymbolicRegression.../Mutate.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/Mutate.jl:139
         [29] regEvolCycle(dataset::SymbolicRegression.../Dataset.jl.Dataset{Float32}, baseline::Float32, pop::Population{Float32}, temperature::Float32, curmaxsize::Int64, frequencyComplexity::Vector{Float32}, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss}, record::Dict{String, Any})
            @ SymbolicRegression.../RegularizedEvolution.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/RegularizedEvolution.jl:62
         [30] SRCycle(dataset::SymbolicRegression.../Dataset.jl.Dataset{Float32}, baseline::Float32, pop::Population{Float32}, ncycles::Int64, curmaxsize::Int64, frequencyComplexity::Vector{Float32}; verbosity::Int64, options::Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss}, record::Dict{String, Any})
            @ SymbolicRegression.../SingleIteration.jl ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/SingleIteration.jl:33
         [31] macro expansion
            @ ~/miniconda3/envs/pysr/share/julia/packages/SymbolicRegression/Z2pqJ/src/SymbolicRegression.jl:577 [inlined]
         [32] (::SymbolicRegression.var"#59#97"{Options{Tuple{typeof(*), typeof(/), typeof(+), typeof(-)}, Tuple{typeof(sin), typeof(cos), typeof(exp), typeof(log_abs)}, L2DistLoss}, Vector{Vector{Float32}}, Population{Float32}, Int64, Float32, SymbolicRegression.../Dataset.jl.Dataset{Float32}, Int64})()
            @ SymbolicRegression ./threadingconstructs.jl:178>
MilesCranmer commented 2 years ago

This occurs at this line: https://github.com/MilesCranmer/SymbolicRegression.jl/blob/60e2fcfd164b2342f7eddd6f91b16de837194c2b/src/EvaluateEquation.jl#L175 which is quite interesting as this means the input is a constant value... so this means the optimizer is producing an Inf in one of the constants! (or, perhaps the simplifier is)

MilesCranmer commented 2 years ago

Possible solutions (will update with ideas):

MilesCranmer commented 2 years ago

Should be fixed now. I also have a unit test for checking this.