[mlpack-git] master: Add implementation of convolution using the naive approach (it's pretty fast for small filter). (1e30b68)

gitdub at big.cc.gt.atl.ga.us gitdub at big.cc.gt.atl.ga.us
Wed Apr 22 08:04:46 EDT 2015


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

On branch  : master
Link       : https://github.com/mlpack/mlpack/compare/e2beb217f3e17729b73f9edc05601195e92f775d...8f85309ae9be40e819b301b39c9a940aa28f3bb2

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

commit 1e30b68a681d0ac8e93ce3b54c7f378a2115d778
Author: Marcus Edel <marcus.edel at fu-berlin.de>
Date:   Mon Apr 20 11:52:35 2015 +0200

    Add implementation of convolution using the naive approach (it's pretty fast for small filter).


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

1e30b68a681d0ac8e93ce3b54c7f378a2115d778
 .../ann/convolution_rules/naive_convolution.hpp    | 101 +++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/src/mlpack/methods/ann/convolution_rules/naive_convolution.hpp b/src/mlpack/methods/ann/convolution_rules/naive_convolution.hpp
new file mode 100644
index 0000000..2275ef0
--- /dev/null
+++ b/src/mlpack/methods/ann/convolution_rules/naive_convolution.hpp
@@ -0,0 +1,101 @@
+/**
+ * @file naive_convolution.hpp
+ * @author Shangtong Zhang
+ * @author Marcus Edel
+ *
+ * Implementation of the convolution.
+ */
+#ifndef __MLPACK_METHODS_ANN_CONVOLUTION_RULES_NAIVE_CONVOLUTION_HPP
+#define __MLPACK_METHODS_ANN_CONVOLUTION_RULES_NAIVE_CONVOLUTION_HPP
+
+#include <mlpack/core.hpp>
+#include "border_modes.hpp"
+
+namespace mlpack {
+namespace ann /** Artificial Neural Network. */ {
+
+/**
+ * Computes the two-dimensional convolution. This class allows specification of
+ * the type of the border type. The convolution can be compute with the valid
+ * border type of the full border type (default).
+ *
+ * FullConvolution: returns the full two-dimensional convolution.
+ * ValidConvolution: returns only those parts of the convolution that are
+ * computed without the zero-padded edges.
+ *
+ * @tparam BorderMode Type of the border mode (FullConvolution or
+ * ValidConvolution).
+ */
+template<typename BorderMode = FullConvolution>
+class NaiveConvolution
+{
+ public:
+  /*
+   * Perform a convolution (valid mode).
+   *
+   * @param input Input used to perform the convolution.
+   * @param filter Filter used to perform the conolution.
+   * @param output Output data that contains the results of the convolution.
+   */
+  template<typename eT, typename Border = BorderMode>
+  static typename std::enable_if<
+      std::is_same<Border, ValidConvolution>::value, void>::type
+  Convolution(const arma::Mat<eT>& input,
+              const arma::Mat<eT>& filter,
+              arma::Mat<eT>& output)
+  {
+    output = arma::zeros<arma::Mat<eT> >(input.n_rows - filter.n_rows + 1,
+        input.n_cols - filter.n_cols + 1);
+
+    // It seems to be about 3.5 times faster to use pointers instead of
+    // filter(ki, kj) * input(leftInput + ki, topInput + kj) and output(i, j).
+    eT* outputPtr = output.memptr();
+
+    for (size_t j = 0; j < output.n_cols; ++j)
+    {
+      for (size_t i = 0; i < output.n_rows; ++i, outputPtr++)
+      {
+        const eT* kernelPtr = filter.memptr();
+        for (size_t kj = 0; kj < filter.n_cols; ++kj)
+        {
+          const eT* inputPtr = input.colptr(kj + j) + i;
+          for (size_t ki = 0; ki < filter.n_rows; ++ki, ++kernelPtr, ++inputPtr)
+            *outputPtr += *kernelPtr * (*inputPtr);
+        }
+      }
+    }
+  }
+
+  /*
+   * Perform a convolution (full mode).
+   *
+   * @param input Input used to perform the convolution.
+   * @param filter Filter used to perform the conolution.
+   * @param output Output data that contains the results of the convolution.
+   */
+  template<typename eT, typename Border = BorderMode>
+  static typename std::enable_if<
+      std::is_same<Border, FullConvolution>::value, void>::type
+  Convolution(const arma::Mat<eT>& input,
+              const arma::Mat<eT>& filter,
+              arma::Mat<eT>& output)
+  {
+    const size_t outputRows = input.n_rows + 2 * (filter.n_rows - 1);
+    const size_t outputCols = input.n_cols + 2 * (filter.n_cols - 1);
+
+    // Pad filter and input to the working output shape.
+    arma::Mat<eT> inputPadded = arma::zeros<arma::Mat<eT> >(outputRows,
+        outputCols);
+    inputPadded.submat(filter.n_rows - 1, filter.n_cols - 1,
+          filter.n_rows - 1 + input.n_rows - 1,
+          filter.n_cols - 1 + input.n_cols - 1) = input;
+
+    NaiveConvolution<ValidConvolution>::Convolution(inputPadded, filter,
+        output);
+  }
+};  // class NaiveConvolution
+
+}; // namespace ann
+}; // namespace mlpack
+
+#endif



More information about the mlpack-git mailing list