Candidate Utilities
As seen in Fitness Functions, fitness strategies require an AbstractCandidate
to compute fitness. To be used by NaiveGAflux, an AbstractCandidate
needs to
- Provide the data needed by the fitness strategy, most commonly the model but also things like lossfunctions and optimisers
- Be able to create a new version of itself given a function which maps its fields to new fields.
Capability 1. is generally performed through functions of the format someproperty(candidate; default)
where in general someproperty(::AbstractCandidate; default=nothing) = default
. Examples of such functions are:
model(c; default)
: Return a modelopt(c; default)
: Return an optimiserlossfun(c; default)
: Return a lossfunction
All such functions are obviously not used by all fitness strategies and some are used more often than others. Whether an AbstractCandidate
returns something other than default
generally depends on whether it is a hyperparameter which is being searched for or not. For example, the very simple CandidateModel
has only a model
while CandidateOptModel
has both a model and an own optimiser which may be mutated/crossedover when evolving.
Capability 2. is what is used then evolving a candidate into a new version of itself. The function to implement for new AbstractCandidate
types is newcand(c::MyCandidate, mapfields)
which in most cases has the implementation newcand(c::MyCandidate, mapfield) = MyCandidate(map(mapfield, getproperty.(c, fieldnames(MyCandidate)))...)
. Furthermore, candidates must also be functors from Functors.jl to support things like GPU<->CPU movement.
Example with a new candidate type and a new fitness strategy for said type:
import Functors
struct ExampleCandidate <: AbstractCandidate
a::Int
b::Int
end
aval(c::ExampleCandidate; default=nothing) = c.a
bval(c::ExampleCandidate; default=nothing) = c.b
Functors.@functor ExampleCandidate
struct ExampleFitness <: AbstractFitness end
NaiveGAflux._fitness(::ExampleFitness, c::AbstractCandidate) = aval(c; default=10) - bval(c; default=5)
Ok, this is alot of work for quite little in this dummy example.
@test fitness(ExampleFitness(), ExampleCandidate(4, 3)) === 1
ctime, examplemetric = fitness(TimeFitness(ExampleFitness()), ExampleCandidate(3,1))
@test examplemetric === 2
@test ctime > 0
This page was generated using Literate.jl.