1#ifndef LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_
2#define LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_
4#include <LightGBM/objective_function.h>
5#include <LightGBM/meta.h>
7#include <LightGBM/utils/common.h>
50 label_ = metadata.
label();
53 CHECK_NOTNULL(label_);
54 Common::CheckElementsIntervalClosed<label_t>(label_, 0.0f, 1.0f, num_data_, GetName());
55 Log::Info(
"[%s:%s]: (objective) labels passed interval [0, 1] check", GetName(), __func__);
57 if (weights_ !=
nullptr) {
60 Common::ObtainMinMaxSum(weights_, num_data_, &minw, (
label_t*)
nullptr, &sumw);
62 Log::Fatal(
"[%s]: at least one weight is negative", GetName());
65 Log::Fatal(
"[%s]: sum of weights is zero", GetName());
71 if (weights_ ==
nullptr) {
73 #pragma omp parallel for schedule(static)
75 const double z = 1.0f / (1.0f + std::exp(-score[i]));
76 gradients[i] =
static_cast<score_t>(z - label_[i]);
77 hessians[i] =
static_cast<score_t>(z * (1.0f - z));
81 #pragma omp parallel for schedule(static)
83 const double z = 1.0f / (1.0f + std::exp(-score[i]));
84 gradients[i] =
static_cast<score_t>((z - label_[i]) * weights_[i]);
85 hessians[i] =
static_cast<score_t>(z * (1.0f - z) * weights_[i]);
90 const char* GetName()
const override {
95 void ConvertOutput(
const double* input,
double* output)
const override {
96 output[0] = 1.0f / (1.0f + std::exp(-input[0]));
99 std::string ToString()
const override {
100 std::stringstream str_buf;
101 str_buf << GetName();
102 return str_buf.str();
106 double BoostFromScore(
int)
const override {
109 if (weights_ !=
nullptr) {
110 #pragma omp parallel for schedule(static) reduction(+:suml, sumw)
112 suml += label_[i] * weights_[i];
116 sumw =
static_cast<double>(num_data_);
117 #pragma omp parallel for schedule(static) reduction(+:suml)
122 double pavg = suml / sumw;
123 pavg = std::min(pavg, 1.0 - kEpsilon);
124 pavg = std::max<double>(pavg, kEpsilon);
125 double initscore = std::log(pavg / (1.0f - pavg));
126 Log::Info(
"[%s:%s]: pavg = %f -> initscore = %f", GetName(), __func__, pavg, initscore);
145 min_weight_ = max_weight_ = 0.0f;
154 num_data_ = num_data;
155 label_ = metadata.
label();
158 CHECK_NOTNULL(label_);
159 Common::CheckElementsIntervalClosed<label_t>(label_, 0.0f, 1.0f, num_data_, GetName());
160 Log::Info(
"[%s:%s]: (objective) labels passed interval [0, 1] check", GetName(), __func__);
162 if (weights_ !=
nullptr) {
163 Common::ObtainMinMaxSum(weights_, num_data_, &min_weight_, &max_weight_, (
label_t*)
nullptr);
164 if (min_weight_ <= 0.0f) {
165 Log::Fatal(
"[%s]: at least one weight is non-positive", GetName());
169 double weight_ratio = max_weight_ / min_weight_;
170 Log::Info(
"[%s:%s]: min, max weights = %f, %f; ratio = %f",
172 min_weight_, max_weight_,
180 if (weights_ ==
nullptr) {
182 #pragma omp parallel for schedule(static)
184 const double z = 1.0f / (1.0f + std::exp(-score[i]));
185 gradients[i] =
static_cast<score_t>(z - label_[i]);
186 hessians[i] =
static_cast<score_t>(z * (1.0f - z));
190 #pragma omp parallel for schedule(static)
192 const double w = weights_[i];
193 const double y = label_[i];
194 const double epf = std::exp(score[i]);
195 const double hhat = std::log(1.0f + epf);
196 const double z = 1.0f - std::exp(-w*hhat);
197 const double enf = 1.0f / epf;
198 gradients[i] =
static_cast<score_t>((1.0f - y / z) * w / (1.0f + enf));
199 const double c = 1.0f / (1.0f - z);
200 double d = 1.0f + epf;
201 const double a = w * epf / (d * d);
203 const double b = (c / (d * d) ) * (1.0f + w * epf - c);
204 hessians[i] =
static_cast<score_t>(a * (1.0f + y * b));
209 const char* GetName()
const override {
222 void ConvertOutput(
const double* input,
double* output)
const override {
223 output[0] = std::log(1.0f + std::exp(input[0]));
226 std::string ToString()
const override {
227 std::stringstream str_buf;
228 str_buf << GetName();
229 return str_buf.str();
232 double BoostFromScore(
int)
const override {
235 if (weights_ !=
nullptr) {
236 #pragma omp parallel for schedule(static) reduction(+:suml, sumw)
238 suml += label_[i] * weights_[i];
242 sumw =
static_cast<double>(num_data_);
243 #pragma omp parallel for schedule(static) reduction(+:suml)
248 double havg = suml / sumw;
249 double initscore = std::log(std::exp(havg) - 1.0f);
250 Log::Info(
"[%s:%s]: havg = %f -> initscore = %f", GetName(), __func__, havg, initscore);
Objective function for alternative parameterization of cross-entropy (see top of file for explanation...
Definition xentropy_objective.hpp:142
void GetGradients(const double *score, score_t *gradients, score_t *hessians) const override
calculating first order derivative of loss function
Definition xentropy_objective.hpp:179
void Init(const Metadata &metadata, data_size_t num_data) override
Initialize.
Definition xentropy_objective.hpp:153
Objective function for cross-entropy (with optional linear weights)
Definition xentropy_objective.hpp:38
void GetGradients(const double *score, score_t *gradients, score_t *hessians) const override
calculating first order derivative of loss function
Definition xentropy_objective.hpp:70
void Init(const Metadata &metadata, data_size_t num_data) override
Initialize.
Definition xentropy_objective.hpp:48
The interface of Objective Function.
Definition objective_function.h:13
desc and descl2 fields must be written in reStructuredText format
Definition application.h:10
float score_t
Type of score, and gradients.
Definition meta.h:26
float label_t
Type of metadata, include weight and label.
Definition meta.h:33
int32_t data_size_t
Type of data size, it is better to use signed type.
Definition meta.h:14