Open wassimj opened 3 months ago
Thanks, @wassimj. This is a bug. This warning should only be printed if you used the delay_after_gen
parameter.
It will be fixed soon.
Hi all,
I've encountered this as well. What's interesting is that if I re-run the code, the warning disapears and the overall performance of the genetic algorithm improves. For example, the first time the warning comes out, the final result is correct, but the fitness history shows that fitness values varied quite strongly - sometimes fitness wasn't even a non-decreasing function, in spite of a non-zero value in the keep_parents
parameter (keeping the so-called 'elite'). Since I haven't been able to reproduce it yet, that's probably for another time.
Back to the delay_after_gen
issue; this is a simple code for a packaging problem - a thief has to choose what to steal with a limited maximum weight he can carry. Items at the house have different values and weights. The goal is to choose the most expensive things without surpassing the weight limit. The code is as follows:
import pygad
import matplotlib.pyplot as plt
house = {
1: ['clock', 100, 7],
2: ['landscape painting', 300, 7],
3: ['portrait painting', 200, 6],
4: ['radio', 40, 2],
5: ['laptop', 500, 5],
6: ['night lamp', 70, 6],
7: ['silver cutlery', 100, 1],
8: ['porcelain', 250, 3],
9: ['bronze figurine', 300, 10],
10: ['leather handbag', 280, 3],
11: ['vacuum cleaner', 300, 15]
}
def fitness_function(genetic_algorithm_instance, solution, solution_index):
weight = 0
fitness = 0
for i in range(len(solution)):
if solution[i] == 1:
fitness += domek[i+1][1]
weight += domek[i+1][2]
if weight > 25:
fitness += -2000
return fitness
ga_instance = pygad.GA(
gene_space=[0, 1],
num_generations=100,
num_parents_mating=15,
fitness_func=fitness_function,
sol_per_pop=40,
num_genes=11,
parent_selection_type="tournament",
keep_parents=5,
crossover_type="single_point",
mutation_type="random",
mutation_probability=0.02
)
# At this point a UserWarning appears
ga_instance.run()
solution, solution_fitness, solution_idx = ga_instance.best_solution()
print("Parameters of the best solution : {solution}".format(solution=solution))
print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness))
prediction = []
money= 0
weight = 0
for i in range(len(solution)):
if solution[i] == 1:
prediction.append(domek[i+1][0])
money += house[i+1][1]
weight += house[i+1][2]
print("Predicted output based on the best solution : {prediction}".format(prediction=prediction))
print(money)
print(weight)
# Ensure any previous plots are cleared
plt.clf()
# Plot the fitness values vs. generations with proper labels (ga_instance.plot_fitness() gives two plots)
plt.plot(ga_instance.best_solutions_fitness, label='Best Fitness')
plt.xlabel("Generation")
plt.ylabel("Fitness")
plt.title("Fitness over Generations")
plt.legend()
plt.show()
The waring I get is this:
C:\Users\Jakub\AppData\Local\Programs\Python\Python311\Lib\site-packages\pygad\pygad.py:1139: UserWarning: The 'delay_after_gen' parameter is deprecated starting from PyGAD 3.3.0. To delay or pause the evolution after each generation, assign a callback function/method to the 'on_generation' parameter to adds some time delay. warnings.warn("The 'delay_after_gen' parameter is deprecated starting from PyGAD 3.3.0. To delay or pause the evolution after each generation, assign a callback function/method to the 'on_generation' parameter to adds some time delay.")
If I re-run the code, result and overall performance improve, while 1the warnings disappear. Fitness plots:
Another matter altogether is that it seems to me that in spite of restarting the kernel, pygad somehow remembers something about previous runs, because while the file is open in PyCharm, the 'bad' fitness history doesn't actually repeat. To be more precise, only at the first run with the kernel still operating does the algorithm get stuck in a local maximum of the fitness function. So that's curious on it's own - I apologise, if my lack of understanding and knowledge is showing.
I debugged the 'ga_instance' initialisation with pydev debugger (build 241.14494.241). The 'delay_after_gen' was indeed set by default to 0.0; after a while I got to this section of the pygad.py file:
# Validate delay_after_gen
if type(delay_after_gen) in GA.supported_int_float_types:
if not self.suppress_warnings:
warnings.warn("The 'delay_after_gen' parameter is deprecated starting from PyGAD 3.3.0. To delay or pause the evolution after each generation, assign a callback function/method to the 'on_generation' parameter to adds some time delay.")
if delay_after_gen >= 0.0:
self.delay_after_gen = delay_after_gen
else:
self.valid_parameters = False
raise ValueError(f"The value passed to the 'delay_after_gen' parameter must be a non-negative number. The value passed is ({delay_after_gen}) of type {type(delay_after_gen)}.")
else:
self.valid_parameters = False
raise TypeError(f"The value passed to the 'delay_after_gen' parameter must be of type int or float but {type(delay_after_gen)} found.")
Since delay_after_gen
is by default set to 0.0, it is a float value and it passes the if type(delay_after_gen) in GA.supported_int_float_types:
check. Then, since (again, by default) the self.suppress_warnings
is set to False
, the warning from the first nested conditional clause is run:
My idea is to change the default value of the delay_after_gen
parameter to None. I guess (haven't checked that yet tbh) that it is not included in the supported types of variables for the parameter. What's the most interesting though, is that when I re-run the code with the same kernel operating, the same default values are assigned to both delay_after_gen
and self.suppress_warnings
, the waring doesn't show and while debugging I didn't get to the section of the code above ^ what else does it depend on? I didn't notice any other change, and the delay_after_gen
falls under the try
clause right in the __init__()
constructor of the GA
class. Since it is not nested in another conditional clause or anything else like that, what's the difference between the first run and the other runs?
Just in case: I'm using Python 3.12.3
and pygad 3.3.1
.
suppress_warnings=True
Hello, I am using PyGAD version: 3.3.1 on Windows with python 3.10 within jupyter notebook.
When I run my GA, I am getting the following user warning. This is not something I am setting. It seems to emanate from the internal pygad code. How can I avoid having this warning displayed? Thank you