OutlierDetectionJL / OutlierDetectionNetworks.jl

Neural-Network Outlier Detection Algorithms for Julia
MIT License
7 stars 2 forks source link

Training `DSADDetector` fails, at least through MLJ interface. #8

Open ablaom opened 1 year ago

ablaom commented 1 year ago

There is also a problem with ESADDetector.

Pkg.activate(temp=true)
Pkg.add("OutlierDetectionNetworks")
Pkg.add("OutlierDetectionData")
Pkg.add("MLJ")

using OutlierDetectionData: ODDS
using MLJ

X, y = ODDS.load("annthyroid")

model = (@load DSADDetector)()
mach = machine(model, X, y)

fit!(mach)
[ Info: Training machine(DSADDetector(encoder = Chain(), …), …).
┌ Error: Problem fitting the machine machine(DSADDetector(encoder = Chain(), …), …). 
└ @ MLJBase ~/.julia/packages/MLJBase/6ooqv/src/machines.jl:627
[ Info: Running type checks... 
[ Info: Type checks okay. 
ERROR: MethodError: no method matching -(::Nothing, ::Float64)
Closest candidates are:
  -(::T, ::T) where T<:Union{Float16, Float32, Float64} at float.jl:384
  -(::Distributions.UnivariateDistribution, ::Real) at ~/.julia/packages/Distributions/gggmX/src/univariate/locationscale.jl:146      
  -(::LinearAlgebra.UniformScaling, ::Number) at /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:146
  ...
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0 [inlined]
  [2] _pullback(::Zygote.Context{true}, ::typeof(-), ::Nothing, ::Float64)
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:9
  [3] (::Zygote.var"#927#931"{Zygote.Context{true}, typeof(-)})(::Nothing, ::Vararg{Any})
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/lib/broadcast.jl:197
  [4] _broadcast_getindex_evalf
    @ ./broadcast.jl:670 [inlined]
  [5] _broadcast_getindex
    @ ./broadcast.jl:643 [inlined]
  [6] getindex
    @ ./broadcast.jl:597 [inlined]
  [7] copy
    @ ./broadcast.jl:899 [inlined]
  [8] materialize
    @ ./broadcast.jl:860 [inlined]
  [9] _broadcast
    @ ~/.julia/packages/Zygote/SmJK6/src/lib/broadcast.jl:174 [inlined]
 [10] adjoint
    @ ~/.julia/packages/Zygote/SmJK6/src/lib/broadcast.jl:197 [inlined]
 [11] _pullback(::Zygote.Context{true}, ::typeof(Base.Broadcast.broadcasted), ::Base.Broadcast.DefaultArrayStyle{2}, ::typeof(-), ::Base.RefValue{Nothing}, ::Matrix{Float64})
    @ Zygote ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65
 [12] _apply(::Function, ::Vararg{Any})
    @ Core ./boot.jl:816
 [13] adjoint
    @ ~/.julia/packages/Zygote/SmJK6/src/lib/lib.jl:203 [inlined]
 [14] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [15] _pullback
    @ ./broadcast.jl:1304 [inlined]
 [16] _pullback
    @ ~/.julia/packages/Flux/FKl3M/src/losses/functions.jl:47 [inlined]
 [17] _pullback(::Zygote.Context{true}, ::Flux.Losses.var"##mse#10", ::typeof(mean), ::typeof(Flux.Losses.mse), ::Nothing, ::Matrix{Float64})                                      
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
 [18] _pullback
    @ ~/.julia/packages/Flux/FKl3M/src/losses/functions.jl:45 [inlined]
 [19] _pullback(::Zygote.Context{true}, ::typeof(Flux.Losses.mse), ::Nothing, ::Matrix{Float64})                                                                                  
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
 [20] _pullback
    @ ~/.julia/packages/OutlierDetectionNetworks/E4kqj/src/models/dsad.jl:90 [inlined]
 [21] _pullback(::Zygote.Context{true}, ::OutlierDetectionNetworks.var"#20#25"{OutlierDetectionNetworks.DSADDetector, Flux.Chain{Tuple{Flux.Chain{Tuple{}}, Flux.Chain{Tuple{}}}}}, ::Matrix{Float64}, ::CategoricalArrays.CategoricalVector{String, UInt32, String, CategoricalArrays.CategoricalValue{String, UInt32}, Union{}})      
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
 [22] _apply
    @ ./boot.jl:816 [inlined]
 [23] adjoint
    @ ~/.julia/packages/Zygote/SmJK6/src/lib/lib.jl:203 [inlined]
 [24] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [25] _pullback
    @ ~/.julia/packages/Flux/FKl3M/src/optimise/train.jl:132 [inlined]
 [26] _pullback(::Zygote.Context{true}, ::Flux.Optimise.var"#37#40"{OutlierDetectionNetworks.var"#20#25"{OutlierDetectionNetworks.DSADDetector, Flux.Chain{Tuple{Flux.Chain{Tuple{}}, Flux.Chain{Tuple{}}}}}, Tuple{Matrix{Float64}, CategoricalArrays.CategoricalVector{String, UInt32, String, CategoricalArrays.CategoricalValue{String, UInt32}, Union{}}}})
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
 [27] pullback(f::Function, ps::Zygote.Params{Zygote.Buffer{Any, Vector{Any}}})
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface.jl:384
 [28] withgradient(f::Function, args::Zygote.Params{Zygote.Buffer{Any, Vector{Any}}})
    @ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface.jl:132
 [29] macro expansion
    @ ~/.julia/packages/Flux/FKl3M/src/optimise/train.jl:131 [inlined]
 [30] macro expansion
    @ ~/.julia/packages/ProgressLogging/6KXlp/src/ProgressLogging.jl:328 [inlined]
 [31] train!(loss::Function, ps::Zygote.Params{Zygote.Buffer{Any, Vector{Any}}}, data::IterTools.NCycle{MLUtils.DataLoader{Tuple{SubArray{Float64, 2, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}}, true}, SubArray{CategoricalArrays.CategoricalValue{String, UInt32}, 1, CategoricalArrays.CategoricalVector{String, UInt32, String, CategoricalArrays.CategoricalValue{String, UInt32}, Union{}}, Tuple{Base.Slice{Base.OneTo{Int64}}}, true}}, Random._GLOBAL_RNG, Val{nothing}}}, opt::Flux.Optimise.Adam; cb::OutlierDetectionNetworks.var"#9#15")                                                        
    @ Flux.Optimise ~/.julia/packages/Flux/FKl3M/src/optimise/train.jl:129
 [32] fit(detector::OutlierDetectionNetworks.DSADDetector, X::SubArray{Float64, 2, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}}, true}, y::SubArray{CategoricalArrays.CategoricalValue{String, UInt32}, 1, CategoricalArrays.CategoricalVector{String, UInt32, String, CategoricalArrays.CategoricalValue{String, UInt32}, Union{}}, Tuple{Base.Slice{Base.OneTo{Int64}}}, true}; verbosity::Int64)
    @ OutlierDetectionNetworks ~/.julia/packages/OutlierDetectionNetworks/E4kqj/src/models/dsad.jl:90                                                                                  
 [33] fit(detector::OutlierDetectionNetworks.DSADDetector, verbosity::Int64, X::SubArray{Float64, 2, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Base.Slice{Base.OneTo{Int64}}}, true}, y::SubArray{CategoricalArrays.CategoricalValue{String, UInt32}, 1, CategoricalArrays.CategoricalVector{String, UInt32, String, CategoricalArrays.CategoricalValue{String, UInt32}, Union{}}, Tuple{Base.Slice{Base.OneTo{Int64}}}, true})
    @ OutlierDetectionInterface ~/.julia/packages/OutlierDetectionInterface/MbsOk/src/interface.jl:15                                                                             
 [34] fit_only!(mach::Machine{OutlierDetectionNetworks.DSADDetector, true}; rows::Nothing, verbosity::Int64, force::Bool)                                                              
    @ MLJBase ~/.julia/packages/MLJBase/6ooqv/src/machines.jl:625
 [35] fit_only!
    @ ~/.julia/packages/MLJBase/6ooqv/src/machines.jl:572 [inlined]
 [36] #fit!#61
    @ ~/.julia/packages/MLJBase/6ooqv/src/machines.jl:693 [inlined]
 [37] fit!(mach::Machine{OutlierDetectionNetworks.DSADDetector, true})
    @ MLJBase ~/.julia/packages/MLJBase/6ooqv/src/machines.jl:690
 [38] top-level scope
    @ REPL[16]:1
 [39] top-level scope
    @ ~/.julia/packages/CUDA/DfvRa/src/initialization.jl:52

