|
About the Meta-evolver
Author: Mitchell Timin
Posted: 06/11/2006
Metavolv.py is a computer
program that searches for a better set of parameters for some
other program, which we call the target
program. The target
program determines
what "better" means, and it writes a merit
value to the screen. The parameters appear
in a configuration file
for the
target program.
Although metavolv.py is written in Python, the target program can be
any executable file that meets two conditions: It must read a
configuration file to get values for parameters, and it
must eventually write a result to the screen.
Metavolv will repeatedly execute the target program, each time
re-writing the configuration file with new parameter values.
Metavolv.py will use two other Python files, modify.py and
editThis.py. The three files together comprise the program.
Metavolv is primarily designed for stochastic
target programs, and also for those that require significant execution
time. For such programs
we cannot be sure of finding a global optimum in a reasonable time
span; we are primarily interested in improving the set of parameters
that we start with. Hence we are primarily attempting to move
toward a local optimum.
2. What's Required to Use it:
You need Python, a free download from www.python.org.
It
should be version 2.4 or later. You will also need
a Python extension called NumPy (numerical python). That's
also a
free download; from sf.net/projects/numpy
(get NumPy 0.9.6 or later).
Finally, you need another Python extension called ctypes.
This is
included in Python 2.5, but if you are using any earlier version then
get ctypes from
sf.net/projects/ctypes. (Of course you need a target
program. A demo
target, hill.c, is supplied with the metavolv package; you will have to
compile it, unless you use Windows. In the latter case you
can
download an executable binary file.)
3. How to Use it:
You must use a text editor to customize editThis.py, which
configures metavolv.py for your particular target. Some examples are
supplied to illustrate this. One example is editThis.4play, which is for
use with 4play. That can be used with no changes, but you must rename it to
editThis.py. There are other examples supplied also. editThis.sail is for use
with EvSail
and editThis.hill is for use with the compiled form of hill.c.
The latter is an example target program that is included in the
metavolv download.
Once editThis.py is suited to the target, and the target is ready to run, metavolv.py is
executed from a command line window. The command is simply
metavolv.py followed by the desired number of trials. For
example "metavolv.py 100". That can optionally be
followed by a filename containing the initial parameter set.
Normally
the parameter set is taken from the initializer in editThis.py, but if
the
name of a file containing the parameter values is given, then those values will
be used. This file should have all of the parameter names and values, and in the same order that
they appear in the initializer.
(This is most commonly used with result.ini, which is created by
metavolv during each run. It contains the best parameter set
found.)
(A pseudocode representation is below.) The general idea is that metavolv.py
writes a new version of the configuration file each time
it executes the target program.
Metavolv receives all of the output that the target sends to
the screen. From
that output it finds the fitness value that the target produced.
(The target
program outputs a fitness value or merit
factor at the end of execution). Then the parameters
are changed, and the above steps are repeated. The best
fitness found is always kept,
as well as the parameter set that produced it.
Of course, the devil is in the details, and there are a lot more
details here. The most important
have to do with how the parameter set is modified. Initially,
we take random jumps in parameter space.
We save all of this data, both the parameter values and the resulting
fitness. After we have enough points, then a
linear function of all of the parameters
is fitted to these points by
the method of least squares. (This is accomplished using the
linalg.lstsq() function of NumPy.) We treat this linear function
as if it were a good approximation to the actual, unknown, function
relating fitness to the parameters. For a linear function
we know which direction to move in order to raise the fitness.
That's the direction of the gradient vector, and we know what
that is.
So we take a step in that direction. However, this step is
not
guaranteed to increase the fitness, for two reasons. 1) the linear
function
is only a rough approximation of the actual function, and 2) our
function may be stochastic, so that there is great random variation in
results returned by the target program. (Programs involving simulated evolution are almost always stochastic.)
There are more details: There is a variable, sigma, which is
related to the step size. When taking random steps it is the
standard
deviation of the random amount added to a parameter.
When taking a projected step using the linear fit, it is the
Euclidean norm
of the N dimensional step. We would like to take
large steps to rapidly find our maximum, but if the step is too large
it is guaranteed to take us
farther from the maximum. Hence there is a best step size.
Furthermore, The best step size depends on how far we are
from the maximum point; smaller steps are necessary as one approaches the maximum.
Therefore we have incorporated a
method of automatically adjusting sigma. Whenever we take a
projected step in the gradient
direction, we also take another step with sigma 50% greater.
Hence we execute the target
twice. We keep only the result with the higher fitness, and
discard the other.
However, if one result was significantly higher than the
other, then we change the step
size. If the shorter step was better
we reduce sigma. If the longer step was
better we increase it.
Another important detail is the transformation
of the parameters so that
they all have similar behavior. The original parameter set
often
has parameters
that are very different. For example, one parameter may be
probability, and must stay between zero and one. Another
parameter
may be a population size that can vary from 20 to 2000.
Clearly,
an appropriate step size cannot be defined that suits both of those
parameters. Hence, we permit the user to define as many custom
transformations as are required by his active parameter set.
However, in most cases some or all of the transformations that
are in modify.py may be used.
To specify that a particular
transformation function is to be used by a particular parameter, put
its name into the appropriate line of the initializer in editThis.py.
Note that these transformation functions must include the
inverse transformation. For example, the function floatXform()
uses the natural log function to transform a parameter. For the
inverse transformation it uses the exponential function. If you
add any new function names, they must be included in the line that
begins "from modify import ....." in metavolv.py.
The goal of each transformation function is to cause the corresponding
active parameter value to vary across a good portion of the range -10
to +10. In many cases all that is required is the log() function,
with exp() for its inverse. However, if the value of the
parameter must be limited, then the transformation function must also
enforce the limits. There are two examples of that in modify.py,
namely probXform() and declineXform(). Finally, the active
parameter set must consist only of floating point numbers. If
some of the original parameters are integers, the transformation
function must translate. An example of this is intXform(), in
modify.py.
If no transformation is needed, then use the null transformation
function, noXform(). This is done when hill.c is the target
program, so you can see it used in editThis.hill. noXform() can
be used with any parameter and any target, but the search results may
not be as good, depending on the behavior of the parameters.
Also, some of the parameters may reach unreasonable values; the effect
of that depends on the target program.
It is the transformed parameters that are used for the search.
The initial parameter set is transformed after it is read in from
the initializer. It is de-transformed in order to re-write the configuration file, or to display it.
pseudocode explanation of how it works:
write new .ini file for target program
(this includes initial vector of parameters)
set bestFitness to very unfit value
set currentParams to transformed values from the .ini
loop forever:
invoke target program
capture its output scanning for
termination
when termination occurs:
scan for the fitness
if fitness > bestFitness:
bestFitness <- fitness
bestParams <- currentParams
else:
restore params to best
store the fitness value
store the xformed param set that
produced it
make some changes to
currentParams
(these
may be based on linear projection, or may be random)
de-transform them and write new .ini file
5. Output and Discussion:
Two text files
are include in the package, output.hill & output.4play. output.hill is a run of 100 trials
using editThis.hill (renamed to
editThis.py). Similarly, output.4play is for 4Play, but
in this case the editThis.py that was used has been pasted into the
file ahead of the output. (It is not exactly the same as
editThis.4Play.) The first line of output shows the name of the
executable, the specified run time per trial, and the allowed overtime per
trial. If the target program does not use a specified run time
then the latter two numbers are meaningless. After that, when one
or more numbers appear on a line, those are merit values which were reached by random steps.
Whenever a new best fitness is found the parameter values will be
printed. Note that the "best fitness" might decrease slightly.
This is because we accept anything very close, or even a little
worse, as a new best. This is done to keep the search point
moving through parameter space, instead of getting stuck for a long
time. This is controlled by the value of epsilon, in editThis.py. Whenever a gradient step
is taken a line like this is printed:
grad-> 3.066 fitness 0.7664 sigma 0.1800
The shows the magnitude of the gradient, the merit value found, and the new step size.
Before examining output.hill, look at the illustration below. This
shows the merit
output of the hill executable for values of X & Y between 0 and 6,
but with no
"jitter" (random noise). For the test run the jitter was set at
.05. The test run began its search at
the point (.75, 1.5), where
the surface is almost flat. It can be seen that metavolv made no
real progress until trial 38, when it finally found a little bit of
slope. From that point on it made fairly steady progress until by
trial 75 it was quite close to the maximum point. (The true
maximum is at (3.0, 4.0) and its value is 5.0 plus the "jitter".
The latter is a normal random variable with zero mean and, in
this case, std. dev. of .05.) Note that after trial 77, sigma is
steadily declining, as it should be when we are closing in on a maximum.
Hill is a very easy problem, being a very smooth function with no local
maxima other than the global maximum, and a parameter space of only two
dimensions. It also executes almost instantaneously. Its
purpose is just to show that there is nothing grossly wrong with
metavolv. Next we will discuss output.4Play, a much more
challenging problem.
4Play is a difficult problem in parameter optimization. There are
8 active parameters. The existence of many local maxima is
likely, but unknown. The fitness function is highly stochastic,
with very large variation. Finally, the execution time per trial
needs to be very long. We chose 15 minutes for this sample run
because we wanted the total run time to be less than 24 hours.
That is not really long enough for 4Play to evolve the perfect
solutions that it is capable of. It is relevant here that
this took place on a fairly fast desktop computer with an AMD Athlon 64
3200+ CPU.
The fitness output seen during the run (output.4play) varies from
a little over .5 to a maximum of .8907. 1.0 is the maximum
possible, and that has been achieved in the past, but it required runs
lasting several hours. Nevertheless, metavolv achieved a
respectable result. In looking at the parameter set, we see that
most of the parameters changed very little, indicating that our initial
choices were not bad. However, some did change a lot.
mutmax went from 1.0 to .422, giving us some useful information
about that parameter. Most problematic was the neuron count which
went from 40 to 15. This tells us that we can get to .89 fitness
with only 15 neurons, and do it quickly. But we are primarily
interested in perfect solutions of 1.0 fitness. Past experience
has given the impression that about 40 neurons were necessary for this.
It seems that a series of runs is needed with at least one hour of
execution time per trial, perhaps more. This will require
several days of computer time.
Definitions:
parameter - A number whose value
you would like to determine. A variable with a numerical value. (For use with metavolv.py it must appear
in a configuration file for the target program.)
active parameters - the
parameters whose values will be varied during the search. The
configuration file will usually contain other
parameters also. The flag field in the initializer determines which
parameters are active.
parameter space - The set of all possible values of all active
parameters. If there are N active parameters then this is an N-dimensional
space.
target - (or target program) An
executable file which can be invoked by
metavolv.py. (It will be invoked over and over again.)
The
target program can be any executable file that meets three conditions:
It must be executable from a command line window, it must read a
configuration file to get values for parameters, and it
must eventually write a merit value to the screen via stdout.
configuration
file - A text file
containing names and values of parameters. The
target program will read it when it begins execution and use the values
found
there.
4Play - A neuroevolution
software package which is a free download from
http://annevolve.sourceforge.net
EvSail - A neuroevolution
software package which is a free download from
http://annevolve.sourceforge.net
merit value or merit factor or
fitness - A number that estimates how good the parameter
set is; larger meaning better. This is usually a
random variable, so a given parameter
set will produce different merit values each time it is used.
stochastic - containing random
influences
initializer - a list
structure at the beginning of editThis.py. Each item of the
list consists of a name, value, flag, and function name.
This mirrors the configuration file of the target program, but
with the flag & function fields added.
trial - a single determination of the merit value. Metavolv
obtains this by running the target program once or twice.
linear function - f(x, y, z, ....) = k + a*x + b*y + c*z + ......... In
this case f is the fitness, x, y, z.... are the parameters of the target
program, and a, b, c .... are the estimated components of the gradient vector.
gradient vector - for a function of several
variables, a vector that points in the direction of greatest rate of
change of the independent variable. This is at a particular point
in the space of the dependent variables.
method of least squares - minimize the sum of the
squares of the errors. The errors are the differences between a
set of given values and corresponding estimated values.
transformation - putting a variable through a function that changes its
characteristics. For example, if x is replaced by
z = x squared, then z will never be negative, like x could be, and z
will vary very slowly when near 0, and very rapidly when far from zero.
step - distance between successive trial points in
parameter space.
In two or three dimensions this is the familiar quantity,
distance. In higher dimensions it is the analogous quantity, the
Euclidean norm.
Driftwood :: Harnessing the Power of Many Computers for Simulated Evolution
Author: Mitchell Timin
Posted: 03/21/2004
Meet ANNEvolve's founder and leader
Author: Mitchell Timin
Posted: 02/16/2004
4-Play Procedure Analysis
Author: Mr. Emile Richard
Posted: 01/23/2004
Shakespeare, Darwin, and the Monkeys
Author: Mitchell Timin
Posted: 12/26/2003
How Simulated Evolution Works
Author: Mitchell Timin
Posted: 11/16/2003
Meet Annevolve's skydiving, mouseball collecting Unix Admin
Author: Eric Anderson
Posted: 11/14/2003
Species Learning and a Hypothesis About Brain Learning
Author: Mitchell Timin
Posted: 10/02/2003
When doing GA, expect a very large variance in the time required to accomplish a certain amount of evolution.
Author: Kent Pault Dolan
Posted: 09/09/2003
An Aspect of Natural Evolution
Author: Mitchell Timin
Posted: 08/31/2003
Genuine Artificial Intelligence :)
Author: Mitchell Timin
Posted: 08/27/2003
|