Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[python-package] Expose ObjectiveFunction class #6586

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Use empty, rename
  • Loading branch information
Atanas Dimitrov committed Sep 2, 2024
commit e52568d4bd1c46b1e7f348fd4d956317b631d3e0
1 change: 1 addition & 0 deletions include/LightGBM/objective_function.h
Original file line number Diff line number Diff line change
@@ -68,6 +68,7 @@ class ObjectiveFunction {
virtual data_size_t NumPositiveData() const { return 0; }

virtual void ConvertOutputs(const int num_data, const double* inputs, double* outputs) const {
#pragma omp parallel for num_threads(OMP_NUM_THREADS()) schedule(static)
for (int i = 0; i < num_data; i ++) {
ConvertOutput(inputs + i, outputs + i);
}
8 changes: 4 additions & 4 deletions python-package/lightgbm/basic.py
Original file line number Diff line number Diff line change
@@ -5331,7 +5331,7 @@ def init(self, dataset: Dataset) -> "ObjectiveFunction":
"""
return self.__init_from_dataset(dataset)

def convert_outputs(self, scores: np.ndarray) -> np.ndarray:
def convert_raw_scores(self, scores: np.ndarray) -> np.ndarray:
"""
Convert the raw scores to the final predictions.

@@ -5353,7 +5353,7 @@ def convert_outputs(self, scores: np.ndarray) -> np.ndarray:
scores = _data_to_2d_numpy(scores, dtype=np.float64, name="scores")

num_data = scores.size
out_preds = np.zeros_like(scores, dtype=np.float64)
out_preds = np.empty_like(scores, dtype=np.float64)

_safe_call(
_LIB.LGBM_ObjectiveFunctionConvertOutputs(
@@ -5387,8 +5387,8 @@ def get_gradients(self, y_pred: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
raise ValueError("ObjectiveFunction was not created properly")

data_shape = self.num_data * self.num_class
grad = np.zeros(dtype=np.float32, shape=data_shape)
hess = np.zeros(dtype=np.float32, shape=data_shape)
grad = np.empty(dtype=np.float32, shape=data_shape)
hess = np.empty(dtype=np.float32, shape=data_shape)

_safe_call(
_LIB.LGBM_ObjectiveFunctionGetGradients(
2 changes: 2 additions & 0 deletions src/objective/multiclass_objective.hpp
Original file line number Diff line number Diff line change
@@ -130,6 +130,7 @@ class MulticlassSoftmax: public ObjectiveFunction {
}

void ConvertOutputs(const int num_data, const double* inputs, double* outputs) const override {
#pragma omp parallel for num_threads(OMP_NUM_THREADS()) schedule(static)
for (int i = 0; i < num_data; i += num_class_) {
ConvertOutput(inputs + i, outputs + i);
}
@@ -243,6 +244,7 @@ class MulticlassOVA: public ObjectiveFunction {
}

void ConvertOutputs(const int num_data, const double* inputs, double* outputs) const override {
#pragma omp parallel for num_threads(OMP_NUM_THREADS()) schedule(static)
for (int i = 0; i < num_data; i += num_class_) {
ConvertOutput(inputs + i, outputs + i);
}
4 changes: 2 additions & 2 deletions tests/python_package_test/test_engine.py
Original file line number Diff line number Diff line change
@@ -4423,7 +4423,7 @@ def test_objective_function_class(use_weight, num_boost_round, custom_objective,
"device": "cpu",
}
builtin_loss = builtin_objective(objective_name, copy.deepcopy(params))
builtin_convert_outputs = lgb.ObjectiveFunction(objective_name, copy.deepcopy(params)).convert_outputs
builtin_convert_scores = lgb.ObjectiveFunction(objective_name, copy.deepcopy(params)).convert_raw_scores

params["objective"] = builtin_loss
booster_exposed = lgb.train(params, lgb_train, num_boost_round=num_boost_round)
@@ -4440,4 +4440,4 @@ def test_objective_function_class(use_weight, num_boost_round, custom_objective,
y_pred = np.zeros_like(booster.predict(X, raw_score=True))
np.testing.assert_allclose(builtin_loss(y_pred, lgb_train), custom_objective(y_pred, lgb_train))

np.testing.assert_allclose(builtin_convert_outputs(booster_exposed.predict(X)), booster.predict(X))
np.testing.assert_allclose(builtin_convert_scores(booster_exposed.predict(X)), booster.predict(X))
Loading
Oops, something went wrong.