nevopy package

Submodules

nevopy.activations module

This module implements some activation functions.

Todo

Make all activation functions compatible with numpy arrays.

nevopy.activations.linear(x)

Linear activation function (simply returns the input, unchanged).

Return type

float

nevopy.activations.sigmoid(x, clip_value=64)

Numeric stable implementation of the sigmoid function.

Estimated lower-bound precision with a clip value of 64: 10^(-28).

Return type

float

nevopy.activations.steepened_sigmoid(x, step=4.9)

Steepened version of the sigmoid function.

The original NEAT paper used a steepened version of the sigmoid function with a step value of 4.9.

“We used a modified sigmoidal transfer function, ϕ(x) = 1 / (1 + exp(−4.9x)), at all nodes. The steepened sigmoid allows more fine tuning at extreme activations. It is optimized to be close to linear during its steepest ascent between activations −0.5 and 0.5.” - [SM02]

Return type

float

nevopy.base_genome module

Declares the base abstract class that defines the behaviour of a genome.

In the context of neuroevolution, a genome is the entity subject to the evolutionary process. It encodes a neural network (the genome’s phenotype), either directly or indirectly.

This module declares the base abstract class that must be inherited by all the different classes of genomes used by the neuroevolutionary algorithms in NEvoPy.

class nevopy.base_genome.BaseGenome

Bases: abc.ABC

Defines the general behaviour of a genome in NEvoPy.

This class must be inherited by all the different classes of genomes present in NEvoPy

In the context of neuroevolution, a genome is the entity subject to the evolutionary process. It encodes a neural network (the genome’s phenotype), either directly or indirectly.

As pointed out by [SM02], direct encoding schemes, employed in most cases, specify in the genome every connection and node that will appear in the phenotype. In contrast, indirect encodings usually only specify rules for constructing a phenotype. These rules can be layer specifications or growth rules through cell division.

One of the goals of this base abstract class is to abstract those details for the user, defining a general interface for the different types of genomes used by the different neuroevolutionary algorithms in NEvoPy. Generally, for NEvoPy, there is no distinction between a genome and the network it encodes.

A genome must be capable of processing inputs based on its nodes and connections in order to produce an output, emulating a neural network. It also must be able to mutate and to generate offspring, in order to evolve.

fitness

The current fitness value of the genome.

Type

float

abstract property config

Settings of the current evolutionary session.

If None, a config object hasn’t been assigned to this genome yet.

Return type

Any

abstract deep_copy()

Makes an exact/deep copy of the genome.

Return type

BaseGenome

Returns

An exact/deep copy of the genome. It has the same topology and connections weights of the original genome.

abstract distance(other)

Calculates the distance between two genomes.

Parameters

other (BaseGenome) – The other genome.

Return type

float

Returns

A float representing the distance between the two genomes. The lower the distance, the more similar the two genomes are.

abstract property input_shape

The expected shape of the inputs that will be fed to the genome.

Return type

Union[int, Tuple[int, …], None]

Returns

  • None, if an input shape has not been defined yet;

  • An int, if the expected inputs are one-dimensional;

  • A tuple with the expected inputs’ dimensions, if they’re multi-dimensional.

classmethod load(abs_path)

Loads the genome from the given absolute path.

This method uses, by default, pickle to load the genome.

Parameters

abs_path (str) – Absolute path of the saved “.pkl” file.

Return type

BaseGenome

Returns

The loaded genome.

abstract mate(other)

Mates two genomes to produce a new genome (offspring).

Implements the sexual reproduction between a pair of genomes. The new genome inherits information from both parents (not necessarily in an equal proportion)

Parameters

other (Any) – The second genome. If it’s not compatible for mating with the current genome (self), an exception will be raised.

Return type

BaseGenome

Returns

A new genome (the offspring born from the sexual reproduction between the current genome and the genome passed as argument).

Raises

IncompatibleGenomesError – If the genome passed as argument to other is incompatible with the current genome (self).

abstract mutate_weights()

Randomly mutates the weights of the genome’s connections.

Return type

None

abstract process(x)

