1
1
/* *
2
- * Copyright 2015-2024 , XGBoost Contributors
2
+ * Copyright 2015-2025 , XGBoost Contributors
3
3
* \file regression_obj.cu
4
4
* \brief Definition of single-value regression and classification objectives.
5
5
* \author Tianqi Chen, Kailong Chen
9
9
#include < algorithm>
10
10
#include < cmath>
11
11
#include < cstdint> // std::int32_t
12
- #include < memory>
13
12
#include < vector>
14
13
15
14
#include " ../common/common.h"
@@ -53,56 +52,56 @@ void CheckRegInputs(MetaInfo const& info, HostDeviceVector<bst_float> const& pre
53
52
CheckInitInputs (info);
54
53
CHECK_EQ (info.labels .Size (), preds.Size ()) << " Invalid shape of labels." ;
55
54
}
55
+
56
+ template <typename Loss>
57
+ void ValidateLabel (Context const * ctx, MetaInfo const & info) {
58
+ auto label = info.labels .View (ctx->Device ());
59
+ auto valid = ctx->DispatchDevice (
60
+ [&] {
61
+ return std::all_of (linalg::cbegin (label), linalg::cend (label),
62
+ [](float y) -> bool { return Loss::CheckLabel (y); });
63
+ },
64
+ [&] {
65
+ #if defined(XGBOOST_USE_CUDA)
66
+ auto cuctx = ctx->CUDACtx ();
67
+ auto it = dh::MakeTransformIterator<bool >(
68
+ thrust::make_counting_iterator (0ul ), [=] XGBOOST_DEVICE (std::size_t i) -> bool {
69
+ auto [m, n] = linalg::UnravelIndex (i, label.Shape ());
70
+ return Loss::CheckLabel (label (m, n));
71
+ });
72
+ return dh::Reduce (cuctx->CTP (), it, it + label.Size (), true , thrust::logical_and<>{});
73
+ #else
74
+ common::AssertGPUSupport ();
75
+ return false ;
76
+ #endif // defined(XGBOOST_USE_CUDA)
77
+ },
78
+ [&] {
79
+ #if defined(XGBOOST_USE_SYCL)
80
+ return sycl::linalg::Validate (ctx->Device (), label,
81
+ [](float y) -> bool { return Loss::CheckLabel (y); });
82
+ #else
83
+ common::AssertSYCLSupport ();
84
+ return false ;
85
+ #endif // defined(XGBOOST_USE_SYCL)
86
+ });
87
+ if (!valid) {
88
+ LOG (FATAL) << Loss::LabelErrorMsg ();
89
+ }
90
+ }
56
91
} // anonymous namespace
57
92
58
93
#if defined(XGBOOST_USE_CUDA)
59
94
DMLC_REGISTRY_FILE_TAG (regression_obj_gpu);
60
95
#endif // defined(XGBOOST_USE_CUDA)
61
96
62
-
63
-
64
97
template <typename Loss>
65
98
class RegLossObj : public FitInterceptGlmLike {
66
99
protected:
67
100
HostDeviceVector<float > additional_input_;
68
101
69
102
public:
70
- void ValidateLabel (MetaInfo const & info) {
71
- auto label = info.labels .View (ctx_->Device ());
72
- auto valid = ctx_->DispatchDevice (
73
- [&] {
74
- return std::all_of (linalg::cbegin (label), linalg::cend (label),
75
- [](float y) -> bool { return Loss::CheckLabel (y); });
76
- },
77
- [&] {
78
- #if defined(XGBOOST_USE_CUDA)
79
- auto cuctx = ctx_->CUDACtx ();
80
- auto it = dh::MakeTransformIterator<bool >(
81
- thrust::make_counting_iterator (0ul ), [=] XGBOOST_DEVICE (std::size_t i) -> bool {
82
- auto [m, n] = linalg::UnravelIndex (i, label.Shape ());
83
- return Loss::CheckLabel (label (m, n));
84
- });
85
- return dh::Reduce (cuctx->CTP (), it, it + label.Size (), true , thrust::logical_and<>{});
86
- #else
87
- common::AssertGPUSupport ();
88
- return false ;
89
- #endif // defined(XGBOOST_USE_CUDA)
90
- },
91
- [&] {
92
- #if defined(XGBOOST_USE_SYCL)
93
- return sycl::linalg::Validate (ctx_->Device (), label,
94
- [](float y) -> bool { return Loss::CheckLabel (y); });
95
- #else
96
- common::AssertSYCLSupport ();
97
- return false ;
98
- #endif // defined(XGBOOST_USE_SYCL)
99
- });
100
- if (!valid) {
101
- LOG (FATAL) << Loss::LabelErrorMsg ();
102
- }
103
- }
104
103
// 0 - scale_pos_weight, 1 - is_null_weight
105
- RegLossObj (): additional_input_(2 ) {}
104
+ RegLossObj () : additional_input_(2 ) {}
106
105
107
106
void Configure (const std::vector<std::pair<std::string, std::string> >& args) override {
108
107
param_.UpdateAllowUnknown (args);
@@ -119,7 +118,7 @@ class RegLossObj : public FitInterceptGlmLike {
119
118
std::int32_t iter, linalg::Matrix<GradientPair>* out_gpair) override {
120
119
CheckRegInputs (info, preds);
121
120
if (iter == 0 ) {
122
- ValidateLabel ( info);
121
+ ValidateLabel<Loss>( this -> ctx_ , info);
123
122
}
124
123
125
124
size_t const ndata = preds.Size ();
@@ -222,10 +221,6 @@ XGBOOST_REGISTER_OBJECTIVE(SquaredLossRegression, LinearSquareLoss::Name())
222
221
.describe(" Regression with squared error." )
223
222
.set_body([]() { return new RegLossObj<LinearSquareLoss>(); });
224
223
225
- XGBOOST_REGISTER_OBJECTIVE (SquareLogError, SquaredLogError::Name())
226
- .describe(" Regression with root mean squared logarithmic error." )
227
- .set_body([]() { return new RegLossObj<SquaredLogError>(); });
228
-
229
224
XGBOOST_REGISTER_OBJECTIVE (LogisticRegression, LogisticRegression::Name())
230
225
.describe(" Logistic regression for probability regression task." )
231
226
.set_body([]() { return new RegLossObj<LogisticRegression>(); });
@@ -251,8 +246,57 @@ XGBOOST_REGISTER_OBJECTIVE(LinearRegression, "reg:linear")
251
246
return new RegLossObj<LinearSquareLoss>(); });
252
247
// End deprecated
253
248
249
+ class SquaredLogErrorRegression : public FitIntercept {
250
+ public:
251
+ static auto Name () { return SquaredLogError::Name (); }
252
+
253
+ void Configure (Args const &) override {}
254
+ [[nodiscard]] ObjInfo Task () const override { return ObjInfo::kRegression ; }
255
+ [[nodiscard]] bst_target_t Targets (MetaInfo const & info) const override {
256
+ return std::max (static_cast <std::size_t >(1 ), info.labels .Shape (1 ));
257
+ }
258
+ void GetGradient (HostDeviceVector<bst_float> const & preds, const MetaInfo& info,
259
+ std::int32_t iter, linalg::Matrix<GradientPair>* out_gpair) override {
260
+ if (iter == 0 ) {
261
+ ValidateLabel<SquaredLogError>(this ->ctx_ , info);
262
+ }
263
+ auto labels = info.labels .View (ctx_->Device ());
264
+
265
+ out_gpair->SetDevice (ctx_->Device ());
266
+ out_gpair->Reshape (info.num_row_ , this ->Targets (info));
267
+ auto gpair = out_gpair->View (ctx_->Device ());
268
+
269
+ preds.SetDevice (ctx_->Device ());
270
+ auto predt = linalg::MakeTensorView (ctx_, &preds, info.num_row_ , this ->Targets (info));
271
+
272
+ info.weights_ .SetDevice (ctx_->Device ());
273
+ common::OptionalWeights weight{ctx_->IsCPU () ? info.weights_ .ConstHostSpan ()
274
+ : info.weights_ .ConstDeviceSpan ()};
275
+ linalg::ElementWiseKernel (this ->ctx_ , labels,
276
+ [=] XGBOOST_DEVICE (std::size_t i, std::size_t j) mutable {
277
+ auto p = predt (i, j);
278
+ auto y = labels (i, j);
279
+ auto w = weight[i];
280
+ auto grad = SquaredLogError::FirstOrderGradient (p, y);
281
+ auto hess = SquaredLogError::SecondOrderGradient (p, y);
282
+ gpair (i) = {grad * w, hess * w};
283
+ });
284
+ }
285
+ [[nodiscard]] const char * DefaultEvalMetric () const override { return " rmsle" ; }
286
+
287
+ void SaveConfig (Json* p_out) const override {
288
+ auto & out = *p_out;
289
+ out[" name" ] = String (Name ());
290
+ }
291
+ void LoadConfig (Json const &) override {}
292
+ };
293
+
294
+ XGBOOST_REGISTER_OBJECTIVE (SquaredLogErrorRegression, SquaredLogErrorRegression::Name())
295
+ .describe(" Root mean squared log error." )
296
+ .set_body([]() { return new SquaredLogErrorRegression (); });
297
+
254
298
class PseudoHuberRegression : public FitIntercept {
255
- PesudoHuberParam param_;
299
+ PseudoHuberParam param_;
256
300
257
301
public:
258
302
void Configure (Args const & args) override { param_.UpdateAllowUnknown (args); }
0 commit comments