#pragma once
#include <dmlc/io.h>
#include <dmlc/parameter.h>
#include <xgboost/learner.h>
#include <vector>
#include <string>
#include <cstring>
#include "xgboost/base.h"
#include "xgboost/feature_map.h"
#include "xgboost/model.h"
#include "xgboost/json.h"
#include "xgboost/parameter.h"
namespace xgboost {
class Json;
namespace gbm {
struct DeprecatedGBLinearModelParam : public dmlc::Parameter<DeprecatedGBLinearModelParam> {
uint32_t deprecated_num_feature;
int32_t deprecated_num_output_group;
int32_t reserved[32];
DeprecatedGBLinearModelParam() {
static_assert(sizeof(*this) == sizeof(int32_t) * 34,
"Model parameter size can not be changed.");
std::memset(this, 0, sizeof(DeprecatedGBLinearModelParam));
}
DMLC_DECLARE_PARAMETER(DeprecatedGBLinearModelParam) {
DMLC_DECLARE_FIELD(deprecated_num_feature);
DMLC_DECLARE_FIELD(deprecated_num_output_group);
}
};
class GBLinearModel : public Model {
private:
DeprecatedGBLinearModelParam param_;
public:
int32_t num_boosted_rounds{0};
LearnerModelParam const* learner_model_param;
public:
explicit GBLinearModel(LearnerModelParam const *learner_model_param)
: learner_model_param{learner_model_param} {}
void Configure(Args const &) { }
std::vector<bst_float> weight;
inline void LazyInitModel() {
if (!weight.empty()) {
return;
}
weight.resize((learner_model_param->num_feature + 1) *
learner_model_param->num_output_group);
std::fill(weight.begin(), weight.end(), 0.0f);
}
void SaveModel(Json *p_out) const override;
void LoadModel(Json const &in) override;
void Save(dmlc::Stream *fo) const {
fo->Write(¶m_, sizeof(param_));
fo->Write(weight);
}
void Load(dmlc::Stream *fi) {
CHECK_EQ(fi->Read(¶m_, sizeof(param_)), sizeof(param_));
fi->Read(&weight);
}
inline bst_float *Bias() {
return &weight[learner_model_param->num_feature *
learner_model_param->num_output_group];
}
inline const bst_float *Bias() const {
return &weight[learner_model_param->num_feature *
learner_model_param->num_output_group];
}
inline bst_float *operator[](size_t i) {
return &weight[i * learner_model_param->num_output_group];
}
inline const bst_float *operator[](size_t i) const {
return &weight[i * learner_model_param->num_output_group];
}
std::vector<std::string> DumpModel(const FeatureMap &, bool,
std::string format) const {
const int ngroup = learner_model_param->num_output_group;
const unsigned nfeature = learner_model_param->num_feature;
std::stringstream fo("");
if (format == "json") {
fo << " { \"bias\": [" << std::endl;
for (int gid = 0; gid < ngroup; ++gid) {
if (gid != 0) {
fo << "," << std::endl;
}
fo << " " << this->Bias()[gid];
}
fo << std::endl
<< " ]," << std::endl
<< " \"weight\": [" << std::endl;
for (unsigned i = 0; i < nfeature; ++i) {
for (int gid = 0; gid < ngroup; ++gid) {
if (i != 0 || gid != 0) {
fo << "," << std::endl;
}
fo << " " << (*this)[i][gid];
}
}
fo << std::endl << " ]" << std::endl << " }";
} else if (format == "text") {
fo << "bias:\n";
for (int gid = 0; gid < ngroup; ++gid) {
fo << this->Bias()[gid] << std::endl;
}
fo << "weight:\n";
for (unsigned i = 0; i < nfeature; ++i) {
for (int gid = 0; gid < ngroup; ++gid) {
fo << (*this)[i][gid] << std::endl;
}
}
} else {
LOG(FATAL) << "Dump format `" << format << "` is not supported by the gblinear model.";
}
std::vector<std::string> v;
v.push_back(fo.str());
return v;
}
};
} }