diff --git a/examples/synthetic_graph_evolution/simple_run.py b/examples/synthetic_graph_evolution/simple_run.py index fdce35f6..85dad723 100644 --- a/examples/synthetic_graph_evolution/simple_run.py +++ b/examples/synthetic_graph_evolution/simple_run.py @@ -30,7 +30,7 @@ def run_graph_search(size=16, timeout=8, visualize=True): requirements = GraphRequirements( early_stopping_iterations=100, timeout=timedelta(minutes=timeout), - n_jobs=-1, + n_jobs=1, ) gp_params = GPAlgorithmParameters( genetic_scheme_type=GeneticSchemeTypesEnum.parameter_free, diff --git a/golem/core/constants.py b/golem/core/constants.py index 4104ead3..d0aaa01d 100644 --- a/golem/core/constants.py +++ b/golem/core/constants.py @@ -4,6 +4,6 @@ MAX_TUNING_METRIC_VALUE = np.inf MIN_TIME_FOR_TUNING_IN_SEC = 3 # Max number of evaluations attempts to collect the next pop; See usages. -EVALUATION_ATTEMPTS_NUMBER = 5 +EVALUATION_ATTEMPTS_NUMBER = 10 # Min pop size to avoid getting stuck in local maximum during optimization. MIN_POP_SIZE = 5 diff --git a/golem/core/optimisers/adaptive/operator_agent.py b/golem/core/optimisers/adaptive/operator_agent.py index 10e0175e..93658d55 100644 --- a/golem/core/optimisers/adaptive/operator_agent.py +++ b/golem/core/optimisers/adaptive/operator_agent.py @@ -102,8 +102,12 @@ def _dbg_log(self, obs, actions, rewards): msg += (f'avg={nonzero.mean()} std={nonzero.std()} ' f'min={nonzero.min()} max={nonzero.max()} ') + def get_name(obj): + return getattr(obj, '__name__', str(obj)) + self._log.info(msg) - self._log.info(f'actions/rewards: {list(zip(actions, rr))}') + action_strs = map(get_name, actions) + self._log.info(f'actions/rewards: {list(zip(action_strs, rr))}') action_values = list(map(self.get_action_values, obs)) action_probs = list(map(self.get_action_probs, obs)) diff --git a/golem/core/optimisers/genetic/evaluation.py b/golem/core/optimisers/genetic/evaluation.py index 3df1a916..a0736c5e 100644 --- a/golem/core/optimisers/genetic/evaluation.py +++ b/golem/core/optimisers/genetic/evaluation.py @@ -146,8 +146,8 @@ def population_evaluation_info(self, pop_size: int, evaluated_pop_size: int): if pop_size == 0 or evaluated_pop_size / pop_size <= STAGNATION_EVALUATION_PERCENTAGE: success_rate = evaluated_pop_size / pop_size if pop_size != 0 else 0 self.logger.warning(f"{evaluated_pop_size} individuals out of {pop_size} in previous population " - f"were evaluated successfully. {success_rate}% " - f"is a fairly small percentage of successful evaluation.") + f"were evaluated successfully. {success_rate} " + f"is a fairly small fraction of successful evaluation.") else: self.logger.message(f"{evaluated_pop_size} individuals out of {pop_size} in previous population " f"were evaluated successfully.") diff --git a/golem/core/optimisers/genetic/operators/reproduction.py b/golem/core/optimisers/genetic/operators/reproduction.py index 60de62f3..16e95fa7 100644 --- a/golem/core/optimisers/genetic/operators/reproduction.py +++ b/golem/core/optimisers/genetic/operators/reproduction.py @@ -83,6 +83,9 @@ def reproduce_uncontrolled(self, new_population = self.crossover(selected_individuals) new_population = ensure_wrapped_in_sequence(self.mutation(new_population)) new_population = evaluator(new_population) + # Guard against None errors + if new_population is None: + new_population = [] return new_population def reproduce(self, diff --git a/golem/core/optimisers/populational_optimizer.py b/golem/core/optimisers/populational_optimizer.py index 478f2a03..5e27c453 100644 --- a/golem/core/optimisers/populational_optimizer.py +++ b/golem/core/optimisers/populational_optimizer.py @@ -46,8 +46,7 @@ def __init__(self, self.generations = GenerationKeeper(self.objective, keep_n_best=requirements.keep_n_best) self.timer = OptimisationTimer(timeout=self.requirements.timeout) - dispatcher_type = MultiprocessingDispatcher if self.requirements.parallelization_mode == 'populational' else \ - SequentialDispatcher + dispatcher_type = MultiprocessingDispatcher if self.requirements.n_jobs != 1 else SequentialDispatcher self.eval_dispatcher = dispatcher_type(adapter=graph_generation_params.adapter, n_jobs=requirements.n_jobs, diff --git a/test/unit/optimizers/gp_operators/test_reproduction_controller.py b/test/unit/optimizers/gp_operators/test_reproduction_controller.py index e1034f45..a7fd660c 100644 --- a/test/unit/optimizers/gp_operators/test_reproduction_controller.py +++ b/test/unit/optimizers/gp_operators/test_reproduction_controller.py @@ -83,7 +83,7 @@ def test_mean_success_rate(reproducer: ReproductionController, success_rate: flo assert np.isclose(reproducer.mean_success_rate, success_rate, rtol=0.1) -@pytest.mark.parametrize('success_rate', [0.0, 0.1]) +@pytest.mark.parametrize('success_rate', [0.0, 0.04]) def test_too_little_valid_evals(reproducer: ReproductionController, success_rate: float): evaluator = MockEvaluator(success_rate) pop = get_rand_population(reproducer.parameters.pop_size) @@ -92,7 +92,7 @@ def test_too_little_valid_evals(reproducer: ReproductionController, success_rate reproducer.reproduce(pop, evaluator) -@pytest.mark.parametrize('success_rate', [0.2]) +@pytest.mark.parametrize('success_rate', [0.15]) def test_minimal_valid_evals(reproducer: ReproductionController, success_rate: float): parameters = reproducer.parameters evaluator = MockEvaluator(success_rate)