[mlpack-git] master: Add implementation of convolution using svd to speeded up the computation. (1068cf5)
gitdub at big.cc.gt.atl.ga.us
gitdub at big.cc.gt.atl.ga.us
Wed Apr 22 08:04:56 EDT 2015
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/e2beb217f3e17729b73f9edc05601195e92f775d...8f85309ae9be40e819b301b39c9a940aa28f3bb2
>---------------------------------------------------------------
commit 1068cf5cfc18982bcd4a671cc08242948f7730e3
Author: Marcus Edel <marcus.edel at fu-berlin.de>
Date: Tue Apr 21 22:39:19 2015 +0200
Add implementation of convolution using svd to speeded up the computation.
>---------------------------------------------------------------
1068cf5cfc18982bcd4a671cc08242948f7730e3
.../ann/convolution_rules/svd_convolution.hpp | 109 +++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/src/mlpack/methods/ann/convolution_rules/svd_convolution.hpp b/src/mlpack/methods/ann/convolution_rules/svd_convolution.hpp
new file mode 100644
index 0000000..d2352de
--- /dev/null
+++ b/src/mlpack/methods/ann/convolution_rules/svd_convolution.hpp
@@ -0,0 +1,109 @@
+/**
+ * @file svd_convolution.hpp
+ * @author Marcus Edel
+ *
+ * Implementation of the convolution using the singular value decomposition to
+ * speeded up the computation.
+ */
+#ifndef __MLPACK_METHODS_ANN_CONVOLUTION_RULES_SVD_CONVOLUTION_HPP
+#define __MLPACK_METHODS_ANN_CONVOLUTION_RULES_SVD_CONVOLUTION_HPP
+
+#include <mlpack/core.hpp>
+#include "border_modes.hpp"
+#include "fft_convolution.hpp"
+#include "naive_convolution.hpp"
+
+namespace mlpack {
+namespace ann /** Artificial Neural Network. */ {
+
+/**
+ * Computes the two-dimensional convolution using singular value decomposition.
+ * 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 SVDConvolution
+{
+ public:
+ /*
+ * Perform a convolution (valid or full mode) using singular value
+ * decomposition. By using singular value decomposition of the filter matrix
+ * the convolution can be expressed as a sum of outer products. Each product
+ * can be computed efficiently as convolution with a row and a column vector.
+ * The individual convolutions are computed with the naive implementation wich
+ * is fast if the filter is low-dimensional.
+ *
+ * @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>
+ static void Convolution(const arma::Mat<eT>& input,
+ const arma::Mat<eT>& filter,
+ arma::Mat<eT>& output)
+ {
+ // Use the naive convolution in case the filter isn't two dimensional or the
+ // filter is bigger than the input.
+ if (filter.n_rows > input.n_rows || filter.n_cols > input.n_cols ||
+ filter.n_rows == 1 || filter.n_cols == 1)
+ {
+ NaiveConvolution<BorderMode>::Convolution(input, filter, output);
+ }
+ else
+ {
+ arma::Mat<eT> U, V, subOutput;
+ arma::Col<eT> s;
+
+ arma::svd_econ(U, s, V, filter);
+
+ // Rank approximation using the singular values calculated with singular
+ // value decomposition of dense filter matrix.
+ const size_t rank = arma::sum(s > (s.n_elem * arma::max(s) *
+ arma::datum::eps));
+
+ // Test for separability based on the rank of the kernel and take
+ // advantage of the low rank.
+ if (rank * (filter.n_rows + filter.n_cols) < filter.n_elem)
+ {
+ arma::Mat<eT> subFilter = V.unsafe_col(0) * s(0);
+ NaiveConvolution<BorderMode>::Convolution(input, subFilter, subOutput);
+
+ subOutput = subOutput.t();
+ NaiveConvolution<BorderMode>::Convolution(subOutput, U.unsafe_col(0),
+ output);
+
+ for (size_t r = 1; r < rank; r++)
+ {
+ subFilter = V.unsafe_col(r) * s(r);
+ NaiveConvolution<BorderMode>::Convolution(input, subFilter,
+ subOutput);
+
+ arma::Mat<eT> temp;
+ subOutput = subOutput.t();
+ NaiveConvolution<BorderMode>::Convolution(subOutput, U.unsafe_col(r),
+ temp);
+ output += temp;
+ }
+
+ output = output.t();
+ }
+ else
+ {
+ FFTConvolution<BorderMode>::Convolution(input, filter, output);
+ }
+ }
+ }
+}; // class SVDConvolution
+
+}; // namespace ann
+}; // namespace mlpack
+
+#endif
More information about the mlpack-git
mailing list