From 3d2d71ced56ec6ad69ac8fa5f7ceb67c8c14a1b0 Mon Sep 17 00:00:00 2001 From: walragatver Date: Wed, 7 Aug 2019 00:08:43 +0530 Subject: [PATCH] add bias_set_visitor --- .../methods/ann/layer/atrous_convolution.hpp | 3 + src/mlpack/methods/ann/layer/convolution.hpp | 3 + src/mlpack/methods/ann/layer/layer_traits.hpp | 4 + src/mlpack/methods/ann/layer/linear.hpp | 3 + .../ann/layer/transposed_convolution.hpp | 3 + src/mlpack/methods/ann/visitor/CMakeLists.txt | 2 + .../methods/ann/visitor/bias_set_visitor.hpp | 80 ++++++++++++++++ .../ann/visitor/bias_set_visitor_impl.hpp | 94 +++++++++++++++++++ 8 files changed, 192 insertions(+) create mode 100644 src/mlpack/methods/ann/visitor/bias_set_visitor.hpp create mode 100644 src/mlpack/methods/ann/visitor/bias_set_visitor_impl.hpp diff --git a/src/mlpack/methods/ann/layer/atrous_convolution.hpp b/src/mlpack/methods/ann/layer/atrous_convolution.hpp index 52281086cc..608f58a045 100644 --- a/src/mlpack/methods/ann/layer/atrous_convolution.hpp +++ b/src/mlpack/methods/ann/layer/atrous_convolution.hpp @@ -165,6 +165,9 @@ class AtrousConvolution //! Modify the output height. size_t& OutputHeight() { return outputHeight; } + //! Modify the bias weights of the layer. + arma::mat& Bias() { return bias; } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index 83c2e09457..5298a69b03 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -161,6 +161,9 @@ class Convolution //! Modify the output height. size_t& OutputHeight() { return outputHeight; } + //! Modify the bias weights of the layer. + arma::mat& Bias() { return bias; } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/layer_traits.hpp b/src/mlpack/methods/ann/layer/layer_traits.hpp index 31a4687dd8..1955235f87 100644 --- a/src/mlpack/methods/ann/layer/layer_traits.hpp +++ b/src/mlpack/methods/ann/layer/layer_traits.hpp @@ -112,6 +112,10 @@ HAS_MEM_FUNC(Loss, HasLoss); // can use with SFINAE to catch when a type has a Run() function. HAS_MEM_FUNC(Run, HasRunCheck); +// This gives us a HasBiasCheck type (where U is a function pointer) we +// can use with SFINAE to catch when a type has a Bias() function. +HAS_MEM_FUNC(Bias, HasBiasCheck); + } // namespace ann } // namespace mlpack diff --git a/src/mlpack/methods/ann/layer/linear.hpp b/src/mlpack/methods/ann/layer/linear.hpp index 74c709adfb..c9b73fd427 100644 --- a/src/mlpack/methods/ann/layer/linear.hpp +++ b/src/mlpack/methods/ann/layer/linear.hpp @@ -117,6 +117,9 @@ class Linear //! Modify the gradient. OutputDataType& Gradient() { return gradient; } + //! Modify the bias weights of the layer. + arma::mat& Bias() { return bias; } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/transposed_convolution.hpp b/src/mlpack/methods/ann/layer/transposed_convolution.hpp index 8df31aa491..012833149c 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution.hpp @@ -162,6 +162,9 @@ class TransposedConvolution //! Modify the output height. size_t& OutputHeight() { return outputHeight; } + //! Modify the bias weights of the layer. + arma::mat& Bias() { return bias; } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/visitor/CMakeLists.txt b/src/mlpack/methods/ann/visitor/CMakeLists.txt index 67178361d8..43bcf71225 100644 --- a/src/mlpack/methods/ann/visitor/CMakeLists.txt +++ b/src/mlpack/methods/ann/visitor/CMakeLists.txt @@ -5,6 +5,8 @@ set(SOURCES add_visitor_impl.hpp backward_visitor.hpp backward_visitor_impl.hpp + bias_set_visitor.hpp + bias_set_visitor_impl.hpp copy_visitor.hpp copy_visitor_impl.hpp delete_visitor.hpp diff --git a/src/mlpack/methods/ann/visitor/bias_set_visitor.hpp b/src/mlpack/methods/ann/visitor/bias_set_visitor.hpp new file mode 100644 index 0000000000..e104f3db58 --- /dev/null +++ b/src/mlpack/methods/ann/visitor/bias_set_visitor.hpp @@ -0,0 +1,80 @@ +/** + * @file bias_set_visitor.hpp + * @author Toshal Agrawal + * + * This file provides an abstraction for the Bias() function for different + * layers and automatically directs any parameter to the right layer type. + * + * 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_VISITOR_BIAS_SET_VISITOR_HPP +#define MLPACK_METHODS_ANN_VISITOR_BIAS_SET_VISITOR_HPP + +#include + +#include + +namespace mlpack { +namespace ann { + +/** + * BiasSetVisitor update the module bias parameters given the parameters set. + */ +class BiasSetVisitor : public boost::static_visitor +{ + public: + //! Update the bias parameters given the parameters set and offset. + BiasSetVisitor(arma::mat&& weight, const size_t offset = 0); + + //! Update the parameters set. + template + size_t operator()(LayerType* layer) const; + + private: + //! The parameters set. + arma::mat&& weight; + + //! The parameters offset. + const size_t offset; + + //! Do not update the bias parameters if the module doesn't implement the + //! Bias() or Model() function. + template + typename std::enable_if< + !HasBiasCheck::value && + !HasModelCheck::value, size_t>::type + LayerSize(T* layer) const; + + //! Update the bias parameters if the module implements the Model() function. + template + typename std::enable_if< + !HasBiasCheck::value && + HasModelCheck::value, size_t>::type + LayerSize(T* layer) const; + + //! Update the bias parameters if the module implements the Bias() function. + template + typename std::enable_if< + HasBiasCheck::value && + !HasModelCheck::value, size_t>::type + LayerSize(T* layer) const; + + //! Update the bias parameters if the module implements the Model() and + //! Bias() function. + template + typename std::enable_if< + HasBiasCheck::value && + HasModelCheck::value, size_t>::type + LayerSize(T* layer) const; +}; + +} // namespace ann +} // namespace mlpack + +// Include implementation. +#include "bias_set_visitor_impl.hpp" + +#endif diff --git a/src/mlpack/methods/ann/visitor/bias_set_visitor_impl.hpp b/src/mlpack/methods/ann/visitor/bias_set_visitor_impl.hpp new file mode 100644 index 0000000000..c27f1bbe95 --- /dev/null +++ b/src/mlpack/methods/ann/visitor/bias_set_visitor_impl.hpp @@ -0,0 +1,94 @@ +/** + * @file bias_set_visitor_impl.hpp + * @author Toshal Agrawal + * + * Implementation of the Bias() function layer abstraction. + * + * 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_VISITOR_BIAS_SET_VISITOR_IMPL_HPP +#define MLPACK_METHODS_ANN_VISITOR_BIAS_SET_VISITOR_IMPL_HPP + +// In case it hasn't been included yet. +#include "bias_set_visitor.hpp" + +namespace mlpack { +namespace ann { + +//! BiasSetVisitor visitor class. +inline BiasSetVisitor::BiasSetVisitor(arma::mat&& weight, const size_t offset) : + weight(std::move(weight)), + offset(offset) +{ + /* Nothing to do here. */ +} + +template +inline size_t BiasSetVisitor::operator()(LayerType* layer) const +{ + return LayerSize(layer); +} + +template +inline typename std::enable_if< + !HasBiasCheck::value && + !HasModelCheck::value, size_t>::type +BiasSetVisitor::LayerSize(T* /* layer */) const +{ + return 0; +} + +template +inline typename std::enable_if< + !HasBiasCheck::value && + HasModelCheck::value, size_t>::type +BiasSetVisitor::LayerSize(T* layer) const +{ + size_t modelOffset = 0; + for (size_t i = 0; i < layer->Model().size(); ++i) + { + modelOffset += boost::apply_visitor(BiasSetVisitor( + std::move(weight), modelOffset + offset), layer->Model()[i]); + } + + return modelOffset; +} + +template +inline typename std::enable_if< + HasBiasCheck::value && + !HasModelCheck::value, size_t>::type +BiasSetVisitor::LayerSize(T* layer) const +{ + layer->Bias() = arma::mat(weight.memptr() + offset, + layer->Bias().n_rows, layer->Bias().n_cols, false, false); + + return layer->Bias().n_elem; +} + +template +inline typename std::enable_if< + HasBiasCheck::value && + HasModelCheck::value, size_t>::type +BiasSetVisitor::LayerSize(T* layer) const +{ + layer->Bias() = arma::mat(weight.memptr() + offset, + layer->Bias().n_rows, layer->Bias().n_cols, false, false); + + size_t modelOffset = layer->Bias().n_elem; + for (size_t i = 0; i < layer->Model().size(); ++i) + { + modelOffset += boost::apply_visitor(BiasSetVisitor( + std::move(weight), modelOffset + offset), layer->Model()[i]); + } + + return modelOffset; +} + +} // namespace ann +} // namespace mlpack + +#endif