spalera_stepsize.hpp
Go to the documentation of this file.
1 
15 #ifndef MLPACK_CORE_OPTIMIZERS_SPALERA_SGD_SPALERA_STEPSIZE_HPP
16 #define MLPACK_CORE_OPTIMIZERS_SPALERA_SGD_SPALERA_STEPSIZE_HPP
17 
18 namespace mlpack {
19 namespace optimization {
20 
39 {
40  public:
51  SPALeRAStepsize(const double alpha = 0.001,
52  const double epsilon = 1e-6,
53  const double adaptRate = 3.10e-8) :
54  alpha(alpha),
55  epsilon(epsilon),
56  adaptRate(adaptRate)
57  {
58  /* Nothing to do here. */
59  }
60 
69  void Initialize(const size_t rows, const size_t cols, const double lambda)
70  {
71  learningRates = arma::ones(rows, cols);
72  relaxedSums = arma::zeros(rows, cols);
73 
74  this->lambda = lambda;
75 
76  mu0 = un = mn = relaxedObjective = phCounter = eveCounter = 0;
77  }
78 
91  bool Update(const double stepSize,
92  const double objective,
93  const size_t batchSize,
94  const size_t numFunctions,
95  arma::mat& iterate,
96  const arma::mat& gradient)
97  {
98  // The ratio of mini-batch size to training set size; needed for the
99  // Page-Hinkley relaxed objective computations.
100  const double mbRatio = batchSize / (double) numFunctions;
101 
102  // Page-Hinkley iteration, check if we have to reset the parameter and
103  // adjust the step size.
104  if (phCounter > (1 / mbRatio))
105  {
106  relaxedObjective = (1 - mbRatio) * relaxedObjective + mbRatio * objective;
107  }
108  else
109  {
110  relaxedObjective = phCounter * relaxedObjective + objective;
111  relaxedObjective /= (phCounter + 1);
112  }
113 
114  // Update the mu0 parameter.
115  mu0 = phCounter * mu0 + relaxedObjective;
116  mu0 = mu0 / (phCounter + 1);
117 
118  // Update the un parameter.
119  un += relaxedObjective - mu0;
120 
121  // Updating the mn parameter.
122  if (un < mn)
123  mn = un;
124 
125  // If the condition is true we reset the parameter and update parameter.
126  if ((un - mn) > lambda)
127  {
128  // Backtracking, reset the parameter.
129  iterate = previousIterate;
130 
131  // Dividing learning rates by 2 as proposed in:
132  // Stochastic Gradient Descent: Going As Fast As Possible But Not Faster.
133  learningRates /= 2;
134 
135  if (arma::any(arma::vectorise(learningRates) <= 1e-15))
136  {
137  // Stop because learning rate too low.
138  return false;
139  }
140 
141  // Reset evaluation and Page-Hinkley counter parameter.
142  mu0 = un = mn = relaxedObjective = phCounter = eveCounter = 0;
143  }
144  else
145  {
146  const double paramMean = (alpha / (2 - alpha) *
147  (1 - std::pow(1 - alpha, 2 * (eveCounter + 1)))) / iterate.n_elem;
148 
149  const double paramStd = (alpha / std::sqrt(iterate.n_elem)) /
150  std::sqrt(iterate.n_elem);
151 
152  const double normGradient = std::sqrt(arma::accu(arma::pow(gradient, 2)));
153 
154  relaxedSums *= (1 - alpha);
155  if (normGradient > epsilon)
156  relaxedSums += gradient * (alpha / normGradient);
157 
158  learningRates %= arma::exp((arma::pow(relaxedSums, 2) - paramMean) *
159  (adaptRate / paramStd));
160 
161  previousIterate = iterate;
162 
163  iterate -= stepSize * (learningRates % gradient);
164 
165  // Keep track of the the number of evaluations and Page-Hinkley steps.
166  eveCounter++;
167  phCounter++;
168  }
169 
170  return true;
171  }
172 
174  double Alpha() const { return alpha; }
176  double& Alpha() { return alpha; }
177 
179  double AdaptRate() const { return adaptRate; }
181  double& AdaptRate() { return adaptRate; }
182 
183  private:
185  double mu0;
186 
188  double un;
189 
191  double mn;
192 
194  double relaxedObjective;
195 
197  size_t phCounter;
198 
200  size_t eveCounter;
201 
203  double alpha;
204 
206  double epsilon;
207 
209  double adaptRate;
210 
212  arma::mat learningRates;
213 
215  arma::mat relaxedSums;
216 
218  double lambda;
219 
221  arma::mat previousIterate;
222 };
223 
224 } // namespace optimization
225 } // namespace mlpack
226 
227 #endif // MLPACK_CORE_OPTIMIZERS_SPALERA_SGD_SPALERA_STEPSIZE_HPP
double & AdaptRate()
Modify the agnostic learning rate update rate.
.hpp
Definition: add_to_po.hpp:21
SPALeRAStepsize(const double alpha=0.001, const double epsilon=1e-6, const double adaptRate=3.10e-8)
Construct the SPALeRAStepsize object with the given parameters.
bool Update(const double stepSize, const double objective, const size_t batchSize, const size_t numFunctions, arma::mat &iterate, const arma::mat &gradient)
This function is called in each iteration.
Definition of the SPALeRA stepize technique, which implementes a change detection mechanism with an a...
double Alpha() const
Get the agnostic learning rate adaptation parameter.
double AdaptRate() const
Get the agnostic learning rate update rate.
void Initialize(const size_t rows, const size_t cols, const double lambda)
The Initialize method is called by SPALeRASGD Optimizer method before the start of the iteration upda...
double & Alpha()
Modify the agnostic learning rate adaptation parameter.