[mlpack-svn] r13337 - mlpack/trunk/src/mlpack/methods/nmf

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Sun Aug 5 00:59:44 EDT 2012


Author: rcurtin
Date: 2012-08-05 00:59:44 -0400 (Sun, 05 Aug 2012)
New Revision: 13337

Modified:
   mlpack/trunk/src/mlpack/methods/nmf/als_update_rules.hpp
   mlpack/trunk/src/mlpack/methods/nmf/nmf_impl.hpp
   mlpack/trunk/src/mlpack/methods/nmf/random_acol_init.hpp
Log:
Minor cleanup of NMF code; I think the residue should be displayed in
non-debugging mode (optionally with -v) so I switched to Log::Info.  Comment on
the change to pinv() then rewrite RandomAcolInitialization a little bit to avoid
allocating memory unnecessarily.  Unfortunately insert_cols() is a little slow
because it allocates more memory and memcpy()s.


Modified: mlpack/trunk/src/mlpack/methods/nmf/als_update_rules.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nmf/als_update_rules.hpp	2012-08-05 03:02:01 UTC (rev 13336)
+++ mlpack/trunk/src/mlpack/methods/nmf/als_update_rules.hpp	2012-08-05 04:59:44 UTC (rev 13337)
@@ -42,9 +42,10 @@
                             arma::mat& W,
                             const arma::mat& H)
   {
-    //W = (inv(H * H.t()) * H * V.t()).t();
+    // The call to inv() sometimes fails; so we are using the psuedoinverse.
+    // W = (inv(H * H.t()) * H * V.t()).t();
     W = V * H.t() * pinv(H * H.t());
-    
+
     // Set all negative numbers to machine epsilon
     for (size_t i = 0; i < W.n_elem; i++)
     {

Modified: mlpack/trunk/src/mlpack/methods/nmf/nmf_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nmf/nmf_impl.hpp	2012-08-05 03:02:01 UTC (rev 13336)
+++ mlpack/trunk/src/mlpack/methods/nmf/nmf_impl.hpp	2012-08-05 04:59:44 UTC (rev 13337)
@@ -89,7 +89,7 @@
     iteration++;
   }
 
-  Log::Debug << "NMF converged to residue of " << sqrt(residue) << " in "
+  Log::Info << "NMF converged to residue of " << sqrt(residue) << " in "
       << iteration << " iterations." << std::endl;
 }
 

Modified: mlpack/trunk/src/mlpack/methods/nmf/random_acol_init.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/nmf/random_acol_init.hpp	2012-08-05 03:02:01 UTC (rev 13336)
+++ mlpack/trunk/src/mlpack/methods/nmf/random_acol_init.hpp	2012-08-05 04:59:44 UTC (rev 13337)
@@ -1,22 +1,29 @@
 /**
- * @file randomacolinit.hpp
+ * @file random_acol_init.hpp
  * @author Mohan Rajendran
  *
- * Intialization rule for the Non-negative Matrix Factorization. This simple
- * initialization is performed by the rendom Acol initialization introduced in
+ * Intialization rule for Non-Negative Matrix Factorization. This simple
+ * initialization is performed by the random Acol initialization introduced in
  * the paper 'Algorithms, Initializations and Convergence' by Langville et al.
- * This method sets each of the column of W by averaging p randomly chosen
- * columns of A.
+ * This method sets each of the columns of W by averaging p randomly chosen
+ * columns of V.
  */
+#ifndef __MLPACK_METHODS_NMF_RANDOM_ACOL_INIT_HPP
+#define __MLPACK_METHODS_NMF_RANDOM_ACOL_INIT_HPP
 
-#ifndef __MLPACK_METHODS_NMF_RANDOMACOLINIT_HPP
-#define __MLPACK_METHODS_NMF_RANDOMACOLINIT_HPP
-
 #include <mlpack/core.hpp>
 
 namespace mlpack {
 namespace nmf {
 
+/**
+ * This class initializes the W matrix of the NMF algorithm by averaging p
+ * randomly chosen columns of V.  In this case, p is a template parameter.  H is
+ * then set randomly.
+ *
+ * @tparam The number of random columns to average for each column of W.
+ */
+template<int p = 5>
 class RandomAcolInitialization
 {
  public:
@@ -29,97 +36,37 @@
                                 arma::mat& W,
                                 arma::mat& H)
   {
-    // Simple implementation. This can be left here.
+    const size_t n = V.n_rows;
+    const size_t m = V.n_cols;
 
-    size_t n = V.n_rows;
-    size_t m = V.n_cols;
-
-    size_t p = 5;    
-
-    if(p > m)
+    if (p > m)
     {
-      Log::Info << "No. of random columns is more than the number of columns "
-          << "available in the V matrix. Setting the no. of random columns "
-          << "to " << m << "." << std::endl;
+      Log::Warn << "Number of random columns is more than the number of columns"
+          << "available in the V matrix; setting to the number of random "
+          << "columns to " << m << "." << std::endl;
       p = m;
     }
 
-    W.reset();
-    
-    // Initialize W matrix
-    arma::vec temp;
-    for(size_t col=0;col<r;col++)
-    {
-      temp.zeros(n);
-      for(size_t randcol=0;randcol<p;randcol++)
-      {
-        size_t rnd = math::RandInt(0,m);
-        temp += V.col(rnd);
-      }
-      W.insert_cols(col,temp/p);
-    }    
-  
-    // Intialize H to random values
-    H.randu(r,m);
-  }
-  
-}; // Class RandomAcolInitialization
+    W.zeros(n, m);
 
-}; // namespace nmf
-}; // namespace mlpack
-
-#endif
-
-/*namespace mlpack {
-namespace nmf {
-
-class RandomAcolInitialization
-{
- private:
-  size_t p;
- public:
-  // Constructor required for the InitializeRule template
-  RandomAcolInitialization()
-  { }
-
-  inline void Init(const arma::mat& V,
-                     arma::mat& W,
-                     arma::mat& H,
-                     const size_t& r)
-  {
-    // Simple inplementation. This can be left here.
-    size_t n = V.n_rows;
-    size_t m = V.n_cols;
-    p = 5;
-    if(p > m)
+    // Initialize W matrix with random columns.
+    for (size_t col = 0; col < r; col++)
     {
-      Log::Info << "No. of random columns is more than the number of columns "
-          << "available in the V matrix. Setting the no. of random columns "
-          << "to " << m << "." << std::endl;
-      p = m;
-    }
-    
-    // Initialize W matrix
-    W.zeros(n,r);
-    arma::colvec temp;
-    for(size_t col=0;col<r;col++)
-    {
-      temp.zeros();
-      for(size_t randcol=0;randcol<p;randcol++)
+      for (size_t randCol = 0; randCol < p; randCol++)
       {
-        size_t rnd = math::RandInt(0,m);
-        temp += V.col(rnd);
+        W.col(col) += V.col(math::RandInt(0, m));
       }
-      W.insert_cols(col,temp/p);
     }
-  
-    // Intialize H to random values
-    H.randu(r,m);
+
+    // Now divide by p.
+    W /= p;
+
+    // Initialize H to random values.
+    H.randu(r, m);
   }
-  
-}; // Class RandomInitialization
+}; // Class RandomAcolInitialization
 
 }; // namespace nmf
 }; // namespace mlpack
 
-#endif*/
+#endif




More information about the mlpack-svn mailing list