From b1a90b262d71a6f74b5d416045cbbd47049af215 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure Date: Fri, 6 Sep 2024 14:19:57 +0200 Subject: [PATCH 01/15] automatically convert input matrix to Float32 --- src/core.jl | 15 +++++++++++---- src/mlj_model_interface.jl | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/core.jl b/src/core.jl index 938dea7f..d2c06481 100644 --- a/src/core.jl +++ b/src/core.jl @@ -268,15 +268,22 @@ input `X` and target `y` in the form required by by `model.batch_size`.) """ -function collate(model, X, y) +function collate(model, X, y, verbosity) row_batches = Base.Iterators.partition(1:nrows(y), model.batch_size) - Xmatrix = reformat(X) + Xmatrix = _f32(reformat(X), verbosity) ymatrix = reformat(y) return [_get(Xmatrix, b) for b in row_batches], [_get(ymatrix, b) for b in row_batches] end -function collate(model::NeuralNetworkBinaryClassifier, X, y) +function collate(model::NeuralNetworkBinaryClassifier, X, y, verbosity) row_batches = Base.Iterators.partition(1:nrows(y), model.batch_size) - Xmatrix = reformat(X) + Xmatrix = _f32(reformat(X), verbosity) yvec = (y .== classes(y)[2])' # convert to boolean return [_get(Xmatrix, b) for b in row_batches], [_get(yvec, b) for b in row_batches] end + +_f32(x::AbstractMatrix{Float32}, verbosity) = x +function _f32(x::AbstractMatrix, verbosity) + verbosity > 0 && @info "MLJFlux: converting input data to Float32" + return Float32.(x) +end + diff --git a/src/mlj_model_interface.jl b/src/mlj_model_interface.jl index aa9850c4..c213c20e 100644 --- a/src/mlj_model_interface.jl +++ b/src/mlj_model_interface.jl @@ -107,7 +107,7 @@ function MLJModelInterface.fit(model::MLJFluxModel, rethrow() end - data = move.(collate(model, X, y)) + data = move.(collate(model, X, y, verbosity)) x = data[1][1] try From ff32ca55244f6a5c6d8b8c214fafeabdb700ad9c Mon Sep 17 00:00:00 2001 From: tiemvanderdeure Date: Mon, 9 Sep 2024 12:41:26 +0200 Subject: [PATCH 02/15] dispatch on array not matrix --- src/core.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core.jl b/src/core.jl index d2c06481..420efbe4 100644 --- a/src/core.jl +++ b/src/core.jl @@ -281,8 +281,8 @@ function collate(model::NeuralNetworkBinaryClassifier, X, y, verbosity) return [_get(Xmatrix, b) for b in row_batches], [_get(yvec, b) for b in row_batches] end -_f32(x::AbstractMatrix{Float32}, verbosity) = x -function _f32(x::AbstractMatrix, verbosity) +_f32(x::AbstractArray{Float32}, verbosity) = x +function _f32(x::AbstractArray, verbosity) verbosity > 0 && @info "MLJFlux: converting input data to Float32" return Float32.(x) end From 56838bf16e99c4106a8e4ab368418e095d9d9e65 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure Date: Mon, 9 Sep 2024 12:41:42 +0200 Subject: [PATCH 03/15] pass verbosity to collate in update --- src/mlj_model_interface.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlj_model_interface.jl b/src/mlj_model_interface.jl index c213c20e..dc6599d4 100644 --- a/src/mlj_model_interface.jl +++ b/src/mlj_model_interface.jl @@ -175,7 +175,7 @@ function MLJModelInterface.update(model::MLJFluxModel, rng = true_rng(model) chain = build(model, rng, shape) |> move # reset `optimiser_state`: - data = move.(collate(model, X, y)) + data = move.(collate(model, X, y, verbosity)) nbatches = length(data[2]) regularized_optimiser = MLJFlux.regularized_optimiser(model, nbatches) optimiser_state = Optimisers.setup(regularized_optimiser, chain) From 5ae2fe5f8ebd0b26a7869f835c987c598cdf391e Mon Sep 17 00:00:00 2001 From: tiemvanderdeure Date: Mon, 9 Sep 2024 12:41:59 +0200 Subject: [PATCH 04/15] add tests and fix existing ones --- Project.toml | 3 ++- test/core.jl | 19 ++++++++++++------- test/mlj_model_interface.jl | 2 +- test/runtests.jl | 1 + 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Project.toml b/Project.toml index ace5f347..537ec16d 100644 --- a/Project.toml +++ b/Project.toml @@ -33,6 +33,7 @@ julia = "1.9" [extras] CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" MLJBase = "a7f614a8-145f-11e9-1d2a-a57a1082229d" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" @@ -42,4 +43,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd" [targets] -test = ["CUDA", "cuDNN", "LinearAlgebra", "MLJBase", "Random", "StableRNGs", "StatisticalMeasures", "StatsBase", "Test"] +test = ["CUDA", "cuDNN", "LinearAlgebra", "Logging", "MLJBase", "Random", "StableRNGs", "StatisticalMeasures", "StatsBase", "Test"] diff --git a/test/core.jl b/test/core.jl index 4bfc400b..94eb1e1f 100644 --- a/test/core.jl +++ b/test/core.jl @@ -14,23 +14,28 @@ rowvec(y::Vector) = reshape(y, 1, length(y)) end @testset "collate" begin - # NeuralNetworRegressor: - Xmatrix = broadcast(x->round(x, sigdigits=2), rand(stable_rng, 10, 3)) + Xmatrix = broadcast(x->round(x, sigdigits=2), rand(stable_rng, Float32, 10, 3)) + Xmat_f64 = Float64.(Xmatrix) # convert to a column table: X = MLJBase.table(Xmatrix) + X_64 = MLJBase.table(Xmat_f64) + # NeuralNetworRegressor: y = rand(stable_rng, Float32, 10) model = MLJFlux.NeuralNetworkRegressor() model.batch_size= 3 - @test MLJFlux.collate(model, X, y) == + @test MLJFlux.collate(model, X, y, 1) == MLJFlux.collate(model, X_64, y, 1) == ([Xmatrix'[:,1:3], Xmatrix'[:,4:6], Xmatrix'[:,7:9], Xmatrix'[:,10:10]], rowvec.([y[1:3], y[4:6], y[7:9], y[10:10]])) + @test_logs (:info,) MLJFlux.collate(model, X_64, y, 1) + @test_logs min_level=Logging.Info MLJFlux.collate(model, X, y, 1) + @test_logs min_level=Logging.Info MLJFlux.collate(model, X, y, 0) # NeuralNetworClassifier: y = categorical(['a', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'b', 'a']) model = MLJFlux.NeuralNetworkClassifier() model.batch_size = 3 - data = MLJFlux.collate(model, X, y) + data = MLJFlux.collate(model, X, y, 1) @test data == ([Xmatrix'[:,1:3], Xmatrix'[:,4:6], Xmatrix'[:,7:9], Xmatrix'[:,10:10]], @@ -42,13 +47,13 @@ end y = MLJBase.table(ymatrix) # a rowaccess table model = MLJFlux.NeuralNetworkRegressor() model.batch_size= 3 - @test MLJFlux.collate(model, X, y) == + @test MLJFlux.collate(model, X, y, 1) == ([Xmatrix'[:,1:3], Xmatrix'[:,4:6], Xmatrix'[:,7:9], Xmatrix'[:,10:10]], rowvec.([ymatrix'[:,1:3], ymatrix'[:,4:6], ymatrix'[:,7:9], ymatrix'[:,10:10]])) y = Tables.columntable(y) # try a columnaccess table - @test MLJFlux.collate(model, X, y) == + @test MLJFlux.collate(model, X, y, 1) == ([Xmatrix'[:,1:3], Xmatrix'[:,4:6], Xmatrix'[:,7:9], Xmatrix'[:,10:10]], rowvec.([ymatrix'[:,1:3], ymatrix'[:,4:6], ymatrix'[:,7:9], ymatrix'[:,10:10]])) @@ -58,7 +63,7 @@ end y = categorical(['a', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'b', 'a']) model = MLJFlux.ImageClassifier(batch_size=2) - data = MLJFlux.collate(model, Xmatrix, y) + data = MLJFlux.collate(model, Xmatrix, y, 1) @test first.(data) == (Float32.(cat(Xmatrix[1], Xmatrix[2], dims=4)), rowvec.([1 0;0 1])) diff --git a/test/mlj_model_interface.jl b/test/mlj_model_interface.jl index 522b059e..24ae4e8d 100644 --- a/test/mlj_model_interface.jl +++ b/test/mlj_model_interface.jl @@ -94,7 +94,7 @@ end # (2) manually train for one epoch explicitly adding a loss penalty: chain = MLJFlux.build(builder, StableRNG(123), 3, 1); penalty = Penalizer(lambda, alpha); # defined in test_utils.jl - X, y = MLJFlux.collate(model, Xuser, yuser); + X, y = MLJFlux.collate(model, Xuser, yuser, 0); loss = model.loss; n_batches = div(nobservations, batch_size) optimiser_state = Optimisers.setup(optimiser, chain); diff --git a/test/runtests.jl b/test/runtests.jl index b7b11d66..2e7c48c9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,6 +13,7 @@ using StableRNGs using CUDA, cuDNN import StatisticalMeasures import Optimisers +import Logging using ComputationalResources using ComputationalResources: CPU1, CUDALibs From 7818959d7c86289e4a7808ac636d93e99f6c9f23 Mon Sep 17 00:00:00 2001 From: Essam Date: Sat, 14 Sep 2024 18:18:56 -0500 Subject: [PATCH 05/15] =?UTF-8?q?=E2=9C=85=20Make=20embedding=20model=20ou?= =?UTF-8?q?tput=20Float32?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entity_embedding.jl | 3 +-- test/entity_embedding.jl | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/entity_embedding.jl b/src/entity_embedding.jl index 3e16ea2e..4009745d 100644 --- a/src/entity_embedding.jl +++ b/src/entity_embedding.jl @@ -36,7 +36,6 @@ julia> output = embedder(batch) ``` """ # 1. Define layer struct to hold parameters struct EntityEmbedder{A1 <: AbstractVector, A2 <: AbstractVector, I <: Integer} - embedders::A1 modifiers::A2 # applied on the input before passing it to the embedder numfeats::I @@ -44,7 +43,7 @@ end # 2. Define the forward pass (i.e., calling an instance of the layer) (m::EntityEmbedder)(x) = - vcat([m.embedders[i](m.modifiers[i](x, i)) for i in 1:m.numfeats]...) + Float32.(vcat([m.embedders[i](m.modifiers[i](x, i)) for i in 1:m.numfeats]...)) # 3. Define the constructor which initializes the parameters and returns the instance function EntityEmbedder(entityprops, numfeats; init = Flux.randn32) diff --git a/test/entity_embedding.jl b/test/entity_embedding.jl index 738351ab..5cc1f23f 100644 --- a/test/entity_embedding.jl +++ b/test/entity_embedding.jl @@ -145,7 +145,8 @@ end numfeats = 4 embedder = MLJFlux.EntityEmbedder(entityprops, 4) output = embedder(batch) - @test output == batch + @test output ≈ batch + @test eltype(output) == Float32 end From 493d23bbb7ab847df56bf9d17c6f0a9695f84cf9 Mon Sep 17 00:00:00 2001 From: Essam Date: Sun, 15 Sep 2024 21:49:09 -0500 Subject: [PATCH 06/15] Fix ordinal encoding float types --- src/encoders.jl | 4 ++-- src/entity_embedding.jl | 2 +- test/encoders.jl | 4 ++-- test/entity_embedding.jl | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/encoders.jl b/src/encoders.jl index de517147..a7eba0b0 100644 --- a/src/encoders.jl +++ b/src/encoders.jl @@ -19,11 +19,11 @@ function ordinal_encoder_fit(X; featinds) feat_col = Tables.getcolumn(Tables.columns(X), i) feat_levels = levels(feat_col) # Check if feat levels is already ordinal encoded in which case we skip - (Set([float(i) for i in 1:length(feat_levels)]) == Set(feat_levels)) && continue + (Set([Float32(i) for i in 1:length(feat_levels)]) == Set(feat_levels)) && continue # Compute the dict using the given feature_mapper function mapping_matrix[i] = Dict{Any, AbstractFloat}( - value => float(index) for (index, value) in enumerate(feat_levels) + value => Float32(index) for (index, value) in enumerate(feat_levels) ) end return mapping_matrix diff --git a/src/entity_embedding.jl b/src/entity_embedding.jl index 4009745d..313e3e6d 100644 --- a/src/entity_embedding.jl +++ b/src/entity_embedding.jl @@ -43,7 +43,7 @@ end # 2. Define the forward pass (i.e., calling an instance of the layer) (m::EntityEmbedder)(x) = - Float32.(vcat([m.embedders[i](m.modifiers[i](x, i)) for i in 1:m.numfeats]...)) + (vcat([m.embedders[i](m.modifiers[i](x, i)) for i in 1:m.numfeats]...)) # 3. Define the constructor which initializes the parameters and returns the instance function EntityEmbedder(entityprops, numfeats; init = Flux.randn32) diff --git a/test/encoders.jl b/test/encoders.jl index 7bd5da9c..50b93b60 100644 --- a/test/encoders.jl +++ b/test/encoders.jl @@ -12,8 +12,8 @@ @test map[2] == Dict('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5) @test map[3] == Dict("b" => 1, "c" => 2, "d" => 3) @test Xenc.Column1 == [1.0, 2.0, 3.0, 4.0, 5.0] - @test Xenc.Column2 == [1.0, 2.0, 3.0, 4.0, 5.0] - @test Xenc.Column3 == [1, 2, 3] + @test Xenc.Column2 == Float32.([1.0, 2.0, 3.0, 4.0, 5.0]) + @test Xenc.Column3 == Float32.([1, 2, 3]) @test Xenc.Column4 == [1.0, 2.0, 3.0, 4.0, 5.0] X = coerce(X, :Column1 => Multiclass) diff --git a/test/entity_embedding.jl b/test/entity_embedding.jl index 5cc1f23f..da0c89ba 100644 --- a/test/entity_embedding.jl +++ b/test/entity_embedding.jl @@ -1,13 +1,13 @@ """ See more functional tests in entity_embedding_utils.jl and mlj_model_interface.jl """ - -batch = [ +batch = Float32.([ 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1; - 1 2 3 4 5 6 7 8 9 10; - 0.9 0.1 0.4 0.5 0.3 0.7 0.8 0.9 1.0 1.1 - 1 1 2 2 1 1 2 2 1 1 -] + 1 2 3 4 5 6 7 8 9 10; + 0.9 0.1 0.4 0.5 0.3 0.7 0.8 0.9 1.0 1.1; + 1 1 2 2 1 1 2 2 1 1 +]) + entityprops = [ (index = 2, levels = 10, newdim = 2), From 09b17da853d72a81fb9e203ce245c05a71792d5f Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Tue, 17 Sep 2024 09:30:09 +1000 Subject: [PATCH 07/15] fix some tests --- src/mlj_model_interface.jl | 16 ++++++++-------- test/classifier.jl | 11 +++++------ test/regressor.jl | 8 ++++---- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/mlj_model_interface.jl b/src/mlj_model_interface.jl index 22e7f7b3..f3d2c9c6 100644 --- a/src/mlj_model_interface.jl +++ b/src/mlj_model_interface.jl @@ -66,21 +66,21 @@ function MLJModelInterface.fit(model::MLJFluxModel, X, y) # GPU and rng related variables - move = Mover(model.acceleration) + move = MLJFlux.Mover(model.acceleration) rng = true_rng(model) # Get input properties shape = MLJFlux.shape(model, X, y) - cat_inds = get_cat_inds(X) + cat_inds = MLJFlux.get_cat_inds(X) pure_continuous_input = isempty(cat_inds) # Decide whether to enable entity embeddings (e.g., ImageClassifier won't) - enable_entity_embs = is_embedding_enabled(model) && !pure_continuous_input + enable_entity_embs = MLJFlux.is_embedding_enabled(model) && !pure_continuous_input # Prepare entity embeddings inputs and encode X if entity embeddings enabled featnames = [] if enable_entity_embs - X = convert_to_table(X) + X = MLJFlux.convert_to_table(X) featnames = Tables.schema(X).names end @@ -88,13 +88,13 @@ function MLJModelInterface.fit(model::MLJFluxModel, # for each categorical feature default_embedding_dims = enable_entity_embs ? model.embedding_dims : Dict{Symbol, Real}() entityprops, entityemb_output_dim = - prepare_entityembs(X, featnames, cat_inds, default_embedding_dims) - X, ordinal_mappings = ordinal_encoder_fit_transform(X; featinds = cat_inds) + MLJFlux.prepare_entityembs(X, featnames, cat_inds, default_embedding_dims) + X, ordinal_mappings = MLJFlux.ordinal_encoder_fit_transform(X; featinds = cat_inds) ## Construct model chain chain = (!enable_entity_embs) ? construct_model_chain(model, rng, shape, move) : - construct_model_chain_with_entityembs( + MLJFlux.construct_model_chain_with_entityembs( model, rng, shape, @@ -104,7 +104,7 @@ function MLJModelInterface.fit(model::MLJFluxModel, ) # Format data as needed by Flux and move to GPU - data = move.(collate(model, X, y, verbosity)) + data = move.(MLJFlux.collate(model, X, y, verbosity)) # Test chain works (as it may be custom) x = data[1][1] diff --git a/test/classifier.jl b/test/classifier.jl index 5d7f1441..4557b595 100644 --- a/test/classifier.jl +++ b/test/classifier.jl @@ -4,18 +4,17 @@ seed!(1234) N = 300 Xm = MLJBase.table(randn(Float32, N, 5)); # purely numeric X = (; Tables.columntable(Xm)..., - Column1 = repeat([1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), + Column1 = repeat(Float32[1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), Column2 = categorical(repeat(['a', 'b', 'c', 'd', 'e'], Int(N / 5))), Column3 = categorical(repeat(["b", "c", "d", "f", "f"], Int(N / 5)), ordered = true), - Column4 = repeat([1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), - Column5 = randn(N), + Column4 = repeat(Float32[1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), + Column5 = randn(Float32, N), Column6 = categorical( repeat(["group1", "group1", "group2", "group2", "group3"], Int(N / 5)), ), ) - -ycont = 2 * X.x1 - X.x3 + 0.1 * rand(N) +ycont = 2 * X.x1 - X.x3 + 0.1 * rand(Float32, N) m, M = minimum(ycont), maximum(ycont) _, a, b, _ = range(m, stop = M, length = 4) |> collect y = map(ycont) do η @@ -126,7 +125,7 @@ end seed!(1234) N = 300 X = MLJBase.table(rand(Float32, N, 4)); -ycont = 2 * X.x1 - X.x3 + 0.1 * rand(N) +ycont = Float32.(2 * X.x1 - X.x3 + 0.1 * rand(N)) m, M = minimum(ycont), maximum(ycont) _, a, _ = range(m, stop = M, length = 3) |> collect y = map(ycont) do η diff --git a/test/regressor.jl b/test/regressor.jl index 74c33a89..0b9c5852 100644 --- a/test/regressor.jl +++ b/test/regressor.jl @@ -3,11 +3,11 @@ Random.seed!(123) N = 200 Xm = MLJBase.table(randn(Float32, N, 5)); # purely numeric X = (; Tables.columntable(Xm)..., - Column1 = repeat([1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), + Column1 = repeat(Float32[1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), Column2 = categorical(repeat(['a', 'b', 'c', 'd', 'e'], Int(N / 5))), Column3 = categorical(repeat(["b", "c", "d", "f", "f"], Int(N / 5)), ordered = true), - Column4 = repeat([1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), - Column5 = randn(N), + Column4 = repeat(Float32[1.0, 2.0, 3.0, 4.0, 5.0], Int(N / 5)), + Column5 = randn(Float32, N), Column6 = categorical( repeat(["group1", "group1", "group2", "group2", "group3"], Int(N / 5)), ), @@ -17,7 +17,7 @@ builder = MLJFlux.Short(σ = identity) optimiser = Optimisers.Adam() Random.seed!(123) -y = 1 .+ X.x1 - X.x2 .- 2X.x4 + X.x5 +y = Float32(1) .+ X.x1 - X.x2 .- 2X.x4 + X.x5 train, test = MLJBase.partition(1:N, 0.7) @testset_accelerated "NeuralNetworkRegressor" accel begin From c57870ba5139b591c3bec0303acf8ad815d7db96 Mon Sep 17 00:00:00 2001 From: Essam Date: Wed, 25 Sep 2024 20:11:33 -0500 Subject: [PATCH 08/15] Fix ordinal encoding ransform type --- src/encoders.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encoders.jl b/src/encoders.jl index a7eba0b0..4d00d2d2 100644 --- a/src/encoders.jl +++ b/src/encoders.jl @@ -67,7 +67,7 @@ function ordinal_encoder_transform(X, mapping_matrix) test_levels = levels(col) check_unkown_levels(train_levels, test_levels) level2scalar = mapping_matrix[ind] - new_col = recode(col, level2scalar...) + new_col = recode(unwrap.(col), level2scalar...) push!(new_feats, new_col) else push!(new_feats, col) From 87c8f66dd479c95383c9ca619c799fa890ff9691 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 27 Sep 2024 09:39:14 +1200 Subject: [PATCH 09/15] ensure ordinal encoder returns concrete type --- src/encoders.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encoders.jl b/src/encoders.jl index 4d00d2d2..31818ab7 100644 --- a/src/encoders.jl +++ b/src/encoders.jl @@ -67,7 +67,7 @@ function ordinal_encoder_transform(X, mapping_matrix) test_levels = levels(col) check_unkown_levels(train_levels, test_levels) level2scalar = mapping_matrix[ind] - new_col = recode(unwrap.(col), level2scalar...) + new_col = [recode(unwrap.(col), level2scalar...)...] push!(new_feats, new_col) else push!(new_feats, col) From 1adf9cf93a14d1a737a7e85900558da0c80d01de Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 27 Sep 2024 10:47:01 +1200 Subject: [PATCH 10/15] tweaks, and relax one tolerance --- test/classifier.jl | 2 +- test/mlj_model_interface.jl | 36 +++++++++++++++++++----------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/test/classifier.jl b/test/classifier.jl index 4557b595..c6539c95 100644 --- a/test/classifier.jl +++ b/test/classifier.jl @@ -110,7 +110,7 @@ end # check different resources (CPU1, CUDALibs, etc)) give about the same loss: reference = losses[1] -@test all(x -> abs(x - reference) / reference < 1e-4, losses[2:end]) +@test all(x -> abs(x - reference) / reference < 1e-3, losses[2:end]) # # NEURAL NETWORK BINARY CLASSIFIER diff --git a/test/mlj_model_interface.jl b/test/mlj_model_interface.jl index 01702544..79849908 100644 --- a/test/mlj_model_interface.jl +++ b/test/mlj_model_interface.jl @@ -76,8 +76,8 @@ end nobservations = 12 Xuser = rand(Float32, nobservations, 3) yuser = rand(Float32, nobservations) - alpha = rand(rng) - lambda = rand(rng) + alpha = rand(rng, Float32) + lambda = rand(rng, Float32) optimiser = Optimisers.Momentum() builder = MLJFlux.Linear() epochs = 1 # don't change this @@ -121,6 +121,7 @@ end # integration test: X, y = MLJBase.make_regression(10) X = Float32.(MLJBase.Tables.matrix(X)) |> MLJBase.Tables.table + y = Float32.(y) mach = MLJBase.machine(model, X, y) MLJBase.fit!(mach, verbosity=0) losses = MLJBase.training_losses(mach) @@ -148,7 +149,8 @@ end builder = LisasBuilder(10), ) - X, y = @load_boston + X = Tables.table(rand(Float32, 75, 2)) + y = rand(Float32, 75) @test_logs( (:error, MLJFlux.ERR_BUILDER), @test_throws UndefVarError(:Chains) MLJBase.fit(model, 0, X, y) @@ -165,16 +167,16 @@ end ] # table case X1 = ( - Column1 = [1.0, 2.0, 3.0, 4.0, 5.0], - Column4 = [1.0, 2.0, 3.0, 4.0, 5.0], - Column5 = randn(5), + Column1 = Float32[1.0, 2.0, 3.0, 4.0, 5.0], + Column4 = Float32[1.0, 2.0, 3.0, 4.0, 5.0], + Column5 = randn(Float32, 5), ) # matrix case - X2 = rand(5, 5) + X2 = rand(Float32, 5, 5) Xs = [X1, X2] y = categorical([0, 1, 0, 1, 1]) - yreg = [0.1, -0.3, 0.2, 0.8, 0.9] + yreg = Float32[0.1, -0.3, 0.2, 0.8, 0.9] ys = [y, y, yreg, yreg] for j in eachindex(Xs) for i in eachindex(models) @@ -210,15 +212,15 @@ end ] X = ( - Column1 = [1.0, 2.0, 3.0, 4.0, 5.0], + Column1 = Float32[1.0, 2.0, 3.0, 4.0, 5.0], Column2 = categorical(['a', 'b', 'c', 'd', 'e']), - Column3 = [1.0, 2.0, 3.0, 4.0, 5.0], - Column4 = randn(5), + Column3 = Float32[1.0, 2.0, 3.0, 4.0, 5.0], + Column4 = randn(Float32, 5), Column5 = categorical(["group1", "group1", "group2", "group2", "group3"]), ) y = categorical([0, 1, 0, 1, 1]) - yreg = [0.1, -0.3, 0.2, 0.8, 0.9] + yreg = Float32[0.1, -0.3, 0.2, 0.8, 0.9] ys = [y, y, yreg, yreg] for i in eachindex(models) @@ -272,15 +274,15 @@ end ] X = ( - Column1 = [1.0, 2.0, 3.0, 4.0, 5.0], + Column1 = Float32[1.0, 2.0, 3.0, 4.0, 5.0], Column2 = categorical(['a', 'b', 'c', 'd', 'e']), - Column3 = [1.0, 2.0, 3.0, 4.0, 5.0], - Column4 = randn(5), + Column3 = Float32[1.0, 2.0, 3.0, 4.0, 5.0], + Column4 = randn(Float32, 5), Column5 = categorical(["group1", "group1", "group2", "group2", "group3"]), ) y = categorical([0, 1, 0, 1, 1]) - yreg = [0.1, -0.3, 0.2, 0.8, 0.9] + yreg = Float32[0.1, -0.3, 0.2, 0.8, 0.9] ys = [y, y, yreg, yreg] for i in eachindex(models) @@ -316,7 +318,7 @@ end [:Column1, :Column2, :Column3, :Column4, :Column5], ) @test mapping_matrices_fit != mapping_matrices_double_fit - # Try model prediction + # Try model prediction Xpred = predict(mach, X) end end From 9aeb7baab0459e963904634f779fcecaca3c00e2 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 27 Sep 2024 11:06:54 +1200 Subject: [PATCH 11/15] try reducing tolerance again --- test/classifier.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/classifier.jl b/test/classifier.jl index c6539c95..b3857b05 100644 --- a/test/classifier.jl +++ b/test/classifier.jl @@ -110,7 +110,8 @@ end # check different resources (CPU1, CUDALibs, etc)) give about the same loss: reference = losses[1] -@test all(x -> abs(x - reference) / reference < 1e-3, losses[2:end]) +println("losses for each resource: $losses") +@test all(x -> abs(x - reference) / reference < 5e-3, losses[2:end]) # # NEURAL NETWORK BINARY CLASSIFIER From fcc4cf8240dc6248dd9d5c1afd40e2850f712d37 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 27 Sep 2024 11:32:36 +1200 Subject: [PATCH 12/15] reduce again --- test/classifier.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/classifier.jl b/test/classifier.jl index b3857b05..89f1e403 100644 --- a/test/classifier.jl +++ b/test/classifier.jl @@ -111,7 +111,7 @@ end # check different resources (CPU1, CUDALibs, etc)) give about the same loss: reference = losses[1] println("losses for each resource: $losses") -@test all(x -> abs(x - reference) / reference < 5e-3, losses[2:end]) +@test all(x -> abs(x - reference) / reference < 1e-2, losses[2:end]) # # NEURAL NETWORK BINARY CLASSIFIER From 3bf09029131d058a641b70eb17122586636efdfe Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Fri, 27 Sep 2024 11:53:36 +1200 Subject: [PATCH 13/15] and again --- test/classifier.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/classifier.jl b/test/classifier.jl index 89f1e403..2dbafef5 100644 --- a/test/classifier.jl +++ b/test/classifier.jl @@ -111,7 +111,7 @@ end # check different resources (CPU1, CUDALibs, etc)) give about the same loss: reference = losses[1] println("losses for each resource: $losses") -@test all(x -> abs(x - reference) / reference < 1e-2, losses[2:end]) +@test all(x -> abs(x - reference) / reference < 0.03, losses[2:end]) # # NEURAL NETWORK BINARY CLASSIFIER From b2bafd27e4ea6bc4f79faa00a1fa975db68b3103 Mon Sep 17 00:00:00 2001 From: Essam Date: Sat, 28 Sep 2024 16:10:10 -0500 Subject: [PATCH 14/15] =?UTF-8?q?=E2=9C=85=20Fix=20float=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/encoders.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encoders.jl b/src/encoders.jl index 31818ab7..5085ce0b 100644 --- a/src/encoders.jl +++ b/src/encoders.jl @@ -22,7 +22,7 @@ function ordinal_encoder_fit(X; featinds) (Set([Float32(i) for i in 1:length(feat_levels)]) == Set(feat_levels)) && continue # Compute the dict using the given feature_mapper function mapping_matrix[i] = - Dict{Any, AbstractFloat}( + Dict{eltype(feat_levels), Float32}( value => Float32(index) for (index, value) in enumerate(feat_levels) ) end From bc805e4fa7c63a77a4f3247d3fc88bed85cb9f8a Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Mon, 30 Sep 2024 09:00:43 +1300 Subject: [PATCH 15/15] remove v -> [v...] from output of encoder --- src/encoders.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encoders.jl b/src/encoders.jl index 5085ce0b..f3961428 100644 --- a/src/encoders.jl +++ b/src/encoders.jl @@ -67,7 +67,7 @@ function ordinal_encoder_transform(X, mapping_matrix) test_levels = levels(col) check_unkown_levels(train_levels, test_levels) level2scalar = mapping_matrix[ind] - new_col = [recode(unwrap.(col), level2scalar...)...] + new_col = recode(unwrap.(col), level2scalar...) push!(new_feats, new_col) else push!(new_feats, col)