From 0ed4da96cdb8e6ebdecf2c6f09b85f4b49c9a51f Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 01:32:55 +0530 Subject: [PATCH 01/12] Added LP lookup layer --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 289 ++++++++++++++++++ .../methods/ann/layer/lp_pooling_impl.hpp | 141 +++++++++ src/mlpack/tests/ann_layer_test.cpp | 48 +++ 3 files changed, 478 insertions(+) create mode 100644 src/mlpack/methods/ann/layer/lp_pooling.hpp create mode 100644 src/mlpack/methods/ann/layer/lp_pooling_impl.hpp diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp new file mode 100644 index 0000000000..e698f89e93 --- /dev/null +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -0,0 +1,289 @@ +/** + * @file methods/ann/layer/lp_pooling.hpp + * @author Abhinav Anan + * + * Definition of the LpPooling layer class. + * + * mlpack is free software; you may redistribute it and/or modify it under the + * terms of the 3-clause BSD license. You should have received a copy of the + * 3-clause BSD license along with mlpack. If not, see + * http://www.opensource.org/licenses/BSD-3-Clause for more information. + */ +#ifndef MLPACK_METHODS_ANN_LAYER_LP_POOLING_HPP +#define MLPACK_METHODS_ANN_LAYER_LP_POOLING_HPP + +#include + +namespace mlpack { +namespace ann /** Artificial Neural Network. */ { + +/** + * Implementation of the LPPooling. + * + * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, + * arma::sp_mat or arma::cube). + * @tparam OutputDataType Type of the output data (arma::colvec, arma::mat, + * arma::sp_mat or arma::cube). + */ +template < + typename InputDataType = arma::mat, + typename OutputDataType = arma::mat +> +class LpPooling +{ + public: + //! Create the LpPooling object. + LpPooling(); + + /** + * Create the LpPooling object using the specified number of units. + * + * @param kernelWidth Width of the pooling window. + * @param kernelHeight Height of the pooling window. + * @param strideWidth Width of the stride operation. + * @param strideHeight Width of the stride operation. + * @param floor Set to true to use floor method. + */ + LpPooling(const size_t norm_type, + const size_t kernelWidth, + const size_t kernelHeight, + const size_t strideWidth = 1, + const size_t strideHeight = 1, + const bool floor = true); + + /** + * Ordinary feed forward pass of a neural network, evaluating the function + * f(x) by propagating the activity forward through f. + * + * @param input Input data used for evaluating the specified function. + * @param output Resulting output activation. + */ + template + void Forward(const arma::Mat& input, arma::Mat& output); + + /** + * Ordinary feed backward pass of a neural network, using 3rd-order tensors as + * input, calculating the function f(x) by propagating x backwards through f. + * Using the results from the feed forward pass. + * + * @param * (input) The propagated input activation. + * @param gy The backpropagated error. + * @param g The calculated gradient. + */ + template + void Backward(const arma::Mat& /* input */, + const arma::Mat& gy, + arma::Mat& g); + + //! Get the output parameter. + OutputDataType const& OutputParameter() const { return outputParameter; } + //! Modify the output parameter. + OutputDataType& OutputParameter() { return outputParameter; } + + //! Get the delta. + OutputDataType const& Delta() const { return delta; } + //! Modify the delta. + OutputDataType& Delta() { return delta; } + + //! Get the intput width. + size_t const& InputWidth() const { return inputWidth; } + //! Modify the input width. + size_t& InputWidth() { return inputWidth; } + + //! Get the input height. + size_t const& InputHeight() const { return inputHeight; } + //! Modify the input height. + size_t& InputHeight() { return inputHeight; } + + //! Get the output width. + size_t const& OutputWidth() const { return outputWidth; } + //! Modify the output width. + size_t& OutputWidth() { return outputWidth; } + + //! Get the output height. + size_t const& OutputHeight() const { return outputHeight; } + //! Modify the output height. + size_t& OutputHeight() { return outputHeight; } + + //! Get the input size. + size_t InputSize() const { return inSize; } + + //! Get the output size. + size_t OutputSize() const { return outSize; } + + //! Get the norm_type. + size_t NormType() const { return norm_type; } + //! Modify the norm_type. + size_t& NormType() const { return norm_type; } + + //! Get the kernel width. + size_t KernelWidth() const { return kernelWidth; } + //! Modify the kernel width. + size_t& KernelWidth() { return kernelWidth; } + + //! Get the kernel height. + size_t KernelHeight() const { return kernelHeight; } + //! Modify the kernel height. + size_t& KernelHeight() { return kernelHeight; } + + //! Get the stride width. + size_t StrideWidth() const { return strideWidth; } + //! Modify the stride width. + size_t& StrideWidth() { return strideWidth; } + + //! Get the stride height. + size_t StrideHeight() const { return strideHeight; } + //! Modify the stride height. + size_t& StrideHeight() { return strideHeight; } + + //! Get the value of the rounding operation + bool const& Floor() const { return floor; } + //! Modify the value of the rounding operation + bool& Floor() { return floor; } + + //! Get the value of the deterministic parameter. + bool Deterministic() const { return deterministic; } + //! Modify the value of the deterministic parameter. + bool& Deterministic() { return deterministic; } + + //! Get the size of the weights. + size_t WeightSize() const { return 0; } + + /** + * Serialize the layer. + */ + template + void serialize(Archive& ar, const uint32_t /* version */); + + private: + /** + * Apply pooling to the input and store the results. + * + * @param input The input to be apply the pooling rule. + * @param output The pooled result. + */ + template + void Pooling(const arma::Mat& input, arma::Mat& output) + { + for (size_t j = 0, colidx = 0; j < output.n_cols; + ++j, colidx += strideHeight) + { + for (size_t i = 0, rowidx = 0; i < output.n_rows; + ++i, rowidx += strideWidth) + { + arma::mat subInput = input( + arma::span(rowidx, rowidx + kernelWidth - 1 - offset), + arma::span(colidx, colidx + kernelHeight - 1 - offset)); + + output(i, j) = arma::pow(arma::accu(arma::pow(subInput, norm_type)), 1.0/norm_type); + } + } + } + + /** + * Apply unpooling to the input and store the results. + * + * @param input The input to be apply the unpooling rule. + * @param output The pooled result. + */ + template + void Unpooling(const arma::Mat& input, + const arma::Mat& error, + arma::Mat& output) + { + const size_t rStep = input.n_rows / error.n_rows - offset; + const size_t cStep = input.n_cols / error.n_cols - offset; + + arma::Mat unpooledError; + for (size_t j = 0; j < input.n_cols - cStep; j += cStep) + { + for (size_t i = 0; i < input.n_rows - rStep; i += rStep) + { + const arma::Mat& inputArea = input(arma::span(i, i + rStep - 1), + arma::span(j, j + cStep - 1)); + size_t sum = arma::pow(arma::accu(arma::pow(inputArea, norm_type)), (norm_type-1) / norm_type); + unpooledError = arma::Mat(inputArea.n_rows, inputArea.n_cols); + unpooledError.fill(error(i / rStep, j / cStep)); + unpooledError %= arma::pow(inputArea, norm_type - 1); + unpooledError /= sum; + output(arma::span(i, i + rStep - 1 - offset), + arma::span(j, j + cStep - 1 - offset)) += unpooledError; + } + } + } + + //! Locally-stored norm_type. + size_t norm_type; + + //! Locally-stored width of the pooling window. + size_t kernelWidth; + + //! Locally-stored height of the pooling window. + size_t kernelHeight; + + //! Locally-stored width of the stride operation. + size_t strideWidth; + + //! Locally-stored height of the stride operation. + size_t strideHeight; + + //! Rounding operation used. + bool floor; + + //! Locally-stored number of input channels. + size_t inSize; + + //! Locally-stored number of output channels. + size_t outSize; + + //! Locally-stored input width. + size_t inputWidth; + + //! Locally-stored input height. + size_t inputHeight; + + //! Locally-stored output width. + size_t outputWidth; + + //! Locally-stored output height. + size_t outputHeight; + + //! Locally-stored reset parameter used to initialize the module once. + bool reset; + + //! If true use maximum a posteriori during the forward pass. + bool deterministic; + + //! Locally-stored stored rounding offset. + size_t offset; + + //! Locally-stored number of input units. + size_t batchSize; + + //! Locally-stored output parameter. + arma::cube outputTemp; + + //! Locally-stored transformed input parameter. + arma::cube inputTemp; + + //! Locally-stored transformed output parameter. + arma::cube gTemp; + + //! Locally-stored delta object. + OutputDataType delta; + + //! Locally-stored gradient object. + OutputDataType gradient; + + //! Locally-stored output parameter object. + OutputDataType outputParameter; +}; // class LpPooling + + +} // namespace ann +} // namespace mlpack + +// Include implementation. +#include "lp_pooling_impl.hpp" + +#endif diff --git a/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp b/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp new file mode 100644 index 0000000000..9f1133aee8 --- /dev/null +++ b/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp @@ -0,0 +1,141 @@ +/** + * @file methods/ann/layer/lp_pooling_impl.hpp + * @author Marcus Edel + * @author Nilay Jain + * + * Implementation of the lpPooling layer class. + * + * mlpack is free software; you may redistribute it and/or modify it under the + * terms of the 3-clause BSD license. You should have received a copy of the + * 3-clause BSD license along with mlpack. If not, see + * http://www.opensource.org/licenses/BSD-3-Clause for more information. + */ +#ifndef MLPACK_METHODS_ANN_LAYER_LP_POOLING_IMPL_HPP +#define MLPACK_METHODS_ANN_LAYER_LP_POOLING_IMPL_HPP + +// In case it hasn't yet been included. +#include "lp_pooling.hpp" + +namespace mlpack { +namespace ann /** Artificial Neural Network. */ { + +template +LpPooling::LpPooling() +{ + // Nothing to do here. +} + +template +LpPooling::LpPooling( + const size_t norm_type, + const size_t kernelWidth, + const size_t kernelHeight, + const size_t strideWidth, + const size_t strideHeight, + const bool floor) : + kernelWidth(kernelWidth), + kernelHeight(kernelHeight), + strideWidth(strideWidth), + strideHeight(strideHeight), + floor(floor), + inSize(0), + outSize(0), + inputWidth(0), + inputHeight(0), + outputWidth(0), + outputHeight(0), + reset(false), + deterministic(false), + offset(0), + batchSize(0) +{ + // Nothing to do here. +} + +template +template +void LpPooling::Forward( + const arma::Mat& input, arma::Mat& output) +{ + batchSize = input.n_cols; + inSize = input.n_elem / (inputWidth * inputHeight * batchSize); + inputTemp = arma::cube(const_cast&>(input).memptr(), + inputWidth, inputHeight, batchSize * inSize, false, false); + + if (floor) + { + outputWidth = std::floor((inputWidth - + (double) kernelWidth) / (double) strideWidth + 1); + outputHeight = std::floor((inputHeight - + (double) kernelHeight) / (double) strideHeight + 1); + + offset = 0; + } + else + { + outputWidth = std::ceil((inputWidth - + (double) kernelWidth) / (double) strideWidth + 1); + outputHeight = std::ceil((inputHeight - + (double) kernelHeight) / (double) strideHeight + 1); + + offset = 1; + } + + outputTemp = arma::zeros >(outputWidth, outputHeight, + batchSize * inSize); + + for (size_t s = 0; s < inputTemp.n_slices; s++) + Pooling(inputTemp.slice(s), outputTemp.slice(s)); + + output = arma::Mat(outputTemp.memptr(), outputTemp.n_elem / batchSize, + batchSize); + + outputWidth = outputTemp.n_rows; + outputHeight = outputTemp.n_cols; + outSize = batchSize * inSize; +} + +template +template +void LpPooling::Backward( + const arma::Mat& /* input */, + const arma::Mat& gy, + arma::Mat& g) +{ + arma::cube mappedError = arma::cube(((arma::Mat&) gy).memptr(), + outputWidth, outputHeight, outSize, false, false); + + gTemp = arma::zeros(inputTemp.n_rows, + inputTemp.n_cols, inputTemp.n_slices); + + for (size_t s = 0; s < mappedError.n_slices; s++) + { + Unpooling(inputTemp.slice(s), mappedError.slice(s), gTemp.slice(s)); + } + + g = arma::mat(gTemp.memptr(), gTemp.n_elem / batchSize, batchSize); +} + +template +template +void LpPooling::serialize( + Archive& ar, + const uint32_t /* version */) +{ + ar(CEREAL_NVP(norm_type)); + ar(CEREAL_NVP(kernelWidth)); + ar(CEREAL_NVP(kernelHeight)); + ar(CEREAL_NVP(strideWidth)); + ar(CEREAL_NVP(strideHeight)); + ar(CEREAL_NVP(batchSize)); + ar(CEREAL_NVP(floor)); + ar(CEREAL_NVP(inputWidth)); + ar(CEREAL_NVP(inputHeight)); + ar(CEREAL_NVP(outputWidth)); + ar(CEREAL_NVP(outputHeight)); +} + +} // namespace ann +} // namespace mlpack + +#endif diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 5e24a995e7..012269e479 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -3838,6 +3838,54 @@ TEST_CASE("TransposedConvolutionLayerPaddingTest", "[ANNLayerTest]") REQUIRE(arma::accu(delta) == 0.0); } +/** + * Simple test for Lp Pooling layer. + */ +TEST_CASE("LpPoolingTestCase", "[ANNLayerTest]") +{ + // For rectangular input to pooling layers. + arma::mat input = arma::mat(8, 1); + arma::mat output; + input.zeros(); + input(0) = input(6) = 30; + input(1) = input(7) = 120; + input(2) = input(4) = 272; + input(3) = input(5) = 315; + // Output-Size should be 1 x 2. + // Square output. + Lp<> module1(4, 2, 2, 2, 2); + module1.InputHeight() = 2; + module1.InputWidth() = 4; + module1.Forward(input, output); + // Calculated using torch.nn.LPPool2d(). + REQUIRE(arma::accu(output) - 706.0 == Approx(0.0).margin(2e-5)); + REQUIRE(output.n_elem == 2); + + // For Square input. + input = arma::mat(16, 1); + input.zeros(); + input(0) = 4; + input(1) = 3; + input(3) = 12; + input(7) = 35; + input(8) = 6; + input(11) = 7; + input(12) = 8; + input(15) = 24; + // Output-Size should be 2 x 2. + // Square output. + Lp<> module3(2, 2, 2, 2, 2); + module3.InputHeight() = 4; + module3.InputWidth() = 4; + module3.Forward(input, output); + // Calculated using torch.nn.LPPool2d(). + REQUIRE(arma::accu(output) - 77.0 == Approx(0.0).margin(2e-5)); + REQUIRE(output.n_elem == 4); + +} + + + /** * Simple test for Max Pooling layer. */ From 89a56d7e878c0da22bd21f77cc8800cdf95c5d59 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 01:46:03 +0530 Subject: [PATCH 02/12] Added LP lookup layer --- src/mlpack/tests/ann_layer_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 012269e479..6608304f3d 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -3853,7 +3853,7 @@ TEST_CASE("LpPoolingTestCase", "[ANNLayerTest]") input(3) = input(5) = 315; // Output-Size should be 1 x 2. // Square output. - Lp<> module1(4, 2, 2, 2, 2); + LpPooling<> module1(4, 2, 2, 2, 2); module1.InputHeight() = 2; module1.InputWidth() = 4; module1.Forward(input, output); @@ -3874,7 +3874,7 @@ TEST_CASE("LpPoolingTestCase", "[ANNLayerTest]") input(15) = 24; // Output-Size should be 2 x 2. // Square output. - Lp<> module3(2, 2, 2, 2, 2); + LpPooling<> module3(2, 2, 2, 2, 2); module3.InputHeight() = 4; module3.InputWidth() = 4; module3.Forward(input, output); From 7772c73332bed0816ca10a33eb90bfa37b88879f Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 02:20:20 +0530 Subject: [PATCH 03/12] minor changes --- src/mlpack/methods/ann/layer/CMakeLists.txt | 2 ++ src/mlpack/methods/ann/layer/layer_types.hpp | 2 ++ src/mlpack/methods/ann/layer_names.hpp | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/mlpack/methods/ann/layer/CMakeLists.txt b/src/mlpack/methods/ann/layer/CMakeLists.txt index b4726b0c6f..5fe560edd4 100644 --- a/src/mlpack/methods/ann/layer/CMakeLists.txt +++ b/src/mlpack/methods/ann/layer/CMakeLists.txt @@ -63,6 +63,8 @@ set(SOURCES log_softmax_impl.hpp lookup.hpp lookup_impl.hpp + lp_pooling.hpp + lp_pooling_impl.hpp lstm.hpp lstm_impl.hpp max_pooling.hpp diff --git a/src/mlpack/methods/ann/layer/layer_types.hpp b/src/mlpack/methods/ann/layer/layer_types.hpp index 1d7fd0ccba..d27a5a6d25 100644 --- a/src/mlpack/methods/ann/layer/layer_types.hpp +++ b/src/mlpack/methods/ann/layer/layer_types.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -282,6 +283,7 @@ using LayerTypes = boost::variant< LSTM*, MaxPooling*, MeanPooling*, + LpPooling*, MiniBatchDiscrimination*, MultiplyConstant*, MultiplyMerge*, diff --git a/src/mlpack/methods/ann/layer_names.hpp b/src/mlpack/methods/ann/layer_names.hpp index be1b1f7fcb..15596efea3 100644 --- a/src/mlpack/methods/ann/layer_names.hpp +++ b/src/mlpack/methods/ann/layer_names.hpp @@ -206,6 +206,17 @@ class LayerNameVisitor : public boost::static_visitor return "meanpooling"; } + /** + * Return the name of the given layer of type LpPooling as a string. + * + * @param * Given layer of type LpPooling. + * @return The string representation of the layer. + */ + std::string LayerString(LpPooling<>* /*layer*/) const + { + return "lppooling"; + } + /** * Return the name of the given layer of type MultiplyConstant as a string. * From 826b1713918a8481386055c45e3160a9321e024c Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 02:28:02 +0530 Subject: [PATCH 04/12] minor --- src/mlpack/tests/ann_layer_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 6608304f3d..cbd66116bf 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -3841,7 +3841,7 @@ TEST_CASE("TransposedConvolutionLayerPaddingTest", "[ANNLayerTest]") /** * Simple test for Lp Pooling layer. */ -TEST_CASE("LpPoolingTestCase", "[ANNLayerTest]") +BOOST_AUTO_TEST_CASE(LpMaxPoolingTestCase) { // For rectangular input to pooling layers. arma::mat input = arma::mat(8, 1); From a88994e48bb72057204b0fbf8c75b10838096127 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 02:43:09 +0530 Subject: [PATCH 05/12] minor --- src/mlpack/methods/ann/layer/layer.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mlpack/methods/ann/layer/layer.hpp b/src/mlpack/methods/ann/layer/layer.hpp index 947395fd6b..9cf806b7e4 100644 --- a/src/mlpack/methods/ann/layer/layer.hpp +++ b/src/mlpack/methods/ann/layer/layer.hpp @@ -47,6 +47,7 @@ #include "linear3d.hpp" #include "log_softmax.hpp" #include "lookup.hpp" +#include "lp_pooling.hpp" #include "lstm.hpp" #include "max_pooling.hpp" #include "mean_pooling.hpp" From c1c0cfbc18c8a4492cf2f0bcab744a01b057b3e7 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 02:49:15 +0530 Subject: [PATCH 06/12] minor change --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp index e698f89e93..ff360f41e7 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -175,7 +175,7 @@ class LpPooling arma::span(rowidx, rowidx + kernelWidth - 1 - offset), arma::span(colidx, colidx + kernelHeight - 1 - offset)); - output(i, j) = arma::pow(arma::accu(arma::pow(subInput, norm_type)), 1.0/norm_type); + output(i, j) = cmath::pow(arma::accu(arma::pow(subInput, norm_type)), 1.0/norm_type); } } } @@ -201,7 +201,7 @@ class LpPooling { const arma::Mat& inputArea = input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)); - size_t sum = arma::pow(arma::accu(arma::pow(inputArea, norm_type)), (norm_type-1) / norm_type); + size_t sum = cmath::pow(arma::accu(arma::pow(inputArea, norm_type)), (norm_type-1) / norm_type); unpooledError = arma::Mat(inputArea.n_rows, inputArea.n_cols); unpooledError.fill(error(i / rStep, j / cStep)); unpooledError %= arma::pow(inputArea, norm_type - 1); From 66dc153ab2504adee07d41015b6288efc37db178 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 02:58:44 +0530 Subject: [PATCH 07/12] minor fix --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 25 ++++++++----------- .../methods/ann/layer/lp_pooling_impl.hpp | 1 - src/mlpack/tests/ann_layer_test.cpp | 3 --- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp index ff360f41e7..6205a0fba1 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -38,6 +38,7 @@ class LpPooling /** * Create the LpPooling object using the specified number of units. * + * @param norm_type Parameter for type of norm. * @param kernelWidth Width of the pooling window. * @param kernelHeight Height of the pooling window. * @param strideWidth Width of the stride operation. @@ -45,11 +46,11 @@ class LpPooling * @param floor Set to true to use floor method. */ LpPooling(const size_t norm_type, - const size_t kernelWidth, - const size_t kernelHeight, - const size_t strideWidth = 1, - const size_t strideHeight = 1, - const bool floor = true); + const size_t kernelWidth, + const size_t kernelHeight, + const size_t strideWidth = 1, + const size_t strideHeight = 1, + const bool floor = true); /** * Ordinary feed forward pass of a neural network, evaluating the function @@ -141,11 +142,6 @@ class LpPooling //! Modify the value of the rounding operation bool& Floor() { return floor; } - //! Get the value of the deterministic parameter. - bool Deterministic() const { return deterministic; } - //! Modify the value of the deterministic parameter. - bool& Deterministic() { return deterministic; } - //! Get the size of the weights. size_t WeightSize() const { return 0; } @@ -175,7 +171,8 @@ class LpPooling arma::span(rowidx, rowidx + kernelWidth - 1 - offset), arma::span(colidx, colidx + kernelHeight - 1 - offset)); - output(i, j) = cmath::pow(arma::accu(arma::pow(subInput, norm_type)), 1.0/norm_type); + output(i, j) = cmath::pow(arma::accu(arma::pow(subInput, + norm_type)), 1.0/norm_type); } } } @@ -201,7 +198,8 @@ class LpPooling { const arma::Mat& inputArea = input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)); - size_t sum = cmath::pow(arma::accu(arma::pow(inputArea, norm_type)), (norm_type-1) / norm_type); + size_t sum = cmath::pow(arma::accu(arma::pow(inputArea, norm_type)), + (norm_type-1) / norm_type); unpooledError = arma::Mat(inputArea.n_rows, inputArea.n_cols); unpooledError.fill(error(i / rStep, j / cStep)); unpooledError %= arma::pow(inputArea, norm_type - 1); @@ -251,9 +249,6 @@ class LpPooling //! Locally-stored reset parameter used to initialize the module once. bool reset; - //! If true use maximum a posteriori during the forward pass. - bool deterministic; - //! Locally-stored stored rounding offset. size_t offset; diff --git a/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp b/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp index 9f1133aee8..e646796360 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp @@ -45,7 +45,6 @@ LpPooling::LpPooling( outputWidth(0), outputHeight(0), reset(false), - deterministic(false), offset(0), batchSize(0) { diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index cbd66116bf..feead2800a 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -3881,11 +3881,8 @@ BOOST_AUTO_TEST_CASE(LpMaxPoolingTestCase) // Calculated using torch.nn.LPPool2d(). REQUIRE(arma::accu(output) - 77.0 == Approx(0.0).margin(2e-5)); REQUIRE(output.n_elem == 4); - } - - /** * Simple test for Max Pooling layer. */ From c9934c3975d03f9b441cafe59847b4481d40b0c8 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 21:18:52 +0530 Subject: [PATCH 08/12] minor fix --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp index 6205a0fba1..aa413c02dc 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -115,7 +115,7 @@ class LpPooling //! Get the norm_type. size_t NormType() const { return norm_type; } //! Modify the norm_type. - size_t& NormType() const { return norm_type; } + size_t& NormType() { return norm_type; } //! Get the kernel width. size_t KernelWidth() const { return kernelWidth; } From 92a8bd69f9c4c79efe83695e29cb5f312489d755 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 21:30:09 +0530 Subject: [PATCH 09/12] minor change --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 4 ++-- src/mlpack/tests/ann_layer_test.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp index aa413c02dc..0f6a2bdb83 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -171,7 +171,7 @@ class LpPooling arma::span(rowidx, rowidx + kernelWidth - 1 - offset), arma::span(colidx, colidx + kernelHeight - 1 - offset)); - output(i, j) = cmath::pow(arma::accu(arma::pow(subInput, + output(i, j) = pow(arma::accu(arma::pow(subInput, norm_type)), 1.0/norm_type); } } @@ -198,7 +198,7 @@ class LpPooling { const arma::Mat& inputArea = input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)); - size_t sum = cmath::pow(arma::accu(arma::pow(inputArea, norm_type)), + size_t sum = pow(arma::accu(arma::pow(inputArea, norm_type)), (norm_type-1) / norm_type); unpooledError = arma::Mat(inputArea.n_rows, inputArea.n_cols); unpooledError.fill(error(i / rStep, j / cStep)); diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index feead2800a..dbb5266798 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -3841,7 +3841,7 @@ TEST_CASE("TransposedConvolutionLayerPaddingTest", "[ANNLayerTest]") /** * Simple test for Lp Pooling layer. */ -BOOST_AUTO_TEST_CASE(LpMaxPoolingTestCase) +TEST_CASE("LpMaxPoolingTestCase", "[ANNLayerTest]") { // For rectangular input to pooling layers. arma::mat input = arma::mat(8, 1); From ada4e570e8d7d43bfeadc7e94dd274e533cc2e09 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 22:35:12 +0530 Subject: [PATCH 10/12] minor fix --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 24 +++++++++---------- .../methods/ann/layer/lp_pooling_impl.hpp | 5 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp index 0f6a2bdb83..aa0f043c33 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -38,14 +38,14 @@ class LpPooling /** * Create the LpPooling object using the specified number of units. * - * @param norm_type Parameter for type of norm. + * @param normType Parameter for type of norm. * @param kernelWidth Width of the pooling window. * @param kernelHeight Height of the pooling window. * @param strideWidth Width of the stride operation. * @param strideHeight Width of the stride operation. * @param floor Set to true to use floor method. */ - LpPooling(const size_t norm_type, + LpPooling(const size_t normType, const size_t kernelWidth, const size_t kernelHeight, const size_t strideWidth = 1, @@ -112,10 +112,10 @@ class LpPooling //! Get the output size. size_t OutputSize() const { return outSize; } - //! Get the norm_type. - size_t NormType() const { return norm_type; } - //! Modify the norm_type. - size_t& NormType() { return norm_type; } + //! Get the normType. + size_t NormType() const { return normType; } + //! Modify the normType. + size_t& NormType() { return normType; } //! Get the kernel width. size_t KernelWidth() const { return kernelWidth; } @@ -172,7 +172,7 @@ class LpPooling arma::span(colidx, colidx + kernelHeight - 1 - offset)); output(i, j) = pow(arma::accu(arma::pow(subInput, - norm_type)), 1.0/norm_type); + normType)), 1.0/normType); } } } @@ -198,11 +198,11 @@ class LpPooling { const arma::Mat& inputArea = input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)); - size_t sum = pow(arma::accu(arma::pow(inputArea, norm_type)), - (norm_type-1) / norm_type); + size_t sum = pow(arma::accu(arma::pow(inputArea, normType)), + (normType-1) / normType); unpooledError = arma::Mat(inputArea.n_rows, inputArea.n_cols); unpooledError.fill(error(i / rStep, j / cStep)); - unpooledError %= arma::pow(inputArea, norm_type - 1); + unpooledError %= arma::pow(inputArea, normType - 1); unpooledError /= sum; output(arma::span(i, i + rStep - 1 - offset), arma::span(j, j + cStep - 1 - offset)) += unpooledError; @@ -210,8 +210,8 @@ class LpPooling } } - //! Locally-stored norm_type. - size_t norm_type; + //! Locally-stored norm type. + size_t normType; //! Locally-stored width of the pooling window. size_t kernelWidth; diff --git a/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp b/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp index e646796360..0abe08ada6 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling_impl.hpp @@ -27,12 +27,13 @@ LpPooling::LpPooling() template LpPooling::LpPooling( - const size_t norm_type, + const size_t normType, const size_t kernelWidth, const size_t kernelHeight, const size_t strideWidth, const size_t strideHeight, const bool floor) : + normType(normType), kernelWidth(kernelWidth), kernelHeight(kernelHeight), strideWidth(strideWidth), @@ -121,7 +122,7 @@ void LpPooling::serialize( Archive& ar, const uint32_t /* version */) { - ar(CEREAL_NVP(norm_type)); + ar(CEREAL_NVP(normType)); ar(CEREAL_NVP(kernelWidth)); ar(CEREAL_NVP(kernelHeight)); ar(CEREAL_NVP(strideWidth)); From b0f6470767d9cc6e708169be698a3174f090f0c8 Mon Sep 17 00:00:00 2001 From: abh2k <41710346+abh2k@users.noreply.github.com> Date: Mon, 8 Feb 2021 09:10:00 +0530 Subject: [PATCH 11/12] Update layer_types.hpp --- src/mlpack/methods/ann/layer/layer_types.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/layer_types.hpp b/src/mlpack/methods/ann/layer/layer_types.hpp index d27a5a6d25..091d7ece35 100644 --- a/src/mlpack/methods/ann/layer/layer_types.hpp +++ b/src/mlpack/methods/ann/layer/layer_types.hpp @@ -220,6 +220,7 @@ class AdaptiveMeanPooling; using MoreTypes = boost::variant< Linear3D*, + LpPooling*, Glimpse*, Highway*, MultiheadAttention*, @@ -283,7 +284,6 @@ using LayerTypes = boost::variant< LSTM*, MaxPooling*, MeanPooling*, - LpPooling*, MiniBatchDiscrimination*, MultiplyConstant*, MultiplyMerge*, From f2284403dfa82872a6500577aec9adbb53a20262 Mon Sep 17 00:00:00 2001 From: abh2k <41710346+abh2k@users.noreply.github.com> Date: Thu, 11 Feb 2021 01:35:26 +0530 Subject: [PATCH 12/12] Apply suggestions from code review Co-authored-by: kartikdutt18 <39593019+kartikdutt18@users.noreply.github.com> --- src/mlpack/methods/ann/layer/lp_pooling.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lp_pooling.hpp b/src/mlpack/methods/ann/layer/lp_pooling.hpp index aa0f043c33..8423dda79f 100644 --- a/src/mlpack/methods/ann/layer/lp_pooling.hpp +++ b/src/mlpack/methods/ann/layer/lp_pooling.hpp @@ -172,7 +172,7 @@ class LpPooling arma::span(colidx, colidx + kernelHeight - 1 - offset)); output(i, j) = pow(arma::accu(arma::pow(subInput, - normType)), 1.0/normType); + normType)), 1.0 / normType); } } } @@ -199,7 +199,7 @@ class LpPooling const arma::Mat& inputArea = input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)); size_t sum = pow(arma::accu(arma::pow(inputArea, normType)), - (normType-1) / normType); + (normType - 1) / normType); unpooledError = arma::Mat(inputArea.n_rows, inputArea.n_cols); unpooledError.fill(error(i / rStep, j / cStep)); unpooledError %= arma::pow(inputArea, normType - 1);