From b8e2ce0c59a3649e33b5ca133cb5273cdac55e67 Mon Sep 17 00:00:00 2001 From: Rishabh Gupta Date: Mon, 19 Jun 2017 00:29:08 -0400 Subject: [PATCH 1/8] lexicase_survival changes --- few/few.py | 8 ++++++-- few/lib/epsilon_lexicase.h | 19 +++++++++++++++---- few/lib/few_lib.pyx | 7 ++++--- few/selection.py | 16 ++++++++++++---- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/few/few.py b/few/few.py index 75f73ee..f1fe05a 100644 --- a/few/few.py +++ b/few/few.py @@ -57,7 +57,7 @@ def __init__(self, population_size=50, generations=100, random_state=np.random.randint(9999999), verbosity=0, scoring_function=None, disable_update_check=False, elitism=True, boolean = False,classification=False,clean=False, - track_diversity=False,mdr=False,otype='f',c=True, weight_parents=False): + track_diversity=False,mdr=False,otype='f',c=True, weight_parents=False, lex_size=False): # sets up GP. # Save params to be recalled later by get_params() @@ -92,6 +92,7 @@ def __init__(self, population_size=50, generations=100, self.op_weight = op_weight self.max_stall = max_stall self.weight_parents = weight_parents + self.lex_size = lex_size self.seed_with_ml = seed_with_ml self.erc = erc self.random_state = random_state @@ -824,6 +825,9 @@ def main(): parser.add_argument('--weight_parents', action='store_true',dest='WEIGHT_PARENTS',default=False, help='Feature importance determines parent pressure for selection.') + parser.add_argument('--lex_size', action='store_true',dest='LEX_SIZE',default=False, + help='Size mediated parent selection for lexicase survival.') + parser.add_argument('-sel', action='store', dest='SEL', default='epsilon_lexicase', choices = ['tournament','lexicase','epsilon_lexicase', @@ -951,7 +955,7 @@ def main(): fit_choice = args.FIT_CHOICE,boolean=args.BOOLEAN, classification=args.CLASSIFICATION,clean = args.CLEAN, track_diversity=args.TRACK_DIVERSITY,mdr=args.MDR, - otype=args.OTYPE,c=args.c, weight_parents = args.WEIGHT_PARENTS) + otype=args.OTYPE,c=args.c, weight_parents = args.WEIGHT_PARENTS, lex_size = args.LEX_SIZE) learner.fit(training_features, training_labels) # pdb.set_trace() diff --git a/few/lib/epsilon_lexicase.h b/few/lib/epsilon_lexicase.h index e9e7b97..2d2dcc0 100644 --- a/few/lib/epsilon_lexicase.h +++ b/few/lib/epsilon_lexicase.h @@ -81,7 +81,7 @@ static random_device rd; static mt19937 gen(rd()); //extern "C" void epsilon_lexicase(const ExtMat & F, int n, int d, - int num_selections, ExtVec& locs) + int num_selections, ExtVec& locs, bool lex_size, ExtVec& sizes) { // training cases // ExtMat T (F, n, d); @@ -96,10 +96,21 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, for (int i = 0; i ind_locs; + if(lex_size){ + //randomly select a size from sizes + int max_index = sizes.size(); + int random_index = rand() % max_index; - // individual locations - vector ind_locs(n); + // individual locations + ind_locs.reserve(sizes[random_index]); + } + else{ + // individual locations + ind_locs.reserve(sizes[n]); + } + iota(ind_locs.begin(),ind_locs.end(),0); // temporary winner pool @@ -121,7 +132,7 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, winner.resize(0); // minimum error on case double minfit; - for (int j = 0; j< can_locs.size(); ++j){ + for (int j = 0; j Date: Fri, 21 Jul 2017 18:26:08 -0400 Subject: [PATCH 2/8] some errors removed --- few/lib/epsilon_lexicase.h | 40 +++++++++++++++++++++++++++++++++----- few/lib/few_lib.pyx | 2 +- few/selection.py | 9 +++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/few/lib/epsilon_lexicase.h b/few/lib/epsilon_lexicase.h index 2d2dcc0..e54e6b3 100644 --- a/few/lib/epsilon_lexicase.h +++ b/few/lib/epsilon_lexicase.h @@ -96,22 +96,52 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, for (int i = 0; i ind_locs; - if(lex_size){ + /*vector ind_locs; + if(lex_size){ //randomly select a size from sizes int max_index = sizes.size(); int random_index = rand() % max_index; // individual locations - ind_locs.reserve(sizes[random_index]); + vector ind_locs_temp(sizes[random_index]); + ind_locs = ind_locs_temp; + //ind_locs.reserve(sizes[random_index]); + } + else{ + // individual locations + vector ind_locs_temp(n); + ind_locs = ind_locs_temp; + //ind_locs.reserve(n); + }*/ + + vector ind_locs; + if(lex_size){ + char message[200]; + PyOS_snprintf(message, sizeof(message),"lex_size"); + //randomly select a size from sizes + int max_index = sizes.size(); + int random_index = rand() % max_index; + vector ind_locs_temp(n); + + // individual locations + int j=0; + for(int i=0;i winner; diff --git a/few/lib/few_lib.pyx b/few/lib/few_lib.pyx index e246812..ddf99b0 100644 --- a/few/lib/few_lib.pyx +++ b/few/lib/few_lib.pyx @@ -10,7 +10,7 @@ cdef extern from "epsilon_lexicase.h": Map[ArrayXi] & locs, bool lex_size, Map[ArrayXi] &sizes) # This will be exposed to Python -def ep_lex(np.ndarray F, int n, int d, int num_selections, np.ndarray locs, np.bool lex_size, np.ndarray sizes): +def ep_lex(np.ndarray F, int n, int d, int num_selections, np.ndarray locs, bool lex_size, np.ndarray sizes): return _epsilon_lexicase(Map[ArrayXXd](F), n, d, num_selections, Map[ArrayXi](locs), lex_size, Map[ArrayXi](sizes)) # WIP diff --git a/few/selection.py b/few/selection.py index 804ab51..79f6509 100644 --- a/few/selection.py +++ b/few/selection.py @@ -26,11 +26,16 @@ def survival(self,parents,offspring,elite=None,elite_index=None,X=None,F=None,F_ elif self.sel == 'epsilon_lexicase': # survivors, survivor_index = self.epsilon_lexicase(parents + offspring, num_selections = len(parents), survival = True) if self.lex_size: + print(parents + offspring) sizes = [len(i.stack) for i in (parents + offspring)] + print(sizes) + print("--") survivor_index = self.epsilon_lexicase(np.vstack((F,F_offspring)), sizes, num_selections = F.shape[0], survival = True) + print(survivor_index) survivors = [(parents+ offspring)[s] for s in survivor_index] else: survivor_index = self.epsilon_lexicase(np.vstack((F,F_offspring)), [], num_selections = F.shape[0], survival = True) + print(survivor_index) survivors = [(parents+ offspring)[s] for s in survivor_index] elif self.sel == 'deterministic_crowding': survivors, survivor_index = self.deterministic_crowding(parents,offspring,X,X_offspring) @@ -121,9 +126,9 @@ def epsilon_lexicase(self, F, sizes, num_selections=None, survival = False): locs = np.empty(num_selections,dtype='int32',order='F') # self.lib.epsilon_lexicase(F,F.shape[0],F.shape[1],num_selections,locs) if self.lex_size: - ep_lex(F,F.shape[0],F.shape[1],num_selections,locs,self.lex_size,sizes) + ep_lex(F,F.shape[0],F.shape[1],num_selections,locs,self.lex_size,np.array(sizes)) else: - ep_lex(F,F.shape[0],F.shape[1],num_selections,locs,self.lex_size,[]) + ep_lex(F,F.shape[0],F.shape[1],num_selections,locs,self.lex_size,np.array([])) return locs else: # use python version if num_selections is None: From f6af3aedb7df7e3f8239caee02a573025f3d2ede Mon Sep 17 00:00:00 2001 From: Rishabh Gupta Date: Mon, 31 Jul 2017 18:16:04 -0400 Subject: [PATCH 3/8] seg fault fixed --- few/lib/epsilon_lexicase.h | 36 ++++-------------------------------- few/selection.py | 5 ----- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/few/lib/epsilon_lexicase.h b/few/lib/epsilon_lexicase.h index e54e6b3..6c8d0a3 100644 --- a/few/lib/epsilon_lexicase.h +++ b/few/lib/epsilon_lexicase.h @@ -96,56 +96,28 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, for (int i = 0; i ind_locs; - if(lex_size){ - //randomly select a size from sizes - int max_index = sizes.size(); - int random_index = rand() % max_index; - - - // individual locations - vector ind_locs_temp(sizes[random_index]); - ind_locs = ind_locs_temp; - //ind_locs.reserve(sizes[random_index]); - } - else{ - // individual locations - vector ind_locs_temp(n); - ind_locs = ind_locs_temp; - //ind_locs.reserve(n); - }*/ - - vector ind_locs; - if(lex_size){ +vector ind_locs(n); +if(lex_size){ char message[200]; - PyOS_snprintf(message, sizeof(message),"lex_size"); //randomly select a size from sizes int max_index = sizes.size(); int random_index = rand() % max_index; - vector ind_locs_temp(n); // individual locations int j=0; for(int i=0;i winner; - for (int i = 0; i Date: Tue, 1 Aug 2017 13:03:49 -0400 Subject: [PATCH 4/8] removed extra line - message array --- few/lib/epsilon_lexicase.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/few/lib/epsilon_lexicase.h b/few/lib/epsilon_lexicase.h index 6c8d0a3..ff0510b 100644 --- a/few/lib/epsilon_lexicase.h +++ b/few/lib/epsilon_lexicase.h @@ -96,9 +96,8 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, for (int i = 0; i ind_locs(n); -if(lex_size){ - char message[200]; + vector ind_locs(n); + if(lex_size){ //randomly select a size from sizes int max_index = sizes.size(); int random_index = rand() % max_index; From 439bf0596ee0caeb519f16d5876ae6e74ac86e9a Mon Sep 17 00:00:00 2001 From: Rishabh Gupta Date: Tue, 1 Aug 2017 13:49:03 -0400 Subject: [PATCH 5/8] ind_locs resize --- few/lib/epsilon_lexicase.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/few/lib/epsilon_lexicase.h b/few/lib/epsilon_lexicase.h index ff0510b..2583571 100644 --- a/few/lib/epsilon_lexicase.h +++ b/few/lib/epsilon_lexicase.h @@ -96,7 +96,7 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, for (int i = 0; i ind_locs(n); + vector ind_locs; if(lex_size){ //randomly select a size from sizes int max_index = sizes.size(); @@ -112,6 +112,7 @@ void epsilon_lexicase(const ExtMat & F, int n, int d, } else{ // individual locations + ind_locs.resize(n); iota(ind_locs.begin(),ind_locs.end(),0); } From be1b7e95993ac51f8c550331f6437cd21e736a07 Mon Sep 17 00:00:00 2001 From: lacava Date: Wed, 2 Aug 2017 15:37:57 -0400 Subject: [PATCH 6/8] shortens line widths, updates version --- few/_version.py | 2 +- few/lib/few_lib.pyx | 17 ++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/few/_version.py b/few/_version.py index 123755b..c65dc2f 100644 --- a/few/_version.py +++ b/few/_version.py @@ -6,4 +6,4 @@ """ -__version__ = '0.0.44' +__version__ = '0.0.45' diff --git a/few/lib/few_lib.pyx b/few/lib/few_lib.pyx index 2e754d1..2ab4dab 100644 --- a/few/lib/few_lib.pyx +++ b/few/lib/few_lib.pyx @@ -7,20 +7,11 @@ from libcpp cimport bool cdef extern from "epsilon_lexicase.h": cdef void _epsilon_lexicase "epsilon_lexicase"(Map[ArrayXXd] & F, int n, int d, int num_selections, - Map[ArrayXi] & locs, bool lex_size, Map[ArrayXi] &sizes) + Map[ArrayXi] & locs, bool lex_size, + Map[ArrayXi] &sizes) # This will be exposed to Python -def ep_lex(np.ndarray F, int n, int d, int num_selections, np.ndarray locs, bool lex_size, np.ndarray sizes): +def ep_lex(np.ndarray F, int n, int d, int num_selections, np.ndarray locs, bool lex_size, + np.ndarray sizes): return _epsilon_lexicase(Map[ArrayXXd](F), n, d, num_selections, Map[ArrayXi](locs), lex_size, Map[ArrayXi](sizes)) -# WIP -# cdef extern from "evaluation.h": -# cdef void _evaluate "evaluate"(node n, Map[ArrayXXd] & features, -# vector[Map[ArrayXd]]] stack_float, -# vector[Map[ArrayXb]] stack_bool) - -# def evaluate(node n, np.ndarray features, vector[np.ndarray] stack_float, -# vector[np.ndarray] stack_bool): -# return _evaluate(node n, Map[ArrayXXd](features), -# vector[Map[ArrayXd]]](stack_float), -# vector[Map[ArrayXb]](stack_bool)) From c647f168b2456bceb9ba3fa33b1938b32bb0af41 Mon Sep 17 00:00:00 2001 From: lacava Date: Wed, 2 Aug 2017 16:10:57 -0400 Subject: [PATCH 7/8] adds test for lex_size flag --- few/tests/test_selection.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/few/tests/test_selection.py b/few/tests/test_selection.py index cf1e143..928be61 100644 --- a/few/tests/test_selection.py +++ b/few/tests/test_selection.py @@ -103,3 +103,24 @@ def test_lexicase_survival_shapes(): i.fitness_vec = np.random.rand(10,1) offspring,locs = few.lexicase(pop.individuals,num_selections=1,survival=True) assert len(offspring) == 1; + +def test_lex_size(): + """test_selection.py: lex_size flag on/off""" + + few = FEW(seed_with_ml=False,population_size=257, lex_size=True) + + Fitness_mat = np.random.rand(257,10) + size_mat = np.random.rand(257,1) + + locs = few.epsilon_lexicase(Fitness_mat,size_mat,num_selections=100, + survival=True) + assert len(locs) == 100 + + few = FEW(seed_with_ml=False,population_size=257, lex_size=False) + + Fitness_mat = np.random.rand(257,10) + size_mat = np.random.rand(257,1) + + locs = few.epsilon_lexicase(Fitness_mat,size_mat,num_selections=100, + survival=True) + assert len(locs) == 100 From 7df082a9c34e5cb89639d300b5011a4306fc72e8 Mon Sep 17 00:00:00 2001 From: lacava Date: Wed, 2 Aug 2017 17:09:09 -0400 Subject: [PATCH 8/8] updates eplex test to set sizes to ints --- few/tests/test_selection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/few/tests/test_selection.py b/few/tests/test_selection.py index 928be61..f40a857 100644 --- a/few/tests/test_selection.py +++ b/few/tests/test_selection.py @@ -110,7 +110,7 @@ def test_lex_size(): few = FEW(seed_with_ml=False,population_size=257, lex_size=True) Fitness_mat = np.random.rand(257,10) - size_mat = np.random.rand(257,1) + size_mat = np.random.randint(1,100,size=257) locs = few.epsilon_lexicase(Fitness_mat,size_mat,num_selections=100, survival=True)