ahmedfgad / GeneticAlgorithmPython

Source code of PyGAD, a Python 3 library for building the genetic algorithm and training machine learning algorithms (Keras & PyTorch).
https://pygad.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.89k stars 464 forks source link

fitness function is being saved? #263

Open acidnik opened 10 months ago

acidnik commented 10 months ago
import numpy
import pygad

function_inputs = [4, -2, 3.5, 5, -11, -4.7]  # Function inputs.
desired_output = 44  # Function output.

def fitness_func(ga_instance, solution, solution_idx):
    # XXX UNCOMMENT THIS
    # print('TEST TEST TEST')
    output = numpy.sum(solution * function_inputs)
    fitness = 1.0 / (numpy.abs(output - desired_output) + 0.000001)
    return fitness

num_generations = 100  # Number of generations.
num_parents_mating = 10  # Number of solutions to be selected as parents in the mating pool.

sol_per_pop = 20  # Number of solutions in the population.
num_genes = len(function_inputs)

# Running the GA to optimize the parameters of the function.
try:
    ga_instance = pygad.load('test')
except:
    ga_instance = pygad.GA(
        num_generations=1,
        num_parents_mating=num_parents_mating,
        sol_per_pop=sol_per_pop,
        num_genes=num_genes,
        fitness_func=fitness_func,
    )
for _ in range(10):
    ga_instance.run()
    ga_instance.save('test')

steps to reproduce:

  1. run this file
  2. uncomment the line marked with XXX
  3. run this file again

expected results: TEST TEST TEST being printed

actual results: nothing happens

does this means that the code of fitness function is saved too? is there a way to update my code after the ga was saved?

acidnik commented 10 months ago

found the workaround myself:

try:
    ga_instance = pygad.load('test')
    ga_instance.fitness_func = fitness_func

still, would be nice to reflect this in documentation

ahmedfgad commented 10 months ago

PyGAD uses the cloudpickle library which is able to pickle not only the objects but also the functions. So, yes the fitness function is pickled.

When you run the code for the first time with the commented print statement, then the cloudpickle library saves the fitness function with the print line commented.

After loading the saved cloudpickle object, it loads the saved fitness function with the commented print statement.

As you suggested, you can force change the fitness function by setting the fitness_func attribute.