LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiHmmOnlineClassifier.h

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

Generated on Sat Apr 10 15:25:38 2010 for LTI-Lib by Doxygen 1.6.1