Project:

⌃ [add582a8] MLJ v0.18.6
  [128abb87] OutlierDetectionData v0.2.0
  [c7f57e37] OutlierDetectionNetworks v0.1.3
davnn commented 1 year ago

Similar to https://github.com/OutlierDetectionJL/OutlierDetection.jl/issues/32. It would make sense to propose a default model architecture or raise an informative error if none is provided, I'll fix that in the next release.

ablaom commented 1 year ago

Elsewhere models that are not wrappers have a constructor with no arguments that returns an instance with default hyper-parameters. That is DSADDetector() should just work. This is not in the spec, but probably should be, and it is assumed to be the case in integration tests at MLJTestIntegration.jl. If this does not make sense for these models, then I suggest we not include them in the model registry (wrappers, like TunedModel and Stack are not in the registry). Let me know if this is the case.

davnn commented 1 year ago

We would probably have to implement https://github.com/OutlierDetectionJL/OutlierDetectionNetworks.jl/issues/3 before to use something like builders as in MLJFlux, otherwise the shape of the data would have to be known beforehand to propose a network architecture.

ablaom commented 1 year ago

Ah, I see. That makes sense. Any objections to (temporarily) deregisteringOutlierDetectionNetwork models? I can add the package to this list.

davnn commented 1 year ago

No objections, we can remove again once the issue is closed.