diff --git a/HISTORY.md b/HISTORY.md index ea75bbbf30..6c59d9507d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,6 @@ ### mlpack ?.?.? ###### ????-??-?? + * Add Model() to the FFN class to access individual layers (#2043). ### mlpack 3.2.1 ###### 2019-10-01 diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 9e875a16f2..6f34381b23 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -257,6 +257,14 @@ class FFN */ void Add(LayerTypes layer) { network.push_back(layer); } + //! Get the network model. + const std::vector >& Model() const + { + return network; + } + //! Modify the network model. + std::vector >& Model() { return network; } + //! Return the number of separable functions (the number of predictor points). size_t NumFunctions() const { return numFunctions; } diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index c47d633ace..b84f2a557b 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -575,4 +575,41 @@ BOOST_AUTO_TEST_CASE(FFNTrainReturnObjective) BOOST_REQUIRE_EQUAL(std::isfinite(objVal), true); } + +/** + * Test that FFN::Model() allows us to access the instantiated network. + */ +BOOST_AUTO_TEST_CASE(FFNReturnModel) +{ + // Create dummy network. + FFN > model; + Linear<>* linearA = new Linear<>(3, 3); + model.Add(linearA); + Linear<>* linearB = new Linear<>(3, 4); + model.Add(linearB); + + // Initialize network parameter. + model.ResetParameters(); + + // Set all network parameter to one. + model.Parameters().ones(); + + // Zero the second layer parameter. + linearB->Parameters().zeros(); + + // Get the layer parameter from layer A and layer B and store them in + // parameterA and parameterB. + arma::mat parameterA, parameterB; + boost::apply_visitor(ParametersVisitor(std::move(parameterA)), + model.Model()[0]); + boost::apply_visitor(ParametersVisitor(std::move(parameterB)), + model.Model()[1]); + + CheckMatrices(parameterA, arma::ones(3 * 3 + 3, 1)); + CheckMatrices(parameterB, arma::zeros(3 * 4 + 4, 1)); + + CheckMatrices(linearA->Parameters(), arma::ones(3 * 3 + 3, 1)); + CheckMatrices(linearB->Parameters(), arma::zeros(3 * 4 + 4, 1)); +} + BOOST_AUTO_TEST_SUITE_END();