• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // Stochastic Linear Ranking algorithms.
18 // This class will implement a set of incremental algorithms for ranking tasks
19 // They support both L1 and L2 regularizations.
20 
21 
22 #ifndef LEARNING_STOCHASTIC_LINEAR_STOCHASTIC_LINEAR_RANKER_H_
23 #define LEARNING_STOCHASTIC_LINEAR_STOCHASTIC_LINEAR_RANKER_H_
24 
25 #include <cmath>
26 #include <hash_map>
27 #include <string>
28 
29 #include <sys/types.h>
30 #include "cutils/log.h"
31 #include "common_defs.h"
32 #include "learning_rate_controller-inl.h"
33 #include "sparse_weight_vector.h"
34 
35 namespace learning_stochastic_linear {
36 
37 // NOTE: This Stochastic Linear Ranker supports only the following update types:
38 // SL: Stochastic Linear
39 // CS: Constraint Satisfaction
40 template<class Key = std::string, class Hash = std::hash_map<std::string, double> >
41 class StochasticLinearRanker {
42  public:
43   // initialize lambda_ and constraint to a meaningful default. Will give
44   // equal weight to the error and regularizer.
StochasticLinearRanker()45   StochasticLinearRanker() {
46     iteration_num_ = 0;
47     lambda_ = 1.0;
48     learning_rate_controller_.SetLambda(lambda_);
49     mini_batch_size_ = 1;
50     learning_rate_controller_.SetMiniBatchSize(mini_batch_size_);
51     adaptation_mode_ = INV_LINEAR;
52     learning_rate_controller_.SetAdaptationMode(adaptation_mode_);
53     update_type_ = SL;
54     regularization_type_ = L2;
55     kernel_type_ = LINEAR;
56     kernel_param_ = 1.0;
57     kernel_gain_ = 1.0;
58     kernel_bias_ = 0.0;
59     rank_loss_type_ = PAIRWISE;
60     acceptence_probability_ = 0.1;
61     mini_batch_counter_ = 0;
62     gradient_l0_norm_ = -1;
63     norm_constraint_ = 1.0;
64   }
65 
~StochasticLinearRanker()66   ~StochasticLinearRanker() {}
67   // Getters and setters
GetIterationNumber()68   double GetIterationNumber() const {
69     return iteration_num_;
70   }
GetNormContraint()71   double GetNormContraint() const {
72     return norm_constraint_;
73   }
GetRegularizationType()74   RegularizationType GetRegularizationType() const {
75     return regularization_type_;
76   }
GetLambda()77   double GetLambda() const {
78     return lambda_;
79   }
GetMiniBatchSize()80   uint64 GetMiniBatchSize() const {
81     return mini_batch_size_;
82   }
GetGradientL0Norm()83   int32 GetGradientL0Norm() const {
84     return gradient_l0_norm_;
85   }
GetUpdateType()86   UpdateType GetUpdateType() const {
87     return update_type_;
88   }
GetAdaptationMode()89   AdaptationMode GetAdaptationMode() const {
90     return adaptation_mode_;
91   }
GetKernelType()92   KernelType GetKernelType() const {
93     return kernel_type_;
94   }
95   // This function returns the basic kernel parameter. In case of
96   // polynomial kernel, it implies the degree of the polynomial.  In case of
97   // RBF kernel, it implies the sigma parameter. In case of linear kernel,
98   // it is not used.
GetKernelParam()99   double GetKernelParam() const {
100     return kernel_param_;
101   }
GetKernelGain()102   double GetKernelGain() const {
103     return kernel_gain_;;
104   }
GetKernelBias()105   double GetKernelBias() const {
106     return kernel_bias_;
107   }
GetRankLossType()108   RankLossType GetRankLossType() const {
109     return rank_loss_type_;
110   }
GetAcceptanceProbability()111   double GetAcceptanceProbability() const {
112     return acceptence_probability_;
113   }
SetIterationNumber(uint64 num)114   void SetIterationNumber(uint64 num) {
115     iteration_num_=num;
116   }
SetNormConstraint(const double norm)117   void SetNormConstraint(const double norm) {
118     norm_constraint_ = norm;
119   }
SetRegularizationType(const RegularizationType r)120   void SetRegularizationType(const RegularizationType r) {
121     regularization_type_ = r;
122   }
SetLambda(double l)123   void SetLambda(double l) {
124     lambda_ = l;
125     learning_rate_controller_.SetLambda(l);
126   }
SetMiniBatchSize(const uint64 msize)127   void SetMiniBatchSize(const uint64 msize) {
128     mini_batch_size_ = msize;
129     learning_rate_controller_.SetMiniBatchSize(msize);
130   }
SetAdaptationMode(AdaptationMode m)131   void SetAdaptationMode(AdaptationMode m) {
132     adaptation_mode_ = m;
133     learning_rate_controller_.SetAdaptationMode(m);
134   }
SetKernelType(KernelType k)135   void SetKernelType(KernelType k ) {
136     kernel_type_ = k;
137   }
138   // This function sets the basic kernel parameter. In case of
139   // polynomial kernel, it implies the degree of the polynomial. In case of
140   // RBF kernel, it implies the sigma parameter. In case of linear kernel,
141   // it is not used.
SetKernelParam(double param)142   void SetKernelParam(double param) {
143     kernel_param_ = param;
144   }
145   // This function sets the kernel gain. NOTE: in most use cases, gain should
146   // be set to 1.0.
SetKernelGain(double gain)147   void SetKernelGain(double gain) {
148     kernel_gain_ = gain;
149   }
150   // This function sets the kernel bias. NOTE: in most use cases, bias should
151   // be set to 0.0.
SetKernelBias(double bias)152   void SetKernelBias(double bias) {
153     kernel_bias_ = bias;
154   }
SetUpdateType(UpdateType u)155   void SetUpdateType(UpdateType u) {
156     update_type_ = u;
157   }
SetRankLossType(RankLossType r)158   void SetRankLossType(RankLossType r) {
159     rank_loss_type_ = r;
160   }
SetAcceptanceProbability(double p)161   void SetAcceptanceProbability(double p) {
162     acceptence_probability_ = p;
163   }
SetGradientL0Norm(const int32 gradient_l0_norm)164   void SetGradientL0Norm(const int32 gradient_l0_norm) {
165     gradient_l0_norm_ = gradient_l0_norm;
166   }
167   // Load an existing model
LoadWeights(const SparseWeightVector<Key,Hash> & model)168   void LoadWeights(const SparseWeightVector<Key, Hash> &model) {
169     weight_.LoadWeightVector(model);
170   }
171   // Save current model
SaveWeights(SparseWeightVector<Key,Hash> * model)172   void SaveWeights(SparseWeightVector<Key, Hash> *model) {
173     model->LoadWeightVector(weight_);
174   }
175   // Scoring
ScoreSample(const SparseWeightVector<Key,Hash> & sample)176   double ScoreSample(const SparseWeightVector<Key, Hash> &sample) {
177     const double dot = weight_.DotProduct(sample);
178     double w_square;
179     double s_square;
180     switch (kernel_type_) {
181       case LINEAR:
182         return dot;
183       case POLY:
184         return pow(kernel_gain_ * dot + kernel_bias_, kernel_param_);
185       case RBF:
186         w_square = weight_.L2Norm();
187         s_square = sample.L2Norm();
188         return exp(-1 * kernel_param_ * (w_square + s_square - 2 * dot));
189       default:
190       ALOGE("unsupported kernel: %d", kernel_type_);
191     }
192     return -1;
193   }
194   // Learning Functions
195   // Return values:
196   // 1 :full update went through
197   // 2 :partial update went through (for SL only)
198   // 0 :no update necessary.
199   // -1:error.
200   int UpdateClassifier(const SparseWeightVector<Key, Hash> &positive,
201                        const SparseWeightVector<Key, Hash> &negative);
202 
203  private:
204   SparseWeightVector<Key, Hash> weight_;
205   double norm_constraint_;
206   double lambda_;
207   RegularizationType regularization_type_;
208   AdaptationMode adaptation_mode_;
209   UpdateType update_type_;
210   RankLossType rank_loss_type_;
211   KernelType kernel_type_;
212   // Kernel gain and bias are typically multiplicative and additive factors to
213   // the dot product while calculating the kernel function. Kernel param is
214   // kernel-specific. In case of polynomial kernel, it is the degree of the
215   // polynomial.
216   double kernel_param_;
217   double kernel_gain_;
218   double kernel_bias_;
219   double acceptence_probability_;
220   SparseWeightVector<Key, Hash> current_negative_;
221   LearningRateController learning_rate_controller_;
222   uint64 iteration_num_;
223   // We average out gradient updates for mini_batch_size_ samples
224   // before performing an iteration of the algorithm.
225   uint64 mini_batch_counter_;
226   uint64 mini_batch_size_;
227   // Specifies the number of non-zero entries allowed in a gradient.
228   // Default is -1 which means we take the gradient as given by data without
229   // adding any new constraints. positive number is treated as an L0 constraint
230   int32 gradient_l0_norm_;
231   // Sub-Gradient Updates
232   // Pure Sub-Gradient update without any reprojection
233   // Note that a form of L2 regularization is built into this
234   void UpdateSubGradient(const SparseWeightVector<Key, Hash> &positive,
235                          const SparseWeightVector<Key, Hash> &negative,
236                          const double learning_rate,
237                          const double positive_score,
238                          const double negative_score,
239                          const int32 gradient_l0_norm);
240 
241 };
242 }  // namespace learning_stochastic_linear
243 #endif  // LEARNING_STOCHASTIC_LINEAR_STOCHASTIC_LINEAR_RANKER_H_
244