$Id: NEURON_GA.dol,v 1.14 2007/12/05 06:18:46 samn Exp $
SA Neymotin , WW Lytton - 3/2007
* What are genetic algorithms?
An introduction to genetic algorithms can be found at :
http://en.wikipedia.org/wiki/Genetic_algorithm
* NEURON interface to GAUL - Genetic Algorithms Utility Library
GAUL is available at : http://gaul.sourceforge.net/
This interface allows the use of genetic algorithms for optimization
and search in high-dimensional spaces from within the NEURON
environment. It includes converted .c,.h files from GAUL wrapped in
proper MOD file syntax as well as MOD code interfacing to the
library. It also comes with hoc utilitiy functions to make it easier
to use the GA.
** Compilation
Compilation was done on a Linux system. It has not been tested on
Windows.
The mod files should be placed in the NEURON project directory and
built with the command
nrnivmodl -loadflags "-pthread -lpthread"
This means you need to have the pthreads library installed on your
machine. Most standard Linux boxes will have pthreads. For more info
on pthreads look here : http://en.wikipedia.org/wiki/POSIX_Threads .
The files in the gaul subdirectory are the .h header files used for
compilation of the MOD files. These should be placed in a subdirectory
of the NEURON project, so that the mod files can access them properly
at compile-time.
ga_hoc.mod has the main interface between NEURON and GAUL.
ga_utils.hoc has the hoc utility functions that make it easier to use.
ga_test.hoc has a simple demonstration showing how to setup and use
the GA. The GA will then solve a polynomial. This should be loaded
with load_file("mosinit.hoc")
The Neural Query System (1) and associated mod and hoc files was also
included because of certain dependencies on it's functionality.
** Usage
The main steps for usage are:
0) Set verbose_GA = 0 unless you want to get lots and lots of
information from the GA printed out during evolution.
1) At the top of your hoc file call install_ga_methods_GA() to install
the mod functions needed by the GA
2) Create a fitness function in hoc : this function will be called by
the genetic algorithm to evaluate members of the population. The
function should be called GetFitness. The following steps must occur
in the fitness function:
a) vparams.get_alleles() //get param/allele values from GA
This will get the population member's properties from the GA and load
them into the Vector vparams
b) The fitness evaluation will take place - this is the custom
part. you should write code that will use the parameters in vparams to
evaluate how 'good' the population member is. The higher the value,
the better the member (and solution), and the more likely it is to
have kids, etc.
c) The function should call the function SetFitness, defined in
ga_hoc.mod, passing it the computed fitness value,
i.e. SetFitness_GA(value_just_computed_in_b)
Here is a sample fitness function:
func GetFitness(){ local fitness
vparams.get_alleles() //get param/allele values from GA
fitness = vparams.sum() //stupid - but works for demo
SetFitness(fitness)
return fitness
}
Other possibilities for a fitness function include running a
simulation on a model file to optimize it's parameters.
3) The following hoc variables must be set:
NumIslands : number of islands that members of population live on - explained
in the GAUL documentation in the link mentioned above
Mutate : mutation rate
Crossover : crossover rate
Migrate : migration rate
PopSize : population size (each island will have this many 'citizens')
MaxGen : maximum generation to run the GA
NumParams : number of variables each population member has to optimize
Elitism : elitism option mentioned in GAUL docs
MinFitness : minimum fitness a 'citizen' can have
4) Set the mininimum and maximum value of each param in the vectors
vallele_mins and vallele_maxs. These vectors must have the same
size as NumParams and each location will specify the min,max value
of the given param. For example, if param0 should be between 0 and
10, you'd do vallele_mins.x(0)=0 vallele_maxs.x(0)=10 . The same
thing should be done for all the params.
5) There are other variables and functions in the file ga_utils.hoc
that must be defined. Don't get rid of them if you want to use the
hoc utility functions. Some of these include:
vparams - stores the parameters passed back and forth between hoc
and the GA
vfitnessbest - Vector for each island containing best fitness of
each generation
vfitnessavg - Vector for each island containing average fitness
of each generation
vfitnessstddev - Vector for each island containing standard
deviation of each generation
UpdateGenStats - updates stats for each generation
6) Plotting/param options in hoc variables:
plot_fitness : whether to plot fitness as a function of
time/generation
save_params : save ga params for a run
7) Another option allows scaling of allele values to be between 0 and
1 for use by GA. When evaluation of the fitness function in NEURON
is called, the value for each parameter/allele, is descaled back to
vallele_mins[i]+(vallele_maxs[i]-vallele_min[i])*value_0_1[i],
where value_0_1 is the scaled value of the parameter between 0 and
1. This option may be useful for allowing "uniform" drift of all
alleles during mutations. This is set with SetAlleleScale_GA(1).
The default is off.
8) By default, GAUL will randomly initialize each population member's
parameters when they are created. There is also an option that
enables a user-defined population member initialization
function. This is by calling
SetHocSeedFunc_GA("FunctionName"). The specified function MUST
call the Vector method v2data (defined in ga_hoc.mod) at the
end. This will copy parameter values to internal variables in the
GA before returning. If this is not done, garbage will be used to
initialize the new entity. The function should also return 1 to
indicate success. Here is an example:
func SetSeed(){ local idx localobj vseed,rdm
rdm=new Random()
vseed = new Vector(NumParams)
for idx=0,NumParams-1 vseed.x(idx)=rdm.uniform(0,1)
vseed.v2data()
return 1.0
}
9) You can set the initial random seed used by GAUL by calling
SetRandSeed_GA(seed_value) and get the random seed value with
GetRandSeed_GA() . This will allow you to re-produce the results
of an evolution/optimization.
10) Call SetStatFile_GA to set the file path for statistics to be
written to during run. If no path is specified, no stats will be
written.
11) There are some other commented functions in ga_hoc.mod which may
be of use. For example, GAPrintSettings_GA() will print the
current settings used by the GA.
12) Final step: Call the hoc function Evolution()
13) Watch the evolution. There will be many printouts if
verbose_GA=1. If not, you will get an update each generation. If
the run takes too long you can abort and look at the results with
the BestIsland() hoc function. This will print the best fitness
and parameters found.
* If you have questions, comments, or want to help improve this
interface:
Email: Sam Neymotin - samn at neurosim dot downstate dot edu
* References:
(1) Lytton WW, Neural Query System: Data-mining from within the NEURON simulator.
Neuroinformatics, 2006 Springer
|