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

ltiHmmClassifier.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 .......: ltiHmmClassifier.h
00027  * authors ....: Benjamin Winkler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 12.04.2002
00030  * revisions ..: $Id: ltiHmmClassifier.h,v 1.9 2006/02/07 18:18:00 ltilib Exp $
00031  */
00032 
00033 
00034 #ifndef _LTI_HMM_CLASSIFIER_H_
00035 #define _LTI_HMM_CLASSIFIER_H_
00036 
00037 #include "ltiSupervisedSequenceClassifier.h"
00038 #include "ltiHmmTrainer.h"
00039 
00040 namespace lti {
00041 
00042   /**
00043    * This class defines training and classification methods for Hidden Markov Models (HMM)
00044    * using observation sequences. The algorithms are taken from "Fundamentals of speech
00045    * recognition" (L. Rabiner and B.-H. Juang, Prentice Hall, 1993) and can also be found in
00046    * "Erkennung kontinuierlicher Gebärdensprache mit Ganzwortmodellen" (H. C. Hienz, PhD thesis,
00047    * Chair of Technical Computer Science, 2000). The notation in this documentation is taken
00048    * from the latter literature.
00049    *
00050    * In case of classification, the probability \f$P(\mathbf{O}|\lambda)\f$ of the
00051    * observation sequence \f$\mathbf{O}\f$ is approximated by the observation probability
00052    * \f$P^*(\mathbf{O}|\lambda)\f$ of the best path \f$\mathbf{q^*}\f$. The best path is found
00053    * with the Viterbi algorithm. Increased computational efficiency and precision are achieved
00054    * by using scores with \f$Score(\mathbf{X}|\lambda):=-\ln P^*(\mathbf{X}|\lambda)\f$
00055    * instead of probabilities. Note that the lowest score corresponds to the highest
00056    * probability and thus represents the best recognition result.
00057    *
00058    * <b>Note</b>: The values in the outputVector are not probabilities!
00059    * To match the value criteria (higher values represent better recognition results, positive values only),
00060    * scores are mapped to values between 0.0 and 1.0. Currently exponential, linear, and none are available.
00061    * <dl>
00062    * <dt>exponential (default)</dt>
00063    * <dd>\f$\left[ \frac{1.0}{score-lowestScore + 1.0} -
00064    * \frac{1.0}{(highestScore-lowestScore)+1.0}\right] \cdot
00065    * \frac{(highestScore-lowestScore)+1.0}{highestScore-lowestScore}\f$</dd>
00066    * <dt>linear</dt>
00067    * <dd>\f$value = \frac{highestScore-score}{highestScore-lowestScore}\f$</dd>
00068    * <dt>none</dt>
00069    * <dd>\f$value = score\f$</dd>
00070    * </dl>
00071    *
00072    */
00073   class hmmClassifier : public supervisedSequenceClassifier {
00074 
00075   public:
00076 
00077     // --------------------------------------------------
00078     // hmmClassifier::parameters
00079     // --------------------------------------------------
00080 
00081     /**
00082      * the parameters for the class hmmClassifier
00083      */
00084     class parameters : public classifier::parameters {
00085     public:
00086 
00087 
00088       /**
00089        * default constructor
00090        */
00091       parameters();
00092 
00093       /**
00094        * copy constructor
00095        * @param other the parameters %object to be copied
00096        */
00097       parameters(const parameters& other);
00098 
00099       /**
00100        * destructor
00101        */
00102       virtual ~parameters();
00103 
00104       /**
00105        * returns name of this type
00106        */
00107       const char* getTypeName() const;
00108 
00109       /**
00110        * copy the contents of a parameters %object
00111        * @param other the parameters %object to be copied
00112        * @return a reference to this parameters %object
00113        */
00114       parameters& copy(const parameters& other);
00115 
00116       /**
00117        * copy the contents of a parameters object
00118        * @param other the parameters object to be copied
00119        * @return a reference to this parameters object
00120        */
00121       parameters& operator=(const parameters& other);
00122 
00123 
00124       /**
00125        * returns a pointer to a clone of the parameters
00126        */
00127       virtual classifier::parameters* clone() const;
00128 
00129       /**
00130        * write the parameters in the given ioHandler
00131        * @param handler the ioHandler to be used
00132        * @param complete if true (the default) the enclosing begin/end will
00133        *        be also written, otherwise only the data block will be written.
00134        * @return true if write was successful
00135        */
00136       virtual bool write(ioHandler& handler,const bool complete=true) const;
00137 
00138       /**
00139        * read the parameters from the given ioHandler
00140        * @param handler the ioHandler to be used
00141        * @param complete if true (the default) the enclosing begin/end will
00142        *        be also written, otherwise only the data block will be written.
00143        * @return true if write was successful
00144        */
00145       virtual bool read(ioHandler& handler,const bool complete=true);
00146 
00147 #     ifdef _LTI_MSC_6
00148       /**
00149        * this function is required by MSVC only, as a workaround for a
00150        * very awful bug, which exists since MSVC V.4.0, and still by
00151        * V.6.0 with all bugfixes (so called "service packs") remains
00152        * there...  This method is also public due to another bug, so please
00153        * NEVER EVER call this method directly: use read() instead
00154        */
00155       bool readMS(ioHandler& handler,const bool complete=true);
00156 
00157       /**
00158        * this function is required by MSVC only, as a workaround for a
00159        * very awful bug, which exists since MSVC V.4.0, and still by
00160        * V.6.0 with all bugfixes (so called "service packs") remains
00161        * there...  This method is also public due to another bug, so please
00162        * NEVER EVER call this method directly: use write() instead
00163        */
00164       bool writeMS(ioHandler& handler,const bool complete=true) const;
00165 #     endif
00166 
00167 
00168       /**
00169        * Parameters used for the training process.
00170        * Changing these parameters only affects the following training processes.
00171        */
00172       hmmTrainer::parameters hmmTrainingParameters;
00173 
00174       /**
00175        * Default hidden markov model used for the training process.
00176        * This can be useful for modifying attributes such as emissionScoreWeight.
00177        * Changing these parameters only affects the following training processes,
00178        * existing models are left untouched.
00179        */
00180       hiddenMarkovModel defaultModel;
00181 
00182 
00183       /**
00184        * Mapping type used for scores. Currently exponential, linear and none are available.
00185        * <dl>
00186        * <dt>exponential</dt>
00187        * <dd>\f$value = \frac{1.0}{score - lowestScore + 1.0}\f$</dd>
00188        * <dt>linear</dt>
00189        * <dd>\f$value = \frac{highestscore-score}{highestScore-lowestScore}\f$</dd>
00190        * <dt>none</dt>
00191        * <dd>\f$value = score\f$</dd>
00192        * </dl>
00193        */
00194       enum mappingType {
00195         exponential,  /*!< choose exponential mapping*/
00196         linear,       /*!< choose linear mapping*/
00197         none          /*!< choose no mapping */
00198       };
00199 
00200       /**
00201        * Specifies the mapping function to be used.
00202        * default: exponentialMapping
00203        */
00204       mappingType mappingFunction;
00205 
00206     };
00207 
00208 
00209     /**
00210      * default constructor
00211      */
00212     hmmClassifier();
00213 
00214     /**
00215      * copy constructor
00216      * @param other the object to be copied
00217      */
00218     hmmClassifier(const hmmClassifier& other);
00219 
00220     /**
00221      * destructor
00222      */
00223     virtual ~hmmClassifier();
00224 
00225     /**
00226      * returns the name of this type ("hmmClassifier")
00227      */
00228     virtual const char* getTypeName() const;
00229 
00230     /**
00231      * copy data of "other" functor.
00232      * @param other the functor to be copied
00233      * @return a reference to this functor object
00234      */
00235     hmmClassifier& copy(const hmmClassifier& other);
00236 
00237     /**
00238      * alias for copy member
00239      * @param other the classifier to be copied
00240      * @return a reference to this classifier object
00241      */
00242     hmmClassifier& operator=(const hmmClassifier& other);
00243 
00244     /**
00245      * returns a pointer to a clone of this functor.
00246      */
00247     virtual classifier* clone() const;
00248 
00249     /**
00250      * returns used parameters
00251      */
00252     const parameters& getParameters() const;
00253 
00254     /**
00255      * write method
00256      */
00257     virtual bool write(ioHandler &handler, const bool complete=true) const;
00258 
00259     /**
00260      * read method
00261      */
00262     virtual bool read(ioHandler &handler, const bool complete=true);
00263 
00264 
00265     //
00266     // training and classification methods:
00267     //
00268 
00269 
00270     /** @name Training routines
00271      *  These methods are needed to train Hidden Markov models.
00272      */
00273     //@{
00274 
00275       /**
00276        * Supervised sequence training.
00277        * The sequences in the <code>input</code> %vector are used for training
00278        * the %sequence %classifier. Each %sequence is associated with an id
00279        * given in the %vector <code>ids</code>.
00280        * Hidden Markov models are created for all given ids, existing models being deleted first.
00281        * After the training process, the outputTemplate is generated on the training set.
00282        * @param input %vector of training %sequences
00283        * @param ids the classes of the training sequences
00284        * @return true if successful, false otherwise.  (if false you can check
00285        *              the error message with getStatusString())
00286        */
00287       virtual bool train(const std::vector< sequence<dvector> > &input,
00288                          const ivector& ids);
00289 
00290       /**
00291        * Training of a single model.
00292        * The given %sequences are used to train the model of the given id.
00293        * If such a model already exists internally, it will be overwritten.
00294        * Training is performed with the training %parameters given in the parameters class.
00295        *
00296        * Note: if you train a single model this way, the output template may contain incorrect values!
00297        */
00298       bool train(std::vector< sequence<dvector> > &input, int id);
00299 
00300       /**
00301        * Deletes all models saved internally.
00302        */
00303       void reset();
00304 
00305     //@}
00306 
00307 
00308     /** @name Classification routines.
00309      *  These methods are used for classification.
00310      */
00311     //@{
00312 
00313 
00314       /**
00315        * Classification.
00316        * Classifies the %sequence of features and returns the outputVector with
00317        * the classification result.
00318        * @param observations the %sequence to be classified
00319        * @param result the result of the classification
00320        * @return false if an error occurred during classification else true
00321        */
00322       virtual bool classify(const sequence<dvector>& observations,
00323                             outputVector& result);
00324 
00325     //@}
00326 
00327     //@{
00328 
00329 
00330     /**
00331      * Reduced Classification.
00332      * Classifies the %sequence of features only with a reduced number
00333      * of models given in usedModelsIDNameMap.
00334      * Returns the outputVector with the classification result.
00335      * @param observations the %sequence to be classified
00336      * @param result the result of the classification
00337      * @param usedModelsIDNameMap map of hmm models given by id and name
00338      * @return false if an error occurred during classification else true
00339      */
00340     bool reducedClassify(const sequence<dvector>& observations,
00341                          outputVector& result,
00342                          std::map<int, std::string> usedModelsIDNameMap);
00343 
00344 
00345     //@}
00346 
00347     /** @name Direct access routines
00348      *  These methods are used to directly access/change the Hidden Markov models used internally.
00349      *  Note that changing single models may lead to incorrect output templates!
00350      */
00351     //@{
00352 
00353       /**
00354        * Query id's of trained models.
00355        * @return vector containing the ids of all models of this classifier.
00356        */
00357       ivector getIDs();
00358 
00359       /**
00360        * Returns a copy of the model with the given id.
00361        * If no such model exists, the empty default model given in parameters is returned.
00362        */
00363       hiddenMarkovModel getHMM(int id) const;
00364 
00365       /**
00366        * Set the model to be used for the given id.
00367        *
00368        * Note: the output template may contain incorrect values hereafter!
00369        *
00370        * @return true, if successful, false otherwise
00371        */
00372       bool setHMM(hiddenMarkovModel &model, int id);
00373 
00374       /**
00375        * Delete the model with the given id.
00376        *
00377        * Note: the output template may contain incorrect values after this!
00378        *
00379        * @return true, if successful, false otherwise.
00380        */
00381       bool deleteHMM(int id);
00382 
00383       /**
00384        * Set the name of a specific model (if a model with the given ID exists).
00385        */
00386       void setName(int id, const std::string &theName);
00387 
00388       /**
00389        * Generate a map ID -> name for all loaded models.
00390        */
00391       void generateIndexNameMap(std::map<int, std::string> &theMap) const;
00392 
00393       /** Returns the length of the shortest model. This allows to tell if
00394         * an observation of a certain length can be classified by this classifier. 
00395         * If no models are available, -1 will be returned. */
00396       int getShortestModelLength() const;
00397 
00398     //@}
00399 
00400 
00401   protected:
00402 
00403     /**
00404      * the models with the given ids.
00405      */
00406     std::map<int, hiddenMarkovModel> theModels;
00407 
00408     /**
00409      * feature dimension (saved here for faster access)
00410      */
00411     int featureDimension;
00412 
00413   };
00414 }
00415 
00416 #endif

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