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 .......: ltiStdLayer.h 00027 * authors ....: Peter Doerfler, Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 11.8.2000 00030 * revisions ..: $Id: ltiStdLayer.h,v 1.3 2006/02/07 18:26:37 ltilib Exp $ 00031 */ 00032 00033 00034 #ifndef _LTI_STD_LAYER_H_ 00035 #define _LTI_STD_LAYER_H_ 00036 00037 #ifndef _INCLUDE_DEPRECATED 00038 #define _INCLUDE_DEPRECATED 00039 #endif 00040 00041 #include <string> 00042 #include <iostream> 00043 00044 #include "ltiMatrix.h" 00045 #include "ltiVector.h" 00046 #include "ltiObject.h" 00047 00048 namespace lti { 00049 00050 /** 00051 * used for flags indicating usage of L1 or L2 norm for 00052 * propagation 00053 */ 00054 enum eNormType { 00055 L1distance, /*!< L1-norm (sum of the absolut values) */ 00056 L2distance /*!< L2-norm (square root of the sum of the squares)*/ 00057 }; 00058 00059 /** 00060 * This abstract class implements a standard neural network layer. 00061 * 00062 * This class contains the weights matrix, the vector with the 00063 * output values, the class id for each output element, the 00064 * dimensionality of the input vector and output layer (which must 00065 * be consistent with the dimensions of the weights matrix and the 00066 * output vector), the name of the layer (an ASCII string) and a learn 00067 * rate value. 00068 * 00069 * The enclosed classes are supponsed to modify this values. There are 00070 * some initialization, activation, propagation and training functors. 00071 */ 00072 class stdLayer : public object { 00073 public: 00074 00075 // ---------------------------------------------- 00076 // initialization functor 00077 // ---------------------------------------------- 00078 00079 /** 00080 * This class and all it's derived classes should initialize 00081 * the network layer 00082 */ 00083 class initFunctor : public object { 00084 public: 00085 /** 00086 * default constructor 00087 */ 00088 initFunctor() 00089 : object() {}; 00090 00091 /** 00092 * destructor 00093 */ 00094 virtual ~initFunctor() {}; 00095 00096 /** 00097 * initialization operator 00098 */ 00099 virtual bool operator()(dmatrix& weights,ivector& outID) = 0; 00100 00101 protected: 00102 00103 /** 00104 * Returns the unique IDs in a vector 00105 */ 00106 ivector uniqueIDs(const ivector& allIDs) const; 00107 00108 /** 00109 * Returns all train vectors of the given class 00110 * @param allVectors the training vectors are in the rows of this matrix 00111 * @param allIDs IDs for the training vectors 00112 * @param nbViews number of views per object 00113 * @param id the ID for which the features are returned 00114 */ 00115 dmatrix classVectors(const dmatrix& allVectors, 00116 const ivector& allIDs, 00117 int nbViews, 00118 int id) const; 00119 }; 00120 00121 // ---------------------------------------------- 00122 // activation functor 00123 // ---------------------------------------------- 00124 00125 /** 00126 * Parent class for all activation function functors 00127 */ 00128 class activationFunctor : public object { 00129 public: 00130 /** 00131 * the functor operator 00132 */ 00133 virtual bool operator()(dvector& output) const = 0; 00134 }; 00135 00136 /** 00137 * a linear activation function 00138 */ 00139 class linearActFunctor : public activationFunctor { 00140 public: 00141 /** 00142 * the functor operator 00143 */ 00144 virtual bool operator()(dvector& output) const {return true;}; 00145 }; 00146 00147 /** 00148 * a gaussian activation function 00149 */ 00150 class gaussActFunctor : public activationFunctor { 00151 protected: 00152 double mu,sigma; 00153 const dvector* sigmaVec; 00154 00155 public: 00156 /** 00157 * constructor for a gaussian activation function with 00158 * mean value theMu and std. deviation theSigma 00159 */ 00160 gaussActFunctor(const double& theMu, 00161 const double& theSigma) 00162 : mu(theMu),sigma(theSigma),sigmaVec(0) {}; 00163 00164 /** 00165 * constructor for a gaussian activation function with 00166 * mean value theMu and std. deviation vector theSigma 00167 */ 00168 gaussActFunctor(const double& theMu, 00169 const dvector& theSigmaVec) 00170 : mu(theMu),sigma(-1),sigmaVec(&theSigmaVec) {}; 00171 00172 00173 /** 00174 * functor operator 00175 */ 00176 bool operator() (dvector& output) const; 00177 }; 00178 00179 /** 00180 * a sigmoid activation function 00181 */ 00182 class sigmoidActFunctor : public activationFunctor { 00183 protected: 00184 double slope; 00185 00186 public: 00187 sigmoidActFunctor(const double& theSlope): 00188 slope(theSlope) {}; 00189 00190 sigmoidActFunctor() : 00191 slope(1.0) {}; 00192 00193 bool operator () (dvector& output) const; 00194 }; 00195 00196 // ---------------------------------------------- 00197 // propagation functor 00198 // ---------------------------------------------- 00199 /** 00200 * Parent class for all propagation functors 00201 * All propagation functors use a given activation function 00202 * to calculate the output layer vector using a given input 00203 * vector and a given weights matrix 00204 */ 00205 class propagationFunctor : public object { 00206 public: 00207 00208 /** 00209 * defines a linear activation function 00210 */ 00211 propagationFunctor(const activationFunctor& theAct) 00212 : act(theAct) {}; 00213 00214 /** 00215 * the functor operator 00216 * @param input the input vector 00217 * @param weights the weights matrix of the layer 00218 * @param outLayer the output vector 00219 */ 00220 virtual bool operator() (const dvector& input, 00221 const dmatrix& weights, 00222 dvector& outLayer) const = 0; 00223 protected: 00224 const activationFunctor& act; 00225 }; 00226 00227 /** 00228 * Distance propagation functor 00229 */ 00230 class distancePropFunctor : public propagationFunctor { 00231 public: 00232 00233 /** 00234 * Default constructor 00235 * For Propagation L1 and L2 norm can be used 00236 */ 00237 distancePropFunctor(const activationFunctor& theAct, 00238 eNormType theNorm = L2distance) 00239 : propagationFunctor(theAct),norm(theNorm) {}; 00240 00241 /** 00242 * The functor operator 00243 * @param input the input vector 00244 * @param weights the weights matrix of the layer 00245 * @param outLayer the output vector 00246 */ 00247 bool operator() (const dvector& input, 00248 const dmatrix& weights, 00249 dvector& outLayer) const; 00250 private: 00251 eNormType norm; 00252 }; 00253 00254 /** 00255 * Dot-Product propagation functor 00256 */ 00257 class dotPropFunctor : public propagationFunctor { 00258 public: 00259 /** 00260 * Default constructor 00261 */ 00262 dotPropFunctor(const activationFunctor& theAct) 00263 : propagationFunctor(theAct) {}; 00264 00265 /** 00266 * The functor operator 00267 * @param input the input vector 00268 * @param weights the weights matrix of the layer 00269 * @param outLayer the output vector 00270 */ 00271 bool operator() (const dvector& input, 00272 const dmatrix& weights, 00273 dvector& outLayer) const; 00274 }; 00275 00276 /** 00277 * training functor 00278 */ 00279 class trainFunctor : public object { 00280 public: 00281 /** 00282 * default constructor 00283 * Both neccessary since there are nets which are trained 00284 * with an overall net error, not a layer error 00285 */ 00286 trainFunctor() 00287 : object() {}; 00288 00289 /** 00290 * destructor 00291 */ 00292 virtual ~trainFunctor() {}; 00293 00294 /** 00295 * set the learn rate 00296 */ 00297 virtual void setLearnRate(const double & lr); 00298 00299 00300 /** 00301 * the functor operator for supervised training requires 00302 * following parameters: 00303 * @param input the input vector 00304 * @param weights the weights matrix to be changed 00305 * @param outLayer the output layer vector 00306 * @param outID the class identification for each output neuron 00307 * @param trainID the class ID for the presented vector 00308 * @param netError the error of the layer 00309 * @param modified indicates whether the weights were modified 00310 */ 00311 virtual bool operator()(const dvector& input, 00312 dmatrix& weights, 00313 dvector& outLayer, 00314 const ivector& outID, 00315 const int& trainID, 00316 dvector& netError, 00317 bool& modified) { 00318 return false; // throw exception("training functor not implemented"); 00319 }; 00320 00321 /** 00322 * the functor operator for unsupervised training requires 00323 * following parameters: 00324 * @param input the input vector 00325 * @param weights the weights matrix to be changed 00326 * @param outLayer the output layer vector 00327 * @param netError the error of the layer 00328 * @param modified indicates whether the weights were modified 00329 */ 00330 virtual bool operator()(const dvector& input, 00331 dmatrix& weights, 00332 dvector& outLayer, 00333 dvector& netError, 00334 bool& modified) { 00335 return false; // throw exception("training functor not implemented"); 00336 }; 00337 00338 /** 00339 * the functor operator for supervised training requires 00340 * following parameters: 00341 * @param input the input vector 00342 * @param weights the weights matrix to be changed 00343 * @param outLayer the output layer vector 00344 * @param outID the class identification for each output neuron 00345 * @param trainID the class ID for the presented vector 00346 * @param modified indicates whether the weights were modified 00347 * @return true if successful, false otherwise 00348 */ 00349 virtual bool operator()(const dvector& input, 00350 dmatrix& weights, 00351 dvector& outLayer, 00352 const ivector& outID, 00353 const int& trainID, 00354 bool& modified) { 00355 return false; // throw exception("training functor not implemented"); 00356 }; 00357 00358 /** 00359 * the functor operator for unsupervised training requires 00360 * following parameters: 00361 * @param input the input vector 00362 * @param weights the weights matrix to be changed 00363 * @param outLayer the output layer vector 00364 * @param modified indicates whether the weights were modified 00365 * @return true if successful, false otherwise 00366 */ 00367 virtual bool operator ()(const dvector& input, 00368 dmatrix& weights, 00369 dvector& outLayer, 00370 bool& modified) { 00371 return false; // throw exception("training functor not implemented"); 00372 }; 00373 00374 protected: 00375 double learnRate; 00376 }; 00377 00378 // ---------------------------------------------- 00379 // standard layer 00380 // ---------------------------------------------- 00381 00382 /** 00383 * default constructor 00384 */ 00385 stdLayer(const std::string& theName); 00386 00387 /** 00388 * copy constructor 00389 */ 00390 stdLayer(const stdLayer& other); 00391 00392 /** 00393 * destructor 00394 */ 00395 virtual ~stdLayer(); 00396 00397 /** 00398 * copy member 00399 */ 00400 stdLayer& copy(const stdLayer& other); 00401 00402 /** 00403 * initialize the weights 00404 */ 00405 virtual void initWeights(initFunctor& initFunc); 00406 00407 /** 00408 * train the network layer (supervised) with the given input vector 00409 * 00410 * Does one step of training, i.e. one feature vector 'input' of class 00411 * 'trainID' is learned by the layer as specified in the trainFunctor 00412 * 00413 * @return false if an error occurred, otherwise true 00414 */ 00415 virtual bool train(const dvector& input, 00416 const int& trainID, 00417 trainFunctor& trainFunc); 00418 00419 /** 00420 * train the network layer (unsupervised) with the given input vector 00421 * 00422 * @return false if an error occurred, otherwise true 00423 */ 00424 virtual bool train(const dvector& input,trainFunctor& trainFunc); 00425 00426 /** 00427 * propagate the vector through the network 00428 * 00429 * @return false if an error occurred, otherwise true 00430 */ 00431 virtual bool propagate(const dvector& input, 00432 propagationFunctor& prop, 00433 dvector& output) const; 00434 00435 /** 00436 * get the output vector 00437 */ 00438 // inline const dvector& getOutput() const; 00439 00440 /** 00441 * get the class IDs for output vector elements 00442 */ 00443 inline const ivector& getOutID() const; 00444 00445 /** 00446 * set the size of the input and output vectors 00447 * @param in size of the input vector 00448 * @param out size of the output vector 00449 */ 00450 void setSize(const int& in, const int& out); 00451 00452 00453 /** 00454 * write the standard layer in the given ioHandler 00455 * @param handler the ioHandler to be used 00456 * @param complete if true (the default) the enclosing begin/end will 00457 * be also written, otherwise only the data block will be written. 00458 * @return true if write was successful 00459 */ 00460 virtual bool write(ioHandler& handler,const bool complete=true) const; 00461 00462 /** 00463 * read the standard layer from the given ioHandler 00464 * @param handler the ioHandler to be used 00465 * @param complete if true (the default) the enclosing begin/end will 00466 * be also written, otherwise only the data block will be written. 00467 * @return true if write was successful 00468 */ 00469 virtual bool read(ioHandler& handler,const bool complete=true); 00470 00471 /** 00472 * return the last message set with setStatusString(). This will 00473 * never return 0. If no status-string has been set yet an empty string 00474 * (pointer to a string with only the char(0)) will be returned. 00475 */ 00476 virtual const char* getStatusString() const; 00477 00478 /** 00479 * set a status string. 00480 * 00481 * @param msg the const string to be reported next time by 00482 * getStatusString(). The given string will be copied 00483 * This message will be usually set within the apply methods to indicate 00484 * an error cause. 00485 * 00486 * Note that the change of the status string is not considered as 00487 * a change in the functor status. 00488 */ 00489 virtual void setStatusString(const char* msg) const; 00490 00491 00492 /** 00493 * get the weights of the layer 00494 */ 00495 inline const dmatrix& getWeights(); 00496 00497 /** 00498 * set the learn rate 00499 */ 00500 inline void setLearnRate(const double& theLR); 00501 00502 00503 /** 00504 * These methods should only be used by the Axiom Java interface 00505 */ 00506 //@{ 00507 00508 /** 00509 * Set the weights of the layer to the given matrix 00510 */ 00511 void setWeights(const dmatrix& weights); 00512 00513 /** 00514 * Set the IDs of the layer to the given vector 00515 */ 00516 void setIDs(const ivector& ids); 00517 00518 //@} 00519 00520 #ifdef _INCLUDE_DEPRECATED 00521 00522 00523 /** 00524 * @name deprecated methods 00525 * Deprecated methods 00526 */ 00527 //@{ 00528 00529 /** 00530 * write the standard layer in the given stream (ascii) 00531 * \deprecated Use write() instead 00532 */ 00533 virtual bool save(std::ostream& out) const; 00534 00535 /** 00536 * read the standard layer from the given stream (ascii) 00537 * \deprecated Use read() instead 00538 */ 00539 virtual bool load(std::istream& in); 00540 00541 /** 00542 * write the standard layer in the given stream (binary) 00543 * \deprecated Use write() instead 00544 */ 00545 virtual bool saveBinary(std::ostream& out) const; 00546 00547 /** 00548 * read the standard layer from the given stream (binary) 00549 * \deprecated Use read() instead 00550 */ 00551 virtual bool loadBinary(std::istream& in); 00552 //@} 00553 #endif 00554 00555 protected: 00556 /** 00557 * weights matrix 00558 */ 00559 dmatrix weights; 00560 00561 /** 00562 * output layer 00563 */ 00564 // dvector outLayer; 00565 00566 /** 00567 * Class ID of output node 00568 */ 00569 ivector outID; 00570 00571 /** 00572 * dimensionality of the input vector 00573 */ 00574 int sizeIn; 00575 00576 /** 00577 * dimensionality of the output vector 00578 */ 00579 int sizeOut; 00580 00581 /** 00582 * name of a layer 00583 */ 00584 std::string layerName; 00585 00586 /** 00587 * learn rate 00588 */ 00589 double learnRate; 00590 00591 /** 00592 * the status string written with setStatusString 00593 */ 00594 mutable char* statusString; 00595 00596 /** 00597 * the empty string returned if the statusString is empty 00598 */ 00599 static const char *const emptyString; 00600 }; 00601 00602 /** 00603 * @name Storable interface for classifiere classes 00604 * Members for the storable interface 00605 */ 00606 00607 //@{ 00608 /** 00609 * read the objectProb from the given ioHandler. The complete flag indicates 00610 * if the enclosing begin and end should be also be readed 00611 */ 00612 bool read(ioHandler& handler, 00613 stdLayer& p, 00614 const bool complete=true); 00615 00616 /** 00617 * write the vector in the given ioHandler. The complete flag indicates 00618 * if the enclosing begin and end should be also be written or not 00619 */ 00620 bool write(ioHandler& handler, 00621 const stdLayer& p, 00622 const bool complete=true); 00623 //@} 00624 // -------------------------------------- 00625 // inline - methods implementation 00626 // -------------------------------------- 00627 00628 // const dvector& stdLayer::getOutput() const { 00629 // return outLayer; 00630 // } 00631 00632 const ivector& stdLayer::getOutID() const { 00633 return outID; 00634 } 00635 00636 void stdLayer::setLearnRate(const double& theLR) { 00637 learnRate=theLR; 00638 } 00639 00640 const dmatrix& stdLayer::getWeights() { 00641 return weights; 00642 } 00643 } 00644 00645 #endif //_LTI_STD_LAYER_H_