Convert labels into tensor. (#7456)
* Add a new ctor to tensor for `initilizer_list`. * Change labels from host device vector to tensor. * Rename the field from `labels_` to `labels` since it's a public member.
This commit is contained in:
@@ -32,17 +32,16 @@ namespace metric {
|
||||
*/
|
||||
template <typename Fn>
|
||||
std::tuple<double, double, double>
|
||||
BinaryAUC(common::Span<float const> predts, common::Span<float const> labels,
|
||||
BinaryAUC(common::Span<float const> predts, linalg::VectorView<float const> labels,
|
||||
OptionalWeights weights,
|
||||
std::vector<size_t> const &sorted_idx, Fn &&area_fn) {
|
||||
CHECK(!labels.empty());
|
||||
CHECK_EQ(labels.size(), predts.size());
|
||||
CHECK_NE(labels.Size(), 0);
|
||||
CHECK_EQ(labels.Size(), predts.size());
|
||||
auto p_predts = predts.data();
|
||||
auto p_labels = labels.data();
|
||||
|
||||
double auc{0};
|
||||
|
||||
float label = p_labels[sorted_idx.front()];
|
||||
float label = labels(sorted_idx.front());
|
||||
float w = weights[sorted_idx[0]];
|
||||
double fp = (1.0 - label) * w, tp = label * w;
|
||||
double tp_prev = 0, fp_prev = 0;
|
||||
@@ -53,7 +52,7 @@ BinaryAUC(common::Span<float const> predts, common::Span<float const> labels,
|
||||
tp_prev = tp;
|
||||
fp_prev = fp;
|
||||
}
|
||||
label = p_labels[sorted_idx[i]];
|
||||
label = labels(sorted_idx[i]);
|
||||
float w = weights[sorted_idx[i]];
|
||||
fp += (1.0f - label) * w;
|
||||
tp += label * w;
|
||||
@@ -82,7 +81,10 @@ double MultiClassOVR(common::Span<float const> predts, MetaInfo const &info,
|
||||
size_t n_classes, int32_t n_threads,
|
||||
BinaryAUC &&binary_auc) {
|
||||
CHECK_NE(n_classes, 0);
|
||||
auto const &labels = info.labels_.ConstHostVector();
|
||||
auto const labels = info.labels.View(GenericParameter::kCpuId);
|
||||
if (labels.Shape(0) != 0) {
|
||||
CHECK_EQ(labels.Shape(1), 1) << "AUC doesn't support multi-target model.";
|
||||
}
|
||||
|
||||
std::vector<double> results_storage(n_classes * 3, 0);
|
||||
linalg::TensorView<double, 2> results(results_storage, {n_classes, static_cast<size_t>(3)},
|
||||
@@ -96,16 +98,17 @@ double MultiClassOVR(common::Span<float const> predts, MetaInfo const &info,
|
||||
predts, {static_cast<size_t>(info.num_row_), n_classes},
|
||||
GenericParameter::kCpuId);
|
||||
|
||||
if (!info.labels_.Empty()) {
|
||||
if (info.labels.Size() != 0) {
|
||||
common::ParallelFor(n_classes, n_threads, [&](auto c) {
|
||||
std::vector<float> proba(info.labels_.Size());
|
||||
std::vector<float> response(info.labels_.Size());
|
||||
std::vector<float> proba(info.labels.Size());
|
||||
std::vector<float> response(info.labels.Size());
|
||||
for (size_t i = 0; i < proba.size(); ++i) {
|
||||
proba[i] = predts_t(i, c);
|
||||
response[i] = labels[i] == c ? 1.0f : 0.0;
|
||||
response[i] = labels(i) == c ? 1.0f : 0.0;
|
||||
}
|
||||
double fp;
|
||||
std::tie(fp, tp(c), auc(c)) = binary_auc(proba, response, weights);
|
||||
std::tie(fp, tp(c), auc(c)) =
|
||||
binary_auc(proba, linalg::MakeVec(response.data(), response.size(), -1), weights);
|
||||
local_area(c) = fp * tp(c);
|
||||
});
|
||||
}
|
||||
@@ -135,9 +138,9 @@ double MultiClassOVR(common::Span<float const> predts, MetaInfo const &info,
|
||||
return auc_sum;
|
||||
}
|
||||
|
||||
std::tuple<double, double, double>
|
||||
BinaryROCAUC(common::Span<float const> predts, common::Span<float const> labels,
|
||||
OptionalWeights weights) {
|
||||
std::tuple<double, double, double> BinaryROCAUC(common::Span<float const> predts,
|
||||
linalg::VectorView<float const> labels,
|
||||
OptionalWeights weights) {
|
||||
auto const sorted_idx = common::ArgSort<size_t>(predts, std::greater<>{});
|
||||
return BinaryAUC(predts, labels, weights, sorted_idx, TrapezoidArea);
|
||||
}
|
||||
@@ -146,15 +149,17 @@ BinaryROCAUC(common::Span<float const> predts, common::Span<float const> labels,
|
||||
* Calculate AUC for 1 ranking group;
|
||||
*/
|
||||
double GroupRankingROC(common::Span<float const> predts,
|
||||
common::Span<float const> labels, float w) {
|
||||
linalg::VectorView<float const> labels, float w) {
|
||||
// on ranking, we just count all pairs.
|
||||
double auc{0};
|
||||
auto const sorted_idx = common::ArgSort<size_t>(labels, std::greater<>{});
|
||||
// argsort doesn't support tensor input yet.
|
||||
auto raw_labels = labels.Values().subspan(0, labels.Size());
|
||||
auto const sorted_idx = common::ArgSort<size_t>(raw_labels, std::greater<>{});
|
||||
w = common::Sqr(w);
|
||||
|
||||
double sum_w = 0.0f;
|
||||
for (size_t i = 0; i < labels.size(); ++i) {
|
||||
for (size_t j = i + 1; j < labels.size(); ++j) {
|
||||
for (size_t i = 0; i < labels.Size(); ++i) {
|
||||
for (size_t j = i + 1; j < labels.Size(); ++j) {
|
||||
auto predt = predts[sorted_idx[i]] - predts[sorted_idx[j]];
|
||||
if (predt > 0) {
|
||||
predt = 1.0;
|
||||
@@ -180,14 +185,14 @@ double GroupRankingROC(common::Span<float const> predts,
|
||||
* https://doi.org/10.1371/journal.pone.0092209
|
||||
*/
|
||||
std::tuple<double, double, double> BinaryPRAUC(common::Span<float const> predts,
|
||||
common::Span<float const> labels,
|
||||
linalg::VectorView<float const> labels,
|
||||
OptionalWeights weights) {
|
||||
auto const sorted_idx = common::ArgSort<size_t>(predts, std::greater<>{});
|
||||
double total_pos{0}, total_neg{0};
|
||||
for (size_t i = 0; i < labels.size(); ++i) {
|
||||
for (size_t i = 0; i < labels.Size(); ++i) {
|
||||
auto w = weights[i];
|
||||
total_pos += w * labels[i];
|
||||
total_neg += w * (1.0f - labels[i]);
|
||||
total_pos += w * labels(i);
|
||||
total_neg += w * (1.0f - labels(i));
|
||||
}
|
||||
if (total_pos <= 0 || total_neg <= 0) {
|
||||
return {1.0f, 1.0f, std::numeric_limits<float>::quiet_NaN()};
|
||||
@@ -211,7 +216,7 @@ std::pair<double, uint32_t> RankingAUC(std::vector<float> const &predts,
|
||||
CHECK_GE(info.group_ptr_.size(), 2);
|
||||
uint32_t n_groups = info.group_ptr_.size() - 1;
|
||||
auto s_predts = common::Span<float const>{predts};
|
||||
auto s_labels = info.labels_.ConstHostSpan();
|
||||
auto labels = info.labels.View(GenericParameter::kCpuId);
|
||||
auto s_weights = info.weights_.ConstHostSpan();
|
||||
|
||||
std::atomic<uint32_t> invalid_groups{0};
|
||||
@@ -222,9 +227,9 @@ std::pair<double, uint32_t> RankingAUC(std::vector<float> const &predts,
|
||||
size_t cnt = info.group_ptr_[g] - info.group_ptr_[g - 1];
|
||||
float w = s_weights.empty() ? 1.0f : s_weights[g - 1];
|
||||
auto g_predts = s_predts.subspan(info.group_ptr_[g - 1], cnt);
|
||||
auto g_labels = s_labels.subspan(info.group_ptr_[g - 1], cnt);
|
||||
auto g_labels = labels.Slice(linalg::Range(info.group_ptr_[g - 1], info.group_ptr_[g]));
|
||||
double auc;
|
||||
if (is_roc && g_labels.size() < 3) {
|
||||
if (is_roc && g_labels.Size() < 3) {
|
||||
// With 2 documents, there's only 1 comparison can be made. So either
|
||||
// TP or FP will be zero.
|
||||
invalid_groups++;
|
||||
@@ -254,11 +259,11 @@ class EvalAUC : public Metric {
|
||||
double auc {0};
|
||||
if (tparam_->gpu_id != GenericParameter::kCpuId) {
|
||||
preds.SetDevice(tparam_->gpu_id);
|
||||
info.labels_.SetDevice(tparam_->gpu_id);
|
||||
info.labels.SetDevice(tparam_->gpu_id);
|
||||
info.weights_.SetDevice(tparam_->gpu_id);
|
||||
}
|
||||
// We use the global size to handle empty dataset.
|
||||
std::array<size_t, 2> meta{info.labels_.Size(), preds.Size()};
|
||||
std::array<size_t, 2> meta{info.labels.Size(), preds.Size()};
|
||||
rabit::Allreduce<rabit::op::Max>(meta.data(), meta.size());
|
||||
if (meta[0] == 0) {
|
||||
// Empty across all workers, which is not supported.
|
||||
@@ -271,8 +276,8 @@ class EvalAUC : public Metric {
|
||||
CHECK_EQ(info.weights_.Size(), info.group_ptr_.size() - 1);
|
||||
}
|
||||
uint32_t valid_groups = 0;
|
||||
if (!info.labels_.Empty()) {
|
||||
CHECK_EQ(info.group_ptr_.back(), info.labels_.Size());
|
||||
if (info.labels.Size() != 0) {
|
||||
CHECK_EQ(info.group_ptr_.back(), info.labels.Size());
|
||||
std::tie(auc, valid_groups) =
|
||||
static_cast<Curve *>(this)->EvalRanking(preds, info);
|
||||
}
|
||||
@@ -304,7 +309,7 @@ class EvalAUC : public Metric {
|
||||
* binary classification
|
||||
*/
|
||||
double fp{0}, tp{0};
|
||||
if (!(preds.Empty() || info.labels_.Empty())) {
|
||||
if (!(preds.Empty() || info.labels.Size() == 0)) {
|
||||
std::tie(fp, tp, auc) =
|
||||
static_cast<Curve *>(this)->EvalBinary(preds, info);
|
||||
}
|
||||
@@ -367,7 +372,7 @@ class EvalROCAUC : public EvalAUC<EvalROCAUC> {
|
||||
double fp, tp, auc;
|
||||
if (tparam_->gpu_id == GenericParameter::kCpuId) {
|
||||
std::tie(fp, tp, auc) =
|
||||
BinaryROCAUC(predts.ConstHostVector(), info.labels_.ConstHostVector(),
|
||||
BinaryROCAUC(predts.ConstHostVector(), info.labels.HostView().Slice(linalg::All(), 0),
|
||||
OptionalWeights{info.weights_.ConstHostSpan()});
|
||||
} else {
|
||||
std::tie(fp, tp, auc) = GPUBinaryROCAUC(predts.ConstDeviceSpan(), info,
|
||||
@@ -420,7 +425,7 @@ class EvalPRAUC : public EvalAUC<EvalPRAUC> {
|
||||
double pr, re, auc;
|
||||
if (tparam_->gpu_id == GenericParameter::kCpuId) {
|
||||
std::tie(pr, re, auc) =
|
||||
BinaryPRAUC(predts.ConstHostSpan(), info.labels_.ConstHostSpan(),
|
||||
BinaryPRAUC(predts.ConstHostSpan(), info.labels.HostView().Slice(linalg::All(), 0),
|
||||
OptionalWeights{info.weights_.ConstHostSpan()});
|
||||
} else {
|
||||
std::tie(pr, re, auc) = GPUBinaryPRAUC(predts.ConstDeviceSpan(), info,
|
||||
@@ -447,7 +452,7 @@ class EvalPRAUC : public EvalAUC<EvalPRAUC> {
|
||||
uint32_t valid_groups = 0;
|
||||
auto n_threads = tparam_->Threads();
|
||||
if (tparam_->gpu_id == GenericParameter::kCpuId) {
|
||||
auto labels = info.labels_.ConstHostSpan();
|
||||
auto labels = info.labels.Data()->ConstHostSpan();
|
||||
if (std::any_of(labels.cbegin(), labels.cend(), PRAUCLabelInvalid{})) {
|
||||
InvalidLabels();
|
||||
}
|
||||
|
||||
@@ -89,12 +89,12 @@ std::tuple<double, double, double>
|
||||
GPUBinaryAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
int32_t device, common::Span<size_t const> d_sorted_idx,
|
||||
Fn area_fn, std::shared_ptr<DeviceAUCCache> cache) {
|
||||
auto labels = info.labels_.ConstDeviceSpan();
|
||||
auto labels = info.labels.View(device);
|
||||
auto weights = info.weights_.ConstDeviceSpan();
|
||||
dh::safe_cuda(cudaSetDevice(device));
|
||||
|
||||
CHECK(!labels.empty());
|
||||
CHECK_EQ(labels.size(), predts.size());
|
||||
CHECK_NE(labels.Size(), 0);
|
||||
CHECK_EQ(labels.Size(), predts.size());
|
||||
|
||||
/**
|
||||
* Linear scan
|
||||
@@ -103,7 +103,7 @@ GPUBinaryAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
auto get_fp_tp = [=]XGBOOST_DEVICE(size_t i) {
|
||||
size_t idx = d_sorted_idx[i];
|
||||
|
||||
float label = labels[idx];
|
||||
float label = labels(idx);
|
||||
float w = get_weight[d_sorted_idx[i]];
|
||||
|
||||
float fp = (1.0 - label) * w;
|
||||
@@ -332,10 +332,10 @@ double GPUMultiClassAUCOVR(common::Span<float const> predts,
|
||||
// Index is sorted within class.
|
||||
auto d_sorted_idx = dh::ToSpan(cache->sorted_idx);
|
||||
|
||||
auto labels = info.labels_.ConstDeviceSpan();
|
||||
auto labels = info.labels.View(device);
|
||||
auto weights = info.weights_.ConstDeviceSpan();
|
||||
|
||||
size_t n_samples = labels.size();
|
||||
size_t n_samples = labels.Shape(0);
|
||||
|
||||
if (n_samples == 0) {
|
||||
dh::TemporaryArray<double> resutls(n_classes * 4, 0.0f);
|
||||
@@ -360,7 +360,7 @@ double GPUMultiClassAUCOVR(common::Span<float const> predts,
|
||||
|
||||
size_t class_id = i / n_samples;
|
||||
// labels is a vector of size n_samples.
|
||||
float label = labels[idx % n_samples] == class_id;
|
||||
float label = labels(idx % n_samples) == class_id;
|
||||
|
||||
float w = get_weight[d_sorted_idx[i] % n_samples];
|
||||
float fp = (1.0 - label) * w;
|
||||
@@ -528,10 +528,10 @@ GPURankingAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
/**
|
||||
* Sort the labels
|
||||
*/
|
||||
auto d_labels = info.labels_.ConstDeviceSpan();
|
||||
auto d_labels = info.labels.View(device);
|
||||
|
||||
auto d_sorted_idx = dh::ToSpan(cache->sorted_idx);
|
||||
dh::SegmentedArgSort<false>(d_labels, d_group_ptr, d_sorted_idx);
|
||||
dh::SegmentedArgSort<false>(d_labels.Values(), d_group_ptr, d_sorted_idx);
|
||||
|
||||
auto d_weights = info.weights_.ConstDeviceSpan();
|
||||
|
||||
@@ -631,19 +631,19 @@ GPUBinaryPRAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
auto d_sorted_idx = dh::ToSpan(cache->sorted_idx);
|
||||
dh::ArgSort<false>(predts, d_sorted_idx);
|
||||
|
||||
auto labels = info.labels_.ConstDeviceSpan();
|
||||
auto labels = info.labels.View(device);
|
||||
auto d_weights = info.weights_.ConstDeviceSpan();
|
||||
auto get_weight = OptionalWeights{d_weights};
|
||||
auto it = dh::MakeTransformIterator<Pair>(
|
||||
thrust::make_counting_iterator(0ul), [=] XGBOOST_DEVICE(size_t i) {
|
||||
auto w = get_weight[d_sorted_idx[i]];
|
||||
return thrust::make_pair(labels[d_sorted_idx[i]] * w,
|
||||
(1.0f - labels[d_sorted_idx[i]]) * w);
|
||||
return thrust::make_pair(labels(d_sorted_idx[i]) * w,
|
||||
(1.0f - labels(d_sorted_idx[i])) * w);
|
||||
});
|
||||
dh::XGBCachingDeviceAllocator<char> alloc;
|
||||
double total_pos, total_neg;
|
||||
thrust::tie(total_pos, total_neg) =
|
||||
thrust::reduce(thrust::cuda::par(alloc), it, it + labels.size(),
|
||||
thrust::reduce(thrust::cuda::par(alloc), it, it + labels.Size(),
|
||||
Pair{0.0, 0.0}, PairPlus<double, double>{});
|
||||
|
||||
if (total_pos <= 0.0 || total_neg <= 0.0) {
|
||||
@@ -679,7 +679,7 @@ double GPUMultiClassPRAUC(common::Span<float const> predts,
|
||||
/**
|
||||
* Get total positive/negative
|
||||
*/
|
||||
auto labels = info.labels_.ConstDeviceSpan();
|
||||
auto labels = info.labels.View(device);
|
||||
auto n_samples = info.num_row_;
|
||||
dh::caching_device_vector<Pair> totals(n_classes);
|
||||
auto key_it =
|
||||
@@ -693,7 +693,7 @@ double GPUMultiClassPRAUC(common::Span<float const> predts,
|
||||
auto idx = d_sorted_idx[i] % n_samples;
|
||||
auto w = get_weight[idx];
|
||||
auto class_id = i / n_samples;
|
||||
auto y = labels[idx] == class_id;
|
||||
auto y = labels(idx) == class_id;
|
||||
return thrust::make_pair(y * w, (1.0f - y) * w);
|
||||
});
|
||||
dh::XGBCachingDeviceAllocator<char> alloc;
|
||||
@@ -726,7 +726,7 @@ GPURankingPRAUCImpl(common::Span<float const> predts, MetaInfo const &info,
|
||||
*/
|
||||
auto d_sorted_idx = dh::ToSpan(cache->sorted_idx);
|
||||
|
||||
auto labels = info.labels_.ConstDeviceSpan();
|
||||
auto labels = info.labels.View(device);
|
||||
auto weights = info.weights_.ConstDeviceSpan();
|
||||
|
||||
uint32_t n_groups = static_cast<uint32_t>(info.group_ptr_.size() - 1);
|
||||
@@ -734,7 +734,7 @@ GPURankingPRAUCImpl(common::Span<float const> predts, MetaInfo const &info,
|
||||
/**
|
||||
* Linear scan
|
||||
*/
|
||||
size_t n_samples = labels.size();
|
||||
size_t n_samples = labels.Shape(0);
|
||||
dh::caching_device_vector<double> d_auc(n_groups, 0);
|
||||
auto get_weight = OptionalWeights{weights};
|
||||
auto d_fptp = dh::ToSpan(cache->fptp);
|
||||
@@ -742,7 +742,7 @@ GPURankingPRAUCImpl(common::Span<float const> predts, MetaInfo const &info,
|
||||
size_t idx = d_sorted_idx[i];
|
||||
|
||||
size_t group_id = dh::SegmentId(d_group_ptr, idx);
|
||||
float label = labels[idx];
|
||||
float label = labels(idx);
|
||||
|
||||
float w = get_weight[group_id];
|
||||
float fp = (1.0 - label) * w;
|
||||
@@ -860,9 +860,9 @@ GPURankingPRAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
dh::SegmentedArgSort<false>(predts, d_group_ptr, d_sorted_idx);
|
||||
|
||||
dh::XGBDeviceAllocator<char> alloc;
|
||||
auto labels = info.labels_.ConstDeviceSpan();
|
||||
if (thrust::any_of(thrust::cuda::par(alloc), dh::tbegin(labels),
|
||||
dh::tend(labels), PRAUCLabelInvalid{})) {
|
||||
auto labels = info.labels.View(device);
|
||||
if (thrust::any_of(thrust::cuda::par(alloc), dh::tbegin(labels.Values()),
|
||||
dh::tend(labels.Values()), PRAUCLabelInvalid{})) {
|
||||
InvalidLabels();
|
||||
}
|
||||
/**
|
||||
@@ -881,7 +881,7 @@ GPURankingPRAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
auto g = dh::SegmentId(d_group_ptr, i);
|
||||
w = d_weights[g];
|
||||
}
|
||||
auto y = labels[i];
|
||||
auto y = labels(i);
|
||||
return thrust::make_pair(y * w, (1.0 - y) * w);
|
||||
});
|
||||
thrust::reduce_by_key(thrust::cuda::par(alloc), key_it,
|
||||
@@ -899,7 +899,7 @@ GPURankingPRAUC(common::Span<float const> predts, MetaInfo const &info,
|
||||
return detail::CalcDeltaPRAUC(fp_prev, fp, tp_prev, tp,
|
||||
d_totals[group_id].first);
|
||||
};
|
||||
return GPURankingPRAUCImpl(predts, info, d_group_ptr, n_groups, cache, fn);
|
||||
return GPURankingPRAUCImpl(predts, info, d_group_ptr, device, cache, fn);
|
||||
}
|
||||
} // namespace metric
|
||||
} // namespace xgboost
|
||||
|
||||
@@ -361,10 +361,10 @@ struct EvalEWiseBase : public Metric {
|
||||
|
||||
double Eval(const HostDeviceVector<bst_float> &preds, const MetaInfo &info,
|
||||
bool distributed) override {
|
||||
CHECK_EQ(preds.Size(), info.labels_.Size())
|
||||
CHECK_EQ(preds.Size(), info.labels.Size())
|
||||
<< "label and prediction size not match, "
|
||||
<< "hint: use merror or mlogloss for multi-class classification";
|
||||
auto result = reducer_.Reduce(*tparam_, info.weights_, info.labels_, preds);
|
||||
auto result = reducer_.Reduce(*tparam_, info.weights_, *info.labels.Data(), preds);
|
||||
|
||||
double dat[2] { result.Residue(), result.Weights() };
|
||||
|
||||
|
||||
@@ -169,19 +169,20 @@ template<typename Derived>
|
||||
struct EvalMClassBase : public Metric {
|
||||
double Eval(const HostDeviceVector<float> &preds, const MetaInfo &info,
|
||||
bool distributed) override {
|
||||
if (info.labels_.Size() == 0) {
|
||||
if (info.labels.Size() == 0) {
|
||||
CHECK_EQ(preds.Size(), 0);
|
||||
} else {
|
||||
CHECK(preds.Size() % info.labels_.Size() == 0) << "label and prediction size not match";
|
||||
CHECK(preds.Size() % info.labels.Size() == 0) << "label and prediction size not match";
|
||||
}
|
||||
double dat[2] { 0.0, 0.0 };
|
||||
if (info.labels_.Size() != 0) {
|
||||
const size_t nclass = preds.Size() / info.labels_.Size();
|
||||
if (info.labels.Size() != 0) {
|
||||
const size_t nclass = preds.Size() / info.labels.Size();
|
||||
CHECK_GE(nclass, 1U)
|
||||
<< "mlogloss and merror are only used for multi-class classification,"
|
||||
<< " use logloss for binary classification";
|
||||
int device = tparam_->gpu_id;
|
||||
auto result = reducer_.Reduce(*tparam_, device, nclass, info.weights_, info.labels_, preds);
|
||||
auto result =
|
||||
reducer_.Reduce(*tparam_, device, nclass, info.weights_, *info.labels.Data(), preds);
|
||||
dat[0] = result.Residue();
|
||||
dat[1] = result.Weights();
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ struct EvalAMS : public Metric {
|
||||
CHECK(!distributed) << "metric AMS do not support distributed evaluation";
|
||||
using namespace std; // NOLINT(*)
|
||||
|
||||
const auto ndata = static_cast<bst_omp_uint>(info.labels_.Size());
|
||||
const auto ndata = static_cast<bst_omp_uint>(info.labels.Size());
|
||||
PredIndPairContainer rec(ndata);
|
||||
|
||||
const auto &h_preds = preds.ConstHostVector();
|
||||
@@ -120,11 +120,11 @@ struct EvalAMS : public Metric {
|
||||
const double br = 10.0;
|
||||
unsigned thresindex = 0;
|
||||
double s_tp = 0.0, b_fp = 0.0, tams = 0.0;
|
||||
const auto& labels = info.labels_.ConstHostVector();
|
||||
const auto& labels = info.labels.View(GenericParameter::kCpuId);
|
||||
for (unsigned i = 0; i < static_cast<unsigned>(ndata-1) && i < ntop; ++i) {
|
||||
const unsigned ridx = rec[i].second;
|
||||
const bst_float wt = info.GetWeight(ridx);
|
||||
if (labels[ridx] > 0.5f) {
|
||||
if (labels(ridx) > 0.5f) {
|
||||
s_tp += wt;
|
||||
} else {
|
||||
b_fp += wt;
|
||||
@@ -164,7 +164,7 @@ struct EvalRank : public Metric, public EvalRankConfig {
|
||||
public:
|
||||
double Eval(const HostDeviceVector<bst_float> &preds, const MetaInfo &info,
|
||||
bool distributed) override {
|
||||
CHECK_EQ(preds.Size(), info.labels_.Size())
|
||||
CHECK_EQ(preds.Size(), info.labels.Size())
|
||||
<< "label size predict size not match";
|
||||
|
||||
// quick consistency when group is not available
|
||||
@@ -194,7 +194,7 @@ struct EvalRank : public Metric, public EvalRankConfig {
|
||||
std::vector<double> sum_tloc(tparam_->Threads(), 0.0);
|
||||
|
||||
if (!rank_gpu_ || tparam_->gpu_id < 0) {
|
||||
const auto &labels = info.labels_.ConstHostVector();
|
||||
const auto& labels = info.labels.View(GenericParameter::kCpuId);
|
||||
const auto &h_preds = preds.ConstHostVector();
|
||||
|
||||
dmlc::OMPException exc;
|
||||
@@ -208,7 +208,7 @@ struct EvalRank : public Metric, public EvalRankConfig {
|
||||
exc.Run([&]() {
|
||||
rec.clear();
|
||||
for (unsigned j = gptr[k]; j < gptr[k + 1]; ++j) {
|
||||
rec.emplace_back(h_preds[j], static_cast<int>(labels[j]));
|
||||
rec.emplace_back(h_preds[j], static_cast<int>(labels(j)));
|
||||
}
|
||||
sum_tloc[omp_get_thread_num()] += this->EvalGroup(&rec);
|
||||
});
|
||||
@@ -348,7 +348,7 @@ struct EvalCox : public Metric {
|
||||
CHECK(!distributed) << "Cox metric does not support distributed evaluation";
|
||||
using namespace std; // NOLINT(*)
|
||||
|
||||
const auto ndata = static_cast<bst_omp_uint>(info.labels_.Size());
|
||||
const auto ndata = static_cast<bst_omp_uint>(info.labels.Size());
|
||||
const auto &label_order = info.LabelAbsSort();
|
||||
|
||||
// pre-compute a sum for the denominator
|
||||
@@ -362,10 +362,10 @@ struct EvalCox : public Metric {
|
||||
double out = 0;
|
||||
double accumulated_sum = 0;
|
||||
bst_omp_uint num_events = 0;
|
||||
const auto& labels = info.labels_.ConstHostVector();
|
||||
const auto& labels = info.labels.HostView();
|
||||
for (bst_omp_uint i = 0; i < ndata; ++i) {
|
||||
const size_t ind = label_order[i];
|
||||
const auto label = labels[ind];
|
||||
const auto label = labels(ind);
|
||||
if (label > 0) {
|
||||
out -= log(h_preds[ind]) - log(exp_p_sum);
|
||||
++num_events;
|
||||
@@ -373,7 +373,7 @@ struct EvalCox : public Metric {
|
||||
|
||||
// only update the denominator after we move forward in time (labels are sorted)
|
||||
accumulated_sum += h_preds[ind];
|
||||
if (i == ndata - 1 || std::abs(label) < std::abs(labels[label_order[i + 1]])) {
|
||||
if (i == ndata - 1 || std::abs(label) < std::abs(labels(label_order[i + 1]))) {
|
||||
exp_p_sum -= accumulated_sum;
|
||||
accumulated_sum = 0;
|
||||
}
|
||||
|
||||
@@ -41,18 +41,18 @@ struct EvalRankGpu : public Metric, public EvalRankConfig {
|
||||
auto device = tparam_->gpu_id;
|
||||
dh::safe_cuda(cudaSetDevice(device));
|
||||
|
||||
info.labels_.SetDevice(device);
|
||||
info.labels.SetDevice(device);
|
||||
preds.SetDevice(device);
|
||||
|
||||
auto dpreds = preds.ConstDevicePointer();
|
||||
auto dlabels = info.labels_.ConstDevicePointer();
|
||||
auto dlabels = info.labels.View(device);
|
||||
|
||||
// Sort all the predictions
|
||||
dh::SegmentSorter<float> segment_pred_sorter;
|
||||
segment_pred_sorter.SortItems(dpreds, preds.Size(), gptr);
|
||||
|
||||
// Compute individual group metric and sum them up
|
||||
return EvalMetricT::EvalMetric(segment_pred_sorter, dlabels, *this);
|
||||
return EvalMetricT::EvalMetric(segment_pred_sorter, dlabels.Values().data(), *this);
|
||||
}
|
||||
|
||||
const char* Name() const override {
|
||||
|
||||
Reference in New Issue
Block a user