Shark machine learning library
About Shark
News!
Contribute
Credits and copyright
Downloads
Getting Started
Installation
Using the docs
Documentation
Tutorials
Quick references
Class list
Global functions
FAQ
Showroom
include
shark
Algorithms
DirectSearch
Operators
PopulationBasedStepSizeAdaptation.h
Go to the documentation of this file.
1
/*!
2
* \brief Implements the tep size adaptation based on the success of the new population compared to the old
3
*
4
* \author O.Krause
5
* \date 2014
6
*
7
* \par Copyright 1995-2017 Shark Development Team
8
*
9
* <BR><HR>
10
* This file is part of Shark.
11
* <http://shark-ml.org/>
12
*
13
* Shark is free software: you can redistribute it and/or modify
14
* it under the terms of the GNU Lesser General Public License as published
15
* by the Free Software Foundation, either version 3 of the License, or
16
* (at your option) any later version.
17
*
18
* Shark is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU Lesser General Public License for more details.
22
*
23
* You should have received a copy of the GNU Lesser General Public License
24
* along with Shark. If not, see <http://www.gnu.org/licenses/>.
25
*
26
*/
27
#ifndef SHARK_ALGORITHMS_DIRECTSEARCH_OPERATORS_POPULATION_BASED_STEP_SIZE_ADAPTATION_H
28
#define SHARK_ALGORITHMS_DIRECTSEARCH_OPERATORS_POPULATION_BASED_STEP_SIZE_ADAPTATION_H
29
30
#include <
shark/LinAlg/Base.h
>
31
#include <cmath>
32
33
namespace
shark
{
34
35
/// \brief Step size adaptation based on the success of the new population compared to the old
36
///
37
/// This is the step size adaptation algorithm as proposed in
38
/// Ilya Loshchilov, "A Computationally Efficient Limited Memory CMA-ES for Large Scale Optimization"
39
///
40
/// It ranks the old and new population together and checks whether the mean rank of the new population
41
/// is lower than the old one in this combined population. If this is true, the step size is increased
42
/// in an exponential fashion. More formally, let \f$ r_t(i) \f$ be the rank of the i-th individual in the
43
/// current population in the combined ranking and \f$ r_{t-1}(i) \f$ the rank of the i-th previous
44
/// individual. Then we have
45
/// \f[ z_t \leftarrow \frac 1 {\lamba^2} \sum_i^{\lambda} r_{t-1}(i) - r_t(i) - z*\f]
46
/// where \f$ z* \f$ is a target success value, which defaults to 0.25
47
/// this statistic is stabilised using an exponential average:
48
/// \f[ s_t \leftarrow (1-c)*s_{t-1} + c*z_t \f]
49
/// where the learning rate c defaults to 0.3
50
/// finally we adapt the step size sigma by
51
/// \f[ \sigma_t = \sigma_{t-1} exp(s_t/d) \f]
52
/// where the damping factor d defaults to 1
53
class
PopulationBasedStepSizeAdaptation
{
54
public
:
55
PopulationBasedStepSizeAdaptation
():
m_targetSuccessRate
(0.25),
m_c
(0.3),
m_d
(1.0){}
56
57
/////Getter and Setter functions/////////
58
59
double
targetSuccessRate
()
const
{
60
return
m_targetSuccessRate
;
61
}
62
63
double
&
targetSuccessRate
(){
64
return
m_targetSuccessRate
;
65
}
66
67
double
learningRate
()
const
{
68
return
m_c
;
69
}
70
71
double
&
learningRate
(){
72
return
m_c
;
73
}
74
75
double
dampingFactor
()
const
{
76
return
m_d
;
77
}
78
79
double
&
dampingFactor
(){
80
return
m_d
;
81
}
82
83
double
stepSize
()
const
{
84
return
m_stepSize
;
85
}
86
87
///\brief Initializes a new trial by setting the initial learning rate and resetting the internal values.
88
void
init
(
double
initialStepSize){
89
m_stepSize
= initialStepSize;
90
m_s
= 0;
91
m_prevFitness
.resize(0);
92
}
93
94
/// \brief updates the step size using the newly sampled population
95
///
96
/// The offspring is assumed to be ordered in ascending order by their penalizedFitness
97
/// (this is the same as ordering by the unpenalized fitness in an unconstrained setting)
98
template
<
class
Population>
99
void
update
(
Population
const
& offspring){
100
std::size_t
lambda
= offspring.size();
101
if
(
m_prevFitness
.size() ==
lambda
){
102
//get estimate of z
103
std::size_t indexOld = 0;
104
std::size_t indexNew = 0;
105
std::size_t rank = 1;
106
double
z = 0;
107
while
(indexOld < lambda && indexNew < lambda){
108
if
(offspring[indexNew].
penalizedFitness
() <=
m_prevFitness
[indexOld]){
109
z-=rank;
110
++indexNew;
111
}
112
else
{
113
z+=rank;
114
++indexOld;
115
}
116
++rank;
117
}
118
//case 1: the worst elements in the old population are better than the worst in the new
119
while
(indexNew < lambda){
120
z-=rank;
121
++indexNew;
122
++rank;
123
}
124
//case 2: the opposite
125
while
(indexOld< lambda){
126
z += rank;
127
++indexOld;
128
++rank;
129
}
130
z /= lambda*
lambda
;
131
z -=
m_targetSuccessRate
;
132
m_s
= (1-
m_c
)*
m_s
+
m_c
*z;
133
m_stepSize
*= std::exp(
m_s
/
m_d
);
134
}
135
136
//store fitness values of last iteration
137
m_prevFitness
.resize(lambda);
138
for
(std::size_t i = 0; i !=
lambda
; ++i)
139
m_prevFitness
(i) = offspring[i].penalizedFitness();
140
}
141
protected
:
142
double
m_stepSize
;
///< current value for the step size
143
RealVector
m_prevFitness
;
///< fitness values of the previous iteration for ranking
144
double
m_s
;
///< The time average of the population success
145
146
//hyper parameters
147
double
m_targetSuccessRate
;
148
double
m_c
;
149
double
m_d
;
150
};
151
152
}
153
154
#endif