diff --git a/src/mlpack/methods/ann/layer/linear_no_bias.hpp b/src/mlpack/methods/ann/layer/linear_no_bias.hpp index 5426f1ff4f..1e85933135 100644 --- a/src/mlpack/methods/ann/layer/linear_no_bias.hpp +++ b/src/mlpack/methods/ann/layer/linear_no_bias.hpp @@ -51,6 +51,18 @@ class LinearNoBias const size_t outSize, RegularizerType regularizer = RegularizerType()); + //! Copy constructor. + LinearNoBias(const LinearNoBias& layer); + + //! Move constructor. + LinearNoBias(LinearNoBias&&); + + //! Copy assignment operator. + LinearNoBias& operator=(const LinearNoBias& layer); + + //! Move assignment operator. + LinearNoBias& operator=(LinearNoBias&& layer); + /* * Reset the layer parameter. */ diff --git a/src/mlpack/methods/ann/layer/linear_no_bias_impl.hpp b/src/mlpack/methods/ann/layer/linear_no_bias_impl.hpp index dbea56e94f..ed26cd59fa 100644 --- a/src/mlpack/methods/ann/layer/linear_no_bias_impl.hpp +++ b/src/mlpack/methods/ann/layer/linear_no_bias_impl.hpp @@ -41,6 +41,62 @@ LinearNoBias::LinearNoBias( weights.set_size(WeightSize(), 1); } +template +LinearNoBias::LinearNoBias( + const LinearNoBias& layer) : + inSize(layer.inSize), + outSize(layer.outSize), + weights(layer.weights), + regularizer(layer.regularizer) +{ + // Nothing to do here. +} + +template +LinearNoBias::LinearNoBias( + LinearNoBias&& layer) : + inSize(0), + outSize(0), + weights(std::move(layer.weights)), + regularizer(std::move(layer.regularizer)) +{ + // Nothing to do here. +} + +template +LinearNoBias& +LinearNoBias:: +operator=(const LinearNoBias& layer) +{ + if (this != &layer) + { + inSize = layer.inSize; + outSize = layer.outSize; + weights = layer.weights; + regularizer = layer.regularizer; + } + return *this; +} + +template +LinearNoBias& +LinearNoBias:: +operator=(LinearNoBias&& layer) +{ + if (this != &layer) + { + inSize = layer.inSize; + outSize = layer.outSize; + weights = std::move(layer.weights); + regularizer = std::move(layer.regularizer); + } + return *this; +} + template void LinearNoBias::Reset() diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index bed64a3846..6fd5af4e30 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -386,6 +386,89 @@ TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } +/** + * Check whether copying and moving Vanila network is working or not. + */ +TEST_CASE("CheckCopyMovingVanillaNetworkTestNoBias", "[FeedForwardNetworkTest]") +{ + // Load the dataset. + arma::mat trainData; + if (!data::Load("thyroid_train.csv", trainData)) + FAIL("Cannot open thyroid_train.csv"); + + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; + trainData.shed_row(trainData.n_rows - 1); + + /* + * Construct a feed forward network with trainData.n_rows input nodes, + * hiddenLayerSize hidden nodes and trainLabels.n_rows output nodes. The + * network structure looks like: + * + * Input Hidden Output + * Layer Layer Layer + * +-----+ +-----+ +-----+ + * | | | | | | + * | +------>| +------>| | + * | | | | | | + * +-----+ +--+--+ +-----+ + */ + + FFN > *model = new FFN >; + model->Add >(trainData.n_rows, 8); + model->Add >(); + model->Add >(8, 3); + model->Add >(); + + FFN > *model1 = new FFN >; + model1->Add >(trainData.n_rows, 8); + model1->Add >(); + model1->Add >(8, 3); + model1->Add >(); + + // Check whether copy constructor is working or not. + CheckCopyFunction<>(model, trainData, trainLabels, 1); + + // Check whether move constructor is working or not. + CheckMoveFunction<>(model1, trainData, trainLabels, 1); +} + +/** + * Check whether copying and moving network with Reparametrization is working or not. + */ +TEST_CASE("CheckCopyMovingReparametrizationNetworkTestNoBias", + "[FeedForwardNetworkTest]") +{ + // Load the dataset. + arma::mat trainData; + data::Load("thyroid_train.csv", trainData, true); + + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; + trainData.shed_row(trainData.n_rows - 1); + + /* + * Construct a feed forward network with trainData.n_rows input nodes, + * followed by a linear layer and then a reparametrization layer. + */ + + FFN > *model = new FFN >; + model->Add >(trainData.n_rows, 8); + model->Add >(4, false, true, 1); + model->Add >(); + + FFN > *model1 = new FFN >; + model1->Add >(trainData.n_rows, 8); + model1->Add >(4, false, true, 1); + model1->Add >(); + + // Check whether copy constructor is working or not. + CheckCopyFunction<>(model, trainData, trainLabels, 1); + + // Check whether move constructor is working or not. + CheckMoveFunction<>(model1, trainData, trainLabels, 1); +} + /** * Train the vanilla network on a larger dataset. */