Mlj.jl: Problems deserialising pipeline models because of auto-generated type name

Created on 28 Aug 2020  Â·  4Comments  Â·  Source: alan-turing-institute/MLJ.jl

From an issue raised on slack:

I am trying to load a saved model (MLJ.save("hottree2.jlso", mtm, compression=:none) )from https://alan-turing-institute.github.io/DataScienceTutorials.jl/isl/lab-8/ but get the following error
julia> mach2 = machine("hottree2.jlso")
ERROR: MethodError: no method matching Machine(::Array{UInt8,1})
Closest candidates are:
Machine(::M, ::AbstractNode...) where M<:MLJModelInterface.Model at /home/jade/.julia/packages/MLJBase/cJmIS/src/machines.jl:19
Stacktrace:
[1] machine(::String; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/jade/.julia/packages/MLJBase/cJmIS/src/machines.jl:676
[2] machine(::String) at /home/jade/.julia/packages/MLJBase/cJmIS/src/machines.jl:674
And my response there:

Interesting issue. I’m assuming you executed the same code that defined your pipeline model before attempting to retrieve the saved machine. In that case I expect I can guess the problem - the auto-generated model type name for the pipeline is different. A workaround is to explicitly give your pipeline mode type a name by specifying @pipeline …… name=MyPipe . Let me know if that works for you.

The workaround resolves the issue.


I personally find the automatic generation of a type name very convenient and am guessing the best solution more generally is to flag the problem in documentation. Any other ideas?

docs

Most helpful comment

Regarding the original post here, one solution is to make all pipeline model a single type, along the lines suggested in https://github.com/alan-turing-institute/MLJ.jl/issues/594, but this is some work and needs to be carefully thought through.

All 4 comments

@ablaom I agree documenting this and also putting this in the doc-string of MLJ.save
But there is another issue that occurs when de-serializing user defined models (including Composites e.g Pipelines) even in the REPL. (well not really an issue if it's documented)
The following code shows this

# enter the following in a REPL session
using MLJ
import RDatasets: dataset

import DataFrames: DataFrame, select, Not
@load DecisionTreeClassifier pkg=DecisionTree

carseats = dataset("ISLR", "Carseats")

High = ifelse.(carseats.Sales .<= 8, "No", "Yes") |> categorical;
carseats[!, :High] = High;

X = select(carseats, Not([:Sales, :High]))
y = carseats.High;

HotTreeClf = @pipeline(OneHotEncoder(),
                       DecisionTreeClassifier(), name = MyPipe) #note that i named my Pipeline

mdl = HotTreeClf
mach = machine(mdl, X, y)
fit!(mach);

MLJ.save("hottree.jlso", mach)
machine("hottree.jlso") # this works

# Now restart the REPL and enter the follwoing code
using MLJ
julia> machine("hottree.jlso")
[warn | JLSO]: UndefVarError: DecisionTree_ not defined
[warn | JLSO]: UndefVarError: DecisionTree_ not defined
[warn | JLSO]: UndefVarError: MyPipe not defined
ERROR: MethodError: no method matching Machine(::Array{UInt8,1})
....

julia> julia> @load DecisionTreeClassifier pkg=DecisionTree
DecisionTreeClassifier(
    max_depth = -1,
    min_samples_leaf = 1,
    min_samples_split = 2,
    min_purity_increase = 0.0,
    n_subfeatures = 0,
    post_prune = false,
    merge_purity_threshold = 1.0,
    pdf_smoothing = 0.0,
    display_depth = 5) @548

julia> machine("hottree.jlso")
[warn | JLSO]: UndefVarError: MyPipe not defined
ERROR: MethodError: no method matching Machine(::Array{UInt8,1})
...

# I had to redefine the MyPipe for this to work
@pipeline(OneHotEncoder(),
                              DecisionTreeClassifier(), name = MyPipe)

julia> machine("hottree.jlso")
Machine{MyPipe} @856 trained 1 time.
  args:

I think we need to document this. i.e for user defined models including Pipelines, the implementation of the models type has to be loaded or defined for deserialization to work.

I think we need to document this. i.e for user defined models including Pipelines, the implementation of the models type has to be loaded or defined for deserialization to work.

I think this is pretty well understood but agree newbies will rub against it, and it should be documented.

Regarding the original post here, one solution is to make all pipeline model a single type, along the lines suggested in https://github.com/alan-turing-institute/MLJ.jl/issues/594, but this is some work and needs to be carefully thought through.

Hello, let me know if I could help in documenting it. Please let us know of any suggestions. Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

juliohm picture juliohm  Â·  8Comments

Sinansi picture Sinansi  Â·  6Comments

ExpandingMan picture ExpandingMan  Â·  7Comments

baggepinnen picture baggepinnen  Â·  6Comments

tlienart picture tlienart  Â·  3Comments