Unverified Commit 22bd5641 authored by Guolin Ke's avatar Guolin Ke Committed by GitHub
Browse files

Auto set `objective=None` when using fobj (#1231)

* fix the bug

* fix R
parent 89ce3d2f
...@@ -209,7 +209,9 @@ Booster <- R6Class( ...@@ -209,7 +209,9 @@ Booster <- R6Class(
# Check if objective is empty # Check if objective is empty
if (is.null(fobj)) { if (is.null(fobj)) {
if (private$set_objective_to_none) {
stop("lgb.Booster.update: cannot update due to null objective function")
}
# Boost iteration from known objective # Boost iteration from known objective
ret <- lgb.call("LGBM_BoosterUpdateOneIter_R", ret = NULL, private$handle) ret <- lgb.call("LGBM_BoosterUpdateOneIter_R", ret = NULL, private$handle)
...@@ -219,7 +221,10 @@ Booster <- R6Class( ...@@ -219,7 +221,10 @@ Booster <- R6Class(
if (!is.function(fobj)) { if (!is.function(fobj)) {
stop("lgb.Booster.update: fobj should be a function") stop("lgb.Booster.update: fobj should be a function")
} }
if (!private$set_objective_to_none) {
self$reset_parameter(objective="none")
private$set_objective_to_none = TRUE
}
# Perform objective calculation # Perform objective calculation
gpair <- fobj(private$inner_predict(1), private$train_set) gpair <- fobj(private$inner_predict(1), private$train_set)
...@@ -449,7 +454,7 @@ Booster <- R6Class( ...@@ -449,7 +454,7 @@ Booster <- R6Class(
init_predictor = NULL, init_predictor = NULL,
eval_names = NULL, eval_names = NULL,
higher_better_inner_eval = NULL, higher_better_inner_eval = NULL,
set_objective_to_none = FALSE,
# Predict data # Predict data
inner_predict = function(idx) { inner_predict = function(idx) {
......
...@@ -1282,6 +1282,7 @@ class Booster(object): ...@@ -1282,6 +1282,7 @@ class Booster(object):
self.__need_reload_eval_info = True self.__need_reload_eval_info = True
self.__train_data_name = "training" self.__train_data_name = "training"
self.__attr = {} self.__attr = {}
self.__set_objective_to_none = False
self.best_iteration = -1 self.best_iteration = -1
self.best_score = {} self.best_score = {}
params = {} if params is None else params params = {} if params is None else params
...@@ -1516,12 +1517,17 @@ class Booster(object): ...@@ -1516,12 +1517,17 @@ class Booster(object):
self.__inner_predict_buffer[0] = None self.__inner_predict_buffer[0] = None
is_finished = ctypes.c_int(0) is_finished = ctypes.c_int(0)
if fobj is None: if fobj is None:
if self.__set_objective_to_none:
raise ValueError('Cannot update due to null objective function.')
_safe_call(_LIB.LGBM_BoosterUpdateOneIter( _safe_call(_LIB.LGBM_BoosterUpdateOneIter(
self.handle, self.handle,
ctypes.byref(is_finished))) ctypes.byref(is_finished)))
self.__is_predicted_cur_iter = [False for _ in range_(self.__num_dataset)] self.__is_predicted_cur_iter = [False for _ in range_(self.__num_dataset)]
return is_finished.value == 1 return is_finished.value == 1
else: else:
if not self.__set_objective_to_none:
self.reset_parameter({"objective": "none"})
self.__set_objective_to_none = True
grad, hess = fobj(self.__inner_predict(0), self.train_set) grad, hess = fobj(self.__inner_predict(0), self.train_set)
return self.__boost(grad, hess) return self.__boost(grad, hess)
......
...@@ -375,10 +375,10 @@ double GBDT::BoostFromAverage() { ...@@ -375,10 +375,10 @@ double GBDT::BoostFromAverage() {
} }
bool GBDT::TrainOneIter(const score_t* gradients, const score_t* hessians) { bool GBDT::TrainOneIter(const score_t* gradients, const score_t* hessians) {
auto init_score = BoostFromAverage(); double init_score = 0.0f;
// boosting first // boosting first
if (gradients == nullptr || hessians == nullptr) { if (gradients == nullptr || hessians == nullptr) {
init_score = BoostFromAverage();
#ifdef TIMETAG #ifdef TIMETAG
auto start_time = std::chrono::steady_clock::now(); auto start_time = std::chrono::steady_clock::now();
#endif #endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment