Skip to content

Commit ab5d486

Browse files
Add DeltaBarDeltaUpdate
1 parent 3027fba commit ab5d486

2 files changed

Lines changed: 168 additions & 0 deletions

File tree

include/ensmallen_bits/gradient_descent/gradient_descent.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#ifndef ENSMALLEN_GRADIENT_DESCENT_GRADIENT_DESCENT_HPP
1313
#define ENSMALLEN_GRADIENT_DESCENT_GRADIENT_DESCENT_HPP
1414

15+
#include "update_policies/delta_bar_delta_update.hpp"
16+
1517
namespace ens {
1618

1719
/**
@@ -225,6 +227,8 @@ class GradientDescentType
225227

226228
using GradientDescent = GradientDescentType<VanillaUpdate, NoDecay>;
227229

230+
using DeltaBarDelta = GradientDescentType<DeltaBarDeltaUpdate, NoDecay>;
231+
228232
} // namespace ens
229233

230234
#include "gradient_descent_impl.hpp"
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* @file delta_bar_delta_update.hpp
3+
* @author Ranjodh Singh
4+
*
5+
* Delta-Bar-Delta update for Gradient Descent.
6+
*
7+
* ensmallen is free software; you may redistribute it and/or modify it under
8+
* the terms of the 3-clause BSD license. You should have received a copy of
9+
* the 3-clause BSD license along with ensmallen. If not, see
10+
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
11+
*/
12+
#ifndef ENSMALLEN_GRAIDENT_DESCENT_DELTA_BAR_DELTA_UPDATE_HPP
13+
#define ENSMALLEN_GRAIDENT_DESCENT_DELTA_BAR_DELTA_UPDATE_HPP
14+
15+
namespace ens {
16+
17+
/**
18+
* DeltaBarDelta Update Policy for Gradient Descent
19+
*
20+
* A heuristic designed to accelerate convergence by
21+
* adapting the learning rate of each paramenter individually.
22+
*
23+
* According to the Delta-Bar-Delta update:
24+
*
25+
* - If the current derivative of a weight and the exponential moving average
26+
* of its previous derivatives have the same sign, then the learning rate
27+
* for that weight is incremented by a constant \f$\kappa\f$.
28+
*
29+
* - If the current derivative of a weight and the exponential moving average
30+
* of its previous derivatives have the opposite signs, then the learning
31+
* rate for that weight is decremented by a proportion \f$\phi\f$ of its
32+
* current value.
33+
*
34+
* @note This implementation introduces a MinimumGain parameter to ensure
35+
* that repeated proportional decrements do not reduce the learning rate
36+
* all the way to zero. This is not present in the paper given below.
37+
*
38+
* @code
39+
* @article{jacobs1988increased,
40+
* title = {Increased Rates of Convergence Through Learning Rate
41+
* Adaptation}, author = {Jacobs, Robert A.}, journal = {Neural Networks},
42+
* volume = {1},
43+
* number = {4},
44+
* pages = {295--307},
45+
* year = {1988},
46+
* publisher = {Pergamon}
47+
* }
48+
*/
49+
class DeltaBarDeltaUpdate
50+
{
51+
public:
52+
/**
53+
* Construct the DeltaBarDelta update policy with given parameters.
54+
*
55+
* @param kappa The kappa hyperparameter
56+
* @param phi The phi hyperparameter
57+
* @param momentum The momentup hyperparameter
58+
* @param minGain The minGain hyperparameter
59+
*/
60+
DeltaBarDeltaUpdate(const double kappa = 0.2,
61+
const double phi = 0.8,
62+
const double momentum = 0.5,
63+
const double minGain = 0.01)
64+
: kappa(kappa), phi(phi), momentum(momentum), minGain(minGain)
65+
{
66+
/* Do nothing. */
67+
}
68+
69+
//! Access kappa.
70+
double Kappa() const { return kappa; }
71+
//! Modify kappa.
72+
double& Kappa() { return kappa; }
73+
74+
//! Access phi.
75+
double Phi() const { return phi; }
76+
//! Modify phi.
77+
double& Phi() { return phi; }
78+
79+
//! Access the momentum.
80+
double Momentum() const { return momentum; }
81+
//! Modify the momentum.
82+
double& Momentum() { return momentum; }
83+
84+
//! Access the minGain
85+
double MinimumGain() const { return minGain; }
86+
//! Modify the minGain.
87+
double& MinimumGain() { return minGain; }
88+
89+
/**
90+
* The UpdatePolicyType policy classes must contain an internal 'Policy'
91+
* template class with two template arguments: MatType and GradType. This is
92+
* instantiated at the start of the optimization, and holds parameters
93+
* specific to an individual optimization.
94+
*/
95+
template <typename MatType, typename GradType>
96+
class Policy
97+
{
98+
public:
99+
/**
100+
* This is called by the optimizer method before the start of the iteration
101+
* update process.
102+
*
103+
* @param parent Instantiated parent class.
104+
* @param rows Number of rows in the gradient matrix.
105+
* @param cols Number of columns in the gradient matrix.
106+
*/
107+
Policy(const DeltaBarDeltaUpdate& parent,
108+
const size_t rows,
109+
const size_t cols)
110+
: parent(parent), velocity(rows, cols)
111+
{
112+
gains.ones(rows, cols);
113+
}
114+
115+
/**
116+
* Update step for Gradient Descent.
117+
*
118+
* @param iterate Parameters that minimize the function.
119+
* @param stepSize Step size to be used for the given iteration.
120+
* @param gradient The gradient matrix.
121+
*/
122+
void Update(MatType& iterate,
123+
const double stepSize,
124+
const GradType& gradient)
125+
{
126+
arma::umat increase = (velocity % gradient) < 0.0;
127+
arma::umat decrease = (velocity % gradient) > 0.0;
128+
gains.elem(arma::find(increase)) += parent.Kappa();
129+
gains.elem(arma::find(decrease)) *= parent.Phi();
130+
gains.elem(arma::find(gains < parent.MinimumGain()))
131+
.fill(parent.MinimumGain());
132+
133+
velocity = parent.momentum * velocity - (stepSize * gains) % gradient;
134+
iterate += velocity;
135+
}
136+
137+
private:
138+
//! The instantiated parent class.
139+
const DeltaBarDeltaUpdate& parent;
140+
141+
//! The gains matrix.
142+
MatType gains;
143+
144+
//! The velocity matrix.
145+
MatType velocity;
146+
};
147+
148+
private:
149+
//! The kappa hyperparameter
150+
double kappa;
151+
152+
//! The phi hyperparameter
153+
double phi;
154+
155+
//! The momentum hyperparameter.
156+
double momentum;
157+
158+
//! The minGain hyperparameter
159+
double minGain;
160+
};
161+
162+
} // namespace ens
163+
164+
#endif // ENSMALLEN_GRAIDENT_DESCENT_DELTA_BAR_DELTA_UPDATE_HPP

0 commit comments

Comments
 (0)