Commit 12a96334 authored by Guolin Ke's avatar Guolin Ke
Browse files

change inner prediction score to double type.

parent 5d12a8db
......@@ -94,7 +94,7 @@ public:
* \param out_len length of returned score
* \return training score
*/
virtual const score_t* GetTrainingScore(int64_t* out_len) = 0;
virtual const double* GetTrainingScore(int64_t* out_len) = 0;
/*!
* \brief Get prediction result at data_idx data
......
......@@ -96,6 +96,8 @@ public:
*/
void SetInitScore(const float* init_score, data_size_t len);
void SetInitScore(const double* init_score, data_size_t len);
/*!
* \brief Save binary data to file
......
......@@ -28,12 +28,12 @@ public:
virtual const std::vector<std::string>& GetName() const = 0;
virtual score_t factor_to_bigger_better() const = 0;
virtual double factor_to_bigger_better() const = 0;
/*!
* \brief Calcaluting and printing metric result
* \param score Current prediction score
*/
virtual std::vector<double> Eval(const score_t* score) const = 0;
virtual std::vector<double> Eval(const double* score) const = 0;
Metric() = default;
/*! \brief Disable copy */
......@@ -69,8 +69,8 @@ public:
* \param num_data Number of data
* \return The DCG score
*/
static score_t CalDCGAtK(data_size_t k, const float* label,
const score_t* score, data_size_t num_data);
static double CalDCGAtK(data_size_t k, const float* label,
const double* score, data_size_t num_data);
/*!
* \brief Calculate the DCG score at multi position
......@@ -81,8 +81,8 @@ public:
* \param out Output result
*/
static void CalDCG(const std::vector<data_size_t>& ks,
const float* label, const score_t* score,
data_size_t num_data, std::vector<score_t>* out);
const float* label, const double* score,
data_size_t num_data, std::vector<double>* out);
/*!
* \brief Calculate the Max DCG score at position k
......@@ -91,7 +91,7 @@ public:
* \param num_data Number of data
* \return The max DCG score
*/
static score_t CalMaxDCGAtK(data_size_t k,
static double CalMaxDCGAtK(data_size_t k,
const float* label, data_size_t num_data);
/*!
......@@ -102,22 +102,22 @@ public:
* \param out Output result
*/
static void CalMaxDCG(const std::vector<data_size_t>& ks,
const float* label, data_size_t num_data, std::vector<score_t>* out);
const float* label, data_size_t num_data, std::vector<double>* out);
/*!
* \brief Get discount score of position k
* \param k The position
* \return The discount of this position
*/
inline static score_t GetDiscount(data_size_t k) { return discount_[k]; }
inline static double GetDiscount(data_size_t k) { return discount_[k]; }
private:
/*! \brief True if inited, avoid init multi times */
static bool is_inited_;
/*! \brief store gains for different label */
static std::vector<score_t> label_gain_;
static std::vector<double> label_gain_;
/*! \brief store discount score for different position */
static std::vector<score_t> discount_;
static std::vector<double> discount_;
/*! \brief max position for eval */
static const data_size_t kMaxPosition;
};
......
......@@ -28,7 +28,7 @@ public:
* \gradients Output gradients
* \hessians Output hessians
*/
virtual void GetGradients(const score_t* score,
virtual void GetGradients(const double* score,
score_t* gradients, score_t* hessians) const = 0;
virtual const char* GetName() const = 0;
......
......@@ -65,7 +65,7 @@ public:
* \param score Will add prediction to score
*/
void AddPredictionToScore(const Dataset* data, data_size_t num_data,
score_t* score) const;
double* score) const;
/*!
* \brief Adding prediction value of this tree model to scorese
......@@ -76,7 +76,7 @@ public:
*/
void AddPredictionToScore(const Dataset* data,
const data_size_t* used_data_indices,
data_size_t num_data, score_t* score) const;
data_size_t num_data, double* score) const;
/*!
* \brief Prediction on one record
......
......@@ -53,7 +53,7 @@ public:
* \brief Using last trained tree to predict score then adding to out_score;
* \param out_score output score
*/
virtual void AddPredictionToScore(score_t *out_score) const = 0;
virtual void AddPredictionToScore(double* out_score) const = 0;
TreeLearner() = default;
/*! \brief Disable copy */
......
......@@ -62,7 +62,7 @@ public:
* \param out_len length of returned score
* \return training score
*/
const score_t* GetTrainingScore(int64_t* out_len) override {
const double* GetTrainingScore(int64_t* out_len) override {
if (!is_update_score_cur_iter_) {
// only drop one time in one iteration
DroppingTrees();
......
......@@ -407,7 +407,7 @@ std::vector<double> GBDT::GetEvalAt(int data_idx) const {
}
/*! \brief Get training scores result */
const score_t* GBDT::GetTrainingScore(int64_t* out_len) {
const double* GBDT::GetTrainingScore(int64_t* out_len) {
*out_len = static_cast<int64_t>(train_score_updater_->num_data()) * num_class_;
return train_score_updater_->score();
}
......@@ -415,7 +415,7 @@ const score_t* GBDT::GetTrainingScore(int64_t* out_len) {
void GBDT::GetPredictAt(int data_idx, double* out_result, int64_t* out_len) {
CHECK(data_idx >= 0 && data_idx <= static_cast<int>(valid_score_updater_.size()));
const score_t* raw_scores = nullptr;
const double* raw_scores = nullptr;
data_size_t num_data = 0;
if (data_idx == 0) {
raw_scores = GetTrainingScore(out_len);
......
......@@ -105,7 +105,7 @@ public:
* \param out_len length of returned score
* \return training score
*/
virtual const score_t* GetTrainingScore(int64_t* out_len) override;
virtual const double* GetTrainingScore(int64_t* out_len) override;
virtual int64_t GetNumPredictAt(int data_idx) const override {
CHECK(data_idx >= 0 && data_idx <= static_cast<int>(valid_score_updater_.size()));
......
......@@ -72,7 +72,7 @@ public:
tree->AddPredictionToScore(data_, data_indices, data_cnt, score_.data() + curr_class * num_data_);
}
/*! \brief Pointer of score */
inline const score_t* score() const { return score_.data(); }
inline const double* score() const { return score_.data(); }
inline const data_size_t num_data() const { return num_data_; }
/*! \brief Disable copy */
......@@ -85,7 +85,7 @@ private:
/*! \brief Pointer of data set */
const Dataset* data_;
/*! \brief Scores for data set */
std::vector<score_t> score_;
std::vector<double> score_;
};
} // namespace LightGBM
......
......@@ -793,7 +793,7 @@ void DatasetLoader::ExtractFeaturesFromMemory(std::vector<std::string>& text_dat
}
} else {
// if need to prediction with initial model
std::vector<score_t> init_score(dataset->num_data_ * num_class_);
std::vector<double> init_score(dataset->num_data_ * num_class_);
#pragma omp parallel for schedule(guided) private(oneline_features) firstprivate(tmp_label)
for (data_size_t i = 0; i < dataset->num_data_; ++i) {
const int tid = omp_get_thread_num();
......@@ -803,7 +803,7 @@ void DatasetLoader::ExtractFeaturesFromMemory(std::vector<std::string>& text_dat
// set initial score
std::vector<double> oneline_init_score = predict_fun_(oneline_features);
for (int k = 0; k < num_class_; ++k) {
init_score[k * dataset->num_data_ + i] = static_cast<float>(oneline_init_score[k]);
init_score[k * dataset->num_data_ + i] = static_cast<double>(oneline_init_score[k]);
}
// set label
dataset->metadata_.SetLabelAt(i, static_cast<float>(tmp_label));
......@@ -837,9 +837,9 @@ void DatasetLoader::ExtractFeaturesFromMemory(std::vector<std::string>& text_dat
/*! \brief Extract local features from file */
void DatasetLoader::ExtractFeaturesFromFile(const char* filename, const Parser* parser, const std::vector<data_size_t>& used_data_indices, Dataset* dataset) {
std::vector<score_t> init_score;
std::vector<double> init_score;
if (predict_fun_ != nullptr) {
init_score = std::vector<score_t>(dataset->num_data_ * num_class_);
init_score = std::vector<double>(dataset->num_data_ * num_class_);
}
std::function<void(data_size_t, const std::vector<std::string>&)> process_fun =
[this, &init_score, &parser, &dataset]
......@@ -856,7 +856,7 @@ void DatasetLoader::ExtractFeaturesFromFile(const char* filename, const Parser*
if (!init_score.empty()) {
std::vector<double> oneline_init_score = predict_fun_(oneline_features);
for (int k = 0; k < num_class_; ++k) {
init_score[k * dataset->num_data_ + start_idx + i] = static_cast<float>(oneline_init_score[k]);
init_score[k * dataset->num_data_ + start_idx + i] = static_cast<double>(oneline_init_score[k]);
}
}
// set label
......
......@@ -279,6 +279,25 @@ void Metadata::SetInitScore(const float* init_score, data_size_t len) {
}
}
void Metadata::SetInitScore(const double* init_score, data_size_t len) {
std::lock_guard<std::mutex> lock(mutex_);
// save to nullptr
if (init_score == nullptr || len == 0) {
init_score_.clear();
num_init_score_ = 0;
return;
}
if ((len % num_data_) != 0) {
Log::Fatal("Initial score size doesn't match data size");
}
if (!init_score_.empty()) { init_score_.clear(); }
num_init_score_ = len;
init_score_ = std::vector<float>(len);
for (data_size_t i = 0; i < len; ++i) {
init_score_[i] = static_cast<float>(init_score[i]);
}
}
void Metadata::SetLabel(const float* label, data_size_t len) {
std::lock_guard<std::mutex> lock(mutex_);
if (label == nullptr) {
......
......@@ -95,20 +95,20 @@ int Tree::Split(int leaf, int feature, BinType bin_type, unsigned int threshold_
return num_leaves_ - 1;
}
void Tree::AddPredictionToScore(const Dataset* data, data_size_t num_data, score_t* score) const {
void Tree::AddPredictionToScore(const Dataset* data, data_size_t num_data, double* score) const {
Threading::For<data_size_t>(0, num_data, [this, data, score](int, data_size_t start, data_size_t end) {
std::vector<std::unique_ptr<BinIterator>> iterators(data->num_features());
for (int i = 0; i < data->num_features(); ++i) {
iterators[i].reset(data->FeatureAt(i)->bin_data()->GetIterator(start));
}
for (data_size_t i = start; i < end; ++i) {
score[i] += static_cast<score_t>(leaf_value_[GetLeaf(iterators, i)]);
score[i] += static_cast<double>(leaf_value_[GetLeaf(iterators, i)]);
}
});
}
void Tree::AddPredictionToScore(const Dataset* data, const data_size_t* used_data_indices,
data_size_t num_data, score_t* score) const {
data_size_t num_data, double* score) const {
Threading::For<data_size_t>(0, num_data,
[this, data, used_data_indices, score](int, data_size_t start, data_size_t end) {
std::vector<std::unique_ptr<BinIterator>> iterators(data->num_features());
......@@ -116,7 +116,7 @@ void Tree::AddPredictionToScore(const Dataset* data, const data_size_t* used_dat
iterators[i].reset(data->FeatureAt(i)->bin_data()->GetIterator(used_data_indices[start]));
}
for (data_size_t i = start; i < end; ++i) {
score[used_data_indices[i]] += static_cast<score_t>(leaf_value_[GetLeaf(iterators, used_data_indices[i])]);
score[used_data_indices[i]] += static_cast<double>(leaf_value_[GetLeaf(iterators, used_data_indices[i])]);
}
});
}
......
......@@ -19,7 +19,7 @@ template<typename PointWiseLossCalculator>
class BinaryMetric: public Metric {
public:
explicit BinaryMetric(const MetricConfig& config) {
sigmoid_ = static_cast<score_t>(config.sigmoid);
sigmoid_ = static_cast<double>(config.sigmoid);
if (sigmoid_ <= 0.0f) {
Log::Fatal("Sigmoid parameter %f should greater than zero", sigmoid_);
}
......@@ -53,17 +53,17 @@ public:
return name_;
}
score_t factor_to_bigger_better() const override {
double factor_to_bigger_better() const override {
return -1.0f;
}
std::vector<double> Eval(const score_t* score) const override {
std::vector<double> Eval(const double* score) const override {
double sum_loss = 0.0f;
if (weights_ == nullptr) {
#pragma omp parallel for schedule(static) reduction(+:sum_loss)
for (data_size_t i = 0; i < num_data_; ++i) {
// sigmoid transform
score_t prob = 1.0f / (1.0f + std::exp(-2.0f * sigmoid_ * score[i]));
double prob = 1.0f / (1.0f + std::exp(-2.0f * sigmoid_ * score[i]));
// add loss
sum_loss += PointWiseLossCalculator::LossOnPoint(label_[i], prob);
}
......@@ -71,7 +71,7 @@ public:
#pragma omp parallel for schedule(static) reduction(+:sum_loss)
for (data_size_t i = 0; i < num_data_; ++i) {
// sigmoid transform
score_t prob = 1.0f / (1.0f + std::exp(-2.0f * sigmoid_ * score[i]));
double prob = 1.0f / (1.0f + std::exp(-2.0f * sigmoid_ * score[i]));
// add loss
sum_loss += PointWiseLossCalculator::LossOnPoint(label_[i], prob) * weights_[i];
}
......@@ -92,7 +92,7 @@ private:
/*! \brief Name of test set */
std::vector<std::string> name_;
/*! \brief Sigmoid parameter */
score_t sigmoid_;
double sigmoid_;
};
/*!
......@@ -102,7 +102,7 @@ class BinaryLoglossMetric: public BinaryMetric<BinaryLoglossMetric> {
public:
explicit BinaryLoglossMetric(const MetricConfig& config) :BinaryMetric<BinaryLoglossMetric>(config) {}
inline static score_t LossOnPoint(float label, score_t prob) {
inline static double LossOnPoint(float label, double prob) {
if (label == 0) {
if (1.0f - prob > kEpsilon) {
return -std::log(1.0f - prob);
......@@ -126,7 +126,7 @@ class BinaryErrorMetric: public BinaryMetric<BinaryErrorMetric> {
public:
explicit BinaryErrorMetric(const MetricConfig& config) :BinaryMetric<BinaryErrorMetric>(config) {}
inline static score_t LossOnPoint(float label, score_t prob) {
inline static double LossOnPoint(float label, double prob) {
if (prob <= 0.5f) {
return label;
} else {
......@@ -155,7 +155,7 @@ public:
return name_;
}
score_t factor_to_bigger_better() const override {
double factor_to_bigger_better() const override {
return 1.0f;
}
......@@ -178,7 +178,7 @@ public:
}
}
std::vector<double> Eval(const score_t* score) const override {
std::vector<double> Eval(const double* score) const override {
// get indices sorted by score, descent order
std::vector<data_size_t> sorted_idx;
for (data_size_t i = 0; i < num_data_; ++i) {
......@@ -193,11 +193,11 @@ public:
double accum = 0.0f;
// temp sum of negative label
double cur_neg = 0.0f;
score_t threshold = score[sorted_idx[0]];
double threshold = score[sorted_idx[0]];
if (weights_ == nullptr) { // no weights
for (data_size_t i = 0; i < num_data_; ++i) {
const float cur_label = label_[sorted_idx[i]];
const score_t cur_score = score[sorted_idx[i]];
const double cur_score = score[sorted_idx[i]];
// new threshold
if (cur_score != threshold) {
threshold = cur_score;
......@@ -213,7 +213,7 @@ public:
} else { // has weights
for (data_size_t i = 0; i < num_data_; ++i) {
const float cur_label = label_[sorted_idx[i]];
const score_t cur_score = score[sorted_idx[i]];
const double cur_score = score[sorted_idx[i]];
const float cur_weight = weights_[sorted_idx[i]];
// new threshold
if (cur_score != threshold) {
......
......@@ -11,8 +11,8 @@ namespace LightGBM {
/*! \brief Declaration for some static members */
bool DCGCalculator::is_inited_ = false;
std::vector<score_t> DCGCalculator::label_gain_;
std::vector<score_t> DCGCalculator::discount_;
std::vector<double> DCGCalculator::label_gain_;
std::vector<double> DCGCalculator::discount_;
const data_size_t DCGCalculator::kMaxPosition = 10000;
void DCGCalculator::Init(std::vector<double> input_label_gain) {
......@@ -20,7 +20,7 @@ void DCGCalculator::Init(std::vector<double> input_label_gain) {
if (is_inited_) { return; }
label_gain_.clear();
for(size_t i = 0;i < input_label_gain.size();++i){
label_gain_.push_back(static_cast<score_t>(input_label_gain[i]));
label_gain_.push_back(static_cast<double>(input_label_gain[i]));
}
label_gain_.shrink_to_fit();
discount_.clear();
......@@ -31,8 +31,8 @@ void DCGCalculator::Init(std::vector<double> input_label_gain) {
is_inited_ = true;
}
score_t DCGCalculator::CalMaxDCGAtK(data_size_t k, const float* label, data_size_t num_data) {
score_t ret = 0.0f;
double DCGCalculator::CalMaxDCGAtK(data_size_t k, const float* label, data_size_t num_data) {
double ret = 0.0f;
// counts for all labels
std::vector<data_size_t> label_cnt(label_gain_.size(), 0);
for (data_size_t i = 0; i < num_data; ++i) {
......@@ -58,14 +58,14 @@ score_t DCGCalculator::CalMaxDCGAtK(data_size_t k, const float* label, data_size
void DCGCalculator::CalMaxDCG(const std::vector<data_size_t>& ks,
const float* label,
data_size_t num_data,
std::vector<score_t>* out) {
std::vector<double>* out) {
std::vector<data_size_t> label_cnt(label_gain_.size(), 0);
// counts for all labels
for (data_size_t i = 0; i < num_data; ++i) {
if (static_cast<size_t>(label[i]) >= label_cnt.size()) { Log::Fatal("Label excel %d", label[i]); }
++label_cnt[static_cast<int>(label[i])];
}
score_t cur_result = 0.0f;
double cur_result = 0.0f;
data_size_t cur_left = 0;
int top_label = static_cast<int>(label_gain_.size()) - 1;
// calculate k Max DCG by one pass
......@@ -88,8 +88,8 @@ void DCGCalculator::CalMaxDCG(const std::vector<data_size_t>& ks,
}
score_t DCGCalculator::CalDCGAtK(data_size_t k, const float* label,
const score_t* score, data_size_t num_data) {
double DCGCalculator::CalDCGAtK(data_size_t k, const float* label,
const double* score, data_size_t num_data) {
// get sorted indices by score
std::vector<data_size_t> sorted_idx;
for (data_size_t i = 0; i < num_data; ++i) {
......@@ -99,7 +99,7 @@ score_t DCGCalculator::CalDCGAtK(data_size_t k, const float* label,
[score](data_size_t a, data_size_t b) {return score[a] > score[b]; });
if (k > num_data) { k = num_data; }
score_t dcg = 0.0f;
double dcg = 0.0f;
// calculate dcg
for (data_size_t i = 0; i < k; ++i) {
data_size_t idx = sorted_idx[i];
......@@ -109,7 +109,7 @@ score_t DCGCalculator::CalDCGAtK(data_size_t k, const float* label,
}
void DCGCalculator::CalDCG(const std::vector<data_size_t>& ks, const float* label,
const score_t * score, data_size_t num_data, std::vector<score_t>* out) {
const double * score, data_size_t num_data, std::vector<double>* out) {
// get sorted indices by score
std::vector<data_size_t> sorted_idx;
for (data_size_t i = 0; i < num_data; ++i) {
......@@ -118,7 +118,7 @@ void DCGCalculator::CalDCG(const std::vector<data_size_t>& ks, const float* labe
std::sort(sorted_idx.begin(), sorted_idx.end(),
[score](data_size_t a, data_size_t b) {return score[a] > score[b]; });
score_t cur_result = 0.0f;
double cur_result = 0.0f;
data_size_t cur_left = 0;
// calculate multi dcg by one pass
for (size_t i = 0; i < ks.size(); ++i) {
......
......@@ -45,11 +45,11 @@ public:
return name_;
}
score_t factor_to_bigger_better() const override {
double factor_to_bigger_better() const override {
return -1.0f;
}
std::vector<double> Eval(const score_t* score) const override {
std::vector<double> Eval(const double* score) const override {
double sum_loss = 0.0;
if (weights_ == nullptr) {
#pragma omp parallel for schedule(static) reduction(+:sum_loss)
......@@ -100,7 +100,7 @@ class MultiErrorMetric: public MulticlassMetric<MultiErrorMetric> {
public:
explicit MultiErrorMetric(const MetricConfig& config) :MulticlassMetric<MultiErrorMetric>(config) {}
inline static score_t LossOnPoint(float label, std::vector<double> score) {
inline static double LossOnPoint(float label, std::vector<double> score) {
size_t k = static_cast<size_t>(label);
for (size_t i = 0; i < score.size(); ++i){
if (i != k && score[i] >= score[k]) {
......@@ -120,11 +120,11 @@ class MultiLoglossMetric: public MulticlassMetric<MultiLoglossMetric> {
public:
explicit MultiLoglossMetric(const MetricConfig& config) :MulticlassMetric<MultiLoglossMetric>(config) {}
inline static score_t LossOnPoint(float label, std::vector<double> score) {
inline static double LossOnPoint(float label, std::vector<double> score) {
size_t k = static_cast<size_t>(label);
Common::Softmax(&score);
if (score[k] > kEpsilon) {
return static_cast<score_t>(-std::log(score[k]));
return static_cast<double>(-std::log(score[k]));
} else {
return -std::log(kEpsilon);
}
......
......@@ -78,17 +78,17 @@ public:
return name_;
}
score_t factor_to_bigger_better() const override {
double factor_to_bigger_better() const override {
return 1.0f;
}
std::vector<double> Eval(const score_t* score) const override {
std::vector<double> Eval(const double* score) const override {
// some buffers for multi-threading sum up
std::vector<std::vector<double>> result_buffer_;
for (int i = 0; i < num_threads_; ++i) {
result_buffer_.emplace_back(eval_at_.size(), 0.0f);
}
std::vector<score_t> tmp_dcg(eval_at_.size(), 0.0f);
std::vector<double> tmp_dcg(eval_at_.size(), 0.0f);
if (query_weights_ == nullptr) {
#pragma omp parallel for schedule(guided) firstprivate(tmp_dcg)
for (data_size_t i = 0; i < num_queries_; ++i) {
......@@ -159,7 +159,7 @@ private:
/*! \brief Evaluate position of NDCG */
std::vector<data_size_t> eval_at_;
/*! \brief Cache the inverse max dcg for all queries */
std::vector<std::vector<score_t>> inverse_max_dcgs_;
std::vector<std::vector<double>> inverse_max_dcgs_;
/*! \brief Number of threads */
int num_threads_;
};
......
......@@ -26,7 +26,7 @@ public:
return name_;
}
score_t factor_to_bigger_better() const override {
double factor_to_bigger_better() const override {
return -1.0f;
}
......@@ -48,7 +48,7 @@ public:
}
}
std::vector<double> Eval(const score_t* score) const override {
std::vector<double> Eval(const double* score) const override {
double sum_loss = 0.0f;
if (weights_ == nullptr) {
#pragma omp parallel for schedule(static) reduction(+:sum_loss)
......@@ -74,9 +74,9 @@ public:
protected:
/*! \brief delta for Huber loss */
score_t huber_delta_;
double huber_delta_;
/*! \brief c for Fair loss */
score_t fair_c_;
double fair_c_;
private:
/*! \brief Number of data */
......@@ -96,7 +96,7 @@ class L2Metric: public RegressionMetric<L2Metric> {
public:
explicit L2Metric(const MetricConfig& config) :RegressionMetric<L2Metric>(config) {}
inline static score_t LossOnPoint(float label, score_t score, float, float) {
inline static double LossOnPoint(float label, double score, double, double) {
return (score - label)*(score - label);
}
......@@ -115,7 +115,7 @@ class L1Metric: public RegressionMetric<L1Metric> {
public:
explicit L1Metric(const MetricConfig& config) :RegressionMetric<L1Metric>(config) {}
inline static score_t LossOnPoint(float label, score_t score, float, float) {
inline static double LossOnPoint(float label, double score, double, double) {
return std::fabs(score - label);
}
inline static const char* Name() {
......@@ -127,11 +127,11 @@ public:
class HuberLossMetric: public RegressionMetric<HuberLossMetric> {
public:
explicit HuberLossMetric(const MetricConfig& config) :RegressionMetric<HuberLossMetric>(config) {
huber_delta_ = static_cast<score_t>(config.huber_delta);
huber_delta_ = static_cast<double>(config.huber_delta);
}
inline static score_t LossOnPoint(float label, score_t score, float delta, float) {
const score_t diff = score - label;
inline static double LossOnPoint(float label, double score, double delta, double) {
const double diff = score - label;
if (std::abs(diff) <= delta) {
return 0.5f * diff * diff;
} else {
......@@ -149,11 +149,11 @@ public:
class FairLossMetric: public RegressionMetric<FairLossMetric> {
public:
explicit FairLossMetric(const MetricConfig& config) :RegressionMetric<FairLossMetric>(config) {
fair_c_ = static_cast<score_t>(config.fair_c);
fair_c_ = static_cast<double>(config.fair_c);
}
inline static score_t LossOnPoint(float label, score_t score, float, float c) {
const score_t x = std::fabs(score - label);
inline static double LossOnPoint(float label, double score, double, double c) {
const double x = std::fabs(score - label);
return c * x - c * c * std::log(1.0f + x / c);
}
......
......@@ -14,11 +14,11 @@ class BinaryLogloss: public ObjectiveFunction {
public:
explicit BinaryLogloss(const ObjectiveConfig& config) {
is_unbalance_ = config.is_unbalance;
sigmoid_ = static_cast<score_t>(config.sigmoid);
sigmoid_ = static_cast<double>(config.sigmoid);
if (sigmoid_ <= 0.0) {
Log::Fatal("Sigmoid parameter %f should be greater than zero", sigmoid_);
}
scale_pos_weight_ = static_cast<score_t>(config.scale_pos_weight);
scale_pos_weight_ = static_cast<double>(config.scale_pos_weight);
}
~BinaryLogloss() {}
void Init(const Metadata& metadata, data_size_t num_data) override {
......@@ -50,39 +50,39 @@ public:
if (is_unbalance_) {
if (cnt_positive > cnt_negative) {
label_weights_[1] = 1.0f;
label_weights_[0] = static_cast<score_t>(cnt_positive) / cnt_negative;
label_weights_[0] = static_cast<double>(cnt_positive) / cnt_negative;
} else {
label_weights_[1] = static_cast<score_t>(cnt_negative) / cnt_positive;
label_weights_[1] = static_cast<double>(cnt_negative) / cnt_positive;
label_weights_[0] = 1.0f;
}
}
label_weights_[1] *= scale_pos_weight_;
}
void GetGradients(const score_t* score, score_t* gradients, score_t* hessians) const override {
void GetGradients(const double* score, score_t* gradients, score_t* hessians) const override {
if (weights_ == nullptr) {
#pragma omp parallel for schedule(static)
for (data_size_t i = 0; i < num_data_; ++i) {
// get label and label weights
const int label = label_val_[static_cast<int>(label_[i])];
const score_t label_weight = label_weights_[static_cast<int>(label_[i])];
const double label_weight = label_weights_[static_cast<int>(label_[i])];
// calculate gradients and hessians
const score_t response = -2.0f * label * sigmoid_ / (1.0f + std::exp(2.0f * label * sigmoid_ * score[i]));
const score_t abs_response = fabs(response);
gradients[i] = response * label_weight;
hessians[i] = abs_response * (2.0f * sigmoid_ - abs_response) * label_weight;
const double response = -2.0f * label * sigmoid_ / (1.0f + std::exp(2.0f * label * sigmoid_ * score[i]));
const double abs_response = fabs(response);
gradients[i] = static_cast<score_t>(response * label_weight);
hessians[i] = static_cast<score_t>(abs_response * (2.0f * sigmoid_ - abs_response) * label_weight);
}
} else {
#pragma omp parallel for schedule(static)
for (data_size_t i = 0; i < num_data_; ++i) {
// get label and label weights
const int label = label_val_[static_cast<int>(label_[i])];
const score_t label_weight = label_weights_[static_cast<int>(label_[i])];
const double label_weight = label_weights_[static_cast<int>(label_[i])];
// calculate gradients and hessians
const score_t response = -2.0f * label * sigmoid_ / (1.0f + std::exp(2.0f * label * sigmoid_ * score[i]));
const score_t abs_response = fabs(response);
gradients[i] = response * label_weight * weights_[i];
hessians[i] = abs_response * (2.0f * sigmoid_ - abs_response) * label_weight * weights_[i];
const double response = -2.0f * label * sigmoid_ / (1.0f + std::exp(2.0f * label * sigmoid_ * score[i]));
const double abs_response = fabs(response);
gradients[i] = static_cast<score_t>(response * label_weight * weights_[i]);
hessians[i] = static_cast<score_t>(abs_response * (2.0f * sigmoid_ - abs_response) * label_weight * weights_[i]);
}
}
}
......@@ -99,14 +99,14 @@ private:
/*! \brief True if using unbalance training */
bool is_unbalance_;
/*! \brief Sigmoid parameter */
score_t sigmoid_;
double sigmoid_;
/*! \brief Values for positive and negative labels */
int label_val_[2];
/*! \brief Weights for positive and negative labels */
score_t label_weights_[2];
double label_weights_[2];
/*! \brief Weights for data */
const float* weights_;
score_t scale_pos_weight_;
double scale_pos_weight_;
};
} // namespace LightGBM
......
......@@ -32,7 +32,7 @@ public:
}
}
void GetGradients(const score_t* score, score_t* gradients, score_t* hessians) const override {
void GetGradients(const double* score, score_t* gradients, score_t* hessians) const override {
if (weights_ == nullptr) {
#pragma omp parallel for schedule(static)
for (data_size_t i = 0; i < num_data_; ++i) {
......@@ -43,14 +43,14 @@ public:
}
Common::Softmax(&rec);
for (int k = 0; k < num_class_; ++k) {
score_t p = static_cast<score_t>(rec[k]);
auto p = rec[k];
size_t idx = static_cast<size_t>(num_data_) * k + i;
if (label_int_[i] == k) {
gradients[idx] = p - 1.0f;
gradients[idx] = static_cast<score_t>(p - 1.0f);
} else {
gradients[idx] = p;
gradients[idx] = static_cast<score_t>(p);
}
hessians[idx] = 2.0f * p * (1.0f - p);
hessians[idx] = static_cast<score_t>(2.0f * p * (1.0f - p));
}
}
} else {
......@@ -63,14 +63,14 @@ public:
}
Common::Softmax(&rec);
for (int k = 0; k < num_class_; ++k) {
score_t p = static_cast<score_t>(rec[k]);
auto p = rec[k];
size_t idx = static_cast<size_t>(num_data_) * k + i;
if (label_int_[i] == k) {
gradients[idx] = (p - 1.0f) * weights_[i];
gradients[idx] = static_cast<score_t>((p - 1.0f) * weights_[i]);
} else {
gradients[idx] = p * weights_[i];
gradients[idx] = static_cast<score_t>(p * weights_[i]);
}
hessians[idx] = 2.0f * p * (1.0f - p) * weights_[i];
hessians[idx] = static_cast<score_t>(2.0f * p * (1.0f - p) * weights_[i]);
}
}
}
......
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