[mlpack-git] master: make MaximalInputs become more general (612e562)

gitdub at big.cc.gt.atl.ga.us gitdub at big.cc.gt.atl.ga.us
Mon Nov 30 10:40:17 EST 2015


Repository : https://github.com/mlpack/mlpack

On branch  : master
Link       : https://github.com/mlpack/mlpack/compare/5aaf0e441dd64a5de9a0210aa7a837eecf162d12...e4519fc42a2a340cf0387ab082bf49b9715c871b

>---------------------------------------------------------------

commit 612e562611da589ce3603070f5a41ac424febade
Author: stereomatchingkiss <stereomatchingkiss at gmail.com>
Date:   Wed Nov 4 20:57:11 2015 +0800

    make MaximalInputs become more general


>---------------------------------------------------------------

612e562611da589ce3603070f5a41ac424febade
 .../methods/sparse_autoencoder/maximal_inputs.cpp  | 127 +++++++++++++--------
 .../methods/sparse_autoencoder/maximal_inputs.hpp  |  45 ++++++--
 2 files changed, 118 insertions(+), 54 deletions(-)

diff --git a/src/mlpack/methods/sparse_autoencoder/maximal_inputs.cpp b/src/mlpack/methods/sparse_autoencoder/maximal_inputs.cpp
index efc66c6..db68616 100644
--- a/src/mlpack/methods/sparse_autoencoder/maximal_inputs.cpp
+++ b/src/mlpack/methods/sparse_autoencoder/maximal_inputs.cpp
@@ -5,71 +5,104 @@ namespace nn {
 
 namespace {
 
-void VisualizeHiddenUnit(arma::uword rows, arma::uword cols,
-                         const arma::mat &input,
-                         arma::mat &output)
+std::pair<arma::uword, arma::uword> GetSize(arma::mat const &input)
 {
-  arma::uword const squareRows = static_cast<arma::uword>(std::sqrt(input.n_rows));
-  arma::uword const buf = 1;
+  arma::uword rows = 0, cols = 0;
+  if(std::pow(std::floor(std::sqrt(input.n_cols)), 2) != input.n_cols)
+  {
+    cols = static_cast<arma::uword>(std::ceil(std::sqrt(input.n_cols)));
+    while(input.n_cols % cols != 0 && cols < 1.2*std::sqrt(input.n_cols))
+    {
+      ++cols;
+    }
+    rows = static_cast<arma::uword>
+           (std::ceil(input.n_cols/static_cast<double>(cols)));
+  }
+  else
+  {
+    cols = static_cast<arma::uword>(std::sqrt(input.n_cols));
+    rows = cols;
+  }
 
-  arma::uword const offset = squareRows+buf;
-  output.ones(buf+rows*(offset),
-              buf+cols*(offset));
+  return {rows, cols};
+}
 
-  arma::uword k = 0;
-  for(arma::uword i = 0; i != rows; ++i) {
-    for(arma::uword j = 0; j != cols; ++j) {
-      if(k >= input.n_cols) {
-        continue;
-      }
-      // Find the maximum element in this row.
-      const double max  = arma::max(arma::abs(input.col(k)));
-      // Now, copy the elements of the row to the output submatrix.
-      const arma::uword minRow = i * offset;
-      const arma::uword minCol = j * offset;
-      const arma::uword maxRow = i * offset + squareRows - 1;
-      const arma::uword maxCol = j * offset + squareRows - 1;
-      // Only divide by the max if it's not 0.
-      if (max != 0.0)
-        output.submat(minRow, minCol, maxRow, maxCol) =
-          arma::reshape(input.col(k), squareRows, squareRows) / max;
-      else
-        output.submat(minRow, minCol, maxRow, maxCol) =
-          arma::reshape(input.col(k), squareRows, squareRows);
-
-      ++k;
+void MaximizeHiddenUnit(arma::uword rows, arma::uword cols,
+                        const arma::mat &input,
+                        arma::mat &output)
+{
+  const arma::uword size = rows * cols;
+  output.set_size(input.n_rows, size);
+  for(arma::uword i = 0; i != size; ++i)
+  {
+    const double max  = arma::max(arma::abs(input.col(i)));
+    if (max != 0.0)
+    {
+      output.col(i) = input.col(i) / max;
+    }
+    else
+    {
+      output.col(i) = input.col(i);
     }
   }
 }
 
 }
 
-void MaximalInputs(const arma::mat &parameters, arma::mat &output, double minRange, double maxRange)
+
+
+std::pair<arma::uword, arma::uword> MaximalInputs(const arma::mat &parameters, arma::mat &output)
 {
   arma::mat paramTemp(parameters.submat(0, 0, (parameters.n_rows-1)/2 - 1,
                                         parameters.n_cols - 2).t());
   double const mean = arma::mean(arma::mean(paramTemp));
   paramTemp -= mean;
 
-  arma::uword rows = 0, cols = 0;
-  if(std::pow(std::floor(std::sqrt(paramTemp.n_cols)), 2) != paramTemp.n_cols) {
-    cols = static_cast<arma::uword>(std::ceil(std::sqrt(paramTemp.n_cols)));
-    while(paramTemp.n_cols % cols != 0 && cols < 1.2*std::sqrt(paramTemp.n_cols)) {
-      ++cols;
-    }
-    rows = static_cast<arma::uword>
-           (std::ceil(paramTemp.n_cols/static_cast<double>(cols)));
-  }else{
-    cols = static_cast<arma::uword>(std::sqrt(paramTemp.n_cols));
-    rows = cols;
+  const auto Size = GetSize(paramTemp);
+  MaximizeHiddenUnit(Size.first, Size.second, paramTemp, output);
+
+  return Size;
+}
+
+void ColumnsToBlocks(const arma::mat &maximalInputs,
+                     arma::mat &outputs, arma::uword rows, arma::uword cols,
+                     bool scale, double minRange,
+                     double maxRange)
+{
+  if(rows * cols != maximalInputs.n_cols)
+  {
+    throw std::range_error("rows * cols != maximalInputs.n_cols");
   }
 
-  VisualizeHiddenUnit(rows, cols, paramTemp, output);
+  arma::uword const squareRows = static_cast<arma::uword>(std::sqrt(maximalInputs.n_rows));
+  arma::uword const buf = 1;
+
+  arma::uword const offset = squareRows+buf;
+  outputs.ones(buf+rows*(offset),
+               buf+cols*(offset));
 
-  double const max = output.max();
-  double const min = output.min();
-  if((max - min) != 0) {
-    output = (output - min) / (max - min) * (maxRange - minRange) + minRange;
+  arma::uword k = 0;
+  for(arma::uword i = 0; i != rows; ++i) {
+    for(arma::uword j = 0; j != cols; ++j) {
+      // Now, copy the elements of the row to the output submatrix.
+      const arma::uword minRow = i * offset;
+      const arma::uword minCol = j * offset;
+      const arma::uword maxRow = i * offset + squareRows - 1;
+      const arma::uword maxCol = j * offset + squareRows - 1;
+
+      outputs.submat(minRow, minCol, maxRow, maxCol) =
+        arma::reshape(maximalInputs.col(k++), squareRows, squareRows);
+    }
+  }
+
+  if(scale)
+  {
+    const double max = outputs.max();
+    const double min = outputs.min();
+    if((max - min) != 0)
+    {
+      outputs = (outputs - min) / (max - min) * (maxRange - minRange) + minRange;
+    }
   }
 }
 
diff --git a/src/mlpack/methods/sparse_autoencoder/maximal_inputs.hpp b/src/mlpack/methods/sparse_autoencoder/maximal_inputs.hpp
index d250792..0a6bc94 100644
--- a/src/mlpack/methods/sparse_autoencoder/maximal_inputs.hpp
+++ b/src/mlpack/methods/sparse_autoencoder/maximal_inputs.hpp
@@ -6,7 +6,6 @@
 namespace mlpack {
 namespace nn {
 
-
 /**
  * Maximize the hidden units of the parameters, details are located at
  * http://deeplearning.stanford.edu/wiki/index.php/Visualizing_a_Trained_Autoencoder.
@@ -14,8 +13,7 @@ namespace nn {
  * http://deeplearning.stanford.edu/wiki/index.php/Exercise:Sparse_Autoencoder
  * @param params The parameters want to maximize
  * @param output Parameters after maximize
- * @param minRange minimum range of the output, default value is 0
- * @param maxRange maximum range of the output, default value is 255
+ * @return Suggestion rows and cols for the function "ColumnsToBlocks"
  * @pre 1 : The layout of the parameters should be same as following
  * //          vSize   1
  * //       |        |  |
@@ -42,12 +40,45 @@ namespace nn {
  * SparseAutoencoder<L_BFGS> encoder2(optimizer);
  *
  * arma::mat maximalInput; //store the features learned by sparse autoencoder
- * mlpack::nn::MaximalInputs(encoder2.Parameters(), maximalInput);
- * maximalInput.save("trained.pgm", arma::pgm_binary);
+ * const auto Size = mlpack::nn::MaximalInputs(encoder2.Parameters(), maximalInput);
+ *
+ * arma::mat outputs;
+ * const bool scale = true;
+ * //put the maximalInput of each col into rows * cols(Size.first * Size.second) blocks,
+ * //rows * cols must same as maximalInput.n_cols.If you are training a bunch of images,
+ * //this function could help you visualize your trained results
+ * mlpack::nn::ColumnsToBlocks(maximalInput, outputs, Size.first, Size.second, scale);
+ *
+ * @endcode
+ */
+std::pair<arma::uword, arma::uword> MaximalInputs(const arma::mat &parameters, arma::mat &output);
+
+/**
+ * Transform the output of "MaximalInputs" to blocks, if your training samples are images,
+ * this function could help you visualize your training results
+ * @param maximalInputs Parameters after maximize by "MaximalInputs", each col assiociate to one sample
+ * @param output Maximal inputs regrouped to blocks
+ * @param rows number of blocks per cols
+ * @param cols number of blocks per rows
+ * @param scale False, the output will not be scaled and vice versa
+ * @param minRange minimum range of the output
+ * @param maxRange maximum range of the output
+ * @code
+ * arma::mat maximalInput; //store the features learned by sparse autoencoder
+ * const auto Size = mlpack::nn::MaximalInputs(encoder2.Parameters(), maximalInput);
+ *
+ * arma::mat outputs;
+ * const bool scale = true;
+ * //put the maximalInput of each col into rows * cols(Size.first * Size.second) blocks,
+ * //rows * cols must same as maximalInput.n_cols.If you are training a bunch of images,
+ * //this function could help you visualize your trained results
+ * mlpack::nn::ColumnsToBlocks(maximalInput, outputs, Size.first, Size.second, scale);
  * @endcode
  */
-void MaximalInputs(const arma::mat &parameters, arma::mat &output,
-                   double minRange = 0, double maxRange = 255);
+void ColumnsToBlocks(const arma::mat &maximalInputs,
+                     arma::mat &outputs, arma::uword rows, arma::uword cols,
+                     bool scale = false,
+                     double minRange = 0, double maxRange = 255);
 
 } // namespace nn
 } // namespace mlpack



More information about the mlpack-git mailing list