Merge pull request #2195 from kartikdutt18/Add-Adaptive-Pooling
Addition of Adaptive Pooling (mean and max).
This commit is contained in:
+2
-1
@@ -1,5 +1,6 @@
|
||||
### mlpack ?.?.?
|
||||
###### ????-??-??
|
||||
* Add adaptive max pooling and adaptive mean pooling layers (#2195).
|
||||
|
||||
### mlpack 3.3.1
|
||||
###### 2020-04-29
|
||||
@@ -82,7 +83,7 @@
|
||||
|
||||
* Add CELU activation function (#2191)
|
||||
|
||||
* Add Log-Hyperbolic-Cosine Loss function (#2207)
|
||||
* Add Log-Hyperbolic-Cosine Loss function (#2207).
|
||||
|
||||
* Change neural network types to avoid unnecessary use of rvalue references
|
||||
(#2259).
|
||||
|
||||
@@ -5,6 +5,10 @@ set(SOURCES
|
||||
add_impl.hpp
|
||||
add_merge.hpp
|
||||
add_merge_impl.hpp
|
||||
adaptive_max_pooling.hpp
|
||||
adaptive_max_pooling_impl.hpp
|
||||
adaptive_mean_pooling.hpp
|
||||
adaptive_mean_pooling_impl.hpp
|
||||
alpha_dropout.hpp
|
||||
alpha_dropout_impl.hpp
|
||||
atrous_convolution.hpp
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* @file adaptive_max_pooling.hpp
|
||||
* @author Kartik Dutt
|
||||
*
|
||||
* Definition of the AdaptiveMaxPooling 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_ADAPTIVE_MAX_POOLING_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_ADAPTIVE_MAX_POOLING_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include "layer_types.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
/**
|
||||
* Implementation of the AdaptiveMaxPooling layer.
|
||||
*
|
||||
* @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 AdaptiveMaxPooling
|
||||
{
|
||||
public:
|
||||
//! Create the AdaptiveMaxPooling object.
|
||||
AdaptiveMaxPooling();
|
||||
|
||||
/**
|
||||
* Create the AdaptiveMaxPooling object.
|
||||
*
|
||||
* @param outputWidth Width of the output.
|
||||
* @param outputHeight Height of the output.
|
||||
*/
|
||||
AdaptiveMaxPooling(const size_t outputWidth,
|
||||
const size_t outputHeight);
|
||||
|
||||
/**
|
||||
* Create the AdaptiveMaxPooling object.
|
||||
*
|
||||
* @param outputShape A two-value tuple indicating width and height of the output.
|
||||
*/
|
||||
AdaptiveMaxPooling(const std::tuple<size_t, size_t>& outputShape);
|
||||
|
||||
/**
|
||||
* 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<typename eT>
|
||||
void Forward(const arma::Mat<eT>& input, arma::Mat<eT>& 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<typename eT>
|
||||
void Backward(const arma::Mat<eT>& input,
|
||||
const arma::Mat<eT>& gy,
|
||||
arma::Mat<eT>& g);
|
||||
|
||||
//! Get the output parameter.
|
||||
const OutputDataType& OutputParameter() const
|
||||
{ return poolingLayer.OutputParameter(); }
|
||||
|
||||
//! Modify the output parameter.
|
||||
OutputDataType& OutputParameter() { return poolingLayer.OutputParameter(); }
|
||||
|
||||
//! Get the delta.
|
||||
const OutputDataType& Delta() const { return poolingLayer.Delta(); }
|
||||
//! Modify the delta.
|
||||
OutputDataType& Delta() { return poolingLayer.Delta(); }
|
||||
|
||||
//! Get the input width.
|
||||
size_t InputWidth() const { return poolingLayer.InputWidth(); }
|
||||
//! Modify the input width.
|
||||
size_t& InputWidth() { return poolingLayer.InputWidth(); }
|
||||
|
||||
//! Get the input height.
|
||||
size_t InputHeight() const { return poolingLayer.InputHeight(); }
|
||||
//! Modify the input height.
|
||||
size_t& InputHeight() { return poolingLayer.InputHeight(); }
|
||||
|
||||
//! Get the output width.
|
||||
size_t OutputWidth() const { return outputWidth; }
|
||||
//! Modify the output width.
|
||||
size_t& OutputWidth() { return outputWidth; }
|
||||
|
||||
//! Get the output height.
|
||||
size_t OutputHeight() const { return outputHeight; }
|
||||
//! Modify the output height.
|
||||
size_t& OutputHeight() { return outputHeight; }
|
||||
|
||||
//! Get the input size.
|
||||
size_t InputSize() const { return poolingLayer.InputSize(); }
|
||||
|
||||
//! Get the output size.
|
||||
size_t OutputSize() const { return poolingLayer.OutputSize(); }
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int version);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize Kernel Size and Stride for Adaptive Pooling.
|
||||
*/
|
||||
void IntializeAdaptivePadding()
|
||||
{
|
||||
poolingLayer.StrideWidth() = std::floor(poolingLayer.InputWidth() /
|
||||
outputWidth);
|
||||
poolingLayer.StrideHeight() = std::floor(poolingLayer.InputHeight() /
|
||||
outputHeight);
|
||||
|
||||
poolingLayer.KernelWidth() = poolingLayer.InputWidth() -
|
||||
(outputWidth - 1) * poolingLayer.StrideWidth();
|
||||
poolingLayer.KernelHeight() = poolingLayer.InputHeight() -
|
||||
(outputHeight - 1) * poolingLayer.StrideHeight();
|
||||
|
||||
if (poolingLayer.KernelHeight() <= 0 || poolingLayer.KernelWidth() <= 0 ||
|
||||
poolingLayer.StrideWidth() <= 0 || poolingLayer.StrideHeight() <= 0)
|
||||
{
|
||||
Log::Fatal << "Given output shape (" << outputWidth << ", "
|
||||
<< outputHeight << ") is not possible for given input shape ("
|
||||
<< poolingLayer.InputWidth() << ", " << poolingLayer.InputHeight()
|
||||
<< ")." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//! Locally stored MaxPooling Object.
|
||||
MaxPooling<InputDataType, OutputDataType> poolingLayer;
|
||||
|
||||
//! Locally-stored output width.
|
||||
size_t outputWidth;
|
||||
|
||||
//! Locally-stored output height.
|
||||
size_t outputHeight;
|
||||
|
||||
//! Locally-stored reset parameter used to initialize the layer once.
|
||||
bool reset;
|
||||
}; // class AdaptiveMaxPooling
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "adaptive_max_pooling_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @file adaptive_max_pooling_impl.hpp
|
||||
* @author Kartik Dutt
|
||||
*
|
||||
* Implementation of the Adaptive Max Pooling 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_ADAPTIVE_MAX_POOLING_IMPL_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_ADAPTIVE_MAX_POOLING_IMPL_HPP
|
||||
|
||||
// In case it hasn't yet been included.
|
||||
#include "adaptive_max_pooling.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
AdaptiveMaxPooling<InputDataType, OutputDataType>::AdaptiveMaxPooling()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template <typename InputDataType, typename OutputDataType>
|
||||
AdaptiveMaxPooling<InputDataType, OutputDataType>::AdaptiveMaxPooling(
|
||||
const size_t outputWidth,
|
||||
const size_t outputHeight) :
|
||||
AdaptiveMaxPooling(std::tuple<size_t, size_t>(outputWidth, outputHeight))
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template <typename InputDataType, typename OutputDataType>
|
||||
AdaptiveMaxPooling<InputDataType, OutputDataType>::AdaptiveMaxPooling(
|
||||
const std::tuple<size_t, size_t>& outputShape):
|
||||
outputWidth(std::get<0>(outputShape)),
|
||||
outputHeight(std::get<1>(outputShape)),
|
||||
reset(false)
|
||||
{
|
||||
poolingLayer = ann::MaxPooling<>(0, 0);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename eT>
|
||||
void AdaptiveMaxPooling<InputDataType, OutputDataType>::Forward(
|
||||
const arma::Mat<eT>& input, arma::Mat<eT>& output)
|
||||
{
|
||||
if (!reset)
|
||||
{
|
||||
IntializeAdaptivePadding();
|
||||
reset = true;
|
||||
}
|
||||
|
||||
poolingLayer.Forward(input, output);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename eT>
|
||||
void AdaptiveMaxPooling<InputDataType, OutputDataType>::Backward(
|
||||
const arma::Mat<eT>& input,
|
||||
const arma::Mat<eT>& gy,
|
||||
arma::Mat<eT>& g)
|
||||
{
|
||||
poolingLayer.Backward(input, gy, g);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename Archive>
|
||||
void AdaptiveMaxPooling<InputDataType, OutputDataType>::serialize(
|
||||
Archive& ar,
|
||||
const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(outputWidth);
|
||||
ar & BOOST_SERIALIZATION_NVP(outputHeight);
|
||||
ar & BOOST_SERIALIZATION_NVP(reset);
|
||||
|
||||
if (version > 0)
|
||||
ar & BOOST_SERIALIZATION_NVP(poolingLayer);
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @file adaptive_mean_pooling.hpp
|
||||
* @author Kartik Dutt
|
||||
*
|
||||
* Definition of the AdaptiveMeanPooling 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_ADAPTIVE_MEAN_POOLING_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_ADAPTIVE_MEAN_POOLING_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include "layer_types.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
/**
|
||||
* Implementation of the AdaptiveMeanPooling.
|
||||
*
|
||||
* @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 AdaptiveMeanPooling
|
||||
{
|
||||
public:
|
||||
//! Create the AdaptiveMeanPooling object.
|
||||
AdaptiveMeanPooling();
|
||||
|
||||
/**
|
||||
* Create the AdaptiveMeanPooling object.
|
||||
*
|
||||
* @param outputWidth Width of the output.
|
||||
* @param outputHeight Height of the output.
|
||||
*/
|
||||
AdaptiveMeanPooling(const size_t outputWidth,
|
||||
const size_t outputHeight);
|
||||
|
||||
/**
|
||||
* Create the AdaptiveMeanPooling object.
|
||||
*
|
||||
* @param outputShape A two-value tuple indicating width and height of the output.
|
||||
*/
|
||||
AdaptiveMeanPooling(const std::tuple<size_t, size_t>& outputShape);
|
||||
|
||||
/**
|
||||
* 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<typename eT>
|
||||
void Forward(const arma::Mat<eT>& input, arma::Mat<eT>& 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<typename eT>
|
||||
void Backward(const arma::Mat<eT>& input,
|
||||
const arma::Mat<eT>& gy,
|
||||
arma::Mat<eT>& g);
|
||||
|
||||
//! Get the output parameter.
|
||||
const OutputDataType& OutputParameter() const
|
||||
{ return poolingLayer.OutputParameter(); }
|
||||
|
||||
//! Modify the output parameter.
|
||||
OutputDataType& OutputParameter() { return poolingLayer.OutputParameter(); }
|
||||
|
||||
//! Get the delta.
|
||||
const OutputDataType& Delta() const { return poolingLayer.Delta(); }
|
||||
//! Modify the delta.
|
||||
OutputDataType& Delta() { return poolingLayer.Delta(); }
|
||||
|
||||
//! Get the input width.
|
||||
size_t InputWidth() const { return poolingLayer.InputWidth(); }
|
||||
//! Modify the input width.
|
||||
size_t& InputWidth() { return poolingLayer.InputWidth(); }
|
||||
|
||||
//! Get the input height.
|
||||
size_t InputHeight() const { return poolingLayer.InputHeight(); }
|
||||
//! Modify the input height.
|
||||
size_t& InputHeight() { return poolingLayer.InputHeight(); }
|
||||
|
||||
//! Get the output width.
|
||||
size_t OutputWidth() const { return outputWidth; }
|
||||
//! Modify the output width.
|
||||
size_t& OutputWidth() { return outputWidth; }
|
||||
|
||||
//! Get the output height.
|
||||
size_t OutputHeight() const { return outputHeight; }
|
||||
//! Modify the output height.
|
||||
size_t& OutputHeight() { return outputHeight; }
|
||||
|
||||
//! Get the input size.
|
||||
size_t InputSize() const { return poolingLayer.InputSize(); }
|
||||
|
||||
//! Get the output size.
|
||||
size_t OutputSize() const { return poolingLayer.OutputSize(); }
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int version);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize Kernel Size and Stride for Adaptive Pooling.
|
||||
*/
|
||||
void IntializeAdaptivePadding()
|
||||
{
|
||||
poolingLayer.StrideWidth() = std::floor(poolingLayer.InputWidth() /
|
||||
outputWidth);
|
||||
poolingLayer.StrideHeight() = std::floor(poolingLayer.InputHeight() /
|
||||
outputHeight);
|
||||
|
||||
poolingLayer.KernelWidth() = poolingLayer.InputWidth() -
|
||||
(outputWidth - 1) * poolingLayer.StrideWidth();
|
||||
poolingLayer.KernelHeight() = poolingLayer.InputHeight() -
|
||||
(outputHeight - 1) * poolingLayer.StrideHeight();
|
||||
|
||||
if (poolingLayer.KernelHeight() <= 0 || poolingLayer.KernelWidth() <= 0 ||
|
||||
poolingLayer.StrideWidth() <= 0 || poolingLayer.StrideHeight() <= 0)
|
||||
{
|
||||
Log::Fatal << "Given output shape (" << outputWidth << ", "
|
||||
<< outputHeight << ") is not possible for given input shape ("
|
||||
<< poolingLayer.InputWidth() << ", " << poolingLayer.InputHeight()
|
||||
<< ")." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//! Locally stored MeanPooling Object.
|
||||
MeanPooling<InputDataType, OutputDataType> poolingLayer;
|
||||
|
||||
//! Locally-stored output width.
|
||||
size_t outputWidth;
|
||||
|
||||
//! Locally-stored output height.
|
||||
size_t outputHeight;
|
||||
|
||||
//! Locally-stored reset parameter used to initialize the layer once.
|
||||
bool reset;
|
||||
}; // class AdaptiveMeanPooling
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "adaptive_mean_pooling_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @file adaptive_mean_pooling_impl.hpp
|
||||
* @author Kartik Dutt
|
||||
*
|
||||
* Implementation of the Adaptive Mean Pooling 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_ADAPTIVE_MEAN_POOLING_IMPL_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_ADAPTIVE_MEAN_POOLING_IMPL_HPP
|
||||
|
||||
// In case it hasn't yet been included.
|
||||
#include "adaptive_mean_pooling.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
AdaptiveMeanPooling<InputDataType, OutputDataType>::AdaptiveMeanPooling()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template <typename InputDataType, typename OutputDataType>
|
||||
AdaptiveMeanPooling<InputDataType, OutputDataType>::AdaptiveMeanPooling(
|
||||
const size_t outputWidth,
|
||||
const size_t outputHeight) :
|
||||
AdaptiveMeanPooling(std::tuple<size_t, size_t>(outputWidth, outputHeight))
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template <typename InputDataType, typename OutputDataType>
|
||||
AdaptiveMeanPooling<InputDataType, OutputDataType>::AdaptiveMeanPooling(
|
||||
const std::tuple<size_t, size_t>& outputShape):
|
||||
outputWidth(std::get<0>(outputShape)),
|
||||
outputHeight(std::get<1>(outputShape)),
|
||||
reset(false)
|
||||
{
|
||||
poolingLayer = ann::MeanPooling<>(0, 0);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename eT>
|
||||
void AdaptiveMeanPooling<InputDataType, OutputDataType>::Forward(
|
||||
const arma::Mat<eT>& input, arma::Mat<eT>& output)
|
||||
{
|
||||
if (!reset)
|
||||
{
|
||||
IntializeAdaptivePadding();
|
||||
reset = true;
|
||||
}
|
||||
|
||||
poolingLayer.Forward(input, output);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename eT>
|
||||
void AdaptiveMeanPooling<InputDataType, OutputDataType>::Backward(
|
||||
const arma::Mat<eT>& input,
|
||||
const arma::Mat<eT>& gy,
|
||||
arma::Mat<eT>& g)
|
||||
{
|
||||
poolingLayer.Backward(input, gy, g);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename Archive>
|
||||
void AdaptiveMeanPooling<InputDataType, OutputDataType>::serialize(
|
||||
Archive& ar,
|
||||
const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(outputWidth);
|
||||
ar & BOOST_SERIALIZATION_NVP(outputHeight);
|
||||
ar & BOOST_SERIALIZATION_NVP(reset);
|
||||
|
||||
if (version > 0)
|
||||
ar & BOOST_SERIALIZATION_NVP(poolingLayer);
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -13,6 +13,8 @@
|
||||
#define MLPACK_METHODS_ANN_LAYER_LAYER_HPP
|
||||
|
||||
#include "add.hpp"
|
||||
#include "adaptive_max_pooling.hpp"
|
||||
#include "adaptive_mean_pooling.hpp"
|
||||
#include "add_merge.hpp"
|
||||
#include "alpha_dropout.hpp"
|
||||
#include "atrous_convolution.hpp"
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <mlpack/methods/ann/layer/multiply_constant.hpp>
|
||||
#include <mlpack/methods/ann/layer/max_pooling.hpp>
|
||||
#include <mlpack/methods/ann/layer/mean_pooling.hpp>
|
||||
#include <mlpack/methods/ann/layer/adaptive_max_pooling.hpp>
|
||||
#include <mlpack/methods/ann/layer/adaptive_mean_pooling.hpp>
|
||||
#include <mlpack/methods/ann/layer/parametric_relu.hpp>
|
||||
#include <mlpack/methods/ann/layer/reinforce_normal.hpp>
|
||||
#include <mlpack/methods/ann/layer/reparametrization.hpp>
|
||||
@@ -179,6 +181,16 @@ template <typename InputDataType,
|
||||
>
|
||||
class WeightNorm;
|
||||
|
||||
template <typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
class AdaptiveMaxPooling;
|
||||
|
||||
template <typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
class AdaptiveMeanPooling;
|
||||
|
||||
using MoreTypes = boost::variant<
|
||||
Recurrent<arma::mat, arma::mat>*,
|
||||
RecurrentAttention<arma::mat, arma::mat>*,
|
||||
@@ -194,6 +206,8 @@ using MoreTypes = boost::variant<
|
||||
|
||||
template <typename... CustomLayers>
|
||||
using LayerTypes = boost::variant<
|
||||
AdaptiveMaxPooling<arma::mat, arma::mat>*,
|
||||
AdaptiveMeanPooling<arma::mat, arma::mat>*,
|
||||
Add<arma::mat, arma::mat>*,
|
||||
AddMerge<arma::mat, arma::mat>*,
|
||||
AtrousConvolution<NaiveConvolution<ValidConvolution>,
|
||||
|
||||
@@ -104,24 +104,24 @@ class MaxPooling
|
||||
//! Modify the delta.
|
||||
OutputDataType& Delta() { return delta; }
|
||||
|
||||
//! Get the width.
|
||||
//! Get the input width.
|
||||
size_t InputWidth() const { return inputWidth; }
|
||||
//! Modify the width.
|
||||
//! Modify the input width.
|
||||
size_t& InputWidth() { return inputWidth; }
|
||||
|
||||
//! Get the height.
|
||||
//! Get the input height.
|
||||
size_t InputHeight() const { return inputHeight; }
|
||||
//! Modify the height.
|
||||
//! Modify the input height.
|
||||
size_t& InputHeight() { return inputHeight; }
|
||||
|
||||
//! Get the width.
|
||||
//! Get the output width.
|
||||
size_t OutputWidth() const { return outputWidth; }
|
||||
//! Modify the width.
|
||||
//! Modify the output width.
|
||||
size_t& OutputWidth() { return outputWidth; }
|
||||
|
||||
//! Get the height.
|
||||
//! Get the output height.
|
||||
size_t OutputHeight() const { return outputHeight; }
|
||||
//! Modify the height.
|
||||
//! Modify the output height.
|
||||
size_t& OutputHeight() { return outputHeight; }
|
||||
|
||||
//! Get the input size.
|
||||
@@ -161,7 +161,7 @@ class MaxPooling
|
||||
bool& Deterministic() { return deterministic; }
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */);
|
||||
|
||||
@@ -84,24 +84,24 @@ class MeanPooling
|
||||
//! Modify the delta.
|
||||
OutputDataType& Delta() { return delta; }
|
||||
|
||||
//! Get the width.
|
||||
//! Get the intput width.
|
||||
size_t const& InputWidth() const { return inputWidth; }
|
||||
//! Modify the width.
|
||||
//! Modify the input width.
|
||||
size_t& InputWidth() { return inputWidth; }
|
||||
|
||||
//! Get the height.
|
||||
//! Get the input height.
|
||||
size_t const& InputHeight() const { return inputHeight; }
|
||||
//! Modify the height.
|
||||
//! Modify the input height.
|
||||
size_t& InputHeight() { return inputHeight; }
|
||||
|
||||
//! Get the width.
|
||||
//! Get the output width.
|
||||
size_t const& OutputWidth() const { return outputWidth; }
|
||||
//! Modify the width.
|
||||
//! Modify the output width.
|
||||
size_t& OutputWidth() { return outputWidth; }
|
||||
|
||||
//! Get the height.
|
||||
//! Get the output height.
|
||||
size_t const& OutputHeight() const { return outputHeight; }
|
||||
//! Modify the height.
|
||||
//! Modify the output height.
|
||||
size_t& OutputHeight() { return outputHeight; }
|
||||
|
||||
//! Get the input size.
|
||||
@@ -141,7 +141,7 @@ class MeanPooling
|
||||
bool& Deterministic() { return deterministic; }
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */);
|
||||
|
||||
@@ -30,6 +30,28 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the given layer of type AdaptiveMaxPooling as string.
|
||||
*
|
||||
* @param Given layer of type AdaptiveMaxPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(AdaptiveMaxPooling<> * /*layer*/) const
|
||||
{
|
||||
return "adaptivemaxpooling";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the given layer of type AdaptiveMeanPooling as string.
|
||||
*
|
||||
* @param Given layer of type AdaptiveMeanPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(AdaptiveMeanPooling<> * /*layer*/) const
|
||||
{
|
||||
return "adaptivemeanpooling";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the given layer of type AtrousConvolution as a string.
|
||||
*
|
||||
|
||||
@@ -3117,4 +3117,201 @@ BOOST_AUTO_TEST_CASE(MaxPoolingTestCase)
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 4);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for Adaptive pooling for Max Pooling layer.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(AdaptiveMaxPoolingTestCase)
|
||||
{
|
||||
// For rectangular input.
|
||||
arma::mat input = arma::mat(12, 1);
|
||||
arma::mat output, delta;
|
||||
|
||||
input.zeros();
|
||||
input(0) = 1;
|
||||
input(1) = 2;
|
||||
input(2) = 3;
|
||||
input(3) = input(8) = 7;
|
||||
input(4) = 4;
|
||||
input(5) = 5;
|
||||
input(6) = input(7) = 6;
|
||||
input(10) = 8;
|
||||
input(11) = 9;
|
||||
// Output-Size should be 2 x 2.
|
||||
// Square output.
|
||||
AdaptiveMaxPooling<> module1(2, 2);
|
||||
module1.InputHeight() = 3;
|
||||
module1.InputWidth() = 4;
|
||||
module1.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveMaxPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 28);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 4);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module1.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 28.0);
|
||||
|
||||
// For Square input.
|
||||
input = arma::mat(9, 1);
|
||||
input.zeros();
|
||||
input(0) = 6;
|
||||
input(1) = 3;
|
||||
input(2) = 9;
|
||||
input(3) = 3;
|
||||
input(6) = 3;
|
||||
// Output-Size should be 1 x 2.
|
||||
// Rectangular output.
|
||||
AdaptiveMaxPooling<> module2(2, 1);
|
||||
module2.InputHeight() = 3;
|
||||
module2.InputWidth() = 3;
|
||||
module2.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveMaxPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 15.0);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 2);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module2.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 15.0);
|
||||
|
||||
// For Square input.
|
||||
input = arma::mat(16, 1);
|
||||
input.zeros();
|
||||
input(0) = 6;
|
||||
input(1) = 3;
|
||||
input(2) = 9;
|
||||
input(4) = 3;
|
||||
input(8) = 3;
|
||||
// Output-Size should be 3 x 3.
|
||||
// Square output.
|
||||
AdaptiveMaxPooling<> module3(std::tuple<size_t, size_t>(3, 3));
|
||||
module3.InputHeight() = 4;
|
||||
module3.InputWidth() = 4;
|
||||
module3.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveMaxPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 30.0);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 9);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module3.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 30.0);
|
||||
|
||||
// For Rectangular input.
|
||||
input = arma::mat(20, 1);
|
||||
input.zeros();
|
||||
input(0) = 1;
|
||||
input(1) = 1;
|
||||
input(3) = 1;
|
||||
// Output-Size should be 2 x 2.
|
||||
// Square output.
|
||||
AdaptiveMaxPooling<> module4(std::tuple<size_t, size_t>(2, 2));
|
||||
module4.InputHeight() = 4;
|
||||
module4.InputWidth() = 5;
|
||||
module4.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveMaxPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 2);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 4);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module4.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 2.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for Adaptive pooling for Mean Pooling layer.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(AdaptiveMeanPoolingTestCase)
|
||||
{
|
||||
// For rectangular input.
|
||||
arma::mat input = arma::mat(12, 1);
|
||||
arma::mat output, delta;
|
||||
|
||||
input.zeros();
|
||||
input(0) = 1;
|
||||
input(1) = 2;
|
||||
input(2) = 3;
|
||||
input(3) = input(8) = 7;
|
||||
input(4) = 4;
|
||||
input(5) = 5;
|
||||
input(6) = input(7) = 6;
|
||||
input(10) = 8;
|
||||
input(11) = 9;
|
||||
// Output-Size should be 2 x 2.
|
||||
// Square output.
|
||||
AdaptiveMeanPooling<> module1(2, 2);
|
||||
module1.InputHeight() = 3;
|
||||
module1.InputWidth() = 4;
|
||||
module1.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveAvgPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 19.75);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 4);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module1.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 7.0);
|
||||
|
||||
// For Square input.
|
||||
input = arma::mat(9, 1);
|
||||
input.zeros();
|
||||
input(0) = 6;
|
||||
input(1) = 3;
|
||||
input(2) = 9;
|
||||
input(3) = 3;
|
||||
input(6) = 3;
|
||||
// Output-Size should be 1 x 2.
|
||||
// Rectangular output.
|
||||
AdaptiveMeanPooling<> module2(1, 2);
|
||||
module2.InputHeight() = 3;
|
||||
module2.InputWidth() = 3;
|
||||
module2.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveAvgPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 4.5);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 2);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module2.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 0.0);
|
||||
|
||||
// For Square input.
|
||||
input = arma::mat(16, 1);
|
||||
input.zeros();
|
||||
input(0) = 6;
|
||||
input(1) = 3;
|
||||
input(2) = 9;
|
||||
input(4) = 3;
|
||||
input(8) = 3;
|
||||
// Output-Size should be 3 x 3.
|
||||
// Square output.
|
||||
AdaptiveMeanPooling<> module3(std::tuple<size_t, size_t>(3, 3));
|
||||
module3.InputHeight() = 4;
|
||||
module3.InputWidth() = 4;
|
||||
module3.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveAvgPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 10.5);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 9);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module3.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 10.5);
|
||||
|
||||
// For Rectangular input.
|
||||
input = arma::mat(24, 1);
|
||||
input.zeros();
|
||||
input(0) = 3;
|
||||
input(1) = 3;
|
||||
input(4) = 3;
|
||||
// Output-Size should be 3 x 3.
|
||||
// Square output.
|
||||
AdaptiveMeanPooling<> module4(std::tuple<size_t, size_t>(3, 3));
|
||||
module4.InputHeight() = 4;
|
||||
module4.InputWidth() = 6;
|
||||
module4.Forward(input, output);
|
||||
// Calculated using torch.nn.AdaptiveAvgPool2d().
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), 2.25);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 9);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 1);
|
||||
// Test the Backward Function.
|
||||
module4.Backward(input, output, delta);
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(delta), 1.5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
Reference in New Issue
Block a user