Feeds the given input to the neural network encoded by the genome.

Parameters

x (Any) – The input(s) to be fed to the neural network encoded by the genome. Usually a NumPy ndarray or a TensorFlow tensor.

Return type

Any

Returns

The output of the network. Usually a NumPy ndarray or a TensorFlow tensor.

Raises

InvalidInputError – If the shape of X doesn’t match the input shape expected by the network.

abstract random_copy()

Makes a deep copy of the genome, but with random weights.

Return type

BaseGenome

Returns

A deep copy of the genome with the same topology of the original genome, but random connections weights.

abstract reset()

Prepares the genome for a new generation.

In this method, relevant actions related to the reset of a genome’s internal state, in order to prepare it to a new generation, are implemented. The implementation of this method is not mandatory.

Return type

None

save(abs_path)

Saves the genome to the given absolute path.

This method uses, by default, pickle to save the genome.

Parameters

abs_path (str) – Absolute path of the saving file. If the given path doesn’t end with the suffix “.pkl”, it will be automatically added.

Return type

None

abstract visualize(**kwargs)

Utility method for visualizing the genome’s neural network.

Return type

None

exception nevopy.base_genome.IncompatibleGenomesError

Bases: Exception

Indicates that an attempt has been made to mate (sexual reproduction) two incompatible genomes.

exception nevopy.base_genome.InvalidInputError

Bases: Exception

Indicates that the a given input isn’t compatible with a given neural network.

nevopy.base_population module

Implementation of the base abstract class that defines a population of genomes, each of which encodes a neural network.

class nevopy.base_population.BasePopulation(size, processing_scheduler)

Bases: abc.ABC, Generic[typing.TGenome]

Base abstract class that defines a population of genomes (neural nets).

This base abstract class defines a population of genomes (each of which encodes a neural network) to be evolved through neuroevolution. It’s in this class’ subclasses where the core of NEvoPy’s neuroevolutionary algorithms are implemented.

Parameters
  • size (int) – Number of genomes (constant) in the population.

  • processing_scheduler (ProcessingScheduler) – Processing scheduler to be used by the population.

scheduler

Processing scheduler used by the population. It’s responsible for abstracting the details on how the processing is done (whether it’s sequential or distributed, local or networked, etc).

Type

ProcessingScheduler

genomes

List with the genomes (neural networks being evolved) currently in the population.

Type

List[TGenome]

stop_evolving

Flag that when set to True stops the evolutionary process being executed by the evolve() method.

Type

bool

DEFAULT_SCHEDULER = None

Default processing scheduler to be used by the population.

average_fitness()

Returns the average fitness of the population’s genomes.

Return type

float

abstract property config

Config object that stores the settings used by the population.

Return type

Any

abstract evolve(generations, fitness_function, callbacks=None, **kwargs)

Evolves the population of genomes through neuroevolution.

This is the main method of this class. It’s here where the main loop of the neuroevolutionary algorithm implemented is located.

Parameters
  • generations (int) – Maximum number of evolutionary generations.

  • fitness_function (Callable[[TGenome], float]) – Fitness function used to compute the fitness of a genome. It must take an instance of class:.BaseGenome as input and return the genome’s fitness (float).

  • callbacks (Optional[List["ne.callbacks.Callback"]]) – List with instances of Callback. The callbacks will be called during different stages of an evolutionary generation. They can be used to customize the algorithm’s behaviour.

Return type

History

Returns

An instance of nevopy.callbacks.History containing relevant information about the evolutionary session.

fittest()

Returns the most fit genome in the population.

Return type

~TGenome

classmethod load(abs_path, scheduler=None)

Loads the population from the given absolute path.

This method uses, by default, pickle to load the population.

Parameters
  • abs_path (str) – Absolute path of the saved “.pkl” file.

  • scheduler (Optional[ProcessingScheduler]) – Processing scheduler to be used by the population. If None, the default one will be used.

Return type

BasePopulation

Returns

The loaded population.

save(abs_path)

Saves the population on the absolute path provided.

