[mlpack-svn] r16000 - mlpack/trunk/src/mlpack/methods/gmm

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Tue Nov 5 22:32:23 EST 2013


Author: rcurtin
Date: Tue Nov  5 22:32:23 2013
New Revision: 16000

Log:
Allow GMMs to be trained using the existing model as a starting point.  This
could probably all use some serious refactoring now.


Modified:
   mlpack/trunk/src/mlpack/methods/gmm/em_fit.hpp
   mlpack/trunk/src/mlpack/methods/gmm/em_fit_impl.hpp
   mlpack/trunk/src/mlpack/methods/gmm/gmm.hpp
   mlpack/trunk/src/mlpack/methods/gmm/gmm_impl.hpp

Modified: mlpack/trunk/src/mlpack/methods/gmm/em_fit.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/gmm/em_fit.hpp	(original)
+++ mlpack/trunk/src/mlpack/methods/gmm/em_fit.hpp	Tue Nov  5 22:32:23 2013
@@ -61,35 +61,47 @@
   /**
    * Fit the observations to a Gaussian mixture model (GMM) using the EM
    * algorithm.  The size of the vectors (indicating the number of components)
-   * must already be set.
+   * must already be set.  Optionally, if useInitialModel is set to true, then
+   * the model given in the means, covariances, and weights parameters is used
+   * as the initial model, instead of using the InitialClusteringType::Cluster()
+   * option.
    *
    * @param observations List of observations to train on.
    * @param means Vector to store trained means in.
    * @param covariances Vector to store trained covariances in.
    * @param weights Vector to store a priori weights in.
+   * @param useInitialModel If true, the given model is used for the initial
+   *      clustering.
    */
   void Estimate(const arma::mat& observations,
                 std::vector<arma::vec>& means,
                 std::vector<arma::mat>& covariances,
-                arma::vec& weights);
+                arma::vec& weights,
+                const bool useInitialModel = false);
 
   /**
    * Fit the observations to a Gaussian mixture model (GMM) using the EM
    * algorithm, taking into account the probabilities of each point being from
    * this mixture.  The size of the vectors (indicating the number of
-   * components) must already be set.
+   * components) must already be set.  Optionally, if useInitialModel is set to
+   * true, then the model given in the means, covariances, and weights
+   * parameters is used as the initial model, instead of using the
+   * InitialClusteringType::Cluster() option.
    *
    * @param observations List of observations to train on.
    * @param probabilities Probability of each point being from this model.
    * @param means Vector to store trained means in.
    * @param covariances Vector to store trained covariances in.
    * @param weights Vector to store a priori weights in.
+   * @param useInitialModel If true, the given model is used for the initial
+   *      clustering.
    */
   void Estimate(const arma::mat& observations,
                 const arma::vec& probabilities,
                 std::vector<arma::vec>& means,
                 std::vector<arma::mat>& covariances,
-                arma::vec& weights);
+                arma::vec& weights,
+                const bool useInitialModel = false);
 
   //! Get the clusterer.
   const InitialClusteringType& Clusterer() const { return clusterer; }

Modified: mlpack/trunk/src/mlpack/methods/gmm/em_fit_impl.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/gmm/em_fit_impl.hpp	(original)
+++ mlpack/trunk/src/mlpack/methods/gmm/em_fit_impl.hpp	Tue Nov  5 22:32:23 2013
@@ -34,9 +34,12 @@
     const arma::mat& observations,
     std::vector<arma::vec>& means,
     std::vector<arma::mat>& covariances,
