popt.update_schemes.cma
1import numpy as np 2from popt.misc_tools import optim_tools as ot 3 4class CMA: 5 6 def __init__(self, ne, dim, alpha_mu=None, n_mu=None, alpha_1=None, alpha_c=None, corr_update=False, equal_weights=True): 7 ''' 8 This is a rather simple simple CMA class 9 10 Parameters 11 ---------------------------------------------------------------------------------------------------------- 12 ne : int 13 Ensemble size 14 15 dim : int 16 Dimensions of control vector 17 18 alpha_mu : float 19 Learning rate for rank-mu update. If None, value proposed in [1] is used. 20 21 n_mu : int, `n_mu < ne` 22 Number of best samples of ne, to be used for rank-mu update. 23 Default is int(ne/2). 24 25 alpha_1 : float 26 Learning rate fro rank-one update. If None, value proposed in [1] is used. 27 28 alpha_c : float 29 Parameter (inverse if backwards time horizen)for evolution path update 30 in the rank-one update. See [1] for more info. If None, value proposed in [1] is used. 31 32 corr_update : bool 33 If True, CMA is used to update a correlation matrix. Default is False. 34 35 equal_weights : bool 36 If True, all n_mu members are assign equal weighting, `w_i = 1/n_mu`. 37 If False, the weighting scheme proposed in [1], where `w_i = log(n_mu + 1)-log(i)`, 38 and normalized such that they sum to one. Defualt is True. 39 40 References 41 ---------------------------------------------------------------------------------------------------------- 42 [1] Hansen, N. (2006). The CMA evolution strategy: a comparing review. 43 In J. Lozano, P. Larranaga, I. Inza & E. Bengoetxea (ed.), Towards a new evolutionary computation. 44 Advances on estimation of distribution algorithms (pp. 75--102) . Springer . 45 ''' 46 self.alpha_mu = alpha_mu 47 self.n_mu = n_mu 48 self.alpha_1 = alpha_1 49 self.alpha_c = alpha_c 50 self.ne = ne 51 self.dim = dim 52 self.evo_path = 0 53 self.corr_update = corr_update 54 55 #If None is given, default values are used 56 if self.n_mu is None: 57 self.n_mu = int(self.ne/2) 58 59 if equal_weights: 60 self.weights = np.ones(self.n_mu)/self.n_mu 61 else: 62 self.weights = np.array([np.log(self.n_mu + 1)-np.log(i+1) for i in range(self.n_mu)]) 63 self.weights = self.weights/np.sum(self.weights) 64 65 self.mu_eff = 1/np.sum(self.weights**2) 66 self.c_cov = 1/self.mu_eff * 2/(dim+2**0.5)**2 +\ 67 (1-1/self.mu_eff)*min(1, (2*self.mu_eff-1)/((dim+2)**2+self.mu_eff)) 68 69 if self.alpha_1 is None: 70 self.alpha_1 = self.c_cov/self.mu_eff 71 if self.alpha_mu is None: 72 self.alpha_mu = self.c_cov*(1-1/self.mu_eff) 73 if self.alpha_c is None: 74 self.alpha_c = 4/(dim+4) 75 76 def _rank_mu(self, X, J): 77 ''' 78 Calculates the rank-mu matrix of CMA-ES. 79 ''' 80 index = J.argsort() # lowest (best) to highest (worst) 81 Xsorted = (X[index[:self.n_mu]] - np.mean(X, axis=0)).T # shape (d, ne) 82 weights = self.weights 83 Cmu = (Xsorted*weights)@Xsorted.T 84 85 if self.corr_update: 86 Cmu = ot.cov2corr(Cmu) 87 88 return Cmu 89 90 def _rank_one(self, step): 91 ''' 92 Calculates the rank-one matrix of CMA-ES. 93 ''' 94 s = self.alpha_c 95 self.evo_path = (1-s)*self.evo_path + np.sqrt(s*(2-s)*self.mu_eff)*step 96 C1 = np.outer(self.evo_path, self.evo_path) 97 98 if self.corr_update: 99 C1 = ot.cov2corr(C1) 100 101 return C1 102 103 def __call__(self, cov, step, X, J): 104 ''' 105 Performs the CMA update. 106 107 Parameters 108 -------------------------------------------------- 109 cov : array_like, of shape (d, d) 110 Current covariance or correlation matrix. 111 112 step : array_like, of shape (d,) 113 New step of control vector. 114 Used to update the evolution path. 115 116 X : array_like, of shape (n, d) 117 Control ensemble of size n. 118 119 J : array_like, of shape (n,) 120 Objective ensemble of size n. 121 122 Returns 123 -------------------------------------------------- 124 out : array_like, of shape (d, d) 125 CMA updated covariance (correlation) matrix. 126 ''' 127 a_mu = self.alpha_mu 128 a_one = self.alpha_1 129 C_mu = self._rank_mu(X, J) 130 C_one = self._rank_one(step) 131 132 cov = (1 - a_one - a_mu)*cov + a_one*C_one + a_mu*C_mu 133 return cov
class
CMA:
5class CMA: 6 7 def __init__(self, ne, dim, alpha_mu=None, n_mu=None, alpha_1=None, alpha_c=None, corr_update=False, equal_weights=True): 8 ''' 9 This is a rather simple simple CMA class 10 11 Parameters 12 ---------------------------------------------------------------------------------------------------------- 13 ne : int 14 Ensemble size 15 16 dim : int 17 Dimensions of control vector 18 19 alpha_mu : float 20 Learning rate for rank-mu update. If None, value proposed in [1] is used. 21 22 n_mu : int, `n_mu < ne` 23 Number of best samples of ne, to be used for rank-mu update. 24 Default is int(ne/2). 25 26 alpha_1 : float 27 Learning rate fro rank-one update. If None, value proposed in [1] is used. 28 29 alpha_c : float 30 Parameter (inverse if backwards time horizen)for evolution path update 31 in the rank-one update. See [1] for more info. If None, value proposed in [1] is used. 32 33 corr_update : bool 34 If True, CMA is used to update a correlation matrix. Default is False. 35 36 equal_weights : bool 37 If True, all n_mu members are assign equal weighting, `w_i = 1/n_mu`. 38 If False, the weighting scheme proposed in [1], where `w_i = log(n_mu + 1)-log(i)`, 39 and normalized such that they sum to one. Defualt is True. 40 41 References 42 ---------------------------------------------------------------------------------------------------------- 43 [1] Hansen, N. (2006). The CMA evolution strategy: a comparing review. 44 In J. Lozano, P. Larranaga, I. Inza & E. Bengoetxea (ed.), Towards a new evolutionary computation. 45 Advances on estimation of distribution algorithms (pp. 75--102) . Springer . 46 ''' 47 self.alpha_mu = alpha_mu 48 self.n_mu = n_mu 49 self.alpha_1 = alpha_1 50 self.alpha_c = alpha_c 51 self.ne = ne 52 self.dim = dim 53 self.evo_path = 0 54 self.corr_update = corr_update 55 56 #If None is given, default values are used 57 if self.n_mu is None: 58 self.n_mu = int(self.ne/2) 59 60 if equal_weights: 61 self.weights = np.ones(self.n_mu)/self.n_mu 62 else: 63 self.weights = np.array([np.log(self.n_mu + 1)-np.log(i+1) for i in range(self.n_mu)]) 64 self.weights = self.weights/np.sum(self.weights) 65 66 self.mu_eff = 1/np.sum(self.weights**2) 67 self.c_cov = 1/self.mu_eff * 2/(dim+2**0.5)**2 +\ 68 (1-1/self.mu_eff)*min(1, (2*self.mu_eff-1)/((dim+2)**2+self.mu_eff)) 69 70 if self.alpha_1 is None: 71 self.alpha_1 = self.c_cov/self.mu_eff 72 if self.alpha_mu is None: 73 self.alpha_mu = self.c_cov*(1-1/self.mu_eff) 74 if self.alpha_c is None: 75 self.alpha_c = 4/(dim+4) 76 77 def _rank_mu(self, X, J): 78 ''' 79 Calculates the rank-mu matrix of CMA-ES. 80 ''' 81 index = J.argsort() # lowest (best) to highest (worst) 82 Xsorted = (X[index[:self.n_mu]] - np.mean(X, axis=0)).T # shape (d, ne) 83 weights = self.weights 84 Cmu = (Xsorted*weights)@Xsorted.T 85 86 if self.corr_update: 87 Cmu = ot.cov2corr(Cmu) 88 89 return Cmu 90 91 def _rank_one(self, step): 92 ''' 93 Calculates the rank-one matrix of CMA-ES. 94 ''' 95 s = self.alpha_c 96 self.evo_path = (1-s)*self.evo_path + np.sqrt(s*(2-s)*self.mu_eff)*step 97 C1 = np.outer(self.evo_path, self.evo_path) 98 99 if self.corr_update: 100 C1 = ot.cov2corr(C1) 101 102 return C1 103 104 def __call__(self, cov, step, X, J): 105 ''' 106 Performs the CMA update. 107 108 Parameters 109 -------------------------------------------------- 110 cov : array_like, of shape (d, d) 111 Current covariance or correlation matrix. 112 113 step : array_like, of shape (d,) 114 New step of control vector. 115 Used to update the evolution path. 116 117 X : array_like, of shape (n, d) 118 Control ensemble of size n. 119 120 J : array_like, of shape (n,) 121 Objective ensemble of size n. 122 123 Returns 124 -------------------------------------------------- 125 out : array_like, of shape (d, d) 126 CMA updated covariance (correlation) matrix. 127 ''' 128 a_mu = self.alpha_mu 129 a_one = self.alpha_1 130 C_mu = self._rank_mu(X, J) 131 C_one = self._rank_one(step) 132 133 cov = (1 - a_one - a_mu)*cov + a_one*C_one + a_mu*C_mu 134 return cov
CMA( ne, dim, alpha_mu=None, n_mu=None, alpha_1=None, alpha_c=None, corr_update=False, equal_weights=True)
7 def __init__(self, ne, dim, alpha_mu=None, n_mu=None, alpha_1=None, alpha_c=None, corr_update=False, equal_weights=True): 8 ''' 9 This is a rather simple simple CMA class 10 11 Parameters 12 ---------------------------------------------------------------------------------------------------------- 13 ne : int 14 Ensemble size 15 16 dim : int 17 Dimensions of control vector 18 19 alpha_mu : float 20 Learning rate for rank-mu update. If None, value proposed in [1] is used. 21 22 n_mu : int, `n_mu < ne` 23 Number of best samples of ne, to be used for rank-mu update. 24 Default is int(ne/2). 25 26 alpha_1 : float 27 Learning rate fro rank-one update. If None, value proposed in [1] is used. 28 29 alpha_c : float 30 Parameter (inverse if backwards time horizen)for evolution path update 31 in the rank-one update. See [1] for more info. If None, value proposed in [1] is used. 32 33 corr_update : bool 34 If True, CMA is used to update a correlation matrix. Default is False. 35 36 equal_weights : bool 37 If True, all n_mu members are assign equal weighting, `w_i = 1/n_mu`. 38 If False, the weighting scheme proposed in [1], where `w_i = log(n_mu + 1)-log(i)`, 39 and normalized such that they sum to one. Defualt is True. 40 41 References 42 ---------------------------------------------------------------------------------------------------------- 43 [1] Hansen, N. (2006). The CMA evolution strategy: a comparing review. 44 In J. Lozano, P. Larranaga, I. Inza & E. Bengoetxea (ed.), Towards a new evolutionary computation. 45 Advances on estimation of distribution algorithms (pp. 75--102) . Springer . 46 ''' 47 self.alpha_mu = alpha_mu 48 self.n_mu = n_mu 49 self.alpha_1 = alpha_1 50 self.alpha_c = alpha_c 51 self.ne = ne 52 self.dim = dim 53 self.evo_path = 0 54 self.corr_update = corr_update 55 56 #If None is given, default values are used 57 if self.n_mu is None: 58 self.n_mu = int(self.ne/2) 59 60 if equal_weights: 61 self.weights = np.ones(self.n_mu)/self.n_mu 62 else: 63 self.weights = np.array([np.log(self.n_mu + 1)-np.log(i+1) for i in range(self.n_mu)]) 64 self.weights = self.weights/np.sum(self.weights) 65 66 self.mu_eff = 1/np.sum(self.weights**2) 67 self.c_cov = 1/self.mu_eff * 2/(dim+2**0.5)**2 +\ 68 (1-1/self.mu_eff)*min(1, (2*self.mu_eff-1)/((dim+2)**2+self.mu_eff)) 69 70 if self.alpha_1 is None: 71 self.alpha_1 = self.c_cov/self.mu_eff 72 if self.alpha_mu is None: 73 self.alpha_mu = self.c_cov*(1-1/self.mu_eff) 74 if self.alpha_c is None: 75 self.alpha_c = 4/(dim+4)
This is a rather simple simple CMA class
Parameters
- ne (int): Ensemble size
- dim (int): Dimensions of control vector
- alpha_mu (float): Learning rate for rank-mu update. If None, value proposed in [1] is used.
- n_mu (int,
n_mu < ne
): Number of best samples of ne, to be used for rank-mu update. Default is int(ne/2). - alpha_1 (float): Learning rate fro rank-one update. If None, value proposed in [1] is used.
- alpha_c (float): Parameter (inverse if backwards time horizen)for evolution path update in the rank-one update. See [1] for more info. If None, value proposed in [1] is used.
- corr_update (bool): If True, CMA is used to update a correlation matrix. Default is False.
- equal_weights (bool):
If True, all n_mu members are assign equal weighting,
w_i = 1/n_mu
. If False, the weighting scheme proposed in [1], wherew_i = log(n_mu + 1)-log(i)
, and normalized such that they sum to one. Defualt is True.
References
[1] Hansen, N. (2006). The CMA evolution strategy: a comparing review. In J. Lozano, P. Larranaga, I. Inza & E. Bengoetxea (ed.), Towards a new evolutionary computation. Advances on estimation of distribution algorithms (pp. 75--102) . Springer .