Using Algorithms¶
Basic Interface¶
Once a SearchAlgorithm instance has been created, e.g.
from evotorch import Problem
from evotorch.algorithms import SNES
import torch
def sphere(x: torch.Tensor) -> torch.Tensor:
return torch.sum(x.pow(2.))
problem = Problem(
'min',
sphere,
solution_length = 10,
initial_bounds = (-1, 1),
)
searcher = SNES(problem, stdev_init = 5)
the main usage is to step the algorithm forward by a single generation
However, a common use-case is to run a SearchAlgorithm instance for many generations. In this case, the run
function provides an easy interface for this,
Important
The above call to run
will not produce any output as the searcher
has no attached loggers.
Accessing the Status¶
Each SearchAlgorithm instance maintains a status
dictionary which tracks various information about the current status of the searcher
. You can discover the available status information for a specific class that inherits SearchAlgorithm using,
Each status property can be accessed by its name
All algorithms currently implemented in EvoTorch applied to single-objective problems will at least have the following status properties:
'best'
, the best discovered solution so far.'worst'
, the worst discovered solution so far.'best_eval'
, the fitness of the best discovered solution so far.'worst_eval'
, the fitness of the worst discovered solution so far.'pop_best'
, the best solution in the population.'pop_best_eval'
, the fitness of the best solution in the population.'mean_eval'
, the mean fitness of the population.'median_eval'
, the best solution in the population.
Changing Data-types and Devices¶
In EvoTorch, problems can be specified to use a specific torch
device and data type. When a SearchAlgorithm instance is created, it is passed a Problem instance, and in doing so, inherits the device and data type from the Problem.
This is easy to observe, as running the following code,
prob = Problem(
'min',
sphere,
solution_length = 10,
initial_bounds = (-1, 1),
dtype = torch.float16,
device = 'cuda:0',
)
searcher = SNES(prob, stdev_init = 5)
searcher.run(10)
and then printing the center of the search distribution using the status
dictionary, will show that the resulting tensor is now using the dtype
and device
that was specified in the instantiation of prob