I contain a population of parameter-combination
Construct me with a callable evaluation func, a sequence of parameter names, and a sequence of bounds containing 2-tuples that each define the lower and upper limits of the values:
func: A callable to which an
Individualcan send its parameter values and from which it receives a sum-of-squared error float value as a result.
- names: A sequence of parameter names.
- bounds: A list of 2-tuples, one for each parameter name. The first element of each tuple is the lower bound of a parameter in the second the upper bound.
The callable func must accept a single 1-D Numpy array as its sole argument and return the sum of squared errors (SSE) as a single float value. To shut down ade, it can return a negative SSE value. If ade is shutting down, it will use None as the argument, and the callable should act accordingly.
My targetFraction attribute determines how much success challengers must have to maintain the status quo in adaptive mode. Consider the default of 2.5%: In a population of 100, that is reached with a score of 2.5, which can be achieved, for example, with
- ten challengers winning with a rounded improvement ratio of 1; or
- one challenger winning with an rir of 2 and five with an rir of 1; or
- just one challenger winning with an rir of 3.
- Or, if you're somehow positioned at a subtle transition in the fitness landscape along just the right multi-dimensional angle, fully half of the challengers winning with an rir of 0. (Unlikely!)
|Parameters||constraints||A single callable object (function, method, class instance with
__call__ method), or a sequence of such objects, that enforce(s) any
constraints on your parameter values. See |
|popsize||The number of individuals per parameter in the population, if not the default.|
|complaintCallback||A callable that my |
|targetFraction||Set this to a (small) float to override my default target for the total score of improvements in each iteration.|
|See Also||asynqueue.util.DeferredTracker, used to limit concurrency
during population |
|Class Variable||N_maxParallel||The maximum number of parallel evaluations during population
|Instance Variable||popsize||The number of individuals per parameter. The population size will scale with the number of parameters, up until Np_max is reached. Default is 10 individuals per parameter.|
|Instance Variable||Np_min||Minimum population size, i.e., my total number of individuals. Default is 20.|
|Instance Variable||Np_max||Maximum population size. Default is 500, which is really pretty big.|
|Instance Variable||Nd||The number of parameters for each individual.|
|Instance Variable||targetFraction||The desired total score of improvements in each iteration in order for
ade's adaptive algorithm to not change the current differential
|Instance Variable||running||Indicates my run status:
|Class Method||load||Returns a new instance of me with values initialized from the original version that was pickled and written with BZ2 compression to filePath.|
|Method||__getstate__||For pickling. Note that neither the user-supplied evaluation function nor any complaint callback function is included.|
|Method||save||Writes a BZ2-compressed pickled version of me to the specified filePath.|
|Method||__getitem__||Sequence-like access to my individuals.|
|Method||__setitem__||Use only this method (item setting) to replace individuals in my iList.|
|Method||__len__||Sequence-like container of individuals: length.|
|Method||__iter__||Sequence-like container of individuals: iteration.|
|Method||__contains__||Sequence-like container of individuals: "in".|
|Method||__bool__||Sequence-like container of individuals: I am
|Method||KS 0||Property: A list of indices to iList, sorted by increasing (worsening) SSE of the individuals there. The best individual will have the first index in KS.|
|Method||KS||Property: "Deleting" my SSE-sorted list of indices forces regeneration of it the next time the KS property is accessed. It also "deletes" iSorted.|
|Method||iSorted 0||Property: A list of my individuals, sorted by increasing (worsening) SSE.|
|Method||iSorted||Property: "Deleting" my sorted list of individuals forces regeneration of the sorted list that will be returned next time the iSorted property is accessed.|
|Method||kBest||Property: The index to iList of the best individual.
|Method||__repr__||An informative string representation with a text table of my best individuals.|
|Method||evalFunc||A wrapper for the user-supplied evaluation function.|
|Method||clear||Wipes out any existing population and sets up everything for a brand new one.|
|Method||limit||Limits the individual's parameter values to the bounds in the way that
|Method||spawn||Spawns a new
|Method||abort||Aborts my operations ASAP. Repeated calls will release any locks that got acquired since the last call.|
|Method||initialize||Invalidates the last sort of my individuals, sets my running flag
|Method||setup||Sets up my initial population using a Latin hypercube to initialize pseudorandom parameter values with minimal clustering.|
|Method||addCallback||Adds callable func to my reporter's list of functions to call
each time there is a significantly better
|Method||setConstraints||Sets the constraint checkers maintained by my
|Method||replacement||Records the replacement of an
|Method||report||Provides a message via the log messenger about the supplied
|Method||showFailedConstraint||Outputs a progress character to indicate a failed constraint.|
|Method||push||Pushes the supplied
|Method||sample||Returns a sample of N indices from my population that are unique from each other and from any excluded indices supplied as additional arguments.|
|Method||individuals||Immediately returns a list of the individuals at the specified integer index or indices.|
|Method||lock||Obtains the locks for individuals at the specified indices, submits a
request to acquire them, and returns a
|Method||release||Releases any active lock for individuals at the specified index or indices.|
|Method||best||Returns my best individual, or
|Method||evalTimes||Returns a list of the most recent elapsed evaluation times for each of my individuals that have done evaluations.|
setup. Uses an instance of
asynqueue.util.DeferredTrackerfor concurrency limiting.
FManagerfor details. The default is 2%. (Previously, it was 2.5% but that seemed too strict for the application the author is mostly using ADE for.)
Trueto show individuals getting replaced. (Results in a very messy log or console display.)
Noneafter instantiation but before
Trueafter setup, and
Falseif ade is aborting.
Population(func, names, bounds, constraints=, popsize=None,
def load(cls, filePath, **kw):
Returns a new instance of me with values initialized from the original version that was pickled and written with BZ2 compression to filePath.
The pickled version will not have a reference to the evaluation func that was supplied to the original version in its constructor, nor to any complaintCallback. If you want to do further evaluations, you can supply a reference to those functions (or even a different one, though that would be weird) with the func and complaintCallback keywords.
Note: For some mysterious reason, the DE algorithm seems to run significantly slower when resuming with a population that has been loaded using this method than with one initialized from scratch.
|Parameters||func||Evaluation function, specify if you want to resume evaluations. All individuals in the loaded population should have their SSEs re-evaluated if anything at all has changed about that function.|
|complaintCallback||Callback function for complaining about new-best reports during resumed evaluations.|
|bounds||A list of bounds to update my restored ParameterManager object with.
Specify if you refined the parameter bounds since the last run and want to
resume evaluations with the refined bounds. Each Individual in the
new instance will have its values limited to the new bounds with a call to
For pickling. Note that neither the user-supplied evaluation function nor any complaint callback function is included.
Writes a BZ2-compressed pickled version of me to the specified filePath.
Note that the user-supplied evaluation function will not be included in
the pickled version. However, you can supply it as a keyword to
Use only this method (item setting) to replace individuals in my iList.
The only other place my iList is ever manipulated directly is the
addIndividual function of
Sequence-like container of individuals: length.
My length will be equal to my Np attribute unless setup has not been completed.
def KS 0(self):
Property: A list of indices to iList, sorted by increasing (worsening) SSE of the individuals there. The best individual will have the first index in KS.
Property: "Deleting" my SSE-sorted list of indices forces regeneration of it the next time the KS property is accessed. It also "deletes" iSorted.
def iSorted 0(self):
Property: A list of my individuals, sorted by increasing (worsening) SSE.
Property: "Deleting" my sorted list of individuals forces regeneration of the sorted list that will be returned next time the iSorted property is accessed.
Property: The index to iList of the best individual.
None if I have no individuals yet.
Limits the individual's parameter values to the bounds in the way that
is configured to do, modifying the individual in place.
Note: The individual's population status is not considered or
affected. If it's a population member, you will want to re-evaluate it and
invalidate my sort with a
del self.KS or
self.iSorted if its SSE has changed.
Spawns a new
Individual with the
supplied values. If fromUnity is set
values are converted from 0-1 range into their proper ranges.
Aborts my operations ASAP. Repeated calls will release any locks that got acquired since the last call.
calls this with ignoreReporter set
True to avoid
Invalidates the last sort of my individuals, sets my running flag
True, and prints/logs a representation of my populated
Sets up my initial population using a Latin hypercube to initialize pseudorandom parameter values with minimal clustering.
Unless uniform is set, that is. Then each parameter values is just uniformly random without regard to the others.
With parameter constraints, the Latin hypercube doesn't work that well. The initial values matrix must be refreshed, perhaps many times. But it may still be better than uniform initial population sampling.
Sets my running flag
True and returns a
Deferred that fires when the population has been set up, with
True if it's ready to go and setup didn't get aborted.
|Parameters||uniform||Use uniform random variates instead of a Latin hypercube (LHS). Using LHS (the default) is usually better because initializes pseudorandom parameter values with minimal clustering.|
Sets the constraint checkers maintained by my
instance pm to the callable function(s), method(s), or object(s)
supplied as one or more args.
What you supply as arguments will replace any constraint checking already in place, so make sure you everything you want is included.
All constraints, and only those constraints, defined by this call will need to be be satisfied with each parameter combination. To clear any existing constraints, call with no args.
True with a probability that increases as
score approaches my statusQuoteScore.
Records the replacement of an
Individual in this
generation or iteration.
Call with an integer rounded improvement ratio in a loser's SSE vs. the successful challenger's SSE, unless you are calling to inquire about whether the status quo F value(s) should be maintained or to set my statusQuoteScore with the sqs keyword.
Three types of calls
The rounded improvement ratio rir indicates how much better the challenger is than the individual it replaced. I use that ratio to adjust a running score for the current iteration to inform the status quo inquiry that will occur when the iteration is done, unless I'm not running in adaptive mode.
You can set my target statusQuoScore by setting sqs to a (small) float value. That will replace my default value for future evaluation of replacement individuals.
Finally, a status quo inquiry is a call with no keywords set. I will
determine if the replacements that occurred in the previous
generation/iteration were enough to warrant maintaining the status quo,
and then reset the record. You will receive a result of
if the status quote should be maintained.
The status quo should be maintained if several small improvements are made, or fewer larger ones, with the required number and/or size increasing for a larger population. For small populations where even a single improvement would be significant, the probability of status quo maintenance increases with smaller population and will sometimes happen even with no improvements for a given generation or iteration.
An rir of 1 indicates that the successful challenger was better (i.e., lower) and not considered equivalent to that of the individual it replaced, and that its SSE was no better than 1.5x as good (2/3 as high) as the replaced individual's SSE. An rir of 2 indicates that the challenger had an SSE between 1.5x and 2.5x better than (2/5 to 2/3 as high as) the individual it replaced.
I give very little weight to an rir of zero, which indicates
that the challenger was better but still has an equivalent SSE, i.e., is
no more than 2% better with the default value of Reporter.minDiff.
I give five times much weight to an rir of 1, though it's still
pretty small. The improvement is modest and could be as little as 2%
Reporter.minDiff=0.02, the default). An rir
of 2 gets three times as much weight as that.
An rir of 3 also gets disproportionately more weight, five times as much as rir=1. Beyond that, though, the weight scales in a nearly linear fashion. For example, an rir of 9 adds just a little more than three times to the score (3.4x) as rir=3 does.
Here's a practical example, with a population of 100 individuals: If you see 10 "1" characters on the screen for one iteration with other 90 being "X," your ratio score for that iteration will be 5.0. But if you see just one non-X individual with a "8" character, the score will be 7.5. That one amazing success story counts more in a sea of failures than a bunch of marginal improvements, which is kind of how evolution works in real life. (See the literature around "hopeful monsters.")
|Parameters||rir||A rounded improvement ratio obtained from a call to |
Provides a message via the log messenger about the supplied
optionally with a comparison to another one.
If no second individual is supplied, the comparison will be with the best individual thus far reported on.
If no individual at all is supplied, reports on my best one, forcing callbacks to run even if the best individual's SSE is equivalent to the last-reported one's.
Deferred that fires when all reporter callbacks
have finished. (And also
Pushes the supplied
onto my population and kicks out the worst individual there to make
Returns a sample of N indices from my population that are unique from each other and from any excluded indices supplied as additional arguments.
The randomBase keyword lets you use a significant improvement
offered by ADE: Non-uniform probability of base individual selection.
Implementation is done by an instance of
The traditional DE/best/1/bin and DE/rand/1/bin are really opposite extremes of what can be a continuous range of base individual selection regimes. By specifying a float value for randomBase between 0.0 and 1.0, you can select a regime anywhere in that range.
The higher the value, the more uniform the probability distribution is. Setting it to near 0.0 makes it much more likely that the index of the best individual or one nearly as good will be chosen. Setting it to near 1.0 makes the worst individual nearly as likely to be chosen as the best.
A randomBase value of 0.5 is a compromise between DE/best/1/bin and DE/rand/1/bin. With that setting, the probability of an individual having its index selected will gradually drop as it gets worse in the SSE rankings. As randomBase goes above 0.5, the probability will take longer to start dropping, until at 1.0 it doesn't drop at all. As randomBase goes below 0.5, the probability will start dropping sooner, until at 0.0 it drops to zero for anything but the best individual.
|Parameters||randomBase||Sample probability uniformity value between 0.0 (only the best individual is ever selected) and 1.0 (uniform probability). Setting it False is equivalent to 0.0, and setting it True (the default) is equivalent to 1.0.|
Immediately returns a list of the individuals at the specified integer index or indices.
Obtains the locks for individuals at the specified indices, submits a
request to acquire them, and returns a
Deferred that fires
when all of them have been acquired.
Release the locks (as soon as possible) by calling
the indices that are locked.
If I'm shutting down, the returned
Releases any active lock for individuals at the specified index or indices.
If no indices are supplied, releases all active locks. (This is for aborting only.)