[mlpack-svn] r12381 - mlpack/trunk/src/mlpack/methods/sparse_coding

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Fri Apr 13 23:51:36 EDT 2012


Author: rcurtin
Date: 2012-04-13 23:51:36 -0400 (Fri, 13 Apr 2012)
New Revision: 12381

Modified:
   mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp
   mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp
   mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp
Log:
Rename some variables in the class.  Not done yet...


Modified: mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp	2012-04-14 02:55:08 UTC (rev 12380)
+++ mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp	2012-04-14 03:51:36 UTC (rev 12381)
@@ -17,44 +17,32 @@
 #define OBJ_TOL 1e-2 // 1E-9
 #define NEWTON_TOL 1e-6 // 1E-9
 
-SparseCoding::SparseCoding(const mat& matX,
+SparseCoding::SparseCoding(const mat& data,
                            const size_t atoms,
                            const double lambda1,
                            const double lambda2) :
-    nDims(matX.n_rows),
-    nAtoms(atoms),
-    nPoints(matX.n_cols),
-    matX(matX),
-    matZ(mat(nAtoms, nPoints)),
+    atoms(atoms),
+    data(data),
+    codes(mat(atoms, data.n_cols)),
     lambda1(lambda1),
     lambda2(lambda2)
 { /* Nothing left to do. */ }
 
-void SparseCoding::SetData(const mat& matX)
-{
-  this->matX = matX;
-}
-
-void SparseCoding::SetDictionary(const mat& matD)
-{
-  this->matD = matD;
-}
-
 // Always a not good decision!
 void SparseCoding::RandomInitDictionary() {
-  matD = randn(nDims, nAtoms);
+  dictionary = randn(data.n_rows, atoms);
 
-  for (size_t j = 0; j < nAtoms; ++j)
-    matD.col(j) /= norm(matD.col(j), 2);
+  for (size_t j = 0; j < atoms; ++j)
+    dictionary.col(j) /= norm(dictionary.col(j), 2);
 }
 
 // The sensible heuristic.
 void SparseCoding::DataDependentRandomInitDictionary()
 {
-  matD = mat(nDims, nAtoms);
-  for (size_t j = 0; j < nAtoms; ++j)
+  dictionary = mat(data.n_rows, atoms);
+  for (size_t j = 0; j < atoms; ++j)
   {
-    vec vecD_j = matD.unsafe_col(j);
+    vec vecD_j = dictionary.unsafe_col(j);
     RandomAtom(vecD_j);
   }
 }
@@ -64,7 +52,7 @@
   atom.zeros();
   const size_t nSeedAtoms = 3;
   for (size_t i = 0; i < nSeedAtoms; i++)
-    atom += matX.col(rand() % nPoints);
+    atom += data.col(rand() % data.n_cols);
 
   atom /= norm(atom, 2);
 }
@@ -76,10 +64,10 @@
   Log::Info << "Initial Coding Step." << endl;
 
   OptimizeCode();
-  uvec adjacencies = find(matZ);
+  uvec adjacencies = find(codes);
 
   Log::Info << "  Sparsity level: "
-      << 100.0 * ((double) (adjacencies.n_elem)) / ((double) (nAtoms * nPoints))
+      << 100.0 * ((double) (adjacencies.n_elem)) / ((double) (atoms * data.n_cols))
       << "%" << endl;
   Log::Info << "  Objective value: " << Objective() << "." << endl;
 
@@ -93,10 +81,10 @@
 
     Log::Info << "Performing coding step..." << endl;
     OptimizeCode();
-    adjacencies = find(matZ);
+    adjacencies = find(codes);
     Log::Info << "  Sparsity level: "
         << 100.0 *
-        ((double) (adjacencies.n_elem)) / ((double) (nAtoms * nPoints))
+        ((double) (adjacencies.n_elem)) / ((double) (atoms * data.n_cols))
         << "%" << endl;
 
     double curObjVal = Objective();
