-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Description
The function remove_keras_spec
has an issue where it removes more models than intended. When creating the to_kill
vector, it deletes all objects whose names start with the name of the model to be deleted. This can cause problems if a user has defined two model specs, for example, my_mlp
and my_mlp_2
. When remove_keras_spec
is called to delete my_mlp
, it will also delete my_mlp_2
because its name also starts with "my_mlp"
.
A more specific approach is needed to create the to_kill
vector. Instead of using a broad pattern, it should use a specific list of suffixes to identify the objects to be removed.
Reprex
# Load necessary libraries
library(kerasnip)
#> Warning: package 'kerasnip' was built under R version 4.5.1
library(parsnip)
#>
#> Attaching package: 'parsnip'
#> The following object is masked from 'package:kerasnip':
#>
#> get_model_env
library(keras3)
#> Warning: package 'keras3' was built under R version 4.5.1
# Create first model spec
create_keras_sequential_spec(
"my_mlp",
list(
input = \(model, input_shape) {
keras_model_sequential(input_shape = input_shape)
},
dense = \(model, units = 16) model |> layer_dense(units = units)
),
"regression"
)
# Create second model spec
create_keras_sequential_spec(
"my_mlp_2",
list(
input = \(model, input_shape) {
keras_model_sequential(input_shape = input_shape)
},
dense = \(model, units = 32) model |> layer_dense(units = units)
),
"regression"
)
# Both models should exist
print(paste("my_mlp exists:", exists("my_mlp")))
#> [1] "my_mlp exists: TRUE"
print(paste("my_mlp_2 exists:", exists("my_mlp_2")))
#> [1] "my_mlp_2 exists: TRUE"
# Remove the first model
remove_keras_spec("my_mlp")
#> Removed from parsnip registry objects: my_mlp, my_mlp_2, my_mlp_2_args, my_mlp_2_encoding, my_mlp_2_fit, my_mlp_2_modes, my_mlp_2_pkgs, my_mlp_2_predict, my_mlp_args, my_mlp_encoding, my_mlp_fit, my_mlp_modes, my_mlp_pkgs, my_mlp_predict
#> Removed 'my_mlp' from parsnip:::get_model_env()$models
# Check if the second model still exists
print(paste("my_mlp exists after removal:", exists("my_mlp")))
#> [1] "my_mlp exists after removal: FALSE"
print(paste("my_mlp_2 exists after removal:", exists("my_mlp_2")))
#> [1] "my_mlp_2 exists after removal: TRUE"
# my_mlp_2 exist in the models list of the parsnip environment but the
# associated objects were deleted as informed by `remove_keras_spec`
Session Info
sessionInfo()
#> R version 4.5.0 (2025-04-11 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 10 x64 (build 19045)
#>
#> Matrix products: default
#> LAPACK version 3.12.1
#>
#> locale:
#> [1] LC_COLLATE=English_United Kingdom.utf8
#> [2] LC_CTYPE=English_United Kingdom.utf8
#> [3] LC_MONETARY=English_United Kingdom.utf8
#> [4] LC_NUMERIC=C
#> [5] LC_TIME=English_United Kingdom.utf8
#>
#> time zone: Europe/Madrid
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] keras3_1.4.0 parsnip_1.3.1 kerasnip_0.0.2.900
#>
#> loaded via a namespace (and not attached):
#> [1] gtable_0.3.6 xfun_0.52 ggplot2_3.5.2
#> [4] recipes_1.3.0 lattice_0.22-6 vctrs_0.6.5
#> [7] tools_4.5.0 tfruns_1.5.3 generics_0.1.3
#> [10] parallel_4.5.0 tibble_3.2.1 pkgconfig_2.0.3
#> [13] Matrix_1.7-3 data.table_1.17.0 lifecycle_1.0.4
#> [16] compiler_4.5.0 munsell_0.5.1 codetools_0.2-20
#> [19] htmltools_0.5.8.1 class_7.3-23 yaml_2.3.10
#> [22] prodlim_2024.06.25 pillar_1.10.2 whisker_0.4.1
#> [25] tidyr_1.3.1 MASS_7.3-65 gower_1.0.2
#> [28] rpart_4.1.24 parallelly_1.43.0 lava_1.8.1
#> [31] tidyselect_1.2.1 digest_0.6.37 future_1.40.0
#> [34] dplyr_1.1.4 purrr_1.0.4 listenv_0.9.1
#> [37] splines_4.5.0 fastmap_1.2.0 grid_4.5.0
#> [40] colorspace_2.1-1 cli_3.6.4 magrittr_2.0.3
#> [43] base64enc_0.1-3 survival_3.8-3 dotty_0.1.0
#> [46] future.apply_1.11.3 withr_3.0.2 scales_1.3.0
#> [49] lubridate_1.9.4 timechange_0.3.0 rmarkdown_2.29
#> [52] globals_0.17.0 nnet_7.3-20 timeDate_4041.110
#> [55] reticulate_1.42.0 png_0.1-8 evaluate_1.0.3
#> [58] knitr_1.50 hardhat_1.4.1 rlang_1.1.6
#> [61] Rcpp_1.0.14 zeallot_0.2.0 glue_1.8.0
#> [64] ipred_0.9-15 reprex_2.1.1 jsonlite_2.0.0
#> [67] R6_2.6.1 fs_1.6.6 tensorflow_2.16.0
Expected Behavior
When remove_keras_spec("my_mlp")
is called, only the my_mlp
model and its associated objects should be removed. The my_mlp_2
model and associated objects should remain untouched.
Actual Behavior
When remove_keras_spec("my_mlp")
is called, objects from both my_mlp
and my_mlp_2
models are removed from the parsnip registry. This is because the function uses a broad grep pattern that matches any model name starting with "my_mlp"
.
Additional Context
The issue is located in the remove_keras_spec.R
file, specifically in the line where the to_kill
vector is created: to_kill <- grep(paste0("^", model_name), all_regs, value = TRUE)
. This should be replaced with a more specific pattern to avoid unintended deletions.