latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2000, 2001, 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 Digital Image/Signal Processing Library 00026 * file .......: ltiRbf.h 00027 * authors ....: Peter Doerfler, Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 11.8.2000 00030 * revisions ..: $Id: ltiRbf.h,v 1.8 2006/02/07 18:22:56 ltilib Exp $ 00031 */ 00032 00033 00034 #ifndef _LTI_RBF_H_ 00035 #define _LTI_RBF_H_ 00036 00037 #include "ltiObject.h" 00038 #include "ltiVector.h" 00039 #include "ltiMatrix.h" 00040 #include "ltiStdLayer.h" 00041 #include "ltiClassifier.h" 00042 #include "ltiSupervisedInstanceClassifier.h" 00043 #include "ltiLvq.h" 00044 00045 namespace lti { 00046 00047 /** 00048 * class which implements RBF networks. 00049 */ 00050 class rbf : public supervisedInstanceClassifier { 00051 public: 00052 00053 // ---------------------------------------------------- 00054 // rbf::parameters 00055 // ---------------------------------------------------- 00056 00057 /** 00058 * parameters class for the RBF-Networks 00059 */ 00060 class parameters: public supervisedInstanceClassifier::parameters { 00061 00062 public: 00063 /** 00064 * type to specify the kind of initialization for the networks 00065 */ 00066 enum eLvqInit { 00067 LvqRand, /*!< random initialization of the vector code */ 00068 LvqMaxDist /*!< initialization with the maximum distance */ 00069 }; 00070 00071 /** 00072 * The LVQ training algorithm 00073 */ 00074 enum eLvqTrainType { 00075 NO_LVQ=-1, /*!< do not use LVQ */ 00076 LVQ1, /*!< use LVQ1 */ 00077 OLVQ1, /*!< use OLVQ1 */ 00078 LVQ3, /*!< use LVQ3 */ 00079 OLVQ3, /*!< use OLVQ3 */ 00080 LVQ4 /*!< use LVQ4 */ 00081 }; 00082 00083 /** 00084 * default constructor 00085 */ 00086 parameters(); 00087 00088 /** 00089 * copy constructor 00090 * @param other the parameters object to be copied 00091 */ 00092 parameters(const parameters& other); 00093 00094 /** 00095 * destructor 00096 */ 00097 virtual ~parameters(); 00098 00099 /** 00100 * returns name of this type 00101 */ 00102 const char* getTypeName() const; 00103 00104 /** 00105 * copy the contents of a parameters object 00106 * @param other the parameters object to be copied 00107 * @return a reference to this parameters object 00108 */ 00109 parameters& copy(const parameters& other); 00110 00111 /** 00112 * Alias for "copy". 00113 * @param other the parameters object to be copied 00114 * @return a reference to this parameters object 00115 */ 00116 inline parameters& operator=(const parameters& other) { 00117 return copy(other); 00118 } 00119 00120 /** 00121 * returns a pointer to a clone of the parameters 00122 */ 00123 virtual classifier::parameters* clone() const; 00124 00125 /** 00126 * write the parameters in the given ioHandler 00127 * @param handler the ioHandler to be used 00128 * @param complete if true (the default) the enclosing begin/end will 00129 * be also written, otherwise only the data block will be written. 00130 * @return true if write was successful 00131 */ 00132 virtual bool write(ioHandler& handler,const bool complete=true) const; 00133 00134 /** 00135 * read the parameters from the given ioHandler 00136 * @param handler the ioHandler to be used 00137 * @param complete if true (the default) the enclosing begin/end will 00138 * be also written, otherwise only the data block will be written. 00139 * @return true if write was successful 00140 */ 00141 virtual bool read(ioHandler& handler,const bool complete=true); 00142 00143 # ifdef _LTI_MSC_6 00144 /** 00145 * this function is required by MSVC only, as a workaround for a 00146 * very awful bug, which exists since MSVC V.4.0, and still by 00147 * V.6.0 with all bugfixes (so called "service packs") remains 00148 * there... This method is also public due to another bug, so please 00149 * NEVER EVER call this method directly: use read() instead 00150 */ 00151 bool readMS(ioHandler& handler,const bool complete=true); 00152 00153 /** 00154 * this function is required by MSVC only, as a workaround for a 00155 * very awful bug, which exists since MSVC V.4.0, and still by 00156 * V.6.0 with all bugfixes (so called "service packs") remains 00157 * there... This method is also public due to another bug, so please 00158 * NEVER EVER call this method directly: use write() instead 00159 */ 00160 bool writeMS(ioHandler& handler,const bool complete=true) const; 00161 # endif 00162 00163 // -------------- 00164 // the parameters 00165 // -------------- 00166 00167 /** 00168 * @name classifier parameters 00169 */ 00170 //@{ 00171 00172 /** 00173 * trainNewNet 00174 * 00175 * Default value: false 00176 */ 00177 // bool trainNewNet; 00178 00179 /** 00180 * convertNet 00181 * 00182 * Default value: false 00183 */ 00184 // bool convertNet; 00185 00186 /** 00187 * doTrain2 00188 * 00189 * Default value: false 00190 */ 00191 bool doTrain2; 00192 00193 /** 00194 * loadNet 00195 * 00196 * Default value: true 00197 */ 00198 // bool loadNet; 00199 00200 /** 00201 * generate statistics? 00202 * 00203 * Default value: false 00204 */ 00205 // bool doStatistics; 00206 00207 /** 00208 * Save/Load in binary mode 00209 * 00210 * Default value: true 00211 */ 00212 // bool binary; 00213 00214 /** 00215 * Save/Load in ASCII mode 00216 * 00217 * Default value: false 00218 */ 00219 // bool ascii; 00220 00221 /** 00222 * convert binary file to ascii file 00223 * 00224 * Default value: true 00225 */ 00226 // bool convertBinToAscii; 00227 00228 /** 00229 * noObjectProbs 00230 * 00231 * Default value: false 00232 */ 00233 // bool noObjectProbs; 00234 00235 /** 00236 * classifyStat 00237 * 00238 * Default value: true 00239 */ 00240 // bool classifyStat; 00241 00242 /** 00243 * mseStat 00244 * 00245 * Default value: false 00246 */ 00247 // bool mseStat; 00248 00249 /** 00250 * mseSave 00251 * 00252 * Default value: false 00253 */ 00254 // bool mseSave; 00255 00256 /** 00257 * firstBestSave 00258 * 00259 * Default value: false 00260 */ 00261 // bool firstBestSave; 00262 00263 /** 00264 * threeBestSave 00265 * 00266 * Default value: true 00267 */ 00268 // bool threeBestSave; 00269 00270 /** 00271 * include the training set in the pattern set for the training 00272 * statistics 00273 * 00274 * Default value: false 00275 */ 00276 // bool alsoTrain; 00277 00278 /** 00279 * nbPresentations1 00280 * 00281 * Default value: 0 00282 */ 00283 int nbPresentations1; 00284 00285 /** 00286 * nbPresentations2 00287 * 00288 * Default value: 20 00289 */ 00290 int nbPresentations2; 00291 00292 /** 00293 * nbHiddenNeurons 00294 * 00295 * Default value: 1 00296 */ 00297 int nbHiddenNeurons; 00298 00299 /** 00300 * learnRate1 00301 * 00302 * Default value: 0.3 00303 */ 00304 double learnRate1; 00305 00306 /** 00307 * learnRate2 00308 * 00309 * Default value: 0.1 00310 */ 00311 double learnRate2; 00312 00313 /** 00314 * learnFactor 00315 * 00316 * Default value: 0.3 00317 */ 00318 double learnFactor; 00319 00320 /** 00321 * windowSize 00322 * 00323 * Default value: 0.2 00324 */ 00325 double windowSize; 00326 00327 /** 00328 * sigma 00329 * 00330 * Default value: 0.0 00331 */ 00332 double sigma; 00333 00334 /** 00335 * sigmaFactor 00336 * 00337 * Default value: 1.6 00338 */ 00339 double sigmaFactor; 00340 00341 /** 00342 * lambda 00343 * 00344 * Default value: 0.0 00345 */ 00346 double lambda; 00347 00348 /** 00349 * this factor determines the value of the sigmoid function that 00350 * will be used as threshold for a correct classification. 00351 * 00352 * Default value: 0.99 00353 */ 00354 double high; 00355 00356 /** 00357 * norm 00358 * 00359 * Default value: L2distance 00360 */ 00361 eNormType norm; 00362 00363 /** 00364 * lvqInitType 00365 * 00366 * Default value: rbf::parameters::LvqMaxDist 00367 */ 00368 eLvqInit lvqInitType; 00369 00370 /** 00371 * specify the type for the first LVQ training 00372 * (usually LVQ1 or OLVQ1) 00373 * 00374 * Default value: OLVQ1 00375 */ 00376 eLvqTrainType lvqType1; 00377 00378 /** 00379 * specify the type for the second LVQ training 00380 * (usually LVQ3 or OLVQ3) 00381 * 00382 * Default value: OLVQ3 00383 */ 00384 eLvqTrainType lvqType2; 00385 00386 /** 00387 * netTrainFile 00388 * 00389 * Default value: "" 00390 */ 00391 // std::string netTrainFile; 00392 00393 /** 00394 * netTrainFile2 00395 * 00396 * Default value: "" 00397 */ 00398 // std::string netTrainFile2; 00399 00400 /** 00401 * netTestFile 00402 * 00403 * Default value: "" 00404 */ 00405 // std::string netTestFile; 00406 00407 /** 00408 * statisticsFile 00409 * 00410 * Default value: "" 00411 */ 00412 // std::string statisticsFile; 00413 00414 /** 00415 * netFilename 00416 * 00417 * Default value: "net.rbf" 00418 */ 00419 // std::string netFilename; 00420 00421 /** 00422 * netFilename2 00423 * 00424 * Default value: "" 00425 */ 00426 // std::string netFilename2; 00427 //@} 00428 }; 00429 00430 // ---------------------------------------------------- 00431 // rbf::initFunctors 00432 // ---------------------------------------------------- 00433 00434 /** 00435 * initialization functor for rbf 00436 */ 00437 class initFunctor1 : public stdLayer::initFunctor { 00438 public: 00439 /** 00440 * default constructor 00441 * @param theFeatures the matrix with the training patterns (each row 00442 * a pattern) 00443 * @param theTrainIDs the numerical ids for each pattern in theFeatures 00444 * @param theNbViewsObj the number of patterns per class 00445 * @param theNbObj the number of classes (or objects) 00446 * @param theNbNeurObj the number of neurons per class 00447 * @param theLvqInit initialization method vor the LVQ training 00448 * @param norm the used distance (L1distance or L2distance) 00449 */ 00450 initFunctor1(const dmatrix& theFeatures, 00451 const ivector& theTrainIDs, 00452 const ivector& theNbViewsObj, 00453 const int& theNbObj, 00454 const int& theNbNeurObj, 00455 const parameters::eLvqInit& theLvqInit, 00456 const eNormType& norm); 00457 00458 /** 00459 * destructor 00460 */ 00461 ~initFunctor1(); 00462 00463 /** 00464 * apply operator 00465 */ 00466 bool operator() (dmatrix& weights, ivector& outID); 00467 00468 /** 00469 * set the train parameters 00470 * @param theTrainType specify training for the LVQ initialization 00471 * @param theLearnRate 00472 * @param theLrFac the learn factor 00473 * @param theWinSize the window size 00474 */ 00475 void setTrainParams(const parameters::eLvqTrainType& theTrainType, 00476 const double& theLearnRate, 00477 const double& theLrFac=0., 00478 const double& theWinSize=0.); 00479 00480 protected: 00481 /** 00482 * a reference to the training patterns 00483 */ 00484 const dmatrix& features; 00485 00486 /** 00487 * a reference to the numerical ids of the training patterns 00488 */ 00489 const ivector& trainIDs; 00490 /** 00491 * a reference to the number of views per object 00492 */ 00493 const ivector& nbViewsObj; 00494 00495 /** 00496 * number of objects 00497 */ 00498 int nbObj; 00499 00500 /** 00501 * number of neurons per object 00502 */ 00503 int nbNeurObj; 00504 00505 /** 00506 * learn rate 00507 */ 00508 double learnRate; 00509 00510 /** 00511 * learn factor 00512 */ 00513 double lrFac; 00514 00515 /** 00516 * window size 00517 */ 00518 double winSize; 00519 00520 parameters::eLvqInit lvqInit; 00521 parameters::eLvqTrainType lvqType; 00522 eNormType norm; 00523 00524 ivector locTrainIDs; 00525 ivector locNbViewsObj; 00526 00527 int locNbObj; 00528 int locNbNeurObj; 00529 stdLayer::linearActFunctor linear; 00530 stdLayer::distancePropFunctor distProp; 00531 lvq::trainFunctor* trainer; 00532 bool changed; 00533 00534 ivector index; 00535 00536 dvector dummy; 00537 00538 int step; 00539 00540 /** 00541 * flag that indicates whether the weights were changed at all during 00542 * the last epoche. If not no further 'training' is performed. 00543 */ 00544 bool modified; 00545 }; 00546 00547 /** 00548 * initialization functor for rbf networks 00549 */ 00550 class initFunctor2 : public stdLayer::initFunctor { 00551 public: 00552 /** 00553 * constructor 00554 */ 00555 initFunctor2(dmatrix& theH, 00556 dmatrix& theHtilde, 00557 const double& theLambda, 00558 const ivector& theTrainIDs); 00559 /** 00560 * apply operator 00561 */ 00562 bool operator()(dmatrix& weights, ivector& outID); 00563 00564 protected: 00565 dmatrix& H; 00566 dmatrix& Htilde; 00567 const ivector& trainIDs; 00568 double lambda; 00569 }; 00570 00571 // ---------------------------------------------------- 00572 // rbf::layer1 00573 // ---------------------------------------------------- 00574 00575 /** 00576 * layer 1 for rbf networks 00577 */ 00578 class layer1 : public stdLayer { 00579 public: 00580 /** 00581 * constructor for the first layer 00582 */ 00583 layer1(std::string theName) : stdLayer(theName) {}; 00584 00585 /** 00586 * destructor 00587 */ 00588 virtual ~layer1() {}; 00589 00590 /** 00591 * train layer 1 00592 */ 00593 bool train(const dvector& input, 00594 const int& trainID, 00595 trainFunctor& trainFunc); 00596 00597 /** 00598 * get matrix H 00599 */ 00600 void getH(const dmatrix& features, 00601 stdLayer::propagationFunctor& prop, 00602 dmatrix& H); 00603 00604 /** 00605 * get matrix H~ 00606 */ 00607 void getHtilde(stdLayer::propagationFunctor& prop,dmatrix& Htilde); 00608 00609 /** 00610 * calculate sigma-factors 00611 */ 00612 void findSigmas(const double& sigmaFac, dvector& sigmas); 00613 00614 /** 00615 * set training parameters 00616 */ 00617 void setTrainParams(initFunctor1& initFunctor, 00618 const parameters::eLvqTrainType& theTrainType, 00619 const double& theLearnRate, 00620 const double& theLrFac=0., 00621 const double& theWinSize=0.); 00622 00623 00624 }; 00625 00626 // ---------------------------------------------------- 00627 // rbf::layer2 00628 // ---------------------------------------------------- 00629 00630 /** 00631 * layer 2 for rbf networks 00632 */ 00633 class layer2 : public stdLayer { 00634 public: 00635 /** 00636 * constructor 00637 */ 00638 layer2(std::string theName) : stdLayer(theName) {}; 00639 /** 00640 * destructor 00641 */ 00642 virtual ~layer2() {}; 00643 00644 /** 00645 * train layer 2 00646 */ 00647 bool train(const dvector& input, 00648 const int& trainID, 00649 trainFunctor& trainFunc); 00650 }; 00651 00652 00653 00654 // ---------------------------------------------------- 00655 // rbf 00656 // ---------------------------------------------------- 00657 00658 /** 00659 * Constructor 00660 */ 00661 rbf(); 00662 00663 /** 00664 * Copy constructor 00665 */ 00666 rbf(const rbf& other); 00667 00668 /** 00669 * Create with the given parameters 00670 */ 00671 rbf(const parameters& param); 00672 00673 /** 00674 * Destructor 00675 */ 00676 ~rbf(); 00677 00678 /** 00679 * get type name 00680 */ 00681 const char* getTypeName() const; 00682 00683 /** 00684 * Training. Mainly organization of data and 00685 * training algorithms 00686 */ 00687 bool train(const dmatrix& input, 00688 const ivector& ids); 00689 00690 /** 00691 * Propagates a feature vector through the network. The winner is 00692 * set to the unit with the maximum value. If an error occurs, the 00693 * %outputVectors recect flag is set to true and false is 00694 * returned. 00695 */ 00696 bool classify(const lti::dvector& feature, outputVector& result) const; 00697 00698 /** 00699 * Get dimensions of the output layer 00700 */ 00701 inline int getDimOutputLayer() const; 00702 00703 /** 00704 * object probabilities are not used 00705 */ 00706 // void noObjProbs(); 00707 00708 /** 00709 * Get the test-data for training statistics 00710 */ 00711 void setTestSet(const dmatrix& input, 00712 const ivector& ids); 00713 00714 /** 00715 * Gets the disjunct training data for object probabilities 00716 */ 00717 void setTrainSet2(const dmatrix& input, 00718 const ivector& ids); 00719 00720 /** 00721 * returns used parameters 00722 */ 00723 const parameters& getParameters() const; 00724 00725 /** 00726 * copy data of "other" functor. 00727 * @param other the functor to be copied 00728 * @return a reference to this functor object 00729 */ 00730 rbf& copy(const rbf& other); 00731 00732 /** 00733 * Alias for copy. 00734 * @param other the functor to be copied 00735 * @return a reference to this functor object 00736 */ 00737 inline rbf& operator=(const rbf& other) { 00738 return copy(other); 00739 } 00740 00741 /** 00742 * returns a pointer to a clone of this functor. 00743 */ 00744 virtual classifier* clone() const; 00745 00746 /** 00747 * @name Methods to access inner data. 00748 * Should not be used for anything but Axioms or others JNI interface 00749 * to use this class. 00750 */ 00751 //@{ 00752 00753 /** 00754 * Returns the weights of layer1 00755 */ 00756 const dmatrix& getWeights1(); 00757 00758 /** 00759 * Returns the sigmas of layer1 00760 */ 00761 const dvector& getSigmas1(); 00762 00763 /** 00764 * Returns the weights of layer2 00765 */ 00766 const dmatrix& getWeights2(); 00767 00768 /** 00769 * Returns the IDs of each neuron of the network 00770 */ 00771 const ivector& getIds(); 00772 00773 /** 00774 * Set the sigmas for layer 1 00775 */ 00776 void setSigmas(const dvector& s); 00777 00778 /** 00779 * Set data of layer1 00780 */ 00781 void setLayer1Data(const dmatrix& weights); 00782 00783 /** 00784 * Set data of layer2 00785 */ 00786 void setLayer2Data(const dmatrix& weights, const ivector& ids); 00787 00788 /** 00789 * Set the size and init functors after data is transmitted to layers 00790 * and sigmas are set. 00791 */ 00792 void initNet(const int& inSize, const int& outSize); 00793 00794 00795 /** 00796 * write the rbf classifier in the given ioHandler 00797 * @param handler the ioHandler to be used 00798 * @param complete if true (the default) the enclosing begin/end will 00799 * be also written, otherwise only the data block will be written. 00800 * @return true if write was successful 00801 */ 00802 virtual bool write(ioHandler& handler,const bool complete=true) const; 00803 00804 /** 00805 * read the rbf classifier from the given ioHandler 00806 * @param handler the ioHandler to be used 00807 * @param complete if true (the default) the enclosing begin/end will 00808 * be also written, otherwise only the data block will be written. 00809 * @return true if write was successful 00810 */ 00811 virtual bool read(ioHandler& handler,const bool complete=true); 00812 00813 #ifdef _INCLUDE_DEPRECATED 00814 /** 00815 * Load information about the network from a '.rbf' file 00816 * \deprecated Use read() instead 00817 */ 00818 // bool load(std::istream& instream); 00819 00820 /** 00821 * Save information about the network in a '.rbf' file 00822 * \deprecated Use write() instead 00823 */ 00824 // bool save(std::ostream& outstream); 00825 00826 /** 00827 * Load information about the network from a binary '.rbf' file 00828 * \deprecated Use read() instead 00829 */ 00830 // bool loadBinary(const char * fname); 00831 00832 /** 00833 * Save information about the network in a binary '.rbf' file 00834 * \deprecated Use write() instead 00835 */ 00836 // bool saveBinary(const char * fname); 00837 #endif // deprecated 00838 00839 protected: 00840 00841 /** 00842 * returns used parameters 00843 */ 00844 // parameters& getParameters(); 00845 00846 layer1 rbf1; 00847 layer2 rbf2; 00848 00849 // output lvqNnoutput; 00850 00851 int sizeIn; 00852 int sizeOut; 00853 00854 ivector trainID; 00855 ivector internToReal; 00856 std::map<int,int> realToIntern; 00857 dmatrix features; 00858 00859 dmatrix train2Features; 00860 ivector train2Ids; 00861 00862 dvector sigmas; 00863 00864 dmatrix testFeatures; 00865 ivector testIDs; 00866 ivector trainStatIDs; 00867 00868 stdLayer::distancePropFunctor* distProp; 00869 stdLayer::dotPropFunctor* dotProp; 00870 stdLayer::gaussActFunctor* gaussAct; 00871 stdLayer::sigmoidActFunctor* sigmoidAct; 00872 00873 // statFunctor* trainStat; 00874 // statFunctor* testStat; 00875 // statFunctor* lvqStat; 00876 00877 std::map<int,dvector> targetVec; 00878 00879 /** 00880 * Calculate object probabilities with given features 00881 */ 00882 bool calcObjProbs(ivector& ids, 00883 dmatrix& feats, 00884 stdLayer::distancePropFunctor& distProp); 00885 00886 // void initStatistics(); 00887 // void statistics(statFunctor& stat, 00888 // ivector& ids, 00889 // dmatrix& feats, 00890 // bool saveMe); 00891 }; 00892 00893 00894 int rbf::getDimOutputLayer() const { 00895 return sizeOut; 00896 } 00897 00898 } 00899 00900 #endif //_LTI_RBF_H_