@@ -118,16 +106,16 @@
 void SparseCoding::OptimizeCode()
 {
   // When using Cholesky version of LARS, this is correct even if lambda2 > 0.
-  mat matGram = trans(matD) * matD;
+  mat matGram = trans(dictionary) * dictionary;
   // mat matGram;
   // if(lambda2 > 0) {
-  //   matGram = trans(matD) * matD + lambda2 * eye(nAtoms, nAtoms);
+  //   matGram = trans(dictionary) * dictionary + lambda2 * eye(atoms, atoms);
   // }
   // else {
-  //   matGram = trans(matD) * matD;
+  //   matGram = trans(dictionary) * dictionary;
   // }
 
-  for (size_t i = 0; i < nPoints; ++i)
+  for (size_t i = 0; i < data.n_cols; ++i)
   {
     // Report progress.
     if ((i % 100) == 0)
@@ -141,11 +129,11 @@
       lars = new LARS(useCholesky, lambda1);
 
     lars->SetGramMem(matGram.memptr(), matGram.n_rows);
-    lars->DoLARS(matD, matX.unsafe_col(i));
+    lars->DoLARS(dictionary, data.unsafe_col(i));
 
     vec beta;
     lars->Solution(beta);
-    matZ.col(i) = beta;
+    codes.col(i) = beta;
 
     delete lars;
   }
@@ -154,25 +142,25 @@
 void SparseCoding::OptimizeDictionary(const uvec& adjacencies)
 {
   // Count the number of atomic neighbors for each point x^i.
-  uvec neighborCounts = zeros<uvec>(nPoints, 1);
+  uvec neighborCounts = zeros<uvec>(data.n_cols, 1);
 
   if (adjacencies.n_elem > 0)
   {
     // This gets the column index.
     // TODO: is this integer division intentional?
-    size_t curPointInd = (size_t) (adjacencies(0) / nAtoms);
+    size_t curPointInd = (size_t) (adjacencies(0) / atoms);
     size_t curCount = 1;
 
     for (size_t l = 1; l < adjacencies.n_elem; ++l)
     {
-      if ((size_t) (adjacencies(l) / nAtoms) == curPointInd)
+      if ((size_t) (adjacencies(l) / atoms) == curPointInd)
       {
         ++curCount;
       }
       else
       {
         neighborCounts(curPointInd) = curCount;
-        curPointInd = (size_t) (adjacencies(l) / nAtoms);
+        curPointInd = (size_t) (adjacencies(l) / atoms);
         curCount = 1;
       }
     }
@@ -183,11 +171,11 @@
   // Handle the case of inactive atoms (atoms not used in the given coding).
   std::vector<size_t> inactiveAtoms;
   std::vector<size_t> activeAtoms;
-  activeAtoms.reserve(nAtoms);
+  activeAtoms.reserve(atoms);
 
-  for (size_t j = 0; j < nAtoms; ++j)
+  for (size_t j = 0; j < atoms; ++j)
   {
-    if (accu(matZ.row(j) != 0) == 0)
+    if (accu(codes.row(j) != 0) == 0)
       inactiveAtoms.push_back(j);
     else
       activeAtoms.push_back(j);
@@ -200,15 +188,15 @@
   mat matActiveZ;
   if (inactiveAtoms.empty())
   {
-    matActiveZ = matZ;
+    matActiveZ = codes;
   }
   else
   {
     uvec inactiveAtomsVec = conv_to<uvec>::from(inactiveAtoms);
-    RemoveRows(matZ, inactiveAtomsVec, matActiveZ);
+    RemoveRows(codes, inactiveAtomsVec, matActiveZ);
   }
 
-  uvec atomReverseLookup = uvec(nAtoms);
+  uvec atomReverseLookup = uvec(atoms);
   for (size_t i = 0; i < nActiveAtoms; ++i)
     atomReverseLookup(activeAtoms[i]) = i;
 
@@ -220,7 +208,7 @@
 
   Log::Debug << "Solving Dual via Newton's Method.\n";
 
-  mat matDEstimate;
+  mat dictionaryEstimate;
   // Solve using Newton's method in the dual - note that the final dot
   // multiplication with inv(A) seems to be unavoidable. Although more
   // expensive, the code written this way (we use solve()) should be more
@@ -233,21 +221,21 @@
   // MATLAB optimizer fmincon does something clever?
   //vec dualVars = 10.0 * randu(nActiveAtoms, 1);
 
-  //vec dualVars = diagvec(solve(matD, matX * trans(matZ))
-  //    - matZ * trans(matZ));
+  //vec dualVars = diagvec(solve(dictionary, data * trans(codes))
+  //    - codes * trans(codes));
   //for (size_t i = 0; i < dualVars.n_elem; i++)
   //  if (dualVars(i) < 0)
   //    dualVars(i) = 0;
 
   bool converged = false;
-  mat matZXT = matActiveZ * trans(matX);
-  mat matZZT = matActiveZ * trans(matActiveZ);
+  mat codesXT = matActiveZ * trans(data);
+  mat codesZT = matActiveZ * trans(matActiveZ);
 
   for (size_t t = 1; !converged; ++t)
   {
-    mat A = matZZT + diagmat(dualVars);
+    mat A = codesZT + diagmat(dualVars);
 
-    mat matAInvZXT = solve(A, matZXT);
+    mat matAInvZXT = solve(A, codesXT);
 
     vec gradient = -(sum(square(matAInvZXT), 1) - ones<vec>(nActiveAtoms));
 
@@ -265,11 +253,11 @@
     /*
     {
       double sumDualVars = sum(dualVars);
-      double fOld = -(-trace(trans(matZXT) * matAInvZXT) - sumDualVars);
+      double fOld = -(-trace(trans(codesXT) * matAInvZXT) - sumDualVars);
       Log::Debug << "fOld = " << fOld << "." << endl;
       double fNew =
-          -(-trace(trans(matZXT) * solve(matZZT +
-          diagmat(dualVars + alpha * searchDirection), matZXT))
+          -(-trace(trans(codesXT) * solve(codesZT +
+          diagmat(dualVars + alpha * searchDirection), codesXT))
           - (sumDualVars + alpha * sum(searchDirection)) );
       Log::Debug << "fNew = " << fNew << "." << endl;
     }
@@ -280,9 +268,9 @@
     {
       // Calculate objective.
       double sumDualVars = sum(dualVars);
-      double fOld = -(-trace(trans(matZXT) * matAInvZXT) - sumDualVars);
-      double fNew = -(-trace(trans(matZXT) * solve(matZZT +
-          diagmat(dualVars + alpha * searchDirection), matZXT)) -
+      double fOld = -(-trace(trans(codesXT) * matAInvZXT) - sumDualVars);
+      double fNew = -(-trace(trans(codesXT) * solve(codesZT +
+          diagmat(dualVars + alpha * searchDirection), codesXT)) -
           (sumDualVars + alpha * sum(searchDirection)));
 
       if (fNew <= fOld + alpha * sufficientDecrease)
@@ -310,48 +298,48 @@
 
   if (inactiveAtoms.empty())
   {
-    matDEstimate = trans(solve(matZZT + diagmat(dualVars), matZXT));
+    dictionaryEstimate = trans(solve(codesZT + diagmat(dualVars), codesXT));
   }
   else
   {
-    mat matDActiveEstimate = trans(solve(matZZT + diagmat(dualVars), matZXT));
-    matDEstimate = zeros(nDims, nAtoms);
+    mat dictionaryActiveEstimate = trans(solve(codesZT + diagmat(dualVars), codesXT));
+    dictionaryEstimate = zeros(data.n_rows, atoms);
 
     for (size_t i = 0; i < nActiveAtoms; ++i)
-      matDEstimate.col(activeAtoms[i]) = matDActiveEstimate.col(i);
+      dictionaryEstimate.col(activeAtoms[i]) = dictionaryActiveEstimate.col(i);
 
     for (size_t i = 0; i < nInactiveAtoms; ++i)
     {
-      vec vecmatDi = matDEstimate.unsafe_col(inactiveAtoms[i]);
-      RandomAtom(vecmatDi);
+      vec vecdictionaryi = dictionaryEstimate.unsafe_col(inactiveAtoms[i]);
+      RandomAtom(vecdictionaryi);
     }
   }
 
-  matD = matDEstimate;
+  dictionary = dictionaryEstimate;
 }
 
 void SparseCoding::ProjectDictionary()
 {
-  for (size_t j = 0; j < nAtoms; j++)
+  for (size_t j = 0; j < atoms; j++)
   {
-    double normD_j = norm(matD.col(j), 2);
+    double normD_j = norm(dictionary.col(j), 2);
     if ((normD_j > 1) && (normD_j - 1.0 > 1e-9))
     {
       Log::Warn << "Norm exceeded 1 by " << std::scientific << normD_j - 1.0
           << ".  Shrinking...\n";
-      matD.col(j) /= normD_j;
+      dictionary.col(j) /= normD_j;
     }
   }
 }
 
 double SparseCoding::Objective()
 {
-  double l11NormZ = sum(sum(abs(matZ)));
-  double froNormResidual = norm(matX - matD * matZ, "fro");
+  double l11NormZ = sum(sum(abs(codes)));
+  double froNormResidual = norm(data - dictionary * codes, "fro");
 
   if (lambda2 > 0)
   {
-    double froNormZ = norm(matZ, "fro");
+    double froNormZ = norm(codes, "fro");
     return 0.5 *
       (froNormResidual * froNormResidual + lambda2 * froNormZ * froNormZ) +
       lambda1 * l11NormZ;
@@ -362,16 +350,6 @@
   }
 }
 
-void SparseCoding::PrintDictionary()
-{
-  Log::Info << "Dictionary: " << endl << matD;
-}
-
-void SparseCoding::PrintCoding()
-{
-  Log::Info << "Coding matrix: " << endl << matZ;
-}
-
 void mlpack::sparse_coding::RemoveRows(const mat& X,
                                        uvec rows_to_remove,
                                        mat& X_mod)

Modified: mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp	2012-04-14 02:55:08 UTC (rev 12380)
+++ mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp	2012-04-14 03:51:36 UTC (rev 12381)
@@ -84,12 +84,12 @@
   /**
    * Set the parameters to SparseCoding. lambda2 defaults to 0.
    *
-   * @param matX Data matrix
+   * @param data Data matrix
    * @param atoms Number of atoms in dictionary
    * @param lambda1 Regularization parameter for l1-norm penalty
    * @param lambda2 Regularization parameter for l2-norm penalty
    */
-  SparseCoding(const arma::mat& matX,
+  SparseCoding(const arma::mat& data,
                const size_t atoms,
                const double lambda1,
                const double lambda2 = 0);
@@ -149,41 +149,33 @@
   double Objective();
 
 
-  // accessors, modifiers, printers
+  //! Access the data.
+  const arma::mat& Data() const { return data; }
+  //! Modify the data.
+  arma::mat& Data() { return data; }
 
-  //! Modifier for matX.
-  void SetData(const arma::mat& matX);
+  //! Access the dictionary.
+  const arma::mat& Dictionary() const { return dictionary; }
+  //! Modify the dictionary.
+  arma::mat& Dictionary() { return dictionary; }
 
-  //! Modifier for matD.
-  void SetDictionary(const arma::mat& matD);
+  //! Access the sparse codes.
+  const arma::mat& Codes() const { return codes; }
+  //! Modify the sparse codes.
+  arma::mat& Codes() { return codes; }
 
-  //! Accessor for matD.
-  const arma::mat& MatD() { return matD; }
-  //! Accessor for matZ
-  const arma::mat& MatZ() { return matZ; }
-
-  // Print the dictionary matD
-  void PrintDictionary();
-
-  // Print the sparse codes matZ
-  void PrintCoding();
-
  private:
-  //! Number of dimensions.
-  size_t nDims;
   //! Number of atoms.
-  size_t nAtoms;
-  //! Number of points.
-  size_t nPoints;
+  size_t atoms;
 
   //! data (columns are points).
-  arma::mat matX;
+  arma::mat data;
 
   //! dictionary (columns are atoms).
-  arma::mat matD;
+  arma::mat dictionary;
 
   //! Sparse codes (columns are points).
-  arma::mat matZ;
+  arma::mat codes;
 
   //! l1 regularization term.
   double lambda1;

Modified: mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp	2012-04-14 02:55:08 UTC (rev 12380)
+++ mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding_main.cpp	2012-04-14 03:51:36 UTC (rev 12381)
@@ -87,15 +87,15 @@
           << "has " << matX.n_rows << " dimensions!" << endl;
     }
 
-    sc.SetDictionary(matInitialD);
+    sc.Dictionary() = matInitialD;
   }
 
   Timer::Start("sparse_coding");
   sc.DoSparseCoding(nIterations);
   Timer::Stop("sparse_coding");
 
-  mat learnedD = sc.MatD();
-  mat learnedZ = sc.MatZ();
+  mat learnedD = sc.Dictionary();
+  mat learnedZ = sc.Codes();
 
   if (strlen(resultsDir) == 0)
   {




More information about the mlpack-svn mailing list