latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiSOFM.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 12.8.2002 00030 * revisions ..: $Id: ltiSOFM.h,v 1.7 2006/02/07 18:23:49 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_S_O_F_M_H_ 00034 #define _LTI_S_O_F_M_H_ 00035 00036 //TODO: include only those files which are needed in this header!! 00037 00038 // TODO: Check this include to parent class: 00039 #include "ltiUnsupervisedClassifier.h" 00040 00041 namespace lti { 00042 /** 00043 * This is the base class for all Self Organizing Feature Maps. They 00044 * are modelled after Kohonen's book 'Self-Organizing Maps' 00045 * published by Springer in 1995. 00046 * <p> SOFMs have a two phase training: In the first phase the 00047 * ordering of the neurons is established. The neighborhood should 00048 * be rather large during this phase. In the second phase the 00049 * neurons are more finely tuned to the underlying probability 00050 * distributions with a small neighborhood. This phase is called 00051 * convergence phase. 00052 00053 * 00054 */ 00055 class SOFM : public unsupervisedClassifier { 00056 public: 00057 /** 00058 * the parameters for the class SOFM 00059 */ 00060 class parameters : public unsupervisedClassifier::parameters { 00061 00062 public: 00063 00064 /** 00065 * Possible types of initialization for the grid of neurons:<p> 00066 * <dl> 00067 * <dt>Random</dt> 00068 * <dd>Grid points are selected randomly from the data.</dd> 00069 * <dt>Linear</dt> 00070 * <dd>The mean as well as the two maximum eigenvalues and 00071 * corresponding eigenvectors of the data are calculted. Then 00072 * the neurons in the grid are uniformly spread over the 00073 * rectangle spanned by the eigenvectors and of the dimensions 00074 * of the eigenvalues. Like this the grid is already ordered and 00075 * neurons should be close to their final destination. Here, it 00076 * is useful to set the parameter calculateSize to true </dd> 00077 * </dl> 00078 */ 00079 enum eInit { 00080 Random = 1, /*!< choose initial values randomly from data */ 00081 Linear = 2 /*!< take max eigenvalues and mean and distribute points */ 00082 }; 00083 00084 /** 00085 * Different metrics can be used to determine the distance 00086 * between an input vector and each neuron. 00087 */ 00088 enum eMetric { 00089 L1 = 1, /*!< use L1 norm */ 00090 L2, /*!< use L2 norm */ 00091 Dot /*!< use dot product */ 00092 }; 00093 00094 /** 00095 * default constructor 00096 */ 00097 parameters(); 00098 00099 /** 00100 * copy constructor 00101 * @param other the parameters object to be copied 00102 */ 00103 parameters(const parameters& other); 00104 00105 /** 00106 * destructor 00107 */ 00108 virtual ~parameters(); 00109 00110 /** 00111 * returns name of this type 00112 */ 00113 const char* getTypeName() const; 00114 00115 /** 00116 * copy the contents of a parameters object 00117 * @param other the parameters object to be copied 00118 * @return a reference to this parameters object 00119 */ 00120 parameters& copy(const parameters& other); 00121 00122 /** 00123 * copy the contents of a parameters object 00124 * @param other the parameters object to be copied 00125 * @return a reference to this parameters object 00126 */ 00127 parameters& operator=(const parameters& other); 00128 00129 00130 /** 00131 * returns a pointer to a clone of the parameters 00132 */ 00133 virtual classifier::parameters* clone() const; 00134 00135 /** 00136 * write the parameters in the given ioHandler 00137 * @param handler the ioHandler to be used 00138 * @param complete if true (the default) the enclosing begin/end will 00139 * be also written, otherwise only the data block will be written. 00140 * @return true if write was successful 00141 */ 00142 virtual bool write(ioHandler& handler,const bool complete=true) const; 00143 00144 /** 00145 * read the parameters from the given ioHandler 00146 * @param handler the ioHandler to be used 00147 * @param complete if true (the default) the enclosing begin/end will 00148 * be also written, otherwise only the data block will be written. 00149 * @return true if write was successful 00150 */ 00151 virtual bool read(ioHandler& handler,const bool complete=true); 00152 00153 # ifdef _LTI_MSC_6 00154 /** 00155 * this function is required by MSVC only, as a workaround for a 00156 * very awful bug, which exists since MSVC V.4.0, and still by 00157 * V.6.0 with all bugfixes (so called "service packs") remains 00158 * there... This method is also public due to another bug, so please 00159 * NEVER EVER call this method directly: use read() instead 00160 */ 00161 bool readMS(ioHandler& handler,const bool complete=true); 00162 00163 /** 00164 * this function is required by MSVC only, as a workaround for a 00165 * very awful bug, which exists since MSVC V.4.0, and still by 00166 * V.6.0 with all bugfixes (so called "service packs") remains 00167 * there... This method is also public due to another bug, so please 00168 * NEVER EVER call this method directly: use write() instead 00169 */ 00170 bool writeMS(ioHandler& handler,const bool complete=true) const; 00171 # endif 00172 00173 // ------------------------------------------------ 00174 // the parameters 00175 // ------------------------------------------------ 00176 00177 //TODO: comment the parameters of your classifier 00178 // If you add more parameters manually, do not forget to do following: 00179 // 1. indicate in the default constructor the default values 00180 // 2. make sure that the copy member also copy your new parameters 00181 // 3. make sure that the read and write members also read and 00182 // write your parameters 00183 00184 00185 /** 00186 * type of initialization method used. See eInit. 00187 */ 00188 eInit initType; 00189 00190 /** 00191 * type of metric used. See eMetric. 00192 */ 00193 eMetric metricType; 00194 00195 /** 00196 * Number of epochs used for ordering in the training 00197 */ 00198 int stepsOrdering; 00199 00200 /** 00201 * Maximum value of learn-rate during ordering 00202 */ 00203 double orderLearnMax; 00204 00205 /** 00206 * Minimum value of learn-rate during ordering 00207 */ 00208 double orderLearnMin; 00209 00210 /** 00211 * Maximum distance to the winner neuron during ordering. The 00212 * unit is in grid steps. E.g. a value of 1 would include 00213 * (theoretically) the 8 neighbors, since a square window is 00214 * assumed. You can change this by setting orderNeighborThresh 00215 * to an appropriate value. 00216 */ 00217 double orderNeighborMax; 00218 00219 /** 00220 * Minimum distance to the winner neuron during ordering. The 00221 * neighborhood stays like this for the convergence phase. This 00222 * value should be rather low, typically 1. For values below 1 00223 * no neighborhood is created which will not work! 00224 */ 00225 double orderNeighborMin; 00226 00227 /** 00228 * The minimum value the neighborhood function assumes (cut-off 00229 * value). This should be rather low. Since a Gaussian kernel is 00230 * used this value steers the size of the kernel to be 00231 * used. I.e. the bigger the value, the faster the training and 00232 * the less precise. E.g. if for the current neighborhood size 00233 * the Gaussian value is smaller than the threshold for the roof 00234 * of the neighborhood value, the kernel size will be lower than 00235 * the roof of the neighborhood size. 00236 */ 00237 double orderNeighborThresh; 00238 00239 00240 00241 /** 00242 * Number of epochs used for convergence in the training 00243 */ 00244 int stepsConvergence; 00245 00246 /** 00247 * Maximum value of learn-rate during convergence 00248 */ 00249 double convergenceLearnMax; 00250 00251 /** 00252 * Minimum value of learn-rate during convergence 00253 */ 00254 double convergenceLearnMin; 00255 00256 00257 }; 00258 00259 /** 00260 * default constructor 00261 */ 00262 SOFM(); 00263 00264 /** 00265 * copy constructor 00266 * @param other the object to be copied 00267 */ 00268 SOFM(const SOFM& other); 00269 00270 /** 00271 * destructor 00272 */ 00273 virtual ~SOFM(); 00274 00275 /** 00276 * returns the name of this type ("SOFM") 00277 */ 00278 virtual const char* getTypeName() const; 00279 00280 /** 00281 * copy data of "other" classifier. 00282 * @param other the classifier to be copied 00283 * @return a reference to this classifier object 00284 */ 00285 SOFM& copy(const SOFM& other); 00286 00287 /** 00288 * alias for copy member 00289 * @param other the classifier to be copied 00290 * @return a reference to this classifier object 00291 */ 00292 SOFM& operator=(const SOFM& other); 00293 00294 /** 00295 * returns a pointer to a clone of this classifier. 00296 */ 00297 virtual classifier* clone() const=0; 00298 00299 /** 00300 * returns used parameters 00301 */ 00302 const parameters& getParameters() const; 00303 00304 /** 00305 * Unsupervised training. The vectors in the <code>input</code> 00306 * matrix will be put into groups according to the training 00307 * algorithm. Additionally, an integer indicating the class each 00308 * point belongs to is returned. 00309 * 00310 * By default this method uses the other train method train(const dmatrix&) 00311 * and then calls classify(const dvector&) to get the ids for each 00312 * trainvector. These ids are then returned. 00313 * 00314 * @param input the matrix with the input vectors (each row is a training 00315 * vector) 00316 * @param ids vector of class ids for each input point 00317 * @return true if successful, false otherwise. (if false you can check 00318 * the error message with getStatusString()) 00319 */ 00320 virtual bool train(const dmatrix& input, 00321 ivector& ids); 00322 00323 /** 00324 * Unsupervised training. 00325 * The row vectors in the <code>input</code> matrix 00326 * are used for training of the classifier. 00327 * @param input the matrix with the input vectors (each row is a training 00328 * vector) 00329 * @return true if successful, false otherwise. (if false you can check 00330 * the error message with getStatusString()) 00331 */ 00332 virtual bool train(const dmatrix& input)=0; 00333 00334 //TODO Check whether you really need a new classify method. 00335 // In some cases the superclasses method will suffice. Then just 00336 // delete the declaration and its implementation stump. 00337 00338 /** 00339 * Classification. 00340 * Classifies the feature and returns the outputVector with 00341 * the classification result. 00342 * @param feature the %vector to be classified 00343 * @param result the result of the classification 00344 * @return false if an error occurred during classification else true 00345 */ 00346 virtual bool 00347 classify(const dvector& feature, outputVector& result) const=0; 00348 00349 /** 00350 * write the SOFM in the given ioHandler 00351 * @param handler the ioHandler to be used 00352 * @param complete if true (the default) the enclosing begin/end will 00353 * be also written, otherwise only the data block will be written. 00354 * @return true if write was successful 00355 */ 00356 virtual bool write(ioHandler& handler,const bool complete=true) const; 00357 00358 /** 00359 * read the SOFM from the given ioHandler 00360 * @param handler the ioHandler to be used 00361 * @param complete if true (the default) the enclosing begin/end will 00362 * be also written, otherwise only the data block will be written. 00363 * @return true if write was successful 00364 */ 00365 virtual bool read(ioHandler& handler,const bool complete=true); 00366 00367 /** 00368 * returns the prototypes of the SOFM. Each row of the matrix 00369 * contains one prototype. Depending on the dimensionality these 00370 * are ordered in dimensions. For two dimensions it is Y,X giving 00371 * first the prototype at (0,0) than at (0,1) and so on. In three 00372 * dimensions Z has the highest order (Z,Y,X): 00373 * (0,0,0),(0,0,1),...,(0,0,n),(0,1,0),... 00374 */ 00375 inline const dmatrix& getPrototypes() const {return grid;}; 00376 00377 protected: 00378 00379 /** weights for each neuron in the grid */ 00380 dmatrix grid; 00381 00382 /** learn-rate for first phase */ 00383 double lrOrder; 00384 /** learn-rate delta for first phase */ 00385 double lrOrderDelta; 00386 /** current sigma for neighborhood */ 00387 double sigma; 00388 /** delta for sigma */ 00389 double sigmaDelta; 00390 /** parameter A for lr = A / (t+B) during convergence */ 00391 double lrConvergeA; 00392 /** parameter B for lr = A / (t+B) during convergence */ 00393 double lrConvergeB; 00394 00395 00396 /** calculate learn-rates and deltas from the parameters. */ 00397 virtual bool setLearnRates(const int& nbData); 00398 00399 }; 00400 } 00401 00402 #endif