-    arma::vec& weights)
+    arma::vec& weights,
+    const bool useInitialModel)
 {
-  InitialClustering(observations, means, covariances, weights);
+  // Only perform initial clustering if the user wanted it.
+  if (!useInitialModel)
+    InitialClustering(observations, means, covariances, weights);
 
   double l = LogLikelihood(observations, means, covariances, weights);
 
@@ -118,9 +121,11 @@
     const arma::vec& probabilities,
     std::vector<arma::vec>& means,
     std::vector<arma::mat>& covariances,
-    arma::vec& weights)
+    arma::vec& weights,
+    const bool useInitialModel)
 {
-  InitialClustering(observations, means, covariances, weights);
+  if (!useInitialModel)
+    InitialClustering(observations, means, covariances, weights);
 
   double l = LogLikelihood(observations, means, covariances, weights);
 

Modified: mlpack/trunk/src/mlpack/methods/gmm/gmm.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/gmm/gmm.hpp	(original)
+++ mlpack/trunk/src/mlpack/methods/gmm/gmm.hpp	Tue Nov  5 22:32:23 2013
@@ -281,15 +281,23 @@
    * with the greatest log-likelihood will be selected.  By default, only one
    * trial is performed.  The log-likelihood of the best fitting is returned.
    *
+   * Optionally, the existing model can be used as an initial model for the
+   * estimation by setting 'useExistingModel' to true.  If the fitting procedure
+   * is deterministic after the initial position is given, then 'trials' should
+   * be set to 1.
+   *
    * @tparam FittingType The type of fitting method which should be used
    *     (EMFit<> is suggested).
    * @param observations Observations of the model.
    * @param trials Number of trials to perform; the model in these trials with
    *      the greatest log-likelihood will be selected.
+   * @param useExistingModel If true, the existing model is used as an initial
+   *      model for the estimation.
    * @return The log-likelihood of the best fit.
    */
   double Estimate(const arma::mat& observations,
-                  const size_t trials = 1);
+                  const size_t trials = 1,
+                  const bool useExistingModel = false);
 
   /**
    * Estimate the probability distribution directly from the given observations,
@@ -301,16 +309,24 @@
    * with the greatest log-likelihood will be selected.  By default, only one
    * trial is performed.  The log-likelihood of the best fitting is returned.
    *
+   * Optionally, the existing model can be used as an initial model for the
+   * estimation by setting 'useExistingModel' to true.  If the fitting procedure
+   * is deterministic after the initial position is given, then 'trials' should
+   * be set to 1.
+   *
    * @param observations Observations of the model.
    * @param probabilities Probability of each observation being from this
    *     distribution.
    * @param trials Number of trials to perform; the model in these trials with
    *     the greatest log-likelihood will be selected.
+   * @param useExistingModel If true, the existing model is used as an initial
+   *     model for the estimation.
    * @return The log-likelihood of the best fit.
    */
   double Estimate(const arma::mat& observations,
                   const arma::vec& probabilities,
-                  const size_t trials = 1);
+                  const size_t trials = 1,
+                  const bool useExistingModel = false);
 
   /**
    * Classify the given observations as being from an individual component in

Modified: mlpack/trunk/src/mlpack/methods/gmm/gmm_impl.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/gmm/gmm_impl.hpp	(original)
+++ mlpack/trunk/src/mlpack/methods/gmm/gmm_impl.hpp	Tue Nov  5 22:32:23 2013
@@ -187,7 +187,8 @@
  */
 template<typename FittingType>
 double GMM<FittingType>::Estimate(const arma::mat& observations,
-                                  const size_t trials)
+                                  const size_t trials,
+                                  const bool useExistingModel)
 {
   double bestLikelihood; // This will be reported later.
 
@@ -196,7 +197,8 @@
   {
     // Train the model.  The user will have been warned earlier if the GMM was
     // initialized with no parameters (0 gaussians, dimensionality of 0).
-    fitter.Estimate(observations, means, covariances, weights);
+    fitter.Estimate(observations, means, covariances, weights,
+        useExistingModel);
 
     bestLikelihood = LogLikelihood(observations, means, covariances, weights);
   }
@@ -205,9 +207,21 @@
     if (trials == 0)
       return -DBL_MAX; // It's what they asked for...
 
+    // If each trial must start from the same initial location, we must save it.
+    std::vector<arma::vec> meansOrig;
+    std::vector<arma::mat> covariancesOrig;
+    arma::vec weightsOrig;
+    if (useExistingModel)
+    {
+      meansOrig = means;
+      covariancesOrig = covariances;
+      weightsOrig = weights;
+    }
+
     // We need to keep temporary copies.  We'll do the first training into the
     // actual model position, so that if it's the best we don't need to copy it.
-    fitter.Estimate(observations, means, covariances, weights);
+    fitter.Estimate(observations, means, covariances, weights,
+        useExistingModel);
 
     bestLikelihood = LogLikelihood(observations, means, covariances, weights);
 
@@ -222,7 +236,15 @@
 
     for (size_t trial = 1; trial < trials; ++trial)
     {
-      fitter.Estimate(observations, meansTrial, covariancesTrial, weightsTrial);
+      if (useExistingModel)
+      {
+        meansTrial = meansOrig;
+        covariancesTrial = covariancesOrig;
+        weightsTrial = weightsOrig;
+      }
+
+      fitter.Estimate(observations, meansTrial, covariancesTrial, weightsTrial,
+          useExistingModel);
 
       // Check to see if the log-likelihood of this one is better.
       double newLikelihood = LogLikelihood(observations, meansTrial,
@@ -256,7 +278,8 @@
 template<typename FittingType>
 double GMM<FittingType>::Estimate(const arma::mat& observations,
                                   const arma::vec& probabilities,
-                                  const size_t trials)
+                                  const size_t trials,
+                                  const bool useExistingModel)
 {
   double bestLikelihood; // This will be reported later.
 
@@ -265,7 +288,8 @@
   {
     // Train the model.  The user will have been warned earlier if the GMM was
     // initialized with no parameters (0 gaussians, dimensionality of 0).
-    fitter.Estimate(observations, probabilities, means, covariances, weights);
+    fitter.Estimate(observations, probabilities, means, covariances, weights,
+        useExistingModel);
 
     bestLikelihood = LogLikelihood(observations, means, covariances, weights);
   }
@@ -274,9 +298,21 @@
     if (trials == 0)
       return -DBL_MAX; // It's what they asked for...
 
+    // If each trial must start from the same initial location, we must save it.
+    std::vector<arma::vec> meansOrig;
+    std::vector<arma::mat> covariancesOrig;
+    arma::vec weightsOrig;
+    if (useExistingModel)
+    {
+      meansOrig = means;
+      covariancesOrig = covariances;
+      weightsOrig = weights;
+    }
+
     // We need to keep temporary copies.  We'll do the first training into the
     // actual model position, so that if it's the best we don't need to copy it.
-    fitter.Estimate(observations, probabilities, means, covariances, weights);
+    fitter.Estimate(observations, probabilities, means, covariances, weights,
+        useExistingModel);
 
     bestLikelihood = LogLikelihood(observations, means, covariances, weights);
 
@@ -291,7 +327,15 @@
 
     for (size_t trial = 1; trial < trials; ++trial)
     {
-      fitter.Estimate(observations, meansTrial, covariancesTrial, weightsTrial);
+      if (useExistingModel)
+      {
+        meansTrial = meansOrig;
+        covariancesTrial = covariancesOrig;
+        weightsTrial = weightsOrig;
+      }
+
+      fitter.Estimate(observations, meansTrial, covariancesTrial, weightsTrial,
+          useExistingModel);
 
       // Check to see if the log-likelihood of this one is better.
       double newLikelihood = LogLikelihood(observations, meansTrial,



More information about the mlpack-svn mailing list