00001 /*************************************************************************** 00002 * Copyright (C) 2005 by Robot Group Leipzig * 00003 * martius@informatik.uni-leipzig.de * 00004 * fhesse@informatik.uni-leipzig.de * 00005 * der@informatik.uni-leipzig.de * 00006 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program; if not, write to the * 00019 * Free Software Foundation, Inc., * 00020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00021 *************************************************************************** 00022 * * 00023 * DESCRIPTION * 00024 * 00025 * Self-Organised Map implementation * 00026 * 00027 * $Log: som.h,v $ 00028 * Revision 1.5 2008/04/17 14:54:45 martius 00029 * randomGen added, which is a random generator with long period and an 00030 * internal state. Each Agent has an instance and passed it to the controller 00031 * and the wiring. This is good for 00032 * a) repeatability on agent basis, 00033 * b) parallel execution as done in ode_robots 00034 * 00035 * Revision 1.4 2007/08/24 12:07:12 martius 00036 * learn optimised, because it does not return output anymore 00037 * 00038 * Revision 1.3 2007/08/01 08:28:16 martius 00039 * Id tag added 00040 * 00041 * Revision 1.2 2007/06/08 15:47:57 martius 00042 * Som tested and with RBF and store and reload 00043 * 00044 * Revision 1.1 2007/05/22 16:01:24 martius 00045 * not yet working 00046 * 00047 * 00048 * * 00049 ***************************************************************************/ 00050 #ifndef __SOM_H 00051 #define __SOM_H 00052 00053 #include "abstractmodel.h" 00054 #include "controller_misc.h" 00055 00056 #include <vector> 00057 00058 /** self-organised map class. Implementation follows normal vector-quantiser 00059 scheme. 00060 The output of the network is \f$exp(- |x-w_i|^2/rdfsize)\f$ for each neuron. 00061 */ 00062 class SOM : public AbstractModel { 00063 public: 00064 typedef std::list< std::pair<int,double> > Neighbours; 00065 typedef std::vector<std::pair<matrix::Matrix,double> > Neighbourhood; 00066 00067 SOM(); 00068 /** create a som 00069 @param dimensions number of dimensions of the neuron lattice 00070 */ 00071 SOM(unsigned int dimensions, double sigma, double eps, double rbfsize, 00072 const std::string& name="SOM", 00073 const std::string& revision = "$Id: som.h,v 1.5 2008/04/17 14:54:45 martius Exp $"); 00074 virtual ~SOM(){}; 00075 00076 /** initialised som 00077 @param inputDim dimension of input vector 00078 @param outputDim number of outputneurons (must be a multiple of "dimensions" given at constructor) 00079 @param unit_map if zero then weights are randomly choosed, otherwise 00080 uniformly distributed in the inputspace of size (unit_map x unit_map x ...) 00081 */ 00082 virtual void init(unsigned int inputDim, unsigned int outputDim, 00083 double unit_map = 0.0, RandGen* randGen = 0); 00084 00085 virtual const matrix::Matrix process (const matrix::Matrix& input); 00086 00087 /* performs training. Nominal output is ignored. 00088 A zero-Matrix is returned. 00089 learnRateFactor can be given to modify eps for this learning step 00090 (process should be called before) 00091 */ 00092 virtual const matrix::Matrix learn (const matrix::Matrix& input, 00093 const matrix::Matrix& nom_output, 00094 double learnRateFactor = 1); 00095 00096 virtual void damp(double damping) { return;} 00097 00098 virtual unsigned int getInputDim() const { return weights[0].getM();} 00099 virtual unsigned int getOutputDim() const { return weights.size();} 00100 00101 00102 virtual bool store(FILE* f) const; 00103 virtual bool restore(FILE* f); 00104 00105 virtual void printWeights(FILE* f) const; 00106 00107 const Neighbourhood& getNeighbourhood(){return neighbourhood;} 00108 00109 protected: 00110 00111 /// activation function (rbf) 00112 static double activationfunction(void* rdfsize, double d); 00113 00114 /// checks whether the given coordinate is within the lattice 00115 static bool validCoord(const matrix::Matrix& m, int size); 00116 /// converts index to coordinates (size is the size of the space) 00117 static int coordToIndex(const matrix::Matrix& m, int size); 00118 /// converts coordinates to index (size is the size of the space) 00119 static matrix::Matrix indexToCoord(int index, int size, int dimensions); 00120 00121 00122 /// initialised neighbourhood 00123 void initNeighbourhood(double sigma); 00124 00125 /** returns neighbourhood as a list of indices with weights 00126 */ 00127 Neighbours getNeighbours(int winner); 00128 00129 00130 public: 00131 double eps; ///< learning rate for weight update 00132 private: 00133 00134 std::vector<matrix::Matrix> weights; 00135 std::vector<matrix::Matrix> diffvectors; ///< temporary difference vectors 00136 matrix::Matrix distances; ///< vector of distances 00137 int dimensions; ///< number of dimensions of lattice 00138 double sigma; ///< neighbourhood size 00139 double rbfsize; ///< size of rbf function 00140 int size; ///< size of the lattice in each dimension 00141 00142 00143 /// list of vectors defining relative neighbourhood coordinates and weights 00144 Neighbourhood neighbourhood; 00145 00146 00147 bool initialised; 00148 }; 00149 00150 00151 #endif