Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

miller.cc

Go to the documentation of this file.
00001 
00025 #include <magic/mclass.h>
00026 #include <inanna/annetwork.h>
00027 #include <inanna/initializer.h>
00028 #include <nhp/individual.h>
00029 #include "annalee/anngenes.h"
00030 #include "annalee/miller.h"
00031 
00032 impl_dynamic (MillerEncoding, {ANNEncoding});
00033 
00034 
00035 
00037 //                                                                          //
00038 //     |   | o | |           -----                      | o                 //
00039 //     |\ /|   | |  ___      |       _    ___           |     _             //
00040 //     | V | | | | /   ) |/\ |---  |/ \  |   \  __   ---| | |/ \   ___      //
00041 //     | | | | | | |---  |   |     |   | |     /  \ (   | | |   | (   \     //
00042 //     |   | | | |  \__  |   |____ |   |  \__/ \__/  ---| | |   |  ---/     //
00043 //                                                                 __/      //
00045 
00046 MillerEncoding::MillerEncoding (const GeneticID& name, const StringMap& params) : ANNEncoding (name, params) {
00047     mPruneInputs    = params["MillerEncoding.pruneInputs"].toInt ();
00048     mPcVariance     = params["MillerEncoding.pcVariance"].toDouble ();
00049     mPcAverage      = params["MillerEncoding.pcAverage"].toDouble ();
00050 }
00051 
00052 MillerEncoding::MillerEncoding (const MillerEncoding& other) : ANNEncoding (other) {
00053     mPruneInputs = other.mPruneInputs;
00054     mPcVariance = other.mPcVariance;
00055     mPcAverage = other.mPcAverage;
00056 }
00057 
00058 void MillerEncoding::copy (const Genstruct& o) {
00059     ANNEncoding::copy (o);
00060     const MillerEncoding& other = static_cast<const MillerEncoding&>(o);
00061     mPruneInputs = other.mPruneInputs;
00062     mPcVariance = other.mPcVariance;
00063     mPcAverage = other.mPcAverage;
00064 }
00065 
00066 void MillerEncoding::addPrivateGenes (Gentainer& g, const StringMap& params) {
00067     Gentainer::addPrivateGenes (g, params);
00068 
00069     // Create genes for the units
00070     int totalUnits = mInputs+mMaxHidden+mOutputs;
00071     for (int i=0; i<totalUnits-mOutputs; i++) {
00072 
00073         // Existance of a neuron. Not encoded for input units if input
00074         // pruning is not enabled, nor output units which always exist
00075         if (i>=mInputs || mPruneInputs)
00076             add (new BinaryGene (format ("E%d", i)));
00077         
00078         // Connect input units and hidden units to all successive neurons
00079         for (int j=i+1; j<totalUnits; j++)
00080                 add (&(new BinaryGene (format ("W%d-%d", i, j)))->hide());
00081     }
00082 }
00083 
00084 void MillerEncoding::init () {
00085     // Find random p_c (connection probability) for the genome
00086     double pc=0.5;
00087     do {
00088         pc = mPcAverage+gaussrnd(mPcVariance);
00089     } while (pc<0.0 || pc>1.0); // Not before it's in a range of a probability value
00090 
00091     // Change the pc of all binary genes we own
00092     for (int i=0; i<size(); i++)
00093         if (BinaryGene* gene = dynamic_cast<BinaryGene*> (&(*this)[i]))
00094             gene->setInitP(pc);
00095 
00096     // Let the superclass implement the initialization
00097     Gentainer::init ();
00098 }
00099 
00100 bool MillerEncoding::execute (const GeneticMsg& msg) const {
00101     // Take pictures only if this is a picture-taking recreation
00102     bool takePics = int(dynamic_cast<const TakeBrainPicsMsg*>(&msg));
00103 
00104     ANNetwork* net = new ANNetwork (format ("%d-%d-%d", mInputs, mMaxHidden, mOutputs));
00105     int totalUnits = mInputs+mMaxHidden+mOutputs;
00106     
00107     // Create and zero the connection matrix. Using this matrix is
00108     // useful mostly just for informative purposes (in logging)
00109     PackTable<int> cmatrix (totalUnits,totalUnits);
00110     for (int i=0; i<cmatrix.rows; i++)
00111         for (int j=0; j<cmatrix.rows; j++)
00112             cmatrix.get(i,j) = 0;
00113 
00114     // Go trough each input and hidden unit and check if it exists
00115     for (int i=0; i<totalUnits-mOutputs; i++) {
00116         if (i>=mInputs || mPruneInputs)
00117             // Enable or disable the unit from the network
00118             cmatrix.get(i,i) =
00119                 static_cast<const BinaryGene&> ((*this)[(CONSTR)format ("E%d", i)]).getvalue();
00120     }
00121 
00122 
00123     // Fill the connection matrix
00124     for (int i=0; i<totalUnits-mOutputs; i++)
00125         for (int j=i+1; j<totalUnits; j++)
00126             if (j>=mInputs)
00127                 if (static_cast<const BinaryGene&> (
00128                     (*this)[(CONSTR)format ("W%d-%d", i, j)]).getvalue())
00129                     cmatrix.get(i,j) = 1;
00130 
00131     // Calculate some statistics (probability of connection)
00132     int conns=0, totconns=0;
00133     for (int i=0; i<totalUnits-mOutputs; i++)
00134         for (int j=(i>=mInputs)?i+1:mInputs; j<totalUnits; j++) {
00135             totconns++;
00136             conns += cmatrix.get(i,j);
00137         }
00138     double pConn = double(conns) / double(totconns);
00139     msg.host.set ("pConn", new String (format ("%f", pConn)));
00140 
00141     // Enable outputs
00142     for (int i=totalUnits-mOutputs; i<totalUnits; i++)
00143         cmatrix.get(i,i) = 1;
00144     
00145     // Enable and connect according to the connection matrix (if both
00146     // source and target units exist and also the connection)
00147     for (int i=0; i<cmatrix.rows; i++) {
00148         (*net)[i].enable(cmatrix.get(i,i));
00149         if (cmatrix.get(i,i))
00150             for (int j=i+1; j<cmatrix.rows; j++)
00151                 if (cmatrix.get(j,j) && cmatrix.get(i,j))
00152                     net->connect (i,j);
00153     }
00154 
00155     //for (int i=totalUnits-mOutputs; i<totalUnits; i++)
00156     //  (*net)[i].setTFunc (FreeNeuron::LINEAR_TF);
00157 
00158     // "Print" network connectivity matrix
00159     String desc; // Printed connection matrix
00160     if (takePics) {
00161         desc.reserve(totalUnits*(totalUnits+1)+10);
00162         for (int i=0; i<cmatrix.rows; i++) {
00163             for (int j=0; j<cmatrix.cols; j++)
00164                 desc += cmatrix.get(i,j)? '1':'0';
00165             desc += '\n';
00166         }
00167     }
00168     
00169     if (net) {
00170         net->setInitializer (new GaussianInitializer (0.5));
00171 
00172         // Take some nice photos
00173         net->cleanup ();
00174         if (takePics)
00175             msg.host.set ("brainpic1", new String (net->drawEPS()));
00176         net->cleanup (true, mPrunePassthroughs);
00177         if (takePics) {
00178             msg.host.set ("brainpic2", new String (net->drawEPS()));
00179             net->drawFeedForward();
00180             msg.host.set ("brainpic3", new String (net->drawEPS()));
00181             msg.host.set ("braindesc1", new String (desc));
00182             delete net; // The net was created only for taking babypics
00183         } else {
00184             // Place the brain description into host
00185             msg.host.set ("brainplan", net);
00186         }
00187     }
00188 
00189     return true;
00190 }
00191 
00192 

Generated on Thu Feb 10 20:21:26 2005 for Annalee by doxygen1.2.18