This method uses, by default, pickle to save the population. The processing scheduler used by the population won’t be saved (a new one will have to be assigned to the population when it’s loaded again).

Parameters

abs_path (str) – Absolute path of the saving file. If the given path doesn’t end with the suffix “.pkl”, it will be automatically added to it.

Return type

None

property size

Size of the population.

Return type

int

nevopy.callbacks module

Defines a base interface for all callbacks and implements simple callbacks.

For NEvoPy, callbacks are utilities called at certain points during the evolution of a population. They are a powerful tool to customize the behavior of a neuroevolutionary algorithm.

Example

To implement your own callback, simply create a class that inherits from Callback and pass an instance of it to BasePopulation.evolve().

class MyCallback(Callback):
    def on_generation_start(self,
                            current_generation,
                            max_generations):
        print("This is printed at the start of every generation!")
        print(f"Starting generation {current_generation} of "
              f"{max_generations}.")

# ...

population.evolve(generations=100,
                  fitness_function=my_func,
                  callbacks=[MyCallback()])
class nevopy.callbacks.BestGenomeCheckpoint(output_path=None, min_improvement_pc=- inf)

Bases: nevopy.callbacks.Callback

Saves the best genome of the population (checkpoint) at different moments of the evolutionary process.

Parameters
  • output_path (Optional[str]) – Path of the output files. By default, the checkpoints are saved to a new directory named according to the current date and time.

  • min_improvement_pc (float) – Minimum improvement (percentage) in the population’s best fitness, since the last checkpoint, necessary for a new checkpoint. If float('-inf') (default) the best genomes of all generations will be saved.

output_path

Path of the output files.

Type

str

min_improvement_pc

Minimum improvement (percentage) in the population’s best fitness, since the last checkpoint, necessary for a new checkpoint.

Type

float

on_fitness_calculated(best_fitness, avg_fitness, **kwargs)

Called right after the fitness values of the population’s genomes are calculated.

Subclasses should override this method for any actions to run.

Parameters
  • best_fitness (float) – Fitness of the fittest genome in the population.

  • avg_fitness (float) – Average fitness of the population’s genomes.

Return type

None

on_generation_start(current_generation, max_generations, **kwargs)

Called at the beginning of each new generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

class nevopy.callbacks.Callback

Bases: abc.ABC

Abstract base class used to build new callbacks.

This class defines the general structure of the callbacks used by NEvoPy’s neuroevolutionary algorithms. It’s not required for a subclass to implement all the methods of this class (you can implement only those that will be useful for your case).

population

Reference to the instance of a subclass of Population being evolved by one of NEvoPy’s neuroevolutionary algorithms.

Type

BasePopulation

on_evolution_end(total_generations, **kwargs)

Called when the evolutionary process ends.

Parameters

total_generations (int) – Total number of generations processed during the evolutionary process. Might not be the maximum number of generations specified by the user, if some sort of early stopping occurs.

Return type

None

on_fitness_calculated(best_fitness, avg_fitness, **kwargs)

Called right after the fitness values of the population’s genomes are calculated.

Subclasses should override this method for any actions to run.

Parameters
  • best_fitness (float) – Fitness of the fittest genome in the population.

  • avg_fitness (float) – Average fitness of the population’s genomes.

Return type

None

on_generation_end(current_generation, max_generations, **kwargs)

Called at the end of each generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_generation_start(current_generation, max_generations, **kwargs)

Called at the beginning of each new generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_mass_extinction_counter_updated(mass_extinction_counter, **kwargs)

Called right after the mass extinction counter is updated.

Subclasses should override this method for any actions to run.

Parameters

mass_extinction_counter (int) – Current value of the mass extinction counter.

Return type

None

on_mass_extinction_start(**kwargs)

Called at the beginning of a mass extinction event.

Subclasses should override this method for any actions to run.

Note

When this is called, on_reproduction_start() is usually not called (depends on the algorithm).

Return type

None

on_reproduction_start(**kwargs)

Called at the beginning of the reproductive process.

Subclasses should override this method for any actions to run.

Note

