From ec14d3275664ab6b6d93b716904078f72b9d64f1 Mon Sep 17 00:00:00 2001 From: tqchen Date: Wed, 30 Apr 2014 22:11:26 -0700 Subject: [PATCH] add softmax --- regrank/xgboost_regrank_obj.h | 1 + regrank/xgboost_regrank_obj.hpp | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/regrank/xgboost_regrank_obj.h b/regrank/xgboost_regrank_obj.h index cc2f1eb2b..a494aa763 100644 --- a/regrank/xgboost_regrank_obj.h +++ b/regrank/xgboost_regrank_obj.h @@ -107,6 +107,7 @@ namespace xgboost{ IObjFunction* CreateObjFunction( const char *name ){ if( !strcmp("reg", name ) ) return new RegressionObj(); if( !strcmp("rank", name ) ) return new PairwiseRankObj(); + if( !strcmp("softmax", name ) ) return new SoftmaxObj(); utils::Error("unknown objective function type"); return NULL; } diff --git a/regrank/xgboost_regrank_obj.hpp b/regrank/xgboost_regrank_obj.hpp index 45f05dd2b..fb20f68a0 100644 --- a/regrank/xgboost_regrank_obj.hpp +++ b/regrank/xgboost_regrank_obj.hpp @@ -47,6 +47,71 @@ namespace xgboost{ }; }; + namespace regrank{ + // simple softmax rak + class SoftmaxObj : public IObjFunction{ + public: + SoftmaxObj(void){ + } + virtual ~SoftmaxObj(){} + virtual void SetParam(const char *name, const char *val){ + } + virtual void GetGradient(const std::vector& preds, + const DMatrix::Info &info, + int iter, + std::vector &grad, + std::vector &hess ) { + grad.resize(preds.size()); hess.resize(preds.size()); + const std::vector &gptr = info.group_ptr; + utils::Assert( gptr.size() != 0 && gptr.back() == preds.size(), "rank loss must have group file" ); + const unsigned ngroup = static_cast( gptr.size() - 1 ); + + #pragma omp parallel + { + std::vector< float > rec; + #pragma for schedule(static) + for (unsigned k = 0; k < ngroup; ++k){ + rec.clear(); + int nhit = 0; + for(unsigned j = gptr[k]; j < gptr[k+1]; ++j ){ + rec.push_back( preds[j] ); + grad[j] = hess[j] = 0.0f; + nhit += info.labels[j]; + } + Softmax( rec ); + if( nhit == 1 ){ + for(unsigned j = gptr[k]; j < gptr[k+1]; ++j ){ + float p = rec[ j - gptr[k] ]; + grad[j] = p - info.labels[j]; + hess[j] = 2.0f * p * ( 1.0f - p ); + } + }else{ + utils::Assert( nhit == 0, "softmax does not allow multiple labels" ); + } + } + } + } + virtual const char* DefaultEvalMetric(void) { + return "pre@1"; + } + private: + inline static void Softmax( std::vector& rec ){ + float wmax = rec[0]; + for( size_t i = 1; i < rec.size(); ++ i ){ + wmax = std::max( rec[i], wmax ); + } + double wsum = 0.0f; + for( size_t i = 0; i < rec.size(); ++ i ){ + rec[i] = expf(rec[i]-wmax); + wsum += rec[i]; + } + for( size_t i = 0; i < rec.size(); ++ i ){ + rec[i] /= wsum; + } + } + }; + }; + namespace regrank{ // simple pairwise rank class PairwiseRankObj : public IObjFunction{