fix base score, and print message

This commit is contained in:
tqchen@graphlab.com 2014-08-18 10:53:15 -07:00
parent 04e04ec5a0
commit f6c763a2a7
7 changed files with 39 additions and 14 deletions

View File

@ -3,7 +3,7 @@ export CXX = g++
export LDFLAGS= -pthread -lm export LDFLAGS= -pthread -lm
ifeq ($(no_omp),1) ifeq ($(no_omp),1)
export CFLAGS = -Wall -O3 -msse2 -Wno-unknown-pragmas export CFLAGS = -Wall -O3 -msse2 -Wno-unknown-pragmas -DDISABLE_OPENMP
else else
export CFLAGS = -Wall -O3 -msse2 -Wno-unknown-pragmas -fopenmp export CFLAGS = -Wall -O3 -msse2 -Wno-unknown-pragmas -fopenmp
endif endif

View File

@ -233,7 +233,7 @@ class GBTree : public IGradBooster<FMatrix> {
pred_counter[bid] = static_cast<unsigned>(trees.size()); pred_counter[bid] = static_cast<unsigned>(trees.size());
pred_buffer[bid] = psum; pred_buffer[bid] = psum;
} }
return psum; return psum + mparam.base_score;
} }
// initialize thread local space for prediction // initialize thread local space for prediction
inline void InitThreadTemp(int nthread) { inline void InitThreadTemp(int nthread) {
@ -296,6 +296,8 @@ class GBTree : public IGradBooster<FMatrix> {
}; };
/*! \brief model parameters */ /*! \brief model parameters */
struct ModelParam { struct ModelParam {
/*! \brief base prediction score of everything */
float base_score;
/*! \brief number of trees */ /*! \brief number of trees */
int num_trees; int num_trees;
/*! \brief number of root: default 0, means single tree */ /*! \brief number of root: default 0, means single tree */
@ -314,6 +316,7 @@ class GBTree : public IGradBooster<FMatrix> {
int reserved[32]; int reserved[32];
/*! \brief constructor */ /*! \brief constructor */
ModelParam(void) { ModelParam(void) {
base_score = 0.0f;
num_trees = 0; num_trees = 0;
num_roots = num_feature = 0; num_roots = num_feature = 0;
num_pbuffer = 0; num_pbuffer = 0;
@ -326,6 +329,7 @@ class GBTree : public IGradBooster<FMatrix> {
* \param val value of the parameter * \param val value of the parameter
*/ */
inline void SetParam(const char *name, const char *val) { inline void SetParam(const char *name, const char *val) {
if (!strcmp("base_score", name)) base_score = static_cast<float>(atof(val));
if (!strcmp("num_pbuffer", name)) num_pbuffer = atol(val); if (!strcmp("num_pbuffer", name)) num_pbuffer = atol(val);
if (!strcmp("num_output_group", name)) num_output_group = atol(val); if (!strcmp("num_output_group", name)) num_output_group = atol(val);
if (!strcmp("bst:num_roots", name)) num_roots = atoi(val); if (!strcmp("bst:num_roots", name)) num_roots = atoi(val);

View File

@ -85,15 +85,22 @@ class BoostLearner {
if (!strcmp(name, "booster")) name_gbm_ = val; if (!strcmp(name, "booster")) name_gbm_ = val;
mparam.SetParam(name, val); mparam.SetParam(name, val);
} }
if (gbm_ != NULL) gbm_->SetParam(name, val);
if (obj_ != NULL) obj_->SetParam(name, val);
cfg_.push_back(std::make_pair(std::string(name), std::string(val))); cfg_.push_back(std::make_pair(std::string(name), std::string(val)));
} }
/*! /*!
* \brief initialize the model * \brief initialize the model
*/ */
inline void InitModel(void) { inline void InitModel(void) {
// initialize model
this->InitObjGBM(); this->InitObjGBM();
// adapt the base score // reset the base score
mparam.base_score = obj_->ProbToMargin(mparam.base_score); mparam.base_score = obj_->ProbToMargin(mparam.base_score);
char tmp[32];
snprintf(tmp, sizeof(tmp), "%g", mparam.base_score);
this->SetParam("base_score", tmp);
// initialize GBM model
gbm_->InitModel(); gbm_->InitModel();
} }
/*! /*!

View File

@ -124,7 +124,7 @@ class RegLossObj : public IObjFunction{
loss.SecondOrderGradient(p, info.labels[j]) * w); loss.SecondOrderGradient(p, info.labels[j]) * w);
} }
} }
virtual const char* DefaultEvalMetric(void) { virtual const char* DefaultEvalMetric(void) const {
return loss.DefaultEvalMetric(); return loss.DefaultEvalMetric();
} }
virtual void PredTransform(std::vector<float> *io_preds) { virtual void PredTransform(std::vector<float> *io_preds) {
@ -135,6 +135,9 @@ class RegLossObj : public IObjFunction{
preds[j] = loss.PredTransform(preds[j]); preds[j] = loss.PredTransform(preds[j]);
} }
} }
virtual float ProbToMargin(float base_score) const {
return loss.ProbToMargin(base_score);
}
protected: protected:
float scale_pos_weight; float scale_pos_weight;
@ -192,7 +195,7 @@ class SoftmaxMultiClassObj : public IObjFunction {
virtual void EvalTransform(std::vector<float> *io_preds) { virtual void EvalTransform(std::vector<float> *io_preds) {
this->Transform(io_preds, 0); this->Transform(io_preds, 0);
} }
virtual const char* DefaultEvalMetric(void) { virtual const char* DefaultEvalMetric(void) const {
return "merror"; return "merror";
} }
@ -320,7 +323,7 @@ class LambdaRankObj : public IObjFunction {
} }
} }
} }
virtual const char* DefaultEvalMetric(void) { virtual const char* DefaultEvalMetric(void) const {
return "map"; return "map";
} }

View File

@ -32,7 +32,7 @@ class IObjFunction{
int iter, int iter,
std::vector<bst_gpair> *out_gpair) = 0; std::vector<bst_gpair> *out_gpair) = 0;
/*! \return the default evaluation metric for the objective */ /*! \return the default evaluation metric for the objective */
virtual const char* DefaultEvalMetric(void) = 0; virtual const char* DefaultEvalMetric(void) const = 0;
// the following functions are optional, most of time default implementation is good enough // the following functions are optional, most of time default implementation is good enough
/*! /*!
* \brief transform prediction values, this is only called when Prediction is called * \brief transform prediction values, this is only called when Prediction is called
@ -53,7 +53,7 @@ class IObjFunction{
* used by gradient boosting * used by gradient boosting
* \return transformed value * \return transformed value
*/ */
virtual float ProbToMargin(float base_score) { virtual float ProbToMargin(float base_score) const {
return base_score; return base_score;
} }
}; };

View File

@ -19,6 +19,7 @@ class TreePruner: public IUpdater<FMatrix> {
// set training parameter // set training parameter
virtual void SetParam(const char *name, const char *val) { virtual void SetParam(const char *name, const char *val) {
param.SetParam(name, val); param.SetParam(name, val);
if (!strcmp(name, "silent")) silent = atoi(val);
} }
// update the tree, do pruning // update the tree, do pruning
virtual void Update(const std::vector<bst_gpair> &gpair, virtual void Update(const std::vector<bst_gpair> &gpair,
@ -32,33 +33,41 @@ class TreePruner: public IUpdater<FMatrix> {
private: private:
// try to prune off current leaf // try to prune off current leaf
inline void TryPruneLeaf(RegTree &tree, int nid, int depth) { inline int TryPruneLeaf(RegTree &tree, int nid, int depth, int npruned) {
if (tree[nid].is_root()) return; if (tree[nid].is_root()) return npruned;
int pid = tree[nid].parent(); int pid = tree[nid].parent();
RegTree::NodeStat &s = tree.stat(pid); RegTree::NodeStat &s = tree.stat(pid);
++s.leaf_child_cnt; ++s.leaf_child_cnt;
if (s.leaf_child_cnt >= 2 && param.need_prune(s.loss_chg, depth - 1)) { if (s.leaf_child_cnt >= 2 && param.need_prune(s.loss_chg, depth - 1)) {
// need to be pruned // need to be pruned
tree.ChangeToLeaf(pid, param.learning_rate * s.base_weight); tree.ChangeToLeaf(pid, param.learning_rate * s.base_weight);
// tail recursion // tail recursion
this->TryPruneLeaf(tree, pid, depth - 1); return this->TryPruneLeaf(tree, pid, depth - 1, npruned+2);
} else {
return npruned;
} }
} }
/*! \brief do prunning of a tree */ /*! \brief do prunning of a tree */
inline void DoPrune(RegTree &tree) { inline void DoPrune(RegTree &tree) {
int npruned = 0;
// initialize auxiliary statistics // initialize auxiliary statistics
for (int nid = 0; nid < tree.param.num_nodes; ++nid) { for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
tree.stat(nid).leaf_child_cnt = 0; tree.stat(nid).leaf_child_cnt = 0;
} }
for (int nid = 0; nid < tree.param.num_nodes; ++nid) { for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
if (tree[nid].is_leaf()) { if (tree[nid].is_leaf()) {
this->TryPruneLeaf(tree, nid, tree.GetDepth(nid)); npruned = this->TryPruneLeaf(tree, nid, tree.GetDepth(nid), npruned);
} }
} }
if (silent == 0) {
printf("tree prunning end, %d roots, %d extra nodes, %d pruned nodes ,max_depth=%d\n",
tree.param.num_roots, tree.num_extra_nodes(), npruned, tree.MaxDepth());
}
} }
private: private:
// shutup
int silent;
// training parameter // training parameter
TrainParam param; TrainParam param;
}; };

View File

@ -8,7 +8,9 @@
#if defined(_OPENMP) #if defined(_OPENMP)
#include <omp.h> #include <omp.h>
#else #else
#ifndef DISABLE_OPENMP
#warning "OpenMP is not available, compile to single thread code" #warning "OpenMP is not available, compile to single thread code"
#endif
inline int omp_get_thread_num() { return 0; } inline int omp_get_thread_num() { return 0; }
inline int omp_get_num_threads() { return 1; } inline int omp_get_num_threads() { return 1; }
inline void omp_set_num_threads(int nthread) {} inline void omp_set_num_threads(int nthread) {}