When this is called, on_mass_extinction_start() is usually not called (depends on the algorithm).

Return type

None

on_speciation_start(**kwargs)

Called at the beginning of the speciation process.

Called after the reproduction or mass extinction have occurred and immediately before the speciation process. If the neuroevolution algorithm doesn’t implement speciation, this method won’t be called.

Subclasses should override this method for any actions to run.

Return type

None

class nevopy.callbacks.CompleteStdOutLogger(colored_text=True, output_cleaner=<function clear_output>)

Bases: nevopy.callbacks.Callback

Callback that prints info to the standard output.

Note

This callback is heavily verbose / wordy! Consider using the reduced logger (SimpleStdOutLogger) if you don’t like too much text on your screen.

SEP_SIZE = 80
TAB_ARGS = {'justify': 'c', 'min_column_width': 14, 'no_borders': False}
on_evolution_end(total_generations, **kwargs)

Called when the evolutionary process ends.

Parameters

total_generations (int) – Total number of generations processed during the evolutionary process. Might not be the maximum number of generations specified by the user, if some sort of early stopping occurs.

Return type

None

on_fitness_calculated(best_fitness, avg_fitness, **kwargs)

Called right after the fitness values of the population’s genomes are calculated.

Subclasses should override this method for any actions to run.

Parameters
  • best_fitness (float) – Fitness of the fittest genome in the population.

  • avg_fitness (float) – Average fitness of the population’s genomes.

Return type

None

on_generation_end(current_generation, max_generations, **kwargs)

Called at the end of each generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_generation_start(current_generation, max_generations, **kwargs)

Called at the beginning of each new generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_mass_extinction_counter_updated(mass_extinction_counter, **kwargs)

Called right after the mass extinction counter is updated.

Subclasses should override this method for any actions to run.

Parameters

mass_extinction_counter (int) – Current value of the mass extinction counter.

Return type

None

on_mass_extinction_start(**kwargs)

Called at the beginning of a mass extinction event.

Subclasses should override this method for any actions to run.

Note

When this is called, on_reproduction_start() is usually not called (depends on the algorithm).

Return type

None

on_reproduction_start(**kwargs)

Called at the beginning of the reproductive process.

Subclasses should override this method for any actions to run.

Note

When this is called, on_mass_extinction_start() is usually not called (depends on the algorithm).

Return type

None

on_speciation_start(**kwargs)

Called at the beginning of the speciation process.

Called after the reproduction or mass extinction have occurred and immediately before the speciation process. If the neuroevolution algorithm doesn’t implement speciation, this method won’t be called.

Subclasses should override this method for any actions to run.

Return type

None

class nevopy.callbacks.FitnessEarlyStopping(fitness_threshold, min_consecutive_generations)

Bases: nevopy.callbacks.Callback

Stops the evolution if a given fitness value is achieved.

This callback is used to halt the evolutionary process when a certain fitness value is achieved by the population’s best genome for a given number of consecutive generations.

Parameters
  • fitness_threshold (float) – Fitness to be achieved for the evolution to stop.

  • min_consecutive_generations (int) – Number of consecutive generations with a fitness equal or higher than fitness_threshold for the early stopping to occur.

fitness_threshold

Fitness to be achieved for the evolution to stop.

Type

float

min_consecutive_generations

Number of consecutive generations with a fitness equal or higher than fitness_threshold for the early stopping to occur.

Type

int

stopped_generation

Generation in which the early stopping occurred. None if the early stopping never occurred.

Type

Optional[int]

on_fitness_calculated(best_fitness, avg_fitness, **kwargs)

Called right after the fitness values of the population’s genomes are calculated.

Subclasses should override this method for any actions to run.

Parameters
  • best_fitness (float) – Fitness of the fittest genome in the population.

  • avg_fitness (float) – Average fitness of the population’s genomes.

Return type

None

on_generation_end(current_generation, max_generations, **kwargs)

Called at the end of each generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

class nevopy.callbacks.History

Bases: nevopy.callbacks.Callback

Callback that records events during the evolutionary process.

