Changeset 1182
- Timestamp:
- 08/31/22 00:05:43 (2 years ago)
- Location:
- framspy
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
framspy/evolalg/dissimilarity/dissimilarity.py
r1145 r1182 11 11 12 12 self.output_field = output_field 13 self.fn_reduce = None13 self.fn_reduce = Dissimilarity.get_reduction_by_name(reduction) 14 14 self.knn = knn 15 if reduction == "mean": # TODO change this 'elif' sequence to dictionary? 16 self.fn_reduce = np.mean 17 elif reduction == "max": 18 self.fn_reduce = np.max 19 elif reduction == "min": 20 self.fn_reduce = np.min 21 elif reduction == "sum": 22 self.fn_reduce = np.sum 23 elif reduction == "knn_mean": 24 self.fn_reduce = self.knn_mean 25 elif reduction == "none" or reduction is None: 26 self.fn_reduce = None 15 16 17 @staticmethod 18 def reduce(dissim_matrix, fn_reduce, knn): 19 if fn_reduce is None: 20 return dissim_matrix 21 elif fn_reduce is Dissimilarity.knn_mean: 22 return fn_reduce(dissim_matrix, 1, knn) 27 23 else: 28 r aise ValueError("Unknown reduction type. Supported: mean, max, min, sum, knn_mean, none")24 return fn_reduce(dissim_matrix, axis=1) 29 25 30 def reduce(self, dissim_matrix):31 if self.fn_reduce is None:32 return dissim_matrix33 return self.fn_reduce(dissim_matrix, axis=1)34 26 35 def knn_mean(self, dissim_matrix,axis): 36 return np.mean(np.partition(dissim_matrix, self.knn)[:,:self.knn],axis=axis) 27 @staticmethod 28 def knn_mean(dissim_matrix, axis, knn): 29 return np.mean(np.partition(dissim_matrix, knn)[:, :knn], axis=axis) 30 31 32 @staticmethod 33 def get_reduction_by_name(reduction: str): 34 35 if reduction not in REDUCTION_FUNCTION: 36 raise ValueError(f"Unknown reduction type '{reduction}'. Supported: {','.join(REDUCTION_FUNCTION.keys())}") 37 38 return REDUCTION_FUNCTION[reduction] 39 40 41 42 REDUCTION_FUNCTION = { 43 "mean": np.mean, 44 "max": np.max, 45 "min": np.min, 46 "sum": np.sum, 47 "knn_mean": Dissimilarity.knn_mean, 48 "none": None 49 } -
framspy/evolalg/dissimilarity/frams_dissimilarity.py
r1145 r1182 6 6 from evolalg.dissimilarity.dissimilarity import Dissimilarity 7 7 8 #TODO eliminate overlap with dissimilarity.py9 10 8 11 9 class FramsDissimilarity(FramsStep): 12 10 13 def __init__(self, frams_lib, reduction="mean", output_field="dissim", 11 def __init__(self, frams_lib, reduction="mean", output_field="dissim",knn=None, *args, **kwargs): 14 12 super(FramsDissimilarity, self).__init__(frams_lib, *args, **kwargs) 15 13 16 14 self.output_field = output_field 17 self.fn_reduce = None15 self.fn_reduce = Dissimilarity.get_reduction_by_name(reduction) 18 16 self.knn = knn 19 if reduction == "mean":20 self.fn_reduce = np.mean21 elif reduction == "max":22 self.fn_reduce = np.max23 elif reduction == "min":24 self.fn_reduce = np.min25 elif reduction == "sum":26 self.fn_reduce = np.sum27 elif reduction == "knn_mean":28 self.fn_reduce = self.knn_mean29 elif reduction == "none" or reduction is None:30 self.fn_reduce = None31 else:32 raise ValueError("Unknown reduction type. Supported: mean, max, min, sum, knn_mean, none")33 17 34 def reduce(self, dissim_matrix):35 if self.fn_reduce is None:36 return dissim_matrix37 return self.fn_reduce(dissim_matrix, axis=1)38 18 39 19 def call(self, population): … … 41 21 if len(population) == 0: 42 22 return [] 43 dissim_matrix = self.frams.dissimilarity([_.genotype for _ in population] )44 dissim = self.reduce(dissim_matrix)23 dissim_matrix = self.frams.dissimilarity([_.genotype for _ in population], 1) 24 dissim = Dissimilarity.reduce(dissim_matrix, self.fn_reduce, self.knn) 45 25 for d,ind in zip(dissim, population): 46 26 setattr(ind, self.output_field, d) 47 27 return population 48 49 def knn_mean(self, dissim_matrix,axis):50 return np.mean(np.partition(dissim_matrix, self.knn)[:,:self.knn],axis=axis) -
framspy/evolalg/dissimilarity/levenshtein.py
r1139 r1182 18 18 gen_dis.append(lev.distance(p.genotype, p2.genotype)) 19 19 dissim.append(gen_dis) 20 dissim = self.reduce(dissim )20 dissim = self.reduce(dissim, self.fn_reduce, self.knn) 21 21 for d, ind in zip(dissim, population): 22 22 setattr(ind, self.output_field, d) -
framspy/evolalg/examples/niching_novelty.py
r1149 r1182 11 11 from evolalg.base.lambda_step import LambdaStep 12 12 from evolalg.base.step import Step 13 from evolalg.dissimilarity.archive import ArchiveDissimilarity 13 14 from evolalg.dissimilarity.frams_dissimilarity import FramsDissimilarity 14 15 from evolalg.dissimilarity.levenshtein import LevenshteinDissimilarity … … 56 57 description='Run this program with "python -u %s" if you want to disable buffering of its output.' % sys.argv[ 57 58 0]) 58 parser.add_argument('-path', type=ensureDir, required=True, help='Path to the Framsticks library without trailing slash.') 59 parser.add_argument('-path', type=ensureDir, required=True, 60 help='Path to the Framsticks library without trailing slash.') 59 61 parser.add_argument('-opt', required=True, 60 62 help='optimization criteria: vertpos, velocity, distance, vertvel, lifespan, numjoints, numparts, numneurons, numconnections (or other as long as it is provided by the .sim file and its .expdef). For multiple criteria optimization, see multicriteria.py.') … … 63 65 parser.add_argument('-genformat', required=False, default="1", 64 66 help='Genetic format for the demo run, for example 4, 9, or B. If not given, f1 is assumed.') 65 parser.add_argument('-sim', required=False, default="eval-allcriteria.sim", help="Name of the .sim file with all parameter values. If you want to provide more files, separate them with a semicolon ';'.") 67 parser.add_argument('-sim', required=False, default="eval-allcriteria.sim", 68 help="Name of the .sim file with all parameter values. If you want to provide more files, separate them with a semicolon ';'.") 66 69 parser.add_argument('-fit', required=False, default=Fitness.raw, type=Fitness, 67 70 help=' Fitness criteria, default: raw', choices=list(Fitness)) 68 71 parser.add_argument('-dissim', required=False, type=Dissim, default=Dissim.frams, 69 72 help='Dissimilarity measure, default: frams', choices=list(Dissim)) 70 parser.add_argument('-knn', type=int, help="'k' value for knn-based fitness criteria (knn-niching and knn-novelty).") 73 parser.add_argument('-knn', type=int, 74 help="'k' value for knn-based fitness criteria (knn-niching and knn-novelty).") 71 75 parser.add_argument('-popsize', type=int, default=50, help="Population size, default: 50.") 72 76 parser.add_argument('-generations', type=int, default=5, help="Number of generations, default: 5.") … … 77 81 parser.add_argument('-max_numneurons', type=int, default=None, help="Maximum number of Neurons. Default: no limit") 78 82 parser.add_argument('-max_numconnections', type=int, default=None, help="Maximum number of Neural connections. Default: no limit") 79 83 parser.add_argument('-max_numgenochars', type=int, default=10000, help="Maximum number of characters in genotype, to disable this option set it to -1. Default: 10 000") 80 84 parser.add_argument('-hof_size', type=int, default=10, help="Number of genotypes in Hall of Fame. Default: 10.") 81 parser.add_argument('-hof_evaluations', type=int, default=20, help="Number of final evaluations of each genotype in Hall of Fame to obtain reliable (averaged) fitness. Default: 20.") 85 parser.add_argument('-hof_evaluations', type=int, default=20, 86 help="Number of final evaluations of each genotype in Hall of Fame to obtain reliable (averaged) fitness. Default: 20.") 82 87 parser.add_argument('-checkpoint_path', required=False, default=None, help="Path to the checkpoint file") 83 88 parser.add_argument('-checkpoint_interval', required=False, type=int, default=100, help="Checkpoint interval") 84 89 parser.add_argument('-debug', dest='debug', action='store_true', help="Prints names of steps as they are executed") 90 parser.add_argument('-archive_size', type=int, default=0, help="Size of the archive size for dissimilarity calculation") 85 91 parser.set_defaults(debug=False) 86 92 return parser.parse_args() … … 131 137 return individual.numconnections > self.max_number 132 138 139 class NumCharsHigher(Remove): 140 def __init__(self, max_number): 141 super(NumCharsHigher, self).__init__() 142 self.max_number = max_number 143 144 def remove(self, individual): 145 return len(individual.genotype) > self.max_number 133 146 134 147 class ReplaceWithHallOfFame(Step): … … 136 149 super(ReplaceWithHallOfFame, self).__init__(*args, **kwargs) 137 150 self.hof = hof 151 138 152 def call(self, population, *args, **kwargs): 139 153 super(ReplaceWithHallOfFame, self).call(population) … … 166 180 parsed_args = parseArguments() 167 181 frams_lib = FramsticksLib(parsed_args.path, parsed_args.lib, 168 parsed_args.sim.split(";"))182 parsed_args.sim.split(";")) 169 183 # Steps for generating first population 170 184 init_stages = [ … … 187 201 188 202 fitness_raw = FitnessStep(frams_lib, fields={parsed_args.opt: "fitness_raw", 189 "numparts": "numparts",190 "numjoints": "numjoints",191 "numneurons": "numneurons",192 "numconnections": "numconnections"},203 "numparts": "numparts", 204 "numjoints": "numjoints", 205 "numneurons": "numneurons", 206 "numconnections": "numconnections"}, 193 207 fields_defaults={parsed_args.opt: None, "numparts": float("inf"), 194 208 "numjoints": float("inf"), "numneurons": float("inf"), 195 209 "numconnections": float("inf")}, 196 210 evaluation_count=1) 197 198 211 199 212 fitness_end = FitnessStep(frams_lib, fields={parsed_args.opt: "fitness_raw"}, … … 213 226 if parsed_args.max_numconnections is not None: 214 227 remove.append(NumConnectionsHigher(parsed_args.max_numconnections)) 228 if parsed_args.max_numgenochars is not -1: 229 remove.append(NumCharsHigher(parsed_args.max_numgenochars)) 215 230 216 231 remove_step = UnionStep(remove) … … 245 260 generation_modifications.append(raw) 246 261 247 if parsed_args.fit == Fitness.niching: # TODO reduce redundancy in the four cases below: dictionary? 262 if parsed_args.fit == Fitness.niching: # TODO reduce redundancy in the four cases below: dictionary? 263 248 264 niching = UnionStep([ 249 dissim,265 ArchiveDissimilarity(parsed_args.archive_size, dissim), 250 266 LambdaStep(func_niching) 251 267 ]) … … 255 271 if parsed_args.fit == Fitness.novelty: 256 272 novelty = UnionStep([ 257 dissim,273 ArchiveDissimilarity(parsed_args.archive_size, dissim), 258 274 LambdaStep(func_novelty) 259 275 ]) 260 276 init_stages.append(novelty) 261 277 generation_modifications.append(novelty) 262 278 263 279 if parsed_args.fit == Fitness.knn_niching: 264 280 knn_niching = UnionStep([ 265 dissim,281 ArchiveDissimilarity(parsed_args.archive_size, dissim), 266 282 LambdaStep(func_knn_niching) 267 283 ]) 268 284 init_stages.append(knn_niching) 269 285 generation_modifications.append(knn_niching) 270 286 271 287 if parsed_args.fit == Fitness.knn_novelty: 272 288 knn_novelty = UnionStep([ 273 dissim,289 ArchiveDissimilarity(parsed_args.archive_size, dissim), 274 290 LambdaStep(func_knn_novelty) 275 291 ]) … … 302 318 fitness_end, 303 319 PopulationSave("halloffame.gen", provider=hall_of_fame.halloffame, fields={"genotype": "genotype", 304 "fitness": "fitness_raw"})]320 "fitness": "fitness_raw"})] 305 321 # ...but custom fields can be added, e.g. "custom": "recording" 306 322 307 323 # ------------------------------------------------- 308 324 309 310 311 325 # Experiment creation 312 313 326 314 327 experiment = Experiment(init_population=init_stages, … … 354 367 355 368 356 357 369 if __name__ == '__main__': 358 359 370 main() -
framspy/run-evolalg-examples.cmd
r1158 r1182 16 16 17 17 18 rem simple one-criterion evolution but more options available in examples.niching_novelty, here: hard limit on the number of parts and debugging messages18 rem simple one-criterion evolution but more options available in examples.niching_novelty, here: hard limit on the number of Parts and debugging messages 19 19 python -m evolalg.examples.niching_novelty -path %DIR_WITH_FRAMS_LIBRARY% -opt velocity -max_numparts 6 -debug 20 20
Note: See TracChangeset
for help on using the changeset viewer.