Population.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 * Verve                                                                 *
00003 * Copyright (C) 2004-2006                                               *
00004 * Tyler Streeter  tylerstreeter@gmail.com                               *
00005 * All rights reserved.                                                  *
00006 * Web: http://verve-agents.sourceforge.net                              *
00007 *                                                                       *
00008 * This library is free software; you can redistribute it and/or         *
00009 * modify it under the terms of EITHER:                                  *
00010 *   (1) The GNU Lesser General Public License as published by the Free  *
00011 *       Software Foundation; either version 2.1 of the License, or (at  *
00012 *       your option) any later version. The text of the GNU Lesser      *
00013 *       General Public License is included with this library in the     *
00014 *       file license-LGPL.txt.                                          *
00015 *   (2) The BSD-style license that is included with this library in     *
00016 *       the file license-BSD.txt.                                       *
00017 *                                                                       *
00018 * This library is distributed in the hope that it will be useful,       *
00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00021 * license-LGPL.txt and license-BSD.txt for more details.                *
00022 ************************************************************************/
00023 
00024 #include "Population.h"
00025 #include "Connection.h"
00026 #include "Neuron.h"
00027 #include "TDProjection.h"
00028 
00029 namespace verve
00030 {
00031         Population::Population()
00032         {
00033         }
00034 
00035         Population::~Population()
00036         {
00037                 clear();
00038         }
00039 
00040         void Population::init(unsigned int numNeurons)
00041         {
00042                 clear();
00043 
00044                 // Allocate room for the new Neurons.  This should run a lot 
00045                 // faster than allocating them one at a time.
00046                 mNeurons.reserve(numNeurons);
00047 
00048                 for (unsigned int i = 0; i < numNeurons; ++i)
00049                 {
00050                         createNeuron(i);
00051                 }
00052         }
00053 
00054         void Population::clear()
00055         {
00056                 while (!mNeurons.empty())
00057                 {
00058                         delete mNeurons.back();
00059                         mNeurons.pop_back();
00060                 }
00061 
00062                 // Destroy output Projections.  This will also destroy the 
00063                 // Connections contained within them.
00064                 while (!mOutputProjections.empty())
00065                 {
00066                         delete mOutputProjections.back();
00067                         mOutputProjections.pop_back();
00068                 }
00069 
00070                 // Do this to change the allocated size to zero.
00071                 mNeurons.clear();
00072         }
00073 
00074         void Population::resetShortTermMemory()
00075         {
00076                 unsigned int size = (unsigned int)mNeurons.size();
00077                 for (unsigned int i = 0; i < size; ++i)
00078                 {
00079                         mNeurons[i]->resetShortTermMemory();
00080                 }
00081 
00082                 size = (unsigned int)mOutputProjections.size();
00083                 for (unsigned int i = 0; i < size; ++i)
00084                 {
00085                         mOutputProjections[i]->resetShortTermMemory();
00086                 }
00087         }
00088 
00089         void Population::project(Population* pop, 
00090                 InitialWeightMethod initWeightMethod, real maxInputPopActivationSum)
00091         {
00092                 Projection* proj = new Projection();
00093                 proj->init(this, pop, initWeightMethod, maxInputPopActivationSum);
00094                 mOutputProjections.push_back(proj);
00095         }
00096 
00097         void Population::projectTD(Population* pop, TDConnectionType type, 
00098                 InitialWeightMethod initWeightMethod, real maxInputPopActivationSum)
00099         {
00100                 TDProjection* proj = new TDProjection(type);
00101                 proj->init(this, pop, initWeightMethod, maxInputPopActivationSum);
00102                 mOutputProjections.push_back(proj);
00103         }
00104 
00105         void Population::updateFiringRatesLinear()
00106         {
00107                 unsigned int size = (unsigned int)mNeurons.size();
00108                 for (unsigned int i = 0; i < size; ++i)
00109                 {
00110                         mNeurons[i]->updateFiringRateLinear();
00111                 }
00112         }
00113 
00114         void Population::updateFiringRatesLinearBoundedNegOneToOne()
00115         {
00116                 unsigned int size = (unsigned int)mNeurons.size();
00117                 for (unsigned int i = 0; i < size; ++i)
00118                 {
00119                         mNeurons[i]->updateFiringRateLinearBoundedNegOneToOne();
00120                 }
00121         }
00122 
00123         void Population::updateFiringRatesLinearBoundedZeroToOne()
00124         {
00125                 unsigned int size = (unsigned int)mNeurons.size();
00126                 for (unsigned int i = 0; i < size; ++i)
00127                 {
00128                         mNeurons[i]->updateFiringRateLinearBoundedZeroToOne();
00129                 }
00130         }
00131 
00132         void Population::updateFiringRatesSigmoid()
00133         {
00134                 unsigned int size = (unsigned int)mNeurons.size();
00135                 for (unsigned int i = 0; i < size; ++i)
00136                 {
00137                         mNeurons[i]->updateFiringRateSigmoid();
00138                 }
00139         }
00140 
00141         real Population::trainPreDeltaRuleLinear(const real* actualOutputs, 
00142                 real learningFactor)
00143         {
00144                 // Here we use the delta rule (for a perceptron, not a multilayer 
00145                 // neural network) to train the presynaptic input Connection 
00146                 // weights.  The general form of the weight update rule is: 
00147                 // 
00148                 // dw = n * (d - post) * g'(h) * pre
00149                 // 
00150                 // ...where dw is weight change, n is learning rate, d is the 
00151                 // desired postsynaptic firing rate, post is the actual 
00152                 // postsynaptic firing rate, g' is the first derivative of the 
00153                 // postsynaptic neuron's activation function, h is the postsynaptic 
00154                 // neuron's weighted input sum, and pre is the actual presynaptic 
00155                 // firing rate (assumed to be >= zero).
00156                 // 
00157                 // For linear (y = x) activation functions (whose first derivative 
00158                 // is 1), the weight update rule is: 
00159                 // 
00160                 // dw = n * (d - post) * pre
00161 
00162                 real mse = 0;
00163 
00164                 unsigned int numNeurons = getNumNeurons();
00165                 for (unsigned int n = 0; n < numNeurons; ++n)
00166                 {
00167                         Neuron* neuron = mNeurons[n];
00168                         real error = actualOutputs[n] - neuron->getFiringRate();
00169                         mse += (error * error);
00170 
00171                         unsigned int numInputs = neuron->getNumDendrites();
00172                         for (unsigned int i = 0; i < numInputs; ++i)
00173                         {
00174                                 Connection* c = neuron->getDendrite(i);
00175                                 c->addToWeight(learningFactor * error * 
00176                                         c->getPreNeuron()->getFiringRate());
00177                         }
00178                 }
00179 
00180                 if (numNeurons > 1)
00181                 {
00182                         mse /= numNeurons;
00183                 }
00184 
00185                 return mse;
00186         }
00187 
00188         unsigned int Population::getNumNeurons()const
00189         {
00190                 return (unsigned int)mNeurons.size();
00191         }
00192 
00193         Neuron* Population::getNeuron(unsigned int i)
00194         {
00195                 return mNeurons.at(i);
00196         }
00197 
00198         void Population::normalizeInputWeights()
00199         {
00200                 unsigned int size = (unsigned int)mNeurons.size();
00201                 for (unsigned int i = 0; i < size; ++i)
00202                 {
00203                         mNeurons[i]->normalizeInputWeights();
00204                 }
00205         }
00206 
00207         void Population::setPostETraceDecayFactors(real value)
00208         {
00209                 unsigned int size = (unsigned int)mOutputProjections.size();
00210                 for (unsigned int i = 0; i < size; ++i)
00211                 {
00212                         static_cast<TDProjection*>(mOutputProjections[i])->
00213                                 setETraceDecayFactor(value);
00214                 }
00215         }
00216 
00217         void Population::setPostTDDiscountFactors(real value)
00218         {
00219                 unsigned int size = (unsigned int)mOutputProjections.size();
00220                 for (unsigned int i = 0; i < size; ++i)
00221                 {
00222                         static_cast<TDProjection*>(mOutputProjections[i])->
00223                                 setTDDiscountFactor(value);
00224                 }
00225         }
00226 
00227         void Population::createNeuron(unsigned int id)
00228         {
00229                 Neuron* neuron = new Neuron(id);
00230                 mNeurons.push_back(neuron);
00231         }
00232 
00233         //Neuron* Population::findNeuronByID(unsigned int id)
00234         //{
00235         //      std::vector<Neuron*>::iterator iter;
00236         //      for (iter = mAllNeurons.begin(); iter != mAllNeurons.end(); ++iter)
00237         //      {
00238         //              if ((*iter)->getID() == id)
00239         //              {
00240         //                      return (*iter);
00241         //              }
00242         //      }
00243 
00244         //      return NULL;
00245         //}
00246 }

Generated on Tue Jan 24 21:46:37 2006 for Verve by  doxygen 1.4.6-NO