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