SciML / Surrogates.jl

Surrogate modeling and optimization for scientific machine learning (SciML)
https://docs.sciml.ai/Surrogates/stable/
Other
328 stars 70 forks source link

Save/load generated surrogate model #389

Open jacktang opened 2 years ago

jacktang commented 2 years ago

Hi,

I want to save/load the surrogate model using JLD2 and BSON, and find the packages can only serialize objects rather than function. So if I load the saved model, it throws error:

UndefVarError: XGBoost not defined

Stacktrace:
  [1] (::BSON.var"#31#32")(m::Module, f::String)
    @ BSON ~/.julia/packages/BSON/rOaki/src/extensions.jl:21
  [2] BottomRF
    @ ./reduce.jl:81 [inlined]
  [3] _foldl_impl(op::Base.BottomRF{BSON.var"#31#32"}, init::Module, itr::Vector{Any})
    @ Base ./reduce.jl:58
  [4] foldl_impl
    @ ./reduce.jl:48 [inlined]
  [5] mapfoldl_impl
    @ ./reduce.jl:44 [inlined]
  [6] _mapreduce_dim
    @ ./reducedim.jl:327 [inlined]
  [7] #mapreduce#725
    @ ./reducedim.jl:322 [inlined]
  [8] #reduce#727
    @ ./reducedim.jl:371 [inlined]
  [9] resolve(fs::Vector{Any}, init::Module)
    @ BSON ~/.julia/packages/BSON/rOaki/src/extensions.jl:21
 [10] (::BSON.var"#35#36")(d::Dict{Symbol, Any}, init::Module)
    @ BSON ~/.julia/packages/BSON/rOaki/src/extensions.jl:64
 [11] _raise_recursive(d::Dict{Symbol, Any}, cache::IdDict{Any, Any}, init::Module)
    @ BSON ~/.julia/packages/BSON/rOaki/src/read.jl:80

BTW: the question on julialang discourse: https://discourse.julialang.org/t/save-and-load-the-model-generated-by-surrogates-jl/83302

vikram-s-narayan commented 2 years ago

Can you please share your full minimum working example so that we can examine it more carefully? Also, can you try with some other surrogate like Radial Basis?

jacktang commented 2 years ago

@vikram-s-narayan For example the random forrest surrogate model: https://surrogates.sciml.ai/dev/randomforest/

using Surrogates
using SurrogatesRandomForest
using Plots
using JLD2
default()

f(x) = sin(x) + sin(10/3 * x)
n_samples = 80
lower_bound = 2.7
upper_bound = 7.5
x = sample(n_samples, lower_bound, upper_bound, SobolSample())
y = f.(x)
scatter(x, y, label="Sampled points", xlims=(lower_bound, upper_bound))
plot!(f, label="True function", xlims=(lower_bound, upper_bound), legend=:top)

num_round = 100
randomforest_surrogate = RandomForestSurrogate(x ,y ,lower_bound, upper_bound, num_round = num_round)
plot(x, y, seriestype=:scatter, label="Sampled points", xlims=(lower_bound, upper_bound), legend=:top)
plot!(f, label="True function",  xlims=(lower_bound, upper_bound), legend=:top)
plot!(randomforest_surrogate, label="Surrogate function",  xlims=(lower_bound, upper_bound), legend=:top)

save_object("/tmp/rf_model.jld", randomforest_surrogate)
sm = load_object("/tmp/rf_model.jld")
sm.(3.5)

PolynomialChaos model works fine, so I think Radial basis should be ok too.

vikram-s-narayan commented 2 years ago

Thanks. With the code you provided the error reads - "ERROR: Call to XGBoost C function XGBoosterPredict failed: ". This appears to be a known issue with XGBoost. One of the package dependencies in SurrogatesRandomForest is XGBoost.

jacktang commented 2 years ago

@vikram-s-narayan If I understand it correctly, the solution is replacing XGBoost by EvoTrees.jl in Surrogates.jl?

vikram-s-narayan commented 2 years ago

@jacktang - I'm not sure if there are any other dependencies involved and whether the function calls need to be changed.