Besides the regular attributes in the methods signature, the caller can also pass other attributes through “kwargs”. All the attributes passed to the methods will have they value stored in the history dictionary.

history

Dictionary that maps an attribute’s name to a list with the attribute’s values along the evolutionary process.

Type

Dict[str, List[Any]]

on_evolution_end(total_generations, **kwargs)

Called when the evolutionary process ends.

Parameters

total_generations (int) – Total number of generations processed during the evolutionary process. Might not be the maximum number of generations specified by the user, if some sort of early stopping occurs.

Return type

None

on_fitness_calculated(best_fitness, avg_fitness, **kwargs)

Called right after the fitness values of the population’s genomes are calculated.

Subclasses should override this method for any actions to run.

Parameters
  • best_fitness (float) – Fitness of the fittest genome in the population.

  • avg_fitness (float) – Average fitness of the population’s genomes.

Return type

None

on_generation_end(current_generation, max_generations, **kwargs)

Called at the end of each generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_generation_start(current_generation, max_generations, **kwargs)

Called at the beginning of each new generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_mass_extinction_counter_updated(mass_extinction_counter, **kwargs)

Called right after the mass extinction counter is updated.

Subclasses should override this method for any actions to run.

Parameters

mass_extinction_counter (int) – Current value of the mass extinction counter.

Return type

None

on_mass_extinction_start(**kwargs)

Called at the beginning of a mass extinction event.

Subclasses should override this method for any actions to run.

Note

When this is called, on_reproduction_start() is usually not called (depends on the algorithm).

Return type

None

on_reproduction_start(**kwargs)

Called at the beginning of the reproductive process.

Subclasses should override this method for any actions to run.

Note

When this is called, on_mass_extinction_start() is usually not called (depends on the algorithm).

Return type

None

on_speciation_start(**kwargs)

Called at the beginning of the speciation process.

Called after the reproduction or mass extinction have occurred and immediately before the speciation process. If the neuroevolution algorithm doesn’t implement speciation, this method won’t be called.

Subclasses should override this method for any actions to run.

Return type

None

visualize(attrs=('best_fitness', 'avg_fitness'), figsize=(10, 6), log_scale=True)

Simple utility method for plotting the recorded information.

This method is a simple wrapper around matplotlib. It isn’t suited for advanced plotting.

attrs

Tuple with the names of the attributes to be plotted. If “all”, all plottable attributes are plotted.

Type

Union[Tuple[str, ..], str]

log_scale

Whether or not to use a logarithmic scale on the y-axis.

Type

bool

Return type

None

class nevopy.callbacks.SimpleStdOutLogger

Bases: nevopy.callbacks.Callback

Callback that prints minimal info to the standard output.

on_evolution_end(total_generations, **kwargs)

Called when the evolutionary process ends.

Parameters

total_generations (int) – Total number of generations processed during the evolutionary process. Might not be the maximum number of generations specified by the user, if some sort of early stopping occurs.

Return type

None

on_fitness_calculated(best_fitness, avg_fitness, **kwargs)

Called right after the fitness values of the population’s genomes are calculated.

Subclasses should override this method for any actions to run.

Parameters
  • best_fitness (float) – Fitness of the fittest genome in the population.

  • avg_fitness (float) – Average fitness of the population’s genomes.

Return type

None

on_generation_start(current_generation, max_generations, **kwargs)

Called at the beginning of each new generation.

Subclasses should override this method for any actions to run.

Parameters
  • current_generation (int) – Number of the current generation.

  • max_generations (int) – Maximum number of generations.

Return type

None

on_mass_extinction_counter_updated(mass_extinction_counter, **kwargs)

Called right after the mass extinction counter is updated.

Subclasses should override this method for any actions to run.

Parameters

mass_extinction_counter (int) – Current value of the mass extinction counter.

Return type

None

on_mass_extinction_start(**kwargs)

Called at the beginning of a mass extinction event.

Subclasses should override this method for any actions to run.

Note

When this is called, on_reproduction_start() is usually not called (depends on the algorithm).

Return type

None

Module contents

Imports the core names of NEvoPy.