def print_mutation_rate_and_strength(self): support.write_to_file( self.log_file, 'Current mean mutation rate: ' + support.float_representation(self.cur_mutation_rate, 5)) n_params = self.models[0].get_number_of_params() support.write_to_file( self.log_file, 'Current mean number of params to change: ' + str(max(1, int(n_params * self.cur_mutation_strength))))
def increase_models_complexity(): support.write_to_file(self.log_file, "\nIncrease models' complexities:") self.models = copy.deepcopy(self.models) index = None for model in self.models: index = model.increase_complexity(index) self.without_changes = 0 self.select(self.size_of_generation, print_iter=False) self.cur_mutation_rate = self.params.mutation_rate self.cur_mutation_strength = self.params.mutation_strength
def run_one_ga_and_one_ls(): while (not self.is_stoped() and self.run_before_ls): self.run_one_iteration() if shared_dict is not None: shared_dict[self.prefix] = (copy.deepcopy(self.models[0]), self.final_models) if not self.run_before_ls: self.run_before_ls = True if self.run_ls: best_model = copy.deepcopy(self.models[0]) support.write_to_file( self.log_file, '\nTry to improve best model (' + self.params.optimize_name + ')') try: # catch error of `Factor is exactly singular` if self.params.optimize_name != 'hill_climbing': if self.out_dir is not None: self.models[0].run_local_search( self.params.optimize_name, os.path.join( self.out_dir, self.params.optimize_name + '_' + str(self.cur_iteration) + '_out')) else: self.models[0].run_local_search( self.params.optimize_name, None) self.check_best_aic() else: self.run_hill_climbing_of_best() self.print_and_draw_best_model(suffix='_ls') except RuntimeError as e: if e.message == 'Factor is exactly singular': support.write_log( self.log_file, 'Local search failed of the following error: Factor is exactly singular.' ) self.models[0] = best_model if not self.run_ls: self.run_ls = True if shared_dict is not None: shared_dict[self.prefix] = (copy.deepcopy(self.models[0]), self.final_models) self.check_best_aic() self.check_claic() self.final_models.append(self.best_model()) self.pickle_final_models() support.print_final_model(self.log_file, self.models[0], self.params) self.cur_iteration += 1
def select(self, size, print_iter=True): """Selection in population of models. size : size of result population If size of current population is bigger than size, then we discard the worst. """ self.models = sorted( self.models, key=lambda x: x.get_fitness_func_value())[:size] if print_iter: support.write_to_file(self.log_file, '\n\nIteration #' + str(self.cur_iteration) + '.') support.print_set_of_models(self.log_file, list(enumerate(self.models)), self.params, first_col='N\t', heading='Current population of models:')
def run(self, shared_dict=None): """Main function to run genetic algorithm. shared_dict : dictionary to share information among processes. """ # checking dirs if self.prefix is not None: self.out_dir = os.path.join(self.params.output_dir, self.prefix) if not os.path.exists(self.out_dir): os.makedirs(self.out_dir) if not self.params.draw_iter == 0: support.ensure_dir_existence( os.path.join(self.out_dir, 'pictures')) if not self.params.code_iter == 0: support.ensure_dir_existence( os.path.join(self.out_dir, 'python_code')) support.ensure_dir_existence(os.path.join( self.out_dir, 'python_code', 'dadi')) support.ensure_dir_existence(os.path.join( self.out_dir, 'python_code', 'moments')) self.log_file = os.path.join(self.out_dir, 'GADMA_GA.log') open(self.log_file, 'a').close() else: self.log_file = None # help functions def run_one_ga_and_one_ls(): while (not self.is_stoped() and self.run_before_ls): self.run_one_iteration() if shared_dict is not None: shared_dict[self.prefix] = ( copy.deepcopy(self.models[0]), self.final_models) if not self.run_before_ls: self.run_before_ls = True if self.run_ls: best_model = copy.deepcopy(self.models[0]) support.write_to_file( self.log_file, '\nTry to improve best model (' + self.params.optimize_name + ')') try: # catch error of `Factor is exactly singular` if self.params.optimize_name != 'hill_climbing': if self.out_dir is not None: self.models[0].run_local_search(self.params.optimize_name, os.path.join( self.out_dir, self.params.optimize_name + '_' + str(self.cur_iteration) + '_out')) else: self.models[0].run_local_search(self.params.optimize_name, None) self.check_best_aic() else: self.run_hill_climbing_of_best() self.print_and_draw_best_model(suffix='_ls') except RuntimeError as e: if e.message == 'Factor is exactly singular': support.write_log(self.log_file, 'Local search failed of the following error: Factor is exactly singular.') self.models[0] = best_model if not self.run_ls: self.run_ls = True if shared_dict is not None: shared_dict[self.prefix] = ( copy.deepcopy(self.models[0]), self.final_models) self.check_best_aic() self.check_claic() self.final_models.append(self.best_model()) self.pickle_final_models() support.print_final_model(self.log_file, self.models[0], self.params) self.cur_iteration += 1 def increase_models_complexity(): support.write_to_file(self.log_file, "\nIncrease models' complexities:") self.models = copy.deepcopy(self.models) index = None for model in self.models: index = model.increase_complexity(index) self.without_changes = 0 self.select(self.size_of_generation, print_iter=False) self.cur_mutation_rate = self.params.mutation_rate self.cur_mutation_strength = self.params.mutation_strength # begin support.write_to_file(self.log_file, '--Start genetic algorithm pipeline--') # initialization of first population self.init_first_population_of_models() if shared_dict is not None: shared_dict[ self.prefix] = ( copy.deepcopy( self.models[0]), self.final_models) self.print_and_draw_best_model() self.cur_iteration += 1 # main part run_one_ga_and_one_ls() if not self.is_custom_model: while not (self.models[0].get_structure() == self.params.final_structure).all(): increase_models_complexity() run_one_ga_and_one_ls() for model in self.models: model.info = 'f' self.check_best_aic() if shared_dict is not None: shared_dict[self.prefix] = ( copy.deepcopy(self.models[0]), self.final_models) # final part if self.out_dir is not None: self.print_and_draw_best_model(final=True) return self.best_model()
def run_one_iteration(self): """Iteration step for genetic algorithm.""" start = time.time() # take self.number_of_old_models best models from previous population new_models = self.models[:self.number_of_old_models] # create probabilities to choose models for crossing and mutation p = [] for m in self.models: p.append(m.get_fitness_func_value()) p = np.array(p) p -= max(p) + 1 p = -p p /= sum(p) # add mutated models to our new population for i in xrange(self.number_of_mutated_models): model = self.get_mutated_model( mutation_strength=self.cur_mutation_strength, mutation_rate=self.cur_mutation_rate, p=p) new_models.append(model) # add crossed models to our new population for i in xrange(self.number_of_crossed_models): first_model_index = np.random.choice(xrange(len(self.models)), p=p) first_model = self.models[first_model_index] p[first_model_index] = 0 p /= sum(p) second_model = np.random.choice(self.models, p=p) new_models.append(first_model.cross_with_other(second_model)) # add random models to our new population for i in xrange(self.number_of_random_models): new_models.append( self.get_random_model( structure=self.models[0].get_structure())) # remember prev best value of fitness function prev_value_of_fit = self.models[0].get_fitness_func_value() # new population become current population self.models = new_models # sort population by fitness function self.select(self.params.size_of_generation) self.print_and_draw_best_model() # try to make better mutated and crossed models, random are so by # definition if self.without_changes == self.it_without_changes_to_stop_ga / 2 or self.is_stoped(): prev_value_of_fit = self.best_fitness_value() support.write_to_file( self.log_file, '\nTime to normalize models with optmal_sfs_scaling:') for model in new_models: if model.info != 'r': model.normalize_by_Nref() self.select(self.size_of_generation, print_iter=False) # update our adaptive mutation_rate and print it to log file self.update_mutation_rate_and_strength(prev_value_of_fit) self.print_mutation_rate_and_strength() self.check_best_aic() # check if we get stuck if abs( prev_value_of_fit - self.best_fitness_value()) < self.params.epsilon: self.without_changes += 1 else: self.without_changes = 0 self.cur_iteration += 1 # print results to log file support.print_best_logll_model_long(self.log_file, self.best_model(), self.params) stop = time.time() self.work_time += stop - start support.write_to_file(self.log_file, '\nMean time: ', self.mean_time())