如果在同一过程中多次重复以下代码路径,则XGDMatrixCreateFromMat在第二次访问期间将失败,并返回-1。作为参考,我遵循了Using XGBOOST in c++。
但是,如果我在助推器中删除了dtrain
(XGBoosterCreate
和后续调用)的使用,则多次调用XGDMatrixCreateFromMat
会在同一过程中成功,但是当然创建DMatrix的目的是要与增强器一起使用进行预测。请注意,以下代码路径在不同进程中多次调用时有效。
DMatrixHandle dtrain[1];
XGDMatrixCreateFromMat(reinterpret_cast<float*>(copied_inputs),
data_size, input_dim, -1, &dtrain[0]);
XGDMatrixSetFloatInfo(dtrain[0], "label", copied_labels, data_size);
XGDMatrixCreateFromMat(reinterpret_cast<float*>(copied_test_inputs),
test_data_size, input_dim, -1, &dtest);
XGDMatrixSetFloatInfo(dtest, "label", copied_test_labels, test_data_size);
XGBoosterCreate(&dtrain[0], 1, &h_booster_);
for (auto param : hyper_params_) {
XGBoosterSetParam(h_booster_, param.first.c_str(), param.second.c_str());
}
for (int iter = 0; iter < num_boost_round_; ++iter) {
XGBoosterUpdateOneIter(h_booster_, iter, dtrain);
const char* eval_out;
XGBoosterEvalOneIter(h_booster_, iter, &dtest, &evnames, 1, &eval_out);
}
std::cout << "Deleting dtrain: " << XGDMatrixFree(dtrain) << std::endl;
std::cout << "Deleting dtest: " << XGDMatrixFree(dtest) << std::endl;
std::cout << "XGBoosterFree: " << XGBoosterFree(h_booster_) << std::endl;
如何创建新的DMatrix并在同一过程中多次在booster中使用它。
答案 0 :(得分:0)
通过添加以下行,我发现了实际错误。
if (XGDMatrixCreateFromMat(copied_inputs, data_size, input_dim, -1, &dmat) != 0) {
std::string error_s(XGBGetLastError());
std::cout << error_s << std::endl;
}
错误为There are NAN in the matrix, however, you did not set missing=NAN
。这提示我创建float*
输入的方式存在问题。虽然,它第一次运行没有问题,但是结果可能是错误的。我正在构建一个像下面的copied_inputs
float** copied_inputs = new float*[input_size];
float* copied_labels = new float[input_size];
for(size_t i = 0; i < input_size; ++i) {
for(size_t j = 0; j < input_dim; ++j) {
copied_inputs[i] = new float[input_dim];
copied_inputs[i][j] = static_cast<float>(inputs[i][j]);
}
copied_labels[i] = static_cast<float>(outputs[i]);
}
copied_inputs
的上述构造显然是错误的,因为在XGDMatrixCreateFromMat
中访问它的方式是:
for (xgboost::bst_ulong i = 0; i < nrow; ++i, data += ncol) {
xgboost::bst_ulong matj = 0;
for (xgboost::bst_ulong j = 0; j < ncol; ++j) {
if (common::CheckNAN(data[j])) {
} else {
if (nan_missing || data[j] != missing) {
data_vec[offset_vec[i] + matj] = Entry(j, data[j]);
++matj;
}
}
}
}
因此,我将copied_inputs
的结构更改为:
float* copied_inputs = new float[data_size * input_dim];
float* copied_labels = new float[data_size];
float* temp_copied_inputs = copied_inputs;
for(size_t i = 0; i < data_size; ++i, temp_copied_inputs += input_dim) {
for(size_t j = 0; j < input_dim; ++j) {
temp_copied_inputs[j] = static_cast<float>(inputs[i][j]);
}
copied_labels[i] = static_cast<float>(outputs[i]);
}
这解决了多次运行的问题。