-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[R-package] enable saving Booster with saveRDS() and loading it with …
…readRDS() (fixes #4296) (#4685) * idiomatic serialization * linter * linter, namespace * comments, linter, fix failing test * standardize error messages for null handles * auto-restore handle in more functions * linter * missing declaration * correct wrong signature * fix docs * Update R-package/R/lgb.train.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/R/lgb.drop_serialized.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/R/lgb.restore_handle.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/R/lgb.restore_handle.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/R/lgb.make_serializable.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * move 'restore_handle' from feature importance to dump method * missing header * move arguments order, update docs * linter * avoid leaving files in working directory * add test for save_model=NULL * missing comma * Update R-package/R/lgb.restore_handle.R Co-authored-by: Nikita Titov <nekit94-08@mail.ru> * Update R-package/src/lightgbm_R.cpp Co-authored-by: Nikita Titov <nekit94-08@mail.ru> * change name of error function * update comment * restore old serialization functions but set as deprecated * Update R-package/R/readRDS.lgb.Booster.R Co-authored-by: Nikita Titov <nekit94-08@mail.ru> * Update R-package/R/saveRDS.lgb.Booster.R Co-authored-by: Nikita Titov <nekit94-08@mail.ru> * update docs * Update R-package/R/readRDS.lgb.Booster.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/R/saveRDS.lgb.Booster.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/tests/testthat/test_basic.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * Update R-package/R/readRDS.lgb.Booster.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * comments * fix variable name * restore serialization test for linear models * Update R-package/R/lightgbm.R Co-authored-by: James Lamb <jaylamb20@gmail.com> * update docs * fix issues with null terminator Co-authored-by: James Lamb <jaylamb20@gmail.com> Co-authored-by: Nikita Titov <nekit94-08@mail.ru>
- Loading branch information
1 parent
f54e32f
commit 12b1527
Showing
25 changed files
with
495 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#' @name lgb.drop_serialized | ||
#' @title Drop serialized raw bytes in a LightGBM model object | ||
#' @description If a LightGBM model object was produced with argument `serializable=TRUE`, the R object will keep | ||
#' a copy of the underlying C++ object as raw bytes, which can be used to reconstruct such object after getting | ||
#' serialized and de-serialized, but at the cost of extra memory usage. If these raw bytes are not needed anymore, | ||
#' they can be dropped through this function in order to save memory. Note that the object will be modified in-place. | ||
#' @param model \code{lgb.Booster} object which was produced with `serializable=TRUE`. | ||
#' | ||
#' @return \code{lgb.Booster} (the same `model` object that was passed as input, as invisible). | ||
#' @seealso \link{lgb.restore_handle}, \link{lgb.make_serializable}. | ||
#' @export | ||
lgb.drop_serialized <- function(model) { | ||
if (!lgb.is.Booster(x = model)) { | ||
stop("lgb.drop_serialized: model should be an ", sQuote("lgb.Booster")) | ||
} | ||
model$drop_raw() | ||
return(invisible(model)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#' @name lgb.make_serializable | ||
#' @title Make a LightGBM object serializable by keeping raw bytes | ||
#' @description If a LightGBM model object was produced with argument `serializable=FALSE`, the R object will not | ||
#' be serializable (e.g. cannot save and load with \code{saveRDS} and \code{readRDS}) as it will lack the raw bytes | ||
#' needed to reconstruct its underlying C++ object. This function can be used to forcibly produce those serialized | ||
#' raw bytes and make the object serializable. Note that the object will be modified in-place. | ||
#' @param model \code{lgb.Booster} object which was produced with `serializable=FALSE`. | ||
#' | ||
#' @return \code{lgb.Booster} (the same `model` object that was passed as input, as invisible). | ||
#' @seealso \link{lgb.restore_handle}, \link{lgb.drop_serialized}. | ||
#' @export | ||
lgb.make_serializable <- function(model) { | ||
if (!lgb.is.Booster(x = model)) { | ||
stop("lgb.make_serializable: model should be an ", sQuote("lgb.Booster")) | ||
} | ||
model$save_raw() | ||
return(invisible(model)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#' @name lgb.restore_handle | ||
#' @title Restore the C++ component of a de-serialized LightGBM model | ||
#' @description After a LightGBM model object is de-serialized through functions such as \code{save} or | ||
#' \code{saveRDS}, its underlying C++ object will be blank and needs to be restored to able to use it. Such | ||
#' object is restored automatically when calling functions such as \code{predict}, but this function can be | ||
#' used to forcibly restore it beforehand. Note that the object will be modified in-place. | ||
#' @param model \code{lgb.Booster} object which was de-serialized and whose underlying C++ object and R handle | ||
#' need to be restored. | ||
#' | ||
#' @return \code{lgb.Booster} (the same `model` object that was passed as input, invisibly). | ||
#' @seealso \link{lgb.make_serializable}, \link{lgb.drop_serialized}. | ||
#' @examples | ||
#' library(lightgbm) | ||
#' data("agaricus.train") | ||
#' model <- lightgbm( | ||
#' agaricus.train$data | ||
#' , agaricus.train$label | ||
#' , params = list(objective = "binary", nthreads = 1L) | ||
#' , nrounds = 5L | ||
#' , save_name = NULL | ||
#' , verbose = 0) | ||
#' fname <- tempfile(fileext="rds") | ||
#' saveRDS(model, fname) | ||
#' | ||
#' model_new <- readRDS(fname) | ||
#' model_new$check_null_handle() | ||
#' lgb.restore_handle(model_new) | ||
#' model_new$check_null_handle() | ||
#' @export | ||
lgb.restore_handle <- function(model) { | ||
if (!lgb.is.Booster(x = model)) { | ||
stop("lgb.restore_handle: model should be an ", sQuote("lgb.Booster")) | ||
} | ||
model$restore_handle() | ||
return(invisible(model)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.