| 381 | |
| 382 | |
| 383 | bool GBDT::TrainOneIter_old(const score_t* gradients, const score_t* hessians) { |
| 384 | std::vector<double> init_scores(num_tree_per_iteration_, 0.0); |
| 385 | // boosting first |
| 386 | if (gradients == nullptr || hessians == nullptr) { |
| 387 | for (int cur_tree_id = 0; cur_tree_id < num_tree_per_iteration_; ++cur_tree_id) { |
| 388 | init_scores[cur_tree_id] = BoostFromAverage(cur_tree_id, true); |
| 389 | } |
| 390 | Boosting(); |
| 391 | gradients = gradients_.data(); |
| 392 | hessians = hessians_.data(); |
| 393 | } |
| 394 | // bagging logic |
| 395 | Bagging(iter_); |
| 396 | |
| 397 | bool should_continue = false; |
| 398 | for (int cur_tree_id = 0; cur_tree_id < num_tree_per_iteration_; ++cur_tree_id) { |
| 399 | const size_t offset = static_cast<size_t>(cur_tree_id) * num_data_; |
| 400 | std::unique_ptr<Tree> new_tree(new Tree(2)); |
| 401 | if (class_need_train_[cur_tree_id] && train_data_->num_features() > 0) { |
| 402 | auto grad = gradients + offset; |
| 403 | auto hess = hessians + offset; |
| 404 | // need to copy gradients for bagging subset. |
| 405 | if (is_use_subset_ && bag_data_cnt_ < num_data_) { |
| 406 | for (int i = 0; i < bag_data_cnt_; ++i) { |
| 407 | gradients_[offset + i] = grad[bag_data_indices_[i]]; |
| 408 | hessians_[offset + i] = hess[bag_data_indices_[i]]; |
| 409 | } |
| 410 | grad = gradients_.data() + offset; |
| 411 | hess = hessians_.data() + offset; |
| 412 | } |
| 413 | new_tree.reset(tree_learner_->Train(grad, hess, is_constant_hessian_, forced_splits_json_)); |
| 414 | } |
| 415 | |
| 416 | if (new_tree->num_leaves() > 1) { |
| 417 | should_continue = true; |
| 418 | auto score_ptr = train_score_updater_->score() + offset; |
| 419 | auto residual_getter = [score_ptr](const label_t* label, int i) {return static_cast<double>(label[i]) - score_ptr[i]; }; |
| 420 | tree_learner_->RenewTreeOutput(new_tree.get(), objective_function_, residual_getter, |
| 421 | num_data_, bag_data_indices_.data(), bag_data_cnt_); |
| 422 | // shrinkage by learning rate |
| 423 | new_tree->Shrinkage(shrinkage_rate_); |
| 424 | // update score |
| 425 | UpdateScore(new_tree.get(), cur_tree_id); |
| 426 | if (std::fabs(init_scores[cur_tree_id]) > kEpsilon) { |
| 427 | new_tree->AddBias(init_scores[cur_tree_id]); |
| 428 | } |
| 429 | } else { |
| 430 | // only add default score one-time |
| 431 | if (models_.size() < static_cast<size_t>(num_tree_per_iteration_)) { |
| 432 | double output = 0.0; |
| 433 | if (!class_need_train_[cur_tree_id]) { |
| 434 | if (objective_function_ != nullptr) { |
| 435 | output = objective_function_->BoostFromScore(cur_tree_id); |
| 436 | } |
| 437 | } else { |
| 438 | output = init_scores[cur_tree_id]; |
| 439 | } |
| 440 | new_tree->AsConstantTree(output); |
nothing calls this directly
no test coverage detected