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 Digital Image/Signal Processing Library 00026 * file .......: ltiHmmOnlineClassifier.h 00027 * authors ....: Benjamin Winkler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 09.07.2002 00030 * revisions ..: $Id: ltiHmmOnlineClassifier.h,v 1.7 2006/02/07 18:18:17 ltilib Exp $ 00031 */ 00032 00033 00034 #ifndef _LTI_HMM_ONLINE_CLASSIFIER_H_ 00035 #define _LTI_HMM_ONLINE_CLASSIFIER_H_ 00036 00037 #include "ltiHmmViterbiPathSearch.h" 00038 #include "ltiHmmClassifier.h" 00039 00040 namespace lti { 00041 00042 /** 00043 * This class allows online classification of word chains. 00044 */ 00045 class hmmOnlineClassifier : public hmmClassifier { 00046 00047 public: 00048 00049 // -------------------------------------------------- 00050 // hmmOnlineClassifier::parameters 00051 // -------------------------------------------------- 00052 00053 /** 00054 * the parameters for the class hmmOnlineClassifier 00055 */ 00056 class parameters : public hmmClassifier::parameters { 00057 public: 00058 00059 00060 /** 00061 * default constructor 00062 */ 00063 parameters(); 00064 00065 /** 00066 * copy constructor 00067 * @param other the parameters %object to be copied 00068 */ 00069 parameters(const parameters& other); 00070 00071 /** 00072 * destructor 00073 */ 00074 virtual ~parameters(); 00075 00076 /** 00077 * returns name of this type 00078 */ 00079 const char* getTypeName() const; 00080 00081 /** 00082 * copy the contents of a parameters %object 00083 * @param other the parameters %object to be copied 00084 * @return a reference to this parameters %object 00085 */ 00086 parameters& copy(const parameters& other); 00087 00088 /** 00089 * copy the contents of a parameters object 00090 * @param other the parameters object to be copied 00091 * @return a reference to this parameters object 00092 */ 00093 parameters& operator=(const parameters& other); 00094 00095 00096 /** 00097 * returns a pointer to a clone of the parameters 00098 */ 00099 virtual classifier::parameters* clone() const; 00100 00101 /** 00102 * write the parameters in the given ioHandler 00103 * @param handler the ioHandler to be used 00104 * @param complete if true (the default) the enclosing begin/end will 00105 * be also written, otherwise only the data block will be written. 00106 * @return true if write was successful 00107 */ 00108 virtual bool write(ioHandler& handler,const bool complete=true) const; 00109 00110 /** 00111 * read the parameters from the given ioHandler 00112 * @param handler the ioHandler to be used 00113 * @param complete if true (the default) the enclosing begin/end will 00114 * be also written, otherwise only the data block will be written. 00115 * @return true if write was successful 00116 */ 00117 virtual bool read(ioHandler& handler,const bool complete=true); 00118 00119 # ifdef _LTI_MSC_6 00120 /** 00121 * this function is required by MSVC only, as a workaround for a 00122 * very awful bug, which exists since MSVC V.4.0, and still by 00123 * V.6.0 with all bugfixes (so called "service packs") remains 00124 * there... This method is also public due to another bug, so please 00125 * NEVER EVER call this method directly: use read() instead 00126 */ 00127 bool readMS(ioHandler& handler,const bool complete=true); 00128 00129 /** 00130 * this function is required by MSVC only, as a workaround for a 00131 * very awful bug, which exists since MSVC V.4.0, and still by 00132 * V.6.0 with all bugfixes (so called "service packs") remains 00133 * there... This method is also public due to another bug, so please 00134 * NEVER EVER call this method directly: use write() instead 00135 */ 00136 bool writeMS(ioHandler& handler,const bool complete=true) const; 00137 # endif 00138 00139 00140 /** 00141 * additive constant used for pruning (beam search). 00142 * all hypotheses that have a score greater than minScore + pruningThreshold 00143 * are thrown away. 00144 * For values lower than 0, no beam search is performed. 00145 * default is 1000, but this is no generally reasonable value. the threshold depends 00146 * strongly on the number of features and the trained data. 00147 */ 00148 float pruningThreshold; 00149 00150 /** 00151 * describes the maximum number of active hypotheses (histogram pruning). 00152 * if more hypotheses (i.e. paths within 00153 * a model) are active, the worst hypotheses are thrown away. 00154 * for value 0, no histogram pruning is performed. 00155 * this value should be adjusted depending on the number of models. 00156 * default is 1000. 00157 */ 00158 int maxActiveHypotheses; 00159 00160 /** 00161 * defines the number of buckets for the bucket-sort-algorithm used in histogram pruning. 00162 * when performing histogram pruning, one bucket-sort-run is performed and the hypotheses 00163 * in the buckets for the lowest scores are kept, so that there are at most maxActiveHypotheses 00164 * active. 00165 * the more buckets there are, the closer the number of surviving hypotheses will get to the 00166 * given maximum count. (the number of buckets has no influence on run time!) 00167 * default is 100. 00168 */ 00169 int numberOfBuckets; 00170 00171 /** 00172 * after the given number of timesteps, a partial trace back is performed and the calculated values 00173 * are saved internally. 00174 * this is done to keep the trace back field small and the scores low. 00175 * a value of 0 disables automatic trace back. 00176 * default is 0. 00177 */ 00178 int automaticTraceBack; 00179 00180 }; 00181 00182 /** 00183 * default constructor 00184 */ 00185 hmmOnlineClassifier(); 00186 00187 /** 00188 * copy constructor 00189 * @param other the object to be copied 00190 */ 00191 hmmOnlineClassifier(const hmmOnlineClassifier& other); 00192 00193 /** 00194 * destructor 00195 */ 00196 virtual ~hmmOnlineClassifier(); 00197 00198 /** 00199 * returns the name of this type ("hmmOnlineClassifier") 00200 */ 00201 virtual const char* getTypeName() const; 00202 00203 /** 00204 * copy data of "other" functor. 00205 * @param other the functor to be copied 00206 * @return a reference to this functor object 00207 */ 00208 hmmOnlineClassifier& copy(const hmmOnlineClassifier& other); 00209 00210 /** 00211 * alias for copy member 00212 * @param other the classifier to be copied 00213 * @return a reference to this classifier object 00214 */ 00215 hmmOnlineClassifier& operator=(const hmmOnlineClassifier& other); 00216 00217 /** 00218 * returns a pointer to a clone of this functor. 00219 */ 00220 virtual classifier* clone() const; 00221 00222 /** 00223 * returns used parameters 00224 */ 00225 const parameters& getParameters() const; 00226 00227 /** 00228 * write method 00229 */ 00230 virtual bool write(ioHandler &handler, const bool complete=true) const; 00231 00232 /** 00233 * read method 00234 */ 00235 virtual bool read(ioHandler &handler, const bool complete=true); 00236 00237 00238 // 00239 // online classification methods: 00240 // 00241 00242 00243 /** @name Online classification routines. 00244 * These methods are used for online classification. 00245 */ 00246 //@{ 00247 00248 00249 /** 00250 * delete all models, hypotheses and traceback fields. 00251 */ 00252 void reset(); 00253 00254 00255 /** 00256 * Empty traceback fields and delete current hypotheses. 00257 * This routine must be called before a new online classification session is started. 00258 */ 00259 void initialize(); 00260 00261 /** 00262 * Online classification step. 00263 * @param observation the observation of this timestep. 00264 * @return false if an error occurred during classification else true 00265 */ 00266 bool classify(const dvector& observation); 00267 00268 //@} 00269 00270 00271 // 00272 // trace back methods 00273 // 00274 00275 00276 /** @name trace back routines 00277 * These methods are used to determine the best word sequence. 00278 */ 00279 //@{ 00280 00281 00282 /** 00283 * Perform partial traceback. 00284 * Find the latest timeframe left to where the word sequence is fixed, i.e. find the start of 00285 * a sentence where later hypotheses have no effect on. This word sequence is returned and 00286 * the internal traceback fields are truncated accordingly. 00287 * Furthermore, the internal scores of all current hypotheses are reduced. 00288 * @return vector describing a sequence of word ids. 00289 */ 00290 ivector partialTraceBack(); 00291 00292 /** 00293 * Perform partial traceback. 00294 * Find the latest timeframe left to where the word sequence is fixed, i.e. find the start of 00295 * a sentence where later hypotheses have no effect on. This word sequence is returned and 00296 * the internal traceback fields are truncated accordingly. 00297 * Furthermore, the internal scores of all current hypotheses are reduced. 00298 * @param wordLength the length of each classified word is saved here. 00299 * @param wordEndScores the score of the word end hypotheses is saved here. 00300 * @return vector describing a sequence of word ids. 00301 */ 00302 ivector partialTraceBack(ivector &wordLength, dvector &wordEndScores); 00303 00304 /** 00305 * Full word sequence traceback 00306 * Return the best word sequence, given the assumption that the word has ended. 00307 * @return vector describing a sequence of word ids. 00308 */ 00309 ivector fullTraceBack() const; 00310 00311 /** 00312 * Full word sequence traceback 00313 * Return the best word sequence, given the assumption that the word has ended. 00314 * @param wordLength the length of each classified word is saved here. 00315 * @param wordEndScores the score of the word end hypotheses is saved here. 00316 * @return vector describing a sequence of word ids. 00317 */ 00318 ivector fullTraceBack(ivector &wordLength, dvector &wordEndScores) const; 00319 00320 /** 00321 * Full traceback of the best active hypothesis. 00322 * Return the word sequence leading to the currently best hypotheses. Note, that this hypothesis might 00323 * not be in a word-end-state. 00324 * @return vector describing a sequence of word ids. 00325 */ 00326 ivector bestHypothesisTraceBack() const; 00327 00328 /** 00329 * Full traceback of the best active hypothesis. 00330 * Return the word sequence leading to the currently best hypotheses. Note, that this hypothesis might 00331 * not be in a word-end-state. 00332 * @param innerState the active state of the hypothesis is saved here. the according model is 00333 * given by the last entry of the return vector. 00334 * @param wordLength the length of each classified word is saved here. 00335 * @param wordEndScores the score of the word end hypotheses is saved here. 00336 * @return vector describing a sequence of word ids. 00337 */ 00338 ivector bestHypothesisTraceBack(int &innerState, ivector &wordLength, dvector &wordEndScores) const; 00339 00340 00341 /** 00342 * @return number of currently active hypotheses. 00343 */ 00344 int getNumberOfHypotheses() const { 00345 return overallActiveHypotheses; 00346 } 00347 00348 00349 //@} 00350 00351 00352 // 00353 // word error routines 00354 // 00355 00356 00357 /** @name word error routines 00358 * These methods are used to determine the word error rate of a classified sentence. 00359 */ 00360 //@{ 00361 00362 00363 /** 00364 * Calculate the Levenshtein distance (also called edit distance). 00365 * The Levenshtein distance of two sentences is the minimum number of substitutions, insertions 00366 * and deletions needed to transform one sentence into the other. 00367 * @return Levenshtein distance of the given word sequences 00368 */ 00369 int wordErrorCount(const ivector &wordSequence1, const ivector &wordSequence2) const; 00370 00371 00372 /** 00373 * The word error rate is defined as the Levenshtein distance divided by 00374 * the length of the correct word sequence. 00375 * @return word error rate 00376 */ 00377 float wordErrorRate(const ivector &correctSequence, const ivector &classifiedSequence) const { 00378 return wordErrorCount(correctSequence, classifiedSequence) / static_cast<float>(correctSequence.size()); 00379 } 00380 00381 //@} 00382 00383 00384 00385 private: 00386 00387 00388 /** 00389 * this class describes an active model 00390 */ 00391 class wordHypothesis : public ioObject { 00392 00393 public: 00394 00395 /** 00396 * default constructor 00397 */ 00398 wordHypothesis(); 00399 00400 /** 00401 * copy constructor 00402 * @param other the object to be copied 00403 */ 00404 wordHypothesis(const wordHypothesis& other); 00405 00406 /** 00407 * destructor 00408 */ 00409 virtual ~wordHypothesis(); 00410 00411 /** 00412 * copy data of "other" wordHypothesis. 00413 * Please note that the status string will _NOT_ be copied! 00414 */ 00415 wordHypothesis& copy(const wordHypothesis& other); 00416 00417 /** 00418 * assigment operator (alias for copy(other)). 00419 * @param other the wordHypothesis to be copied 00420 * @return a reference to the actual wordHypothesis 00421 */ 00422 wordHypothesis& operator=(const wordHypothesis& other); 00423 00424 /** 00425 * returns name of this type 00426 */ 00427 const char* getTypeName() const; 00428 00429 /** 00430 * write the parameters in the given ioHandler 00431 * @param handler the ioHandler to be used 00432 * @param complete if true (the default) the enclosing begin/end will 00433 * be also written, otherwise only the data block will be written. 00434 * @return true if write was successful 00435 */ 00436 virtual bool write(ioHandler& handler, const bool complete=true) const; 00437 00438 /** 00439 * read the parameters from the given ioHandler 00440 * @param handler the ioHandler to be used 00441 * @param complete if true (the default) the enclosing begin/end will 00442 * be also written, otherwise only the data block will be written. 00443 * @return true if write was successful 00444 */ 00445 virtual bool read(ioHandler& handler,const bool complete=true); 00446 00447 # ifdef _LTI_MSC_6 00448 /** 00449 * this function is required by MSVC only, as a workaround for a 00450 * very awful bug, which exists since MSVC V.4.0, and still by 00451 * V.6.0 with all bugfixes (so called "service packs") remains 00452 * there... This method is public due to another bug!, so please 00453 * NEVER EVER call this method directly 00454 */ 00455 bool readMS(ioHandler& handler,const bool complete=true); 00456 00457 /** 00458 * this function is required by MSVC only, as a workaround for a 00459 * very awful bug, which exists since MSVC V.4.0, and still by 00460 * V.6.0 with all bugfixes (so called "service packs") remains 00461 * there... This method is public due to another bug!, so please 00462 * NEVER EVER call this method directly 00463 */ 00464 bool writeMS(ioHandler& handler,const bool complete=true) const; 00465 # endif 00466 00467 00468 /** 00469 * id of the model 00470 */ 00471 int modelID; 00472 00473 /** 00474 * word length of the current hypothesis (life time) 00475 */ 00476 int wordLength; 00477 00478 /** 00479 * interim result vector 00480 */ 00481 dvector resultVector; 00482 }; 00483 00484 00485 00486 00487 /** 00488 * this class describes a traceback entry, i.e. a word end hypothesis 00489 */ 00490 class wordEndHypothesis : public ioObject { 00491 00492 public: 00493 00494 /** 00495 * default constructor 00496 */ 00497 wordEndHypothesis(); 00498 00499 /** 00500 * copy constructor 00501 * @param other the object to be copied 00502 */ 00503 wordEndHypothesis(const wordEndHypothesis& other); 00504 00505 /** 00506 * destructor 00507 */ 00508 virtual ~wordEndHypothesis(); 00509 00510 /** 00511 * copy data of "other" wordEndHypothesis. 00512 * Please note that the status string will _NOT_ be copied! 00513 */ 00514 wordEndHypothesis& copy(const wordEndHypothesis& other); 00515 00516 /** 00517 * assigment operator (alias for copy(other)). 00518 * @param other the wordEndHypothesis to be copied 00519 * @return a reference to the actual wordEndHypothesis 00520 */ 00521 wordEndHypothesis& operator=(const wordEndHypothesis& other); 00522 00523 /** 00524 * returns name of this type 00525 */ 00526 const char* getTypeName() const; 00527 00528 /** 00529 * write the parameters in the given ioHandler 00530 * @param handler the ioHandler to be used 00531 * @param complete if true (the default) the enclosing begin/end will 00532 * be also written, otherwise only the data block will be written. 00533 * @return true if write was successful 00534 */ 00535 virtual bool write(ioHandler& handler, const bool complete=true) const; 00536 00537 /** 00538 * read the parameters from the given ioHandler 00539 * @param handler the ioHandler to be used 00540 * @param complete if true (the default) the enclosing begin/end will 00541 * be also written, otherwise only the data block will be written. 00542 * @return true if write was successful 00543 */ 00544 virtual bool read(ioHandler& handler,const bool complete=true); 00545 00546 # ifdef _LTI_MSC_6 00547 /** 00548 * this function is required by MSVC only, as a workaround for a 00549 * very awful bug, which exists since MSVC V.4.0, and still by 00550 * V.6.0 with all bugfixes (so called "service packs") remains 00551 * there... This method is public due to another bug!, so please 00552 * NEVER EVER call this method directly 00553 */ 00554 bool readMS(ioHandler& handler,const bool complete=true); 00555 00556 /** 00557 * this function is required by MSVC only, as a workaround for a 00558 * very awful bug, which exists since MSVC V.4.0, and still by 00559 * V.6.0 with all bugfixes (so called "service packs") remains 00560 * there... This method is public due to another bug!, so please 00561 * NEVER EVER call this method directly 00562 */ 00563 bool writeMS(ioHandler& handler,const bool complete=true) const; 00564 # endif 00565 00566 00567 /** 00568 * id of the model 00569 */ 00570 int modelID; 00571 00572 /** 00573 * word length of the current hypothesis (life time) 00574 */ 00575 int wordLength; 00576 00577 /** 00578 * score of the model's last state 00579 */ 00580 float score; 00581 }; 00582 00583 00584 /** 00585 * prune one model hypothesis, adjust minScore. 00586 * return false if no hypotheses survive, else true. 00587 */ 00588 int pruneModelHypothesis(dvector &resultVector, float &minScore, float &maxScore) const; 00589 00590 00591 /** 00592 * trace back from given position. 00593 * return word vector, word lengths and relative word scores 00594 */ 00595 void traceBack(int traceBackIndex, ivector &wordIDs, ivector &wordLength, dvector &wordEndScores) const; 00596 00597 00598 /** 00599 * find last collective starting point for all active hypotheses 00600 */ 00601 int findCollectiveStartingPoint() const; 00602 00603 00604 /** 00605 * reduce scores of all hypotheses by given value 00606 */ 00607 void reduceScores(float value); 00608 00609 00610 /** 00611 * append internally saved vectors to the front of the given vectors 00612 */ 00613 void appendTracebackVectors(ivector &wordIDs, ivector &wordLength, dvector &wordEndScores) const; 00614 00615 00616 /** 00617 * all running hypotheses are saved here 00618 */ 00619 std::list<wordHypothesis> activeHypotheses; 00620 00621 00622 /** 00623 * traceback field containing the word end hypotheses for all time frames. 00624 */ 00625 std::vector<wordEndHypothesis> traceBackField; 00626 00627 00628 /** 00629 * copy of model with best hypotheses. 00630 */ 00631 wordHypothesis bestHypothesis; 00632 00633 00634 /** 00635 * temporary copy for faster access 00636 */ 00637 float pruningThreshold; 00638 00639 /** 00640 * number of active hypotheses 00641 */ 00642 int overallActiveHypotheses; 00643 00644 /** 00645 * the results of the automatic partial trace back are saved here 00646 */ 00647 int timestepCounter; 00648 ivector partialWordHyp; 00649 ivector partialWordLengths; 00650 dvector partialWordEndScores; 00651 00652 }; 00653 00654 } 00655 00656 #endif