| 
 | 1 | +#include <cmath>  | 
 | 2 | +#include "learner.h"  | 
 | 3 | + | 
 | 4 | +namespace adPredictAlgo {  | 
 | 5 | + | 
 | 6 | +class SGD : public Learner {  | 
 | 7 | +  public:  | 
 | 8 | +    SGD() {  | 
 | 9 | +      num_fea = 0;  | 
 | 10 | +      epochs = 1;  | 
 | 11 | +      alpha = 0.1;  | 
 | 12 | +    }  | 
 | 13 | + | 
 | 14 | +    virtual ~SGD() {  | 
 | 15 | +    }  | 
 | 16 | + | 
 | 17 | +    void Configure(const std::vector<std::pair<std::string,std::string> > &cfg)   | 
 | 18 | +    {  | 
 | 19 | +      for(const auto &kv : cfg)  | 
 | 20 | +        cfg_[kv.first] = kv.second;  | 
 | 21 | + | 
 | 22 | +      if(cfg_.count("num_fea"))  | 
 | 23 | +        num_fea = static_cast<uint32_t>(atoi(cfg_["num_fea"].c_str()));  | 
 | 24 | +      if(cfg_.count("alpha"))  | 
 | 25 | +        alpha = static_cast<float>(atof(cfg_["alpha"].c_str()));  | 
 | 26 | +        std::cout << alpha << std::endl;  | 
 | 27 | +      if(cfg_.count("epochs"))  | 
 | 28 | +        epochs = static_cast<int>(atoi(cfg_["epochs"].c_str()));  | 
 | 29 | +    }  | 
 | 30 | + | 
 | 31 | +    void Train(float *primal,  | 
 | 32 | +               float *dual,  | 
 | 33 | +               float *cons,  | 
 | 34 | +               float rho,  | 
 | 35 | +               dmlc::RowBlockIter<unsigned> *dtrain)  | 
 | 36 | +    {  | 
 | 37 | +      memset(primal,0.1,sizeof(float)*num_fea);  | 
 | 38 | +      for(int iter = 0; iter < epochs;iter++){  | 
 | 39 | +        dtrain->BeforeFirst();  | 
 | 40 | +        while(dtrain->Next())  {  | 
 | 41 | +          const dmlc::RowBlock<unsigned> &batch = dtrain->Value();  | 
 | 42 | +          for(size_t i = 0;i < batch.size;i++)  | 
 | 43 | +          {  | 
 | 44 | +            dmlc::Row<unsigned> v = batch[i];  | 
 | 45 | +            float grad = PredIns(v,primal) - v.get_label();  | 
 | 46 | +            float grad_tmp = grad;  | 
 | 47 | + | 
 | 48 | +            for(unsigned j = 0;j < v.length;j++) {  | 
 | 49 | +              unsigned fea_index = v.index[j];   | 
 | 50 | +              grad_tmp += dual[fea_index] + rho * (primal[fea_index] - cons[fea_index]);  | 
 | 51 | +              primal[fea_index] -= alpha * grad_tmp;  | 
 | 52 | +//              std::cout << primal[fea_index] << " " << alpha * grad_tmp << std::endl;  | 
 | 53 | +              grad_tmp = grad;  | 
 | 54 | +            }  | 
 | 55 | +          }  | 
 | 56 | +        }  | 
 | 57 | +      }  | 
 | 58 | +    }  | 
 | 59 | + | 
 | 60 | +    float PredIns(const dmlc::Row<unsigned> &v,  | 
 | 61 | +                         const float *w) {  | 
 | 62 | +      float inner = 0.0f;  | 
 | 63 | +      for(unsigned i = 0;i < v.length;i++) {  | 
 | 64 | +        inner += w[v.index[i]];  | 
 | 65 | +      }  | 
 | 66 | +      return Sigmoid(inner);  | 
 | 67 | +    }  | 
 | 68 | + | 
 | 69 | +    inline float Sigmoid(const float &inx) {  | 
 | 70 | +      return 1.0f / (1.0f + std::exp(-inx));  | 
 | 71 | +    }  | 
 | 72 | + | 
 | 73 | +  private:  | 
 | 74 | +    float alpha;  | 
 | 75 | +    uint32_t num_fea;  | 
 | 76 | +    int epochs;  | 
 | 77 | + | 
 | 78 | +    std::map<std::string,std::string> cfg_;  | 
 | 79 | +};  | 
 | 80 | + | 
 | 81 | +}  | 
0 commit comments