diff --git a/.gitignore b/.gitignore index bfdf5d69..0b96b80c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ examples/data/*.npy release_video/ .pytest_cache/ .claude/ + +# Superpowers brainstorming companion +.superpowers/ diff --git a/docs/source/images/pygad_vilvik_cloud.png b/docs/source/images/pygad_vilvik_cloud.png new file mode 100644 index 00000000..7401ec9a Binary files /dev/null and b/docs/source/images/pygad_vilvik_cloud.png differ diff --git a/docs/source/images/pygad_vilvik_cloud.svg b/docs/source/images/pygad_vilvik_cloud.svg new file mode 100644 index 00000000..2b2262cd --- /dev/null +++ b/docs/source/images/pygad_vilvik_cloud.svg @@ -0,0 +1,24 @@ + + + + + + + + + + Run PyGAD in the Cloud + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/index.md b/docs/source/index.md index 62de4da0..85a322aa 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -2,7 +2,17 @@ [PyGAD](https://github.com/ahmedfgad/GeneticAlgorithmPython) is an open-source Python library for building the genetic algorithm and optimizing machine learning algorithms. It works with [Keras](https://keras.io) and [PyTorch](https://pytorch.org). -> Try the [Optimization Gadget](https://optimgadget.com), a free cloud-based tool powered by PyGAD. It makes optimization easier by reducing or removing the need for coding, and it shows helpful visualizations. +> Try [Vilvik](https://vilvik.com), a free cloud-based tool powered by PyGAD. It makes optimization easier by reducing or removing the need for coding, and it shows helpful visualizations. + +> Run PyGAD in the cloud with [Vilvik](https://vilvik.com): push your PyGAD problem to Vilvik, let it run in the cloud, and get the results back. + +:::{figure} images/pygad_vilvik_cloud.* +:alt: Run PyGAD in the cloud with Vilvik +:width: 100% +:align: center + +Push your PyGAD problem to [Vilvik](https://vilvik.com) and run it in the cloud. +::: [PyGAD](https://github.com/ahmedfgad/GeneticAlgorithmPython) supports different types of crossover, mutation, and parent selection operators. It lets you optimize many types of problems with the genetic algorithm by writing your own fitness function. It works with both single-objective and multi-objective optimization problems. diff --git a/pygad/kerasga/__init__.py b/pygad/kerasga/__init__.py index 88e4c10a..5c712675 100644 --- a/pygad/kerasga/__init__.py +++ b/pygad/kerasga/__init__.py @@ -1,3 +1,3 @@ from .kerasga import * -__version__ = "1.3.2" +__version__ = "1.3.3" diff --git a/pygad/kerasga/kerasga.py b/pygad/kerasga/kerasga.py index 98380b73..44f83131 100644 --- a/pygad/kerasga/kerasga.py +++ b/pygad/kerasga/kerasga.py @@ -79,8 +79,8 @@ def predict(model, steps=None): """ Load the given solution as the model's weights and run a forward - pass on ``data``. The model is cloned first so the caller's - instance is left untouched. + pass on ``data``. The model's original weights are restored + afterwards, so the model passed by the caller is not changed. Parameters ---------- @@ -105,12 +105,24 @@ def predict(model, # Fetch the parameters of the best solution. solution_weights = model_weights_as_matrix(model=model, weights_vector=solution) - _model = tensorflow.keras.models.clone_model(model) - _model.set_weights(solution_weights) - predictions = _model.predict(x=data, - batch_size=batch_size, - verbose=verbose, - steps=steps) + + # Set the solution as the model weights, then put the original weights + # back at the end. The model is not cloned because cloning it on every + # call is slow when predict() is used inside a fitness function. + original_weights = model.get_weights() + model.set_weights(solution_weights) + try: + if batch_size is None and steps is None: + # When no batching is asked for, call the model directly. This + # is faster than model.predict() when called once per solution. + predictions = numpy.array(model(data, training=False)) + else: + predictions = model.predict(x=data, + batch_size=batch_size, + verbose=verbose, + steps=steps) + finally: + model.set_weights(original_weights) return predictions diff --git a/pygad/pygad.py b/pygad/pygad.py index 37eba68e..7db5f560 100644 --- a/pygad/pygad.py +++ b/pygad/pygad.py @@ -203,7 +203,6 @@ def save(self, filename): cloudpickle_serialized_object = cloudpickle.dumps(self) with open(filename + ".pkl", 'wb') as file: file.write(cloudpickle_serialized_object) - cloudpickle.dump(self, file) def push_to_vilvik(self, *, api_key=None, **overrides): """