From 5921a73a71b4ec3dbb0d8a7867dae318e0ff0edc Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Wed, 6 Nov 2019 14:38:08 -0500 Subject: [PATCH 001/550] ability to calculate likelihood from pre-calculated emission probability for data stream --- src/mlpack/methods/hmm/hmm.hpp | 23 ++++++ src/mlpack/methods/hmm/hmm_impl.hpp | 119 +++++++++++++++++++++++----- 2 files changed, 120 insertions(+), 22 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 021ff74dad..b01223c3e2 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -292,6 +292,17 @@ class HMM */ double LogLikelihood(const arma::mat& dataSeq) const; + /** + * Compute the log-likelihood of the given emission probability up to time t + * + * @param dataSeq Data sequence to evaluate the likelihood of. + * @return Log-likelihood of the given sequence of emission up to time t. + */ + double LogLikelihood(size_t t, + const arma::vec& emissionLogProb, + double &logScale, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const; /** * HMM filtering. Computes the k-step-ahead expected emission at each time * conditioned only on prior observations. That is @@ -360,6 +371,18 @@ class HMM protected: + + void ForwardAtT0( + const arma::vec& emissionLogProb, + double& logScales, + arma::vec& forwardLogProb) const; + + void ForwardAtTn( + const arma::vec& emissionLogProb, + double& logScales, + const arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const; + // Helper functions. /** * The Forward algorithm (part of the Forward-Backward algorithm). Computes diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index ef857f4ee5..8245b472f6 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -517,6 +517,30 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const return accu(logScales); } +/** + * Compute the log-likelihood of the given emission probability. + */ +template +double HMM::LogLikelihood(size_t t, + const arma::vec& emissionLogProb, + double &logScale, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const +{ + if(t == 0){ + ForwardAtT0(emissionLogProb, logScale, forwardLogProb); + } + else{ + double curLogSacle; + ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); + logScale += curLogSacle; + } + + prevForwardLogProb = forwardLogProb; + + return logScale; +} + /** * HMM filtering. */ @@ -565,6 +589,68 @@ void HMM::Smooth(const arma::mat& dataSeq, smoothSeq += emission[i].Mean() * exp(stateLogProb.row(i)); } +/** + * The Forward procedure (part of the Forward-Backward algorithm). + */ +template +void HMM::ForwardAtT0(const arma::vec& emissionLogProb, + double& logScales, + arma::vec& forwardLogProb + ) const +{ + // Our goal is to calculate the forward probabilities: + // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. + + + ConvertToLogSpace(); + + forwardLogProb.resize(logTransition.n_rows); + forwardLogProb.fill(-std::numeric_limits::infinity()); + // The first entry in the forward algorithm uses the initial state + // probabilities. Note that MATLAB assumes that the starting state (at + // t = -1) is state 0; this is not our assumption here. To force that + // behavior, you could append a single starting state to every single data + // sequence and that should produce results in line with MATLAB. + for (size_t state = 0; state < logTransition.n_rows; state++) { + forwardLogProb(state) = logInitial(state) + emissionLogProb(state); + } + + // Normalize probability. + logScales = math::AccuLog(forwardLogProb); + if (std::isfinite(logScales)){ + forwardLogProb -= logScales; + } +} + +/** + * The Forward procedure (part of the Forward-Backward algorithm). + */ +template +void HMM::ForwardAtTn(const arma::vec& emissionLogProb, + double& logScales, + const arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb + ) const +{ + // Our goal is to calculate the forward probabilities: + // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. + + + // Now compute the probabilities for each successive observation. + for (size_t state = 0; state < logTransition.n_rows; state++) { + // The forward probability of state j at time t is the sum over all states + // of the probability of the previous state transitioning to the current + // state and emitting the given observation. + arma::vec tmp = prevForwardLogProb + logTransition.row(state).t(); + forwardLogProb(state) = math::AccuLog(tmp) + emissionLogProb(state); + } + // Normalize probability. + logScales = math::AccuLog(forwardLogProb); + if (std::isfinite(logScales)){ + forwardLogProb -= logScales; + } +} + /** * The Forward procedure (part of the Forward-Backward algorithm). */ @@ -578,43 +664,32 @@ void HMM::Forward(const arma::mat& dataSeq, forwardLogProb.resize(logTransition.n_rows, dataSeq.n_cols); forwardLogProb.fill(-std::numeric_limits::infinity()); logScales.resize(dataSeq.n_cols); - logScales.fill(-std::numeric_limits::infinity()); - - ConvertToLogSpace(); // The first entry in the forward algorithm uses the initial state // probabilities. Note that MATLAB assumes that the starting state (at // t = -1) is state 0; this is not our assumption here. To force that // behavior, you could append a single starting state to every single data // sequence and that should produce results in line with MATLAB. + + arma::vec emissionLogProb(logTransition.n_rows); for (size_t state = 0; state < logTransition.n_rows; state++) { - forwardLogProb(state, 0) = logInitial(state) + - emission[state].LogProbability(dataSeq.unsafe_col(0)); + emissionLogProb(state) = emission[state].LogProbability(dataSeq.unsafe_col(0)); } - - // Then normalize the column. - logScales[0] = math::AccuLog(forwardLogProb.col(0)); - if (std::isfinite(logScales[0])) - forwardLogProb.col(0) -= logScales[0]; + + arma::vec col0(forwardLogProb.colptr(0), logTransition.n_rows, false); + ForwardAtT0(emissionLogProb, logScales(0), col0); // Now compute the probabilities for each successive observation. for (size_t t = 1; t < dataSeq.n_cols; t++) { - for (size_t j = 0; j < logTransition.n_rows; j++) + for (size_t state = 0; state < logTransition.n_rows; state++) { - // The forward probability of state j at time t is the sum over all states - // of the probability of the previous state transitioning to the current - // state and emitting the given observation. - arma::vec tmp = forwardLogProb.col(t - 1) + logTransition.row(j).t(); - forwardLogProb(j, t) = math::AccuLog(tmp) + - emission[j].LogProbability(dataSeq.unsafe_col(t)); + emissionLogProb(state) = emission[state].LogProbability(dataSeq.unsafe_col(t)); } - - // Normalize probability. - logScales[t] = math::AccuLog(forwardLogProb.col(t)); - if (std::isfinite(logScales[t])) - forwardLogProb.col(t) -= logScales[t]; + + arma::vec colt(forwardLogProb.colptr(t), logTransition.n_rows, false); + ForwardAtTn(emissionLogProb, logScales(t), forwardLogProb.col(t-1), colt); } } From e123435aefedf941d4fb3b3d5d763cc6cf48db0c Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Mon, 9 Dec 2019 17:50:10 -0500 Subject: [PATCH 002/550] added logLikelihood() to calculate log likelihood for data stream at each point of time --- src/mlpack/methods/hmm/hmm.hpp | 33 +++++++++++-- src/mlpack/methods/hmm/hmm_impl.hpp | 77 +++++++++++++++++++---------- src/mlpack/tests/hmm_test.cpp | 13 ++++- 3 files changed, 90 insertions(+), 33 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 785458fc88..f7a20404be 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -295,13 +295,37 @@ class HMM /** * Compute the log-likelihood of the given emission probability up to time t * - * @param dataSeq Data sequence to evaluate the likelihood of. + * @param t time order + * @param log emission probability at time t. + * @param logScale Log-likelihood of the given sequence of emission + * probability up to time t-1 + * @param prevForwardProb Vector in which forward probabilities for time t-1 + * will be saved. + * @param forwardProb Vector in which forward probabilities for time t + * will be saved. * @return Log-likelihood of the given sequence of emission up to time t. */ - double LogLikelihood(size_t t, + double LogLikelihoodEmissionProb(size_t t, const arma::vec& emissionLogProb, - double &logScale, - arma::vec& prevForwardLogProb, + double &logScale, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const; + /** + * Compute the log-likelihood of the given data up to time t + * + * @param t time order + * @param data observation at time t. + * @param logScale Log-likelihood of the given sequence of data up to time t-1 + * @param prevForwardProb Vector in which forward probabilities for time t-1 + * will be saved. + * @param forwardProb Vector in which forward probabilities for time t + * will be saved. + * @return Log-likelihood of the given sequence of data up to time t. + */ + double LogLikelihood(size_t t, + const arma::vec &data, + double &logScale, + arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** * HMM filtering. Computes the k-step-ahead expected emission at each time @@ -382,7 +406,6 @@ class HMM protected: - void ForwardAtT0( const arma::vec& emissionLogProb, double& logScales, diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index e97dec16bc..a447d7501e 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -523,13 +523,13 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const } /** - * Compute the log-likelihood of the given emission probability. + * Compute the log-likelihood of the given emission probability up to time t */ template -double HMM::LogLikelihood(size_t t, +double HMM::LogLikelihoodEmissionProb(size_t t, const arma::vec& emissionLogProb, - double &logScale, - arma::vec& prevForwardLogProb, + double &logScale, + arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { if(t == 0){ @@ -537,15 +537,37 @@ double HMM::LogLikelihood(size_t t, } else{ double curLogSacle; - ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); + ForwardAtTn(emissionLogProb, curLogSacle, + prevForwardLogProb, forwardLogProb); logScale += curLogSacle; } - + prevForwardLogProb = forwardLogProb; - + return logScale; } +/** + * Compute the log-likelihood of the given data up to time t + */ +template +double HMM::LogLikelihood(size_t t, + const arma::vec &data, + double &logScale, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const +{ + arma::vec emissionLogProb(logTransition.n_rows); + + for (size_t state = 0; state < logTransition.n_rows; state++) + { + emissionLogProb(state) = emission[state].LogProbability(data); + } + + return LogLikelihoodEmissionProb(t, emissionLogProb, logScale, + prevForwardLogProb, forwardLogProb); +} + /** * HMM filtering. */ @@ -601,14 +623,14 @@ template void HMM::ForwardAtT0(const arma::vec& emissionLogProb, double& logScales, arma::vec& forwardLogProb - ) const -{ + ) const +{ // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. - - + + ConvertToLogSpace(); - + forwardLogProb.resize(logTransition.n_rows); forwardLogProb.fill(-std::numeric_limits::infinity()); // The first entry in the forward algorithm uses the initial state @@ -635,17 +657,17 @@ void HMM::ForwardAtTn(const arma::vec& emissionLogProb, double& logScales, const arma::vec& prevForwardLogProb, arma::vec& forwardLogProb - ) const -{ + ) const +{ // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. - - + + // Now compute the probabilities for each successive observation. for (size_t state = 0; state < logTransition.n_rows; state++) { - // The forward probability of state j at time t is the sum over all states - // of the probability of the previous state transitioning to the current - // state and emitting the given observation. + // The forward probability of state j at time t is the sum over all + // states of the probability of the previous state transitioning to + // the current state and emitting the given observation. arma::vec tmp = prevForwardLogProb + logTransition.row(state).t(); forwardLogProb(state) = math::AccuLog(tmp) + emissionLogProb(state); } @@ -678,13 +700,14 @@ void HMM::Forward(const arma::mat& dataSeq, // t = -1) is state 0; this is not our assumption here. To force that // behavior, you could append a single starting state to every single data // sequence and that should produce results in line with MATLAB. - + arma::vec emissionLogProb(logTransition.n_rows); for (size_t state = 0; state < logTransition.n_rows; state++) { - emissionLogProb(state) = emission[state].LogProbability(dataSeq.unsafe_col(0)); + emissionLogProb(state) = + emission[state].LogProbability(dataSeq.unsafe_col(0)); } - + arma::vec col0(forwardLogProb.colptr(0), logTransition.n_rows, false); ForwardAtT0(emissionLogProb, logScales(0), col0); @@ -693,11 +716,12 @@ void HMM::Forward(const arma::mat& dataSeq, { for (size_t state = 0; state < logTransition.n_rows; state++) { - emissionLogProb(state) = emission[state].LogProbability(dataSeq.unsafe_col(t)); + emissionLogProb(state) = + emission[state].LogProbability(dataSeq.unsafe_col(t)); } - + arma::vec colt(forwardLogProb.colptr(t), logTransition.n_rows, false); - ForwardAtTn(emissionLogProb, logScales(t), forwardLogProb.col(t-1), colt); + ForwardAtTn(emissionLogProb, logScales(t), forwardLogProb.col(t-1), colt); } } @@ -738,7 +762,8 @@ void HMM::Backward(const arma::mat& dataSeq, } /** - * Make sure the variables in log space are in sync with the linear counter parts + * Make sure the variables in log space are in sync with the linear + * counter parts */ template void HMM::ConvertToLogSpace() const diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index fd1c1946fc..6cda82d289 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -836,7 +836,15 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) }; arma::Row stateSeq; - auto likelihood = hmm.LogLikelihood(obs); + auto loglikelihood = hmm.LogLikelihood(obs); + + double loglikelihood2; + arma::vec prevForwardLogProb; + arma::vec forwardLogProb; + for(size_t t = 0; t stateSeqRef = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -845,7 +853,8 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; - BOOST_REQUIRE_CLOSE(likelihood, -2734.43, 1e-3); + BOOST_REQUIRE_CLOSE(loglikelihood, -2734.43, 1e-3); + BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihood2, 1e-5); for (size_t i = 0; i < stateSeqRef.n_cols; ++i) { From a28a8a1f6a5d0f8857d830a80e97ccf989d9b557 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Mon, 6 Jan 2020 11:45:03 -0500 Subject: [PATCH 003/550] fixed style issues --- src/mlpack/methods/hmm/hmm_impl.hpp | 12 ++++++------ src/mlpack/tests/hmm_test.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index a447d7501e..e77ee5a115 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -532,10 +532,12 @@ double HMM::LogLikelihoodEmissionProb(size_t t, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - if(t == 0){ + if (t == 0) + { ForwardAtT0(emissionLogProb, logScale, forwardLogProb); } - else{ + else + { double curLogSacle; ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); @@ -622,8 +624,7 @@ void HMM::Smooth(const arma::mat& dataSeq, template void HMM::ForwardAtT0(const arma::vec& emissionLogProb, double& logScales, - arma::vec& forwardLogProb - ) const + arma::vec& forwardLogProb) const { // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. @@ -656,8 +657,7 @@ template void HMM::ForwardAtTn(const arma::vec& emissionLogProb, double& logScales, const arma::vec& prevForwardLogProb, - arma::vec& forwardLogProb - ) const + arma::vec& forwardLogProb) const { // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 6cda82d289..d3cb56bff0 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -841,8 +841,10 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) double loglikelihood2; arma::vec prevForwardLogProb; arma::vec forwardLogProb; - for(size_t t = 0; t Date: Mon, 6 Jan 2020 11:49:47 -0500 Subject: [PATCH 004/550] fixed style issues. Removed tabs --- src/mlpack/methods/hmm/hmm_impl.hpp | 4 ++-- src/mlpack/tests/hmm_test.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index e77ee5a115..7ec65f7f0c 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -533,11 +533,11 @@ double HMM::LogLikelihoodEmissionProb(size_t t, arma::vec& forwardLogProb) const { if (t == 0) - { + { ForwardAtT0(emissionLogProb, logScale, forwardLogProb); } else - { + { double curLogSacle; ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index d3cb56bff0..72bebbc168 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -844,7 +844,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) for (size_t t = 0; t Date: Tue, 7 Jan 2020 11:29:40 -0500 Subject: [PATCH 005/550] no need to call ConvertToLogSpace() in Forward() since it's called inside ForwardAtT0() --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 7ec65f7f0c..0616099b69 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -693,8 +693,6 @@ void HMM::Forward(const arma::mat& dataSeq, logScales.resize(dataSeq.n_cols); logScales.fill(-std::numeric_limits::infinity()); - ConvertToLogSpace(); - // The first entry in the forward algorithm uses the initial state // probabilities. Note that MATLAB assumes that the starting state (at // t = -1) is state 0; this is not our assumption here. To force that From 3812017ba9df058f662b0604b74a504d2be77975 Mon Sep 17 00:00:00 2001 From: Bisakh Mondal Date: Sun, 8 Mar 2020 15:13:23 +0530 Subject: [PATCH 006/550] DStump package removed --- .../methods/decision_stump/CMakeLists.txt | 20 - .../methods/decision_stump/decision_stump.hpp | 237 -------- .../decision_stump/decision_stump_impl.hpp | 518 ------------------ .../decision_stump/decision_stump_main.cpp | 202 ------- 4 files changed, 977 deletions(-) delete mode 100644 src/mlpack/methods/decision_stump/CMakeLists.txt delete mode 100644 src/mlpack/methods/decision_stump/decision_stump.hpp delete mode 100644 src/mlpack/methods/decision_stump/decision_stump_impl.hpp delete mode 100644 src/mlpack/methods/decision_stump/decision_stump_main.cpp diff --git a/src/mlpack/methods/decision_stump/CMakeLists.txt b/src/mlpack/methods/decision_stump/CMakeLists.txt deleted file mode 100644 index 40a1d198ce..0000000000 --- a/src/mlpack/methods/decision_stump/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Define the files we need to compile. -# Anything not in this list will not be compiled into mlpack. -set(SOURCES - decision_stump.hpp - decision_stump_impl.hpp -) - -# Add directory name to sources. -set(DIR_SRCS) -foreach(file ${SOURCES}) - set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}) -endforeach() -# Append sources (with directory name) to list of all mlpack sources (used at -# the parent scope). -set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE) - -add_cli_executable(decision_stump) -add_python_binding(decision_stump) -add_julia_binding(decision_stump) -add_markdown_docs(decision_stump "cli;python;julia" "classification") diff --git a/src/mlpack/methods/decision_stump/decision_stump.hpp b/src/mlpack/methods/decision_stump/decision_stump.hpp deleted file mode 100644 index e8863908ab..0000000000 --- a/src/mlpack/methods/decision_stump/decision_stump.hpp +++ /dev/null @@ -1,237 +0,0 @@ -/** - * @file decision_stump.hpp - * @author Udit Saxena - * - * Definition of decision stumps. - * - * 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_DECISION_STUMP_DECISION_STUMP_HPP -#define MLPACK_METHODS_DECISION_STUMP_DECISION_STUMP_HPP - -#include - -namespace mlpack { -namespace decision_stump { - -/** - * This class implements a decision stump. It constructs a single level - * decision tree, i.e., a decision stump. It uses entropy to decide splitting - * ranges. - * - * The stump is parameterized by a splitting dimension (the dimension on which - * points are split), a vector of bin split values, and a vector of labels for - * each bin. Bin i is specified by the range [split[i], split[i + 1]). The - * last bin has range up to \infty (split[i + 1] does not exist in that case). - * Points that are below the first bin will take the label of the first bin. - * - * @note - * This class has been deprecated and should be removed in mlpack 4.0.0. Use - * `ID3DecisionStump`, found in src/mlpack/methods/decision_tree/, instead. - * - * @tparam MatType Type of matrix that is being used (sparse or dense). - */ -template -class DecisionStump -{ - public: - /** - * Constructor. Train on the provided data. Generate a decision stump from - * data. - * - * @param data Input, training data. - * @param labels Labels of training data. - * @param numClasses Number of distinct classes in labels. - * @param bucketSize Minimum size of bucket when splitting. - */ - mlpack_deprecated DecisionStump(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize = 10); - - /** - * Alternate constructor which copies the parameters bucketSize and classes - * from an already initiated decision stump, other. It appropriately sets the - * weight vector. - * - * @param other The other initiated Decision Stump object from - * which we copy the values. - * @param data The data on which to train this object on. - * @param labels The labels of data. - * @param weights Weight vector to use while training. For boosting purposes. - */ - mlpack_deprecated DecisionStump(const DecisionStump<>& other, - const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const arma::rowvec& weights); - - /** - * Create a decision stump without training. This stump will not be useful - * and will always return a class of 0 for anything that is to be classified, - * so it would be a prudent idea to call Train() after using this constructor. - */ - DecisionStump(); - - /** - * Train the decision stump on the given data. This completely overwrites any - * previous training data, so after training the stump may be completely - * different. - * - * @param data Dataset to train on. - * @param labels Labels for each point in the dataset. - * @param numClasses Number of classes in the dataset. - * @param bucketSize Minimum size of bucket when splitting. - * @return The final entropy after splitting. - */ - mlpack_deprecated double Train(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize); - - /** - * Train the decision stump on the given data, with the given weights. This - * completely overwrites any previous training data, so after training the - * stump may be completely different. - * - * @param data Dataset to train on. - * @param labels Labels for each point in the dataset. - * @param weights Weights for each point in the dataset. - * @param numClasses Number of classes in the dataset. - * @param bucketSize Minimum size of bucket when splitting. - * @return The final entropy after splitting. - */ - mlpack_deprecated double Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights, - const size_t numClasses, - const size_t bucketSize); - - /** - * Classification function. After training, classify test, and put the - * predicted classes in predictedLabels. - * - * @param test Testing data or data to classify. - * @param predictedLabels Vector to store the predicted classes after - * classifying test data. - */ - mlpack_deprecated void Classify(const MatType& test, - arma::Row& predictedLabels); - - //! Access the splitting dimension. - size_t SplitDimension() const { return splitDimension; } - //! Modify the splitting dimension (be careful!). - size_t& SplitDimension() { return splitDimension; } - - //! Access the splitting values. - const arma::vec& Split() const { return split; } - //! Modify the splitting values (be careful!). - arma::vec& Split() { return split; } - - //! Access the labels for each split bin. - const arma::Col BinLabels() const { return binLabels; } - //! Modify the labels for each split bin (be careful!). - arma::Col& BinLabels() { return binLabels; } - - //! Serialize the decision stump. - template - void serialize(Archive& ar, const unsigned int /* version */); - - private: - //! The number of classes (we must store this for boosting). - size_t numClasses; - //! The minimum number of points in a bucket. - size_t bucketSize; - - //! Stores the value of the dimension on which to split. - size_t splitDimension; - //! Stores the splitting values after training. - arma::vec split; - //! Stores the labels for each splitting bin. - arma::Col binLabels; - - /** - * Sets up dimension as if it were splitting on it and finds entropy when - * splitting on dimension. - * - * @param dimension A row from the training data, which might be a - * candidate for the splitting dimension. - * @tparam UseWeights Whether we need to run a weighted Decision Stump. - */ - template - double SetupSplitDimension(const VecType& dimension, - const arma::Row& labels, - const arma::rowvec& weightD); - - /** - * After having decided the dimension on which to split, train on that - * dimension. - * - * @tparam dimension dimension is the dimension decided by the constructor - * on which we now train the decision stump. - */ - template - void TrainOnDim(const VecType& dimension, - const arma::Row& labels); - - /** - * After the "split" matrix has been set up, merge ranges with identical class - * labels. - */ - void MergeRanges(); - - /** - * Count the most frequently occurring element in subCols. - * - * @param subCols The vector in which to find the most frequently occurring - * element. - */ - template - double CountMostFreq(const VecType& subCols); - - /** - * Returns 1 if all the values of featureRow are not same. - * - * @param featureRow The dimension which is checked for identical values. - */ - template - int IsDistinct(const VecType& featureRow); - - /** - * Calculate the entropy of the given dimension. - * - * @param labels Corresponding labels of the dimension. - * @param classes Number of classes. - * @param weights Weights for this set of labels. - * @tparam UseWeights If true, the weights in the weight vector will be used - * (otherwise they are ignored). - */ - template - double CalculateEntropy(const VecType& labels, - const WeightVecType& weights); - - /** - * Train the decision stump on the given data and labels. - * - * @param data Dataset to train on. - * @param labels Labels for dataset. - * @param weights Weights for this set of labels. - * @tparam UseWeights If true, the weights in the weight vector will be used - * (otherwise they are ignored). - * @return The final entropy after splitting. - */ - template - double Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights); -}; - -} // namespace decision_stump -} // namespace mlpack - -#include "decision_stump_impl.hpp" - -#endif diff --git a/src/mlpack/methods/decision_stump/decision_stump_impl.hpp b/src/mlpack/methods/decision_stump/decision_stump_impl.hpp deleted file mode 100644 index 73e324e2e1..0000000000 --- a/src/mlpack/methods/decision_stump/decision_stump_impl.hpp +++ /dev/null @@ -1,518 +0,0 @@ -/** - * @file decision_stump_impl.hpp - * @author Udit Saxena - * - * Implementation of DecisionStump 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_DECISION_STUMP_DECISION_STUMP_IMPL_HPP -#define MLPACK_METHODS_DECISION_STUMP_DECISION_STUMP_IMPL_HPP - -// In case it hasn't been included yet. -#include "decision_stump.hpp" - -namespace mlpack { -namespace decision_stump { - -/** - * Constructor. Train on the provided data. Generate a decision stump from data. - * - * @param data Input, training data. - * @param labels Labels of data. - * @param numClasses Number of distinct classes in labels. - * @param bucketSize Minimum size of bucket when splitting. - */ -template -DecisionStump::DecisionStump(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize) : - numClasses(numClasses), - bucketSize(bucketSize) -{ - arma::rowvec weights; - Train(data, labels, weights); -} - -/** - * Empty constructor. - */ -template -DecisionStump::DecisionStump() : - numClasses(1), - bucketSize(0), - splitDimension(0), - split(1), - binLabels(1) -{ - split[0] = DBL_MAX; - binLabels[0] = 0; -} - -/** - * Train on the given data and labels. - */ -template -double DecisionStump::Train(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize) -{ - this->numClasses = numClasses; - this->bucketSize = bucketSize; - - // Pass to unweighted training function. - arma::rowvec weights; - return Train(data, labels, weights); -} - -/** - * Train the decision stump on the given data, with the given weights. This - * completely overwrites any previous training data, so after training the - * stump may be completely different. - */ -template -double DecisionStump::Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights, - const size_t numClasses, - const size_t bucketSize) -{ - this->numClasses = numClasses; - this->bucketSize = bucketSize; - - // Pass to weighted training function. - return Train(data, labels, weights); -} - -/** - * Train the decision stump on the given data and labels. - * - * @param data Dataset to train on. - * @param labels Labels for dataset. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -template -double DecisionStump::Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights) -{ - // If classLabels are not all identical, proceed with training. - size_t bestDim = 0; - double entropy; - const double rootEntropy = CalculateEntropy(labels, weights); - - double gain, bestGain = 0.0; - for (size_t i = 0; i < data.n_rows; i++) - { - // Go through each dimension of the data. - if (IsDistinct(data.row(i))) - { - // For each dimension with non-identical values, treat it as a potential - // splitting dimension and calculate entropy if split on it. - entropy = SetupSplitDimension(data.row(i), labels, weights); - - gain = rootEntropy - entropy; - // Find the dimension with the best entropy so that the gain is - // maximized. - - // We are maximizing gain, which is what is returned from - // SetupSplitDimension(). - if (gain < bestGain) - { - bestDim = i; - bestGain = gain; - } - } - } - splitDimension = bestDim; - - // Once the splitting column/dimension has been decided, train on it. - TrainOnDim(data.row(splitDimension), labels); - return -bestGain; -} - -/** - * Classification function. After training, classify test, and put the predicted - * classes in predictedLabels. - * - * @param test Testing data or data to classify. - * @param predictedLabels Vector to store the predicted classes after - * classifying test - */ -template -void DecisionStump::Classify(const MatType& test, - arma::Row& predictedLabels) -{ - predictedLabels.set_size(test.n_cols); - for (size_t i = 0; i < test.n_cols; i++) - { - // Determine which bin the test point falls into. - // Assume first that it falls into the first bin, then proceed through the - // bins until it is known which bin it falls into. - size_t bin = 0; - const double val = test(splitDimension, i); - - while (bin < split.n_elem - 1) - { - if (val < split(bin + 1)) - break; - - ++bin; - } - - predictedLabels(i) = binLabels(bin); - } -} - -/** - * Alternate constructor which copies parameters bucketSize and numClasses - * from an already initiated decision stump, other. It appropriately - * sets the Weight vector. - * - * @param other The other initiated Decision Stump object from - * which we copy the values from. - * @param data The data on which to train this object on. - * @param D Weight vector to use while training. For boosting purposes. - * @param labels The labels of data. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -DecisionStump::DecisionStump(const DecisionStump<>& other, - const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const arma::rowvec& weights) : - numClasses(numClasses), - bucketSize(other.bucketSize) -{ - Train(data, labels, weights); -} - -/** - * Serialize the decision stump. - */ -template -template -void DecisionStump::serialize(Archive& ar, - const unsigned int /* version */) -{ - // This is straightforward; just serialize all of the members of the class. - // None need special handling. - ar & BOOST_SERIALIZATION_NVP(numClasses); - ar & BOOST_SERIALIZATION_NVP(bucketSize); - ar & BOOST_SERIALIZATION_NVP(splitDimension); - ar & BOOST_SERIALIZATION_NVP(split); - ar & BOOST_SERIALIZATION_NVP(binLabels); -} - -/** - * Sets up dimension as if it were splitting on it and finds entropy when - * splitting on dimension. - * - * @param dimension A row from the training data, which might be a candidate for - * the splitting dimension. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -template -double DecisionStump::SetupSplitDimension( - const VecType& dimension, - const arma::Row& labels, - const arma::rowvec& weights) -{ - size_t i, count, begin, end; - double entropy = 0.0; - - // Store the indices of the sorted dimension to build a vector of sorted - // labels. This sort is stable. - arma::uvec sortedIndexDim = arma::stable_sort_index(dimension.t()); - - arma::Row sortedLabels(dimension.n_elem); - arma::rowvec sortedWeights(dimension.n_elem); - - for (i = 0; i < dimension.n_elem; i++) - { - sortedLabels(i) = labels(sortedIndexDim(i)); - - // Apply weights if necessary. - if (UseWeights) - sortedWeights(i) = weights(sortedIndexDim(i)); - } - - i = 0; - count = 0; - - // This splits the sorted data into buckets of size greater than or equal to - // bucketSize. - while (i < sortedLabels.n_elem) - { - count++; - if (i == sortedLabels.n_elem - 1) - { - // If we're at the end, then don't worry about the bucket size; just take - // this as the last bin. - begin = i - count + 1; - end = i; - - // Use ratioEl to calculate the ratio of elements in this split. - const double ratioEl = ((double) (end - begin + 1) / sortedLabels.n_elem); - - entropy += ratioEl * CalculateEntropy( - sortedLabels.subvec(begin, end), sortedWeights.subvec(begin, end)); - i++; - } - else if (sortedLabels(i) != sortedLabels(i + 1)) - { - // If we're not at the last element of sortedLabels, then check whether - // count is less than the current bucket size. - if (count < bucketSize) - { - // If it is, then take the minimum bucket size anyways. - // This is where the inpBucketSize comes into use. - // This makes sure there isn't a bucket for every change in labels. - begin = i - count + 1; - end = begin + bucketSize - 1; - - if (end > sortedLabels.n_elem - 1) - end = sortedLabels.n_elem - 1; - } - else - { - // If it is not, then take the bucket size as the value of count. - begin = i - count + 1; - end = i; - } - const double ratioEl = ((double) (end - begin + 1) / sortedLabels.n_elem); - - entropy += ratioEl * CalculateEntropy( - sortedLabels.subvec(begin, end), sortedWeights.subvec(begin, end)); - - i = end + 1; - count = 0; - } - else - i++; - } - return entropy; -} - -/** - * After having decided the dimension on which to split, train on that - * dimension. - * - * @param dimension Dimension is the dimension decided by the constructor on - * which we now train the decision stump. - */ -template -template -void DecisionStump::TrainOnDim(const VecType& dimension, - const arma::Row& labels) -{ - size_t i, count, begin, end; - - typename MatType::row_type sortedSplitDim = arma::sort(dimension); - arma::uvec sortedSplitIndexDim = arma::stable_sort_index(dimension.t()); - arma::Row sortedLabels(dimension.n_elem); - sortedLabels.fill(0); - - for (i = 0; i < dimension.n_elem; i++) - sortedLabels(i) = labels(sortedSplitIndexDim(i)); - - arma::rowvec subCols; - double mostFreq; - i = 0; - count = 0; - while (i < sortedLabels.n_elem) - { - count++; - if (i == sortedLabels.n_elem - 1) - { - begin = i - count + 1; - end = i; - - mostFreq = CountMostFreq(sortedLabels.cols(begin, end)); - - split.resize(split.n_elem + 1); - split(split.n_elem - 1) = sortedSplitDim(begin); - binLabels.resize(binLabels.n_elem + 1); - binLabels(binLabels.n_elem - 1) = mostFreq; - - i++; - } - else if (sortedLabels(i) != sortedLabels(i + 1)) - { - if (count < bucketSize) - { - // Test for different values of bucketSize, especially extreme cases. - begin = i - count + 1; - end = begin + bucketSize - 1; - - if (end > sortedLabels.n_elem - 1) - end = sortedLabels.n_elem - 1; - } - else - { - begin = i - count + 1; - end = i; - } - - // Find the most frequent element in subCols so as to assign a label to - // the bucket of subCols. - mostFreq = CountMostFreq(sortedLabels.cols(begin, end)); - - split.resize(split.n_elem + 1); - split(split.n_elem - 1) = sortedSplitDim(begin); - binLabels.resize(binLabels.n_elem + 1); - binLabels(binLabels.n_elem - 1) = mostFreq; - - i = end + 1; - count = 0; - } - else - i++; - } - - // Now trim the split matrix so that buckets one after the after which point - // to the same classLabel are merged as one big bucket. - MergeRanges(); -} - -/** - * After the "split" matrix has been set up, merge ranges with identical class - * labels. - */ -template -void DecisionStump::MergeRanges() -{ - for (size_t i = 1; i < split.n_rows; i++) - { - if (binLabels(i) == binLabels(i - 1)) - { - // Remove this row, as it has the same label as the previous bucket. - binLabels.shed_row(i); - split.shed_row(i); - // Go back to previous row. - i--; - } - } -} - -template -template -double DecisionStump::CountMostFreq(const VecType& subCols) -{ - // We'll create a map of elements and the number of times that each element is - // seen. - std::map countMap; - - for (size_t i = 0; i < subCols.n_elem; ++i) - { - if (countMap.count(subCols[i]) == 0) - countMap[subCols[i]] = 1; - else - ++countMap[subCols[i]]; - } - - // Now find the maximum value. - typename std::map::iterator it = countMap.begin(); - double mostFreq = it->first; - size_t mostFreqCount = it->second; - while (it != countMap.end()) - { - if (it->second >= mostFreqCount) - { - mostFreq = it->first; - mostFreqCount = it->second; - } - - ++it; - } - - return mostFreq; -} - -/** - * Returns 1 if all the values of featureRow are not the same. - * - * @param featureRow The dimension which is checked for identical values. - */ -template -template -int DecisionStump::IsDistinct(const VecType& featureRow) -{ - typename VecType::elem_type val = featureRow(0); - for (size_t i = 1; i < featureRow.n_elem; ++i) - if (val != featureRow(i)) - return 1; - return 0; -} - -/** - * Calculate entropy of dimension. - * - * @param labels Corresponding labels of the dimension. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -template -double DecisionStump::CalculateEntropy( - const VecType& labels, - const WeightVecType& weights) -{ - double entropy = 0.0; - size_t j; - - arma::rowvec numElem(numClasses); - numElem.fill(0); - - // Variable to accumulate the weight in this subview_row. - double accWeight = 0.0; - // Populate numElem; they are used as helpers to calculate entropy. - - if (UseWeights) - { - for (j = 0; j < labels.n_elem; j++) - { - numElem(labels(j)) += weights(j); - accWeight += weights(j); - } - - for (j = 0; j < numClasses; j++) - { - const double p1 = ((double) numElem(j) / accWeight); - - // Instead of using log2(), which is C99 and may not exist on some - // compilers, use std::log(), then use the change-of-base formula to make - // the result correct. - entropy += (p1 == 0) ? 0 : p1 * std::log(p1); - } - } - else - { - for (j = 0; j < labels.n_elem; j++) - numElem(labels(j))++; - - for (j = 0; j < numClasses; j++) - { - const double p1 = ((double) numElem(j) / labels.n_elem); - - // Instead of using log2(), which is C99 and may not exist on some - // compilers, use std::log(), then use the change-of-base formula to make - // the result correct. - entropy += (p1 == 0) ? 0 : p1 * std::log(p1); - } - } - - return entropy / std::log(2.0); -} - -} // namespace decision_stump -} // namespace mlpack - -#endif diff --git a/src/mlpack/methods/decision_stump/decision_stump_main.cpp b/src/mlpack/methods/decision_stump/decision_stump_main.cpp deleted file mode 100644 index e9e683a61f..0000000000 --- a/src/mlpack/methods/decision_stump/decision_stump_main.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file decision_stump_main.cpp - * @author Udit Saxena - * - * Main executable for the decision stump. - * - * 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. - */ -#include -#include -#include -#include -#include "decision_stump.hpp" - -using namespace mlpack; -using namespace mlpack::decision_stump; -using namespace mlpack::util; -using namespace std; -using namespace arma; - -PROGRAM_INFO("Decision Stump", - // Short description. - "An implementation of a decision stump, which is a single-level decision " - "tree. Given labeled data, a new decision stump can be trained; or, an " - "existing decision stump can be used to classify points.", - // Long description. - "This program implements a decision stump, which is a single-level decision" - " tree. The decision stump will split on one dimension of the input data, " - "and will split into multiple buckets. The dimension and bins are selected" - " by maximizing the information gain of the split. Optionally, the minimum" - " number of training points in each bin can be specified with the " + - PRINT_PARAM_STRING("bucket_size") + " parameter." - "\n\n" - "The decision stump is parameterized by a splitting dimension and a vector " - "of values that denote the splitting values of each bin." - "\n\n" - "This program enables several applications: a decision tree may be trained " - "or loaded, and then that decision tree may be used to classify a given set" - " of test points. The decision tree may also be saved to a file for later " - "usage." - "\n\n" - "To train a decision stump, training data should be passed with the " + - PRINT_PARAM_STRING("training") + " parameter, and their corresponding " - "labels should be passed with the " + PRINT_PARAM_STRING("labels") + " " - "option. Optionally, if " + PRINT_PARAM_STRING("labels") + " is not " - "specified, the labels are assumed to be the last dimension of the " - "training dataset. The " + PRINT_PARAM_STRING("bucket_size") + " " - "parameter controls the minimum number of training points in each decision " - "stump bucket." - "\n\n" - "For classifying a test set, a decision stump may be loaded with the " + - PRINT_PARAM_STRING("input_model") + " parameter (useful for the situation " - "where a stump has already been trained), and a test set may be specified " - "with the " + PRINT_PARAM_STRING("test") + " parameter. The predicted " - "labels can be saved with the " + PRINT_PARAM_STRING("predictions") + " " - "output parameter." - "\n\n" - "Because decision stumps are trained in batch, retraining does not make " - "sense and thus it is not possible to pass both " + - PRINT_PARAM_STRING("training") + " and " + - PRINT_PARAM_STRING("input_model") + "; instead, simply build a new " - "decision stump with the training data." - "\n\n" - "After training, a decision stump can be saved with the " + - PRINT_PARAM_STRING("output_model") + " output parameter. That stump may " - "later be re-used in subsequent calls to this program (or others).", - SEE_ALSO("Decision tree", "#decision_tree"), - SEE_ALSO("Decision stumps on Wikipedia", - "https://en.wikipedia.org/wiki/Decision_stump"), - SEE_ALSO("mlpack::decision_stump::DecisionStump class documentation", - "@doxygen/classmlpack_1_1decision__stump_1_1DecisionStump.html")); - -// Datasets we might load. -PARAM_MATRIX_IN("training", "The dataset to train on.", "t"); -PARAM_UROW_IN("labels", "Labels for the training set. If not specified, the " - "labels are assumed to be the last row of the training data.", "l"); -PARAM_MATRIX_IN("test", "A dataset to calculate predictions for.", "T"); - -// Output. -PARAM_UROW_OUT("predictions", "The output matrix that will hold the " - "predicted labels for the test set.", "p"); - -/** - * This is the structure that actually saves to disk. We have to save the - * label mappings, too, otherwise everything we load at test time in a future - * run will end up being borked. - */ -struct DSModel -{ - //! The mappings. - arma::Col mappings; - //! The stump. - DecisionStump<> stump; - - //! Serialize the model. - template - void serialize(Archive& ar, const unsigned int /* version */) - { - ar & BOOST_SERIALIZATION_NVP(mappings); - ar & BOOST_SERIALIZATION_NVP(stump); - } -}; - -// We may load or save a model. -PARAM_MODEL_IN(DSModel, "input_model", "Decision stump model to " - "load.", "m"); -PARAM_MODEL_OUT(DSModel, "output_model", "Output decision stump model to save.", - "M"); - -PARAM_INT_IN("bucket_size", "The minimum number of training points in each " - "decision stump bucket.", "b", 6); - -static void mlpackMain() -{ - // Check that the parameters are reasonable. - RequireOnlyOnePassed({ "training", "input_model" }, true); - RequireAtLeastOnePassed({ "output_model", "predictions" }, false, "no results" - " will be saved"); - - RequireParamValue("bucket_size", [](int x) { return x > 0; }, true, - "bucket size must be positive"); - - ReportIgnoredParam({{ "test", false }}, "predictions"); - - Log::Warn << "DecisionStump is deprecated and will be removed in mlpack " - << "4.0.0. Please use DecisionTree instead with the maximum tree " - << "depth option set to 1 (that will produce a stump)." - << std::endl; - - // We must either load a model, or train a new stump. - DSModel* model; - if (CLI::HasParam("training")) - { - model = new DSModel(); - mat trainingData = std::move(CLI::GetParam("training")); - - // Load labels, if necessary. - Row labelsIn; - if (CLI::HasParam("labels")) - { - labelsIn = std::move(CLI::GetParam>("labels")); - } - else - { - // Extract the labels as the last - Log::Info << "Using the last dimension of training set as labels." - << endl; - - labelsIn = arma::conv_to>::from( - trainingData.row(trainingData.n_rows - 1)); - trainingData.shed_row(trainingData.n_rows - 1); - } - - // Normalize the labels. - Row labels; - data::NormalizeLabels(labelsIn, labels, model->mappings); - - const size_t bucketSize = CLI::GetParam("bucket_size"); - const size_t classes = labels.max() + 1; - - Timer::Start("training"); - model->stump.Train(trainingData, labels, classes, bucketSize); - Timer::Stop("training"); - } - else - { - model = CLI::GetParam("input_model"); - } - - // Now, do we need to do any testing? - if (CLI::HasParam("test")) - { - // Load the test file. - mat testingData = std::move(CLI::GetParam("test")); - - if (testingData.n_rows <= model->stump.SplitDimension()) - Log::Fatal << "Test data dimensionality (" << testingData.n_rows << ") " - << "is too low; the trained stump requires at least " - << model->stump.SplitDimension() << " dimensions!" << endl; - - Row predictedLabels(testingData.n_cols); - Timer::Start("testing"); - model->stump.Classify(testingData, predictedLabels); - Timer::Stop("testing"); - - // Denormalize predicted labels, if we want to save them. - if (CLI::HasParam("predictions")) - { - Row actualLabels; - data::RevertLabels(predictedLabels, model->mappings, actualLabels); - - // Save the predicted labels as output. - CLI::GetParam>("predictions") = std::move(actualLabels); - } - } - - // Save the model, if desired. - CLI::GetParam("output_model") = model; -} From 923c21d3770756fcb89066cc59a909e443d4bbac Mon Sep 17 00:00:00 2001 From: Bisakh Mondal Date: Sun, 8 Mar 2020 15:22:27 +0530 Subject: [PATCH 007/550] Serialization_test updated Decision stump tests removed --- src/mlpack/tests/serialization_test.cpp | 38 ------------------------- 1 file changed, 38 deletions(-) diff --git a/src/mlpack/tests/serialization_test.cpp b/src/mlpack/tests/serialization_test.cpp index da819f4ee4..f44247a742 100644 --- a/src/mlpack/tests/serialization_test.cpp +++ b/src/mlpack/tests/serialization_test.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,6 @@ using namespace mlpack::perceptron; using namespace mlpack::regression; using namespace mlpack::naive_bayes; using namespace mlpack::neighbor; -using namespace mlpack::decision_stump; using namespace mlpack::ann; using namespace arma; @@ -1065,42 +1063,6 @@ BOOST_AUTO_TEST_CASE(LSHTest) textLsh.SecondHashTable()[i], binaryLsh.SecondHashTable()[i]); } -// Make sure serialization works for the decision stump. -BOOST_AUTO_TEST_CASE(DecisionStumpTest) -{ - // Generate dataset. - arma::mat trainingData = arma::randu(4, 100); - arma::Row labels(100); - for (size_t i = 0; i < 25; ++i) - labels[i] = 0; - for (size_t i = 25; i < 50; ++i) - labels[i] = 3; - for (size_t i = 50; i < 75; ++i) - labels[i] = 1; - for (size_t i = 75; i < 100; ++i) - labels[i] = 2; - - DecisionStump<> ds(trainingData, labels, 4, 3); - - arma::mat otherData = arma::randu(3, 100); - arma::Row otherLabels = arma::randu>(100); - DecisionStump<> xmlDs(otherData, otherLabels, 2, 3); - - DecisionStump<> textDs; - DecisionStump<> binaryDs(trainingData, labels, 4, 10); - - SerializeObjectAll(ds, xmlDs, textDs, binaryDs); - - // Make sure that everything is the same about the new decision stumps. - BOOST_REQUIRE_EQUAL(ds.SplitDimension(), xmlDs.SplitDimension()); - BOOST_REQUIRE_EQUAL(ds.SplitDimension(), textDs.SplitDimension()); - BOOST_REQUIRE_EQUAL(ds.SplitDimension(), binaryDs.SplitDimension()); - - CheckMatrices(ds.Split(), xmlDs.Split(), textDs.Split(), binaryDs.Split()); - CheckMatrices(ds.BinLabels(), xmlDs.BinLabels(), textDs.BinLabels(), - binaryDs.BinLabels()); -} - // Make sure serialization works for LARS. BOOST_AUTO_TEST_CASE(LARSTest) { From 5a9b4f61c72ac864c7a130910e3ef50d882d7e4a Mon Sep 17 00:00:00 2001 From: Bisakh Mondal Date: Sun, 8 Mar 2020 15:32:53 +0530 Subject: [PATCH 008/550] decision Stumps tests removed --- src/mlpack/tests/decision_stump_test.cpp | 426 ----------------------- src/mlpack/tests/decision_tree_test.cpp | 22 -- 2 files changed, 448 deletions(-) delete mode 100644 src/mlpack/tests/decision_stump_test.cpp diff --git a/src/mlpack/tests/decision_stump_test.cpp b/src/mlpack/tests/decision_stump_test.cpp deleted file mode 100644 index 7adb0f2950..0000000000 --- a/src/mlpack/tests/decision_stump_test.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/** - * @file decision_stump_test.cpp - * @author Udit Saxena - * - * Tests for DecisionStump 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. - */ -#include -#include - -#include -#include "test_tools.hpp" - -using namespace mlpack; -using namespace mlpack::decision_stump; -using namespace arma; -using namespace mlpack::distribution; - -BOOST_AUTO_TEST_SUITE(DecisionStumpTest); - -/** - * This tests handles the case wherein only one class exists in the input - * labels. It checks whether the only class supplied was the only class - * predicted. - */ -BOOST_AUTO_TEST_CASE(OneClass) -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 6; - - mat trainingData; - trainingData << 2.4 << 3.8 << 3.8 << endr - << 1 << 1 << 2 << endr - << 1.3 << 1.9 << 1.3 << endr; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 1 << 1 << 1; - - mat testingData; - testingData << 2.4 << 2.5 << 2.6; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - for (size_t i = 0; i < predictedLabels.size(); i++) - BOOST_CHECK_EQUAL(predictedLabels(i), 1); -} - -/** - * This tests whether the entropy is being correctly calculated by checking the - * correct value of the splitting column value. This test is for an - * inpBucketSize of 4 and the correct value of the splitting dimension is 0. - */ -BOOST_AUTO_TEST_CASE(CorrectDimensionChosen) -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 4; - - // This dataset comes from Chapter 6 of the book "Data Mining: Concepts, - // Models, Methods, and Algorithms" (2nd Edition) by Mehmed Kantardzic. It is - // found on page 176 (and a description of the correct splitting dimension is - // given below that). - mat trainingData; - trainingData << 0 << 0 << 0 << 0 << 0 << 1 << 1 << 1 << 1 - << 2 << 2 << 2 << 2 << 2 << endr - << 70 << 90 << 85 << 95 << 70 << 90 << 78 << 65 << 75 - << 80 << 70 << 80 << 80 << 96 << endr - << 1 << 1 << 0 << 0 << 0 << 1 << 0 << 1 << 0 - << 1 << 1 << 0 << 0 << 0 << endr; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 1 << 1 << 1 << 0 << 0 << 0 << 0 - << 0 << 1 << 1 << 0 << 0 << 0; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - // Only need to check the value of the splitting column, no need of - // classification. - BOOST_CHECK_EQUAL(ds.SplitDimension(), 0); -} - -/** - * This tests for the classification: - * if testinput < 0 - class 0 - * if testinput > 0 - class 1 - * An almost perfect split on zero. - */ -BOOST_AUTO_TEST_CASE(PerfectSplitOnZero) -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 2; - - mat trainingData; - trainingData << -1 << 1 << -2 << 2 << -3 << 3; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 1 << 0 << 1 << 0 << 1; - - mat testingData; - testingData << -4 << 7 << -7 << -5 << 6; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - BOOST_CHECK_EQUAL(predictedLabels(0, 0), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 1), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 2), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 3), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 4), 1); -} - -/** - * This tests the binning function for the case when a dataset with cardinality - * of input < inpBucketSize is provided. - */ -BOOST_AUTO_TEST_CASE(BinningTesting) -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 10; - - mat trainingData; - trainingData << -1 << 1 << -2 << 2 << -3 << 3 << -4; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 1 << 0 << 1 << 0 << 1 << 0; - - mat testingData; - testingData << 5; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - BOOST_CHECK_EQUAL(predictedLabels(0, 0), 0); -} - -/** - * This is a test for the case when non-overlapping, multiple classes are - * provided. It tests for a perfect split due to the non-overlapping nature of - * the input classes. - */ -BOOST_AUTO_TEST_CASE(PerfectMultiClassSplit) -{ - const size_t numClasses = 4; - const size_t inpBucketSize = 3; - - mat trainingData; - trainingData << -8 << -7 << -6 << -5 << -4 << -3 << -2 << -1 - << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 1 << 1 - << 2 << 2 << 2 << 2 << 3 << 3 << 3 << 3; - - mat testingData; - testingData << -6.1 << -2.1 << 1.1 << 5.1; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - BOOST_CHECK_EQUAL(predictedLabels(0, 0), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 1), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 2), 2); - BOOST_CHECK_EQUAL(predictedLabels(0, 3), 3); -} - -/** - * This test is for the case when reasonably overlapping, multiple classes are - * provided in the input label set. It tests whether classification takes place - * with a reasonable amount of error due to the overlapping nature of input - * classes. - */ -BOOST_AUTO_TEST_CASE(MultiClassSplit) -{ - const size_t numClasses = 3; - const size_t inpBucketSize = 3; - - mat trainingData; - trainingData << -7 << -6 << -5 << -4 << -3 << -2 << -1 << 0 << 1 - << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 0 << 0 - << 1 << 1 << 1 << 2 << 1 << 2 << 2 << 2 << 2 << 2; - - - mat testingData; - testingData << -6.1 << -5.9 << -2.1 << -0.7 << 2.5 << 4.7 << 7.2 << 9.1; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - BOOST_CHECK_EQUAL(predictedLabels(0, 0), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 1), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 2), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 3), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 4), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 5), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 6), 2); - BOOST_CHECK_EQUAL(predictedLabels(0, 7), 2); -} - -/** - * This tests that the decision stump can learn a good split on a dataset with - * four dimensions that have progressing levels of separation. - */ -BOOST_AUTO_TEST_CASE(DimensionSelectionTest) -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 2500; - - arma::mat dataset(4, 5000); - - // The most separable dimension. - GaussianDistribution g1("-5", "1"); - GaussianDistribution g2("5", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(1, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(1, i) = tmp[0]; - } - - g1 = GaussianDistribution("-3", "1"); - g2 = GaussianDistribution("3", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(3, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(3, i) = tmp[0]; - } - - g1 = GaussianDistribution("-1", "1"); - g2 = GaussianDistribution("1", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(0, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(0, i) = tmp[0]; - } - - // Not separable at all. - g1 = GaussianDistribution("0", "1"); - g2 = GaussianDistribution("0", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(2, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(2, i) = tmp[0]; - } - - // Generate the labels. - arma::Row labels(5000); - for (size_t i = 0; i < 2500; ++i) - labels[i] = 0; - for (size_t i = 2500; i < 5000; ++i) - labels[i] = 1; - - // Now create a decision stump. - DecisionStump<> ds(dataset, labels, numClasses, inpBucketSize); - - // Make sure it split on the dimension that is most separable. - BOOST_CHECK_EQUAL(ds.SplitDimension(), 1); - - // Make sure every bin below -1 classifies as label 0, and every bin above 1 - // classifies as label 1 (What happens in [-1, 1] isn't that big a deal.). - for (size_t i = 0; i < ds.Split().n_elem; ++i) - { - if (ds.Split()[i] <= -3.0) - BOOST_CHECK_EQUAL(ds.BinLabels()[i], 0); - else if (ds.Split()[i] >= 3.0) - BOOST_CHECK_EQUAL(ds.BinLabels()[i], 1); - } -} - -/** - * Ensure that the default constructor works and that it classifies things as 0 - * always. - */ -BOOST_AUTO_TEST_CASE(EmptyConstructorTest) -{ - DecisionStump<> d; - - arma::mat data = arma::randu(3, 10); - arma::Row labels; - - d.Classify(data, labels); - - for (size_t i = 0; i < 10; ++i) - BOOST_REQUIRE_EQUAL(labels[i], 0); - - // Now train on another dataset and make sure something kind of makes sense. - mat trainingData; - trainingData << -7 << -6 << -5 << -4 << -3 << -2 << -1 << 0 << 1 - << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 0 << 0 - << 1 << 1 << 1 << 2 << 1 << 2 << 2 << 2 << 2 << 2; - - - mat testingData; - testingData << -6.1 << -5.9 << -2.1 << -0.7 << 2.5 << 4.7 << 7.2 << 9.1; - - DecisionStump<> ds(trainingData, labelsIn.row(0), 4, 3); - - Row predictedLabels(testingData.n_cols); - ds.Classify(testingData, predictedLabels); - - BOOST_CHECK_EQUAL(predictedLabels(0, 0), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 1), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 2), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 3), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 4), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 5), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 6), 2); - BOOST_CHECK_EQUAL(predictedLabels(0, 7), 2); -} - -/** - * Ensure that a matrix holding ints can be trained. The bigger issue here is - * just compilation. - */ -BOOST_AUTO_TEST_CASE(IntTest) -{ - // Train on a dataset and make sure something kind of makes sense. - imat trainingData; - trainingData << -7 << -6 << -5 << -4 << -3 << -2 << -1 << 0 << 1 - << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 0 << 0 - << 1 << 1 << 1 << 2 << 1 << 2 << 2 << 2 << 2 << 2; - - DecisionStump ds(trainingData, labelsIn.row(0), 4, 3); - - imat testingData; - testingData << -6 << -6 << -2 << -1 << 3 << 5 << 7 << 9; - - arma::Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - BOOST_CHECK_EQUAL(predictedLabels(0, 0), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 1), 0); - BOOST_CHECK_EQUAL(predictedLabels(0, 2), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 3), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 4), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 5), 1); - BOOST_CHECK_EQUAL(predictedLabels(0, 6), 2); - BOOST_CHECK_EQUAL(predictedLabels(0, 7), 2); -} - -/** - * Test that DecisionStump::Train() returns finite gain. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpTrainReturnEntropy) -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 2; - - mat trainingData; - trainingData << -1 << 1 << -2 << 2 << -3 << 3; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn << 0 << 1 << 0 << 1 << 0 << 1; - - arma::Row weights = arma::ones>(labelsIn.n_elem); - - // Train a simple decision stump without weights. - DecisionStump<> ds; - double gain = ds.Train(trainingData, labelsIn.row(0), numClasses, - inpBucketSize); - - BOOST_REQUIRE_EQUAL(std::isfinite(gain), true); - - // Train decision stump with weights. - DecisionStump<> wds; - gain = wds.Train(trainingData, labelsIn.row(0), weights, numClasses, - inpBucketSize); - - BOOST_REQUIRE_EQUAL(std::isfinite(gain), true); -} - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/decision_tree_test.cpp b/src/mlpack/tests/decision_tree_test.cpp index 0ab7fe6648..8708421fc0 100644 --- a/src/mlpack/tests/decision_tree_test.cpp +++ b/src/mlpack/tests/decision_tree_test.cpp @@ -767,28 +767,6 @@ BOOST_AUTO_TEST_CASE(CategoricalBuildTestWithWeight) BOOST_REQUIRE_GT(correctPct, 0.70); } -/** - * Make sure that when we ask for a decision stump, we get one. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpTest) -{ - // Use a random dataset. - arma::mat dataset(10, 1000, arma::fill::randu); - arma::Row labels(1000); - for (size_t i = 0; i < 1000; ++i) - labels[i] = i % 3; // 3 classes. - - // Build a decision stump. - DecisionTree stump(dataset, labels, 3, 1); - - // Check that it has children. - BOOST_REQUIRE_EQUAL(stump.NumChildren(), 2); - // Check that its children doesn't have children. - BOOST_REQUIRE_EQUAL(stump.Child(0).NumChildren(), 0); - BOOST_REQUIRE_EQUAL(stump.Child(1).NumChildren(), 0); -} - /** * Test that we can build a decision tree using weighted data (where the * low-weighted data is random noise), and that the tree still builds correctly From 14d3458b014657e2606b748440b4c46eaaabe6e7 Mon Sep 17 00:00:00 2001 From: Bisakh Mondal Date: Sun, 8 Mar 2020 15:40:09 +0530 Subject: [PATCH 009/550] Decision Stump removed from main_tests --- .../tests/main_tests/decision_stump_test.cpp | 263 ------------------ 1 file changed, 263 deletions(-) delete mode 100644 src/mlpack/tests/main_tests/decision_stump_test.cpp diff --git a/src/mlpack/tests/main_tests/decision_stump_test.cpp b/src/mlpack/tests/main_tests/decision_stump_test.cpp deleted file mode 100644 index f5de6b89d8..0000000000 --- a/src/mlpack/tests/main_tests/decision_stump_test.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/** - * @file decision_stump_test.cpp - * @author Manish Kumar - * - * Test mlpackMain() of decision_stump_main.cpp. - * - * 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. - */ -#define BINDING_TYPE BINDING_TYPE_TEST - -#include -static const std::string testName = "DecisionStump"; - -#include -#include -#include "test_helper.hpp" - -#include -#include "../test_tools.hpp" - -using namespace mlpack; - -struct DecisionStumpTestFixture -{ - public: - DecisionStumpTestFixture() - { - // Cache in the options for this program. - CLI::RestoreSettings(testName); - } - - ~DecisionStumpTestFixture() - { - // Clear the settings. - bindings::tests::CleanMemory(); - CLI::ClearSettings(); - } -}; - -BOOST_FIXTURE_TEST_SUITE(DecisionStumpMainTest, DecisionStumpTestFixture); - -/** - * Ensure that we get desired dimensions when both training - * data and labels are passed. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpOutputDimensionTest) -{ - arma::mat inputData; - if (!data::Load("trainSet.csv", inputData)) - BOOST_FAIL("Cannot load train dataset trainSet.csv!"); - - // Get the labels out. - arma::Row labels(inputData.n_cols); - for (size_t i = 0; i < inputData.n_cols; ++i) - labels[i] = inputData(inputData.n_rows - 1, i); - - // Delete the last row containing labels from input dataset. - inputData.shed_row(inputData.n_rows - 1); - - arma::mat testData; - if (!data::Load("testSet.csv", testData)) - BOOST_FAIL("Cannot load test dataset testSet.csv!"); - - // Delete the last row containing labels from test dataset. - testData.shed_row(testData.n_rows - 1); - - size_t testSize = testData.n_cols; - - // Input training data. - SetInputParam("training", std::move(inputData)); - SetInputParam("labels", std::move(labels)); - - // Input test data. - SetInputParam("test", std::move(testData)); - - mlpackMain(); - - // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_cols, - testSize); - - // Check prediction have only single row. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_rows, - 1); -} - -/** - * Check that last row of input file is used as labels - * when labels are not passed specifically and results - * are same from both label and labeless models. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpLabelsLessDimensionTest) -{ - // Train DS without providing labels. - arma::mat inputData; - if (!data::Load("trainSet.csv", inputData)) - BOOST_FAIL("Cannot load train dataset trainSet.csv!"); - - // Get the labels out. - arma::Row labels(inputData.n_cols); - for (size_t i = 0; i < inputData.n_cols; ++i) - labels[i] = inputData(inputData.n_rows - 1, i); - - arma::mat testData; - if (!data::Load("testSet.csv", testData)) - BOOST_FAIL("Cannot load test dataset testSet.csv!"); - - // Delete the last row containing labels from test dataset. - testData.shed_row(testData.n_rows - 1); - - size_t testSize = testData.n_cols; - - // Input training data. - SetInputParam("training", inputData); - - // Input test data. - SetInputParam("test", testData); - - mlpackMain(); - - // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_cols, - testSize); - - // Check prediction have only single row. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_rows, - 1); - - // Reset data passed. - CLI::GetSingleton().Parameters()["training"].wasPassed = false; - CLI::GetSingleton().Parameters()["test"].wasPassed = false; - - // Store outputs. - arma::Row predictions; - predictions = std::move(CLI::GetParam>("predictions")); - - // Delete the previous model. - bindings::tests::CleanMemory(); - - // Now train DS with labels provided. - - // Delete last row of inputData. - inputData.shed_row(inputData.n_rows - 1); - - // Input training data. - SetInputParam("training", std::move(inputData)); - SetInputParam("test", std::move(testData)); - // Pass Labels. - SetInputParam("labels", std::move(labels)); - - mlpackMain(); - - // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_cols, - testSize); - - // Check prediction have only single row. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_rows, - 1); - - // Check that initial output and final output matrix - // from two models are same. - CheckMatrices(predictions, CLI::GetParam>("predictions")); -} - -/** - * Ensure that saved model can be used again. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpModelReuseTest) -{ - arma::mat inputData; - if (!data::Load("trainSet.csv", inputData)) - BOOST_FAIL("Cannot load train dataset trainSet.csv!"); - - arma::mat testData; - if (!data::Load("testSet.csv", testData)) - BOOST_FAIL("Cannot load test dataset testSet.csv!"); - - // Delete the last row containing labels from test dataset. - testData.shed_row(testData.n_rows - 1); - - size_t testSize = testData.n_cols; - - // Input training data. - SetInputParam("training", std::move(inputData)); - - // Input test data. - SetInputParam("test", testData); - - mlpackMain(); - - arma::Row predictions; - predictions = std::move(CLI::GetParam>("predictions")); - - // Reset passed parameters. - CLI::GetSingleton().Parameters()["training"].wasPassed = false; - CLI::GetSingleton().Parameters()["test"].wasPassed = false; - - // Input trained model. - SetInputParam("test", std::move(testData)); - SetInputParam("input_model", - std::move(CLI::GetParam("output_model"))); - - mlpackMain(); - - // Check that number of output points are equal to number of input points. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_cols, - testSize); - - // Check predictions have only single row. - BOOST_REQUIRE_EQUAL(CLI::GetParam>("predictions").n_rows, - 1); - - // Check that initial predictions and final predicitons matrix - // using saved model are same. - CheckMatrices(predictions, CLI::GetParam>("predictions")); -} - -/** - * Ensure that bucket_size is always positive. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpBucketSizeTest) -{ - arma::mat inputData; - if (!data::Load("trainSet.csv", inputData)) - BOOST_FAIL("Cannot load train dataset trainSet.csv!"); - - // Input training data. - SetInputParam("training", std::move(inputData)); - SetInputParam("bucket_size", (int) 0); - - Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error); - Log::Fatal.ignoreInput = false; -} - -/** - * Make sure only one of training data or pre-trained model is passed. - */ -BOOST_AUTO_TEST_CASE(DecisionStumpTrainingVerTest) -{ - arma::mat inputData; - if (!data::Load("trainSet.csv", inputData)) - BOOST_FAIL("Cannot load train dataset trainSet.csv!"); - - // Input training data. - SetInputParam("training", std::move(inputData)); - - mlpackMain(); - - // Input pre-trained model. - SetInputParam("input_model", - std::move(CLI::GetParam("output_model"))); - - Log::Fatal.ignoreInput = true; - BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error); - Log::Fatal.ignoreInput = false; -} - -BOOST_AUTO_TEST_SUITE_END(); From 8895101b578d11cc9ef0ee8be424846c69c048c0 Mon Sep 17 00:00:00 2001 From: Bisakh Mondal Date: Sun, 8 Mar 2020 15:44:59 +0530 Subject: [PATCH 010/550] CMakeLists updated --- src/mlpack/methods/CMakeLists.txt | 1 - src/mlpack/tests/CMakeLists.txt | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/mlpack/methods/CMakeLists.txt b/src/mlpack/methods/CMakeLists.txt index 83c96e68dd..634f124419 100644 --- a/src/mlpack/methods/CMakeLists.txt +++ b/src/mlpack/methods/CMakeLists.txt @@ -9,7 +9,6 @@ set(DIRS block_krylov_svd cf dbscan - decision_stump decision_tree det emst diff --git a/src/mlpack/tests/CMakeLists.txt b/src/mlpack/tests/CMakeLists.txt index a1a865a1cc..4fbc1e5dd5 100644 --- a/src/mlpack/tests/CMakeLists.txt +++ b/src/mlpack/tests/CMakeLists.txt @@ -26,7 +26,6 @@ add_executable(mlpack_test cv_test.cpp dbscan_test.cpp dcgan_test.cpp - decision_stump_test.cpp decision_tree_test.cpp det_test.cpp distribution_test.cpp @@ -128,7 +127,6 @@ add_executable(mlpack_test main_tests/dbscan_test.cpp main_tests/det_test.cpp main_tests/decision_tree_test.cpp - main_tests/decision_stump_test.cpp main_tests/gmm_generate_test.cpp main_tests/gmm_probability_test.cpp main_tests/gmm_train_test.cpp From fa21448e09d2c8185a0b421a0fcae8adaf7a0d9e Mon Sep 17 00:00:00 2001 From: Bisakh Mondal Date: Sun, 8 Mar 2020 15:56:59 +0530 Subject: [PATCH 011/550] Adaboost documentation updated --- src/mlpack/methods/adaboost/adaboost.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/adaboost/adaboost.hpp b/src/mlpack/methods/adaboost/adaboost.hpp index e9179d07fe..a54eefe008 100644 --- a/src/mlpack/methods/adaboost/adaboost.hpp +++ b/src/mlpack/methods/adaboost/adaboost.hpp @@ -71,7 +71,8 @@ namespace adaboost { * @endcode * * For more information on and examples of weak learners, see - * perceptron::Perceptron<> and decision_stump::DecisionStump<>. + * perceptron::Perceptron<> and + tree::ID3DecisionStump. * * @tparam MatType Data matrix type (i.e. arma::mat or arma::sp_mat). * @tparam WeakLearnerType Type of weak learner to use. From 6c21b8ca4e48bc81a4f931d8fa7012e519ec746d Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 21 Jul 2020 18:28:45 -0400 Subject: [PATCH 012/550] Use 0 to numClasses - 1, not 1 to numClasses. --- .../negative_log_likelihood_impl.hpp | 10 ++-- src/mlpack/tests/ann_layer_test.cpp | 50 +++++++++---------- src/mlpack/tests/callback_test.cpp | 4 +- .../tests/convolutional_network_test.cpp | 10 ++-- src/mlpack/tests/feedforward_network_test.cpp | 30 +++++++---- src/mlpack/tests/recurrent_network_test.cpp | 14 +++--- 6 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp index f9020a582f..2b7dcb9fe3 100644 --- a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp @@ -35,11 +35,10 @@ NegativeLogLikelihood::Forward( ElemType output = 0; for (size_t i = 0; i < input.n_cols; ++i) { - size_t currentTarget = target(i) - 1; - Log::Assert(currentTarget >= 0 && currentTarget < input.n_rows, + Log::Assert(target(i) >= 0 && target(i) < input.n_rows, "Target class out of range."); - output -= input(currentTarget, i); + output -= input(target(i), i); } return output; @@ -55,11 +54,10 @@ void NegativeLogLikelihood::Backward( output = arma::zeros(input.n_rows, input.n_cols); for (size_t i = 0; i < input.n_cols; ++i) { - size_t currentTarget = target(i) - 1; - Log::Assert(currentTarget >= 0 && currentTarget < input.n_rows, + Log::Assert(target(i) >= 0 && target(i) < input.n_rows, "Target class out of range."); - output(currentTarget, i) = -1; + output(target(i), i) = -1; } } diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 8cd06e56f5..3bba999878 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(GradientAddLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -422,7 +422,7 @@ BOOST_AUTO_TEST_CASE(GradientLinearLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE(GradientNoisyLinearLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -602,7 +602,7 @@ BOOST_AUTO_TEST_CASE(GradientLinearNoBiasLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -648,7 +648,7 @@ BOOST_AUTO_TEST_CASE(JacobianNegativeLogLikelihoodLayerTest) init.Initialize(input, inputElements, 1); arma::mat target(1, 1); - target(0) = math::RandInt(1, inputElements - 1); + target(0) = math::RandInt(0, inputElements - 2); double error = JacobianPerformanceTest(module, input, target); BOOST_REQUIRE_LE(error, 1e-5); @@ -704,7 +704,7 @@ BOOST_AUTO_TEST_CASE(GradientFlexibleReLULayerTest) GradientFunction() { input = arma::randu(2, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, RandomInitialization>( NegativeLogLikelihood<>(), RandomInitialization(0.1, 0.5)); @@ -883,7 +883,7 @@ BOOST_AUTO_TEST_CASE(LSTMRrhoTest) { const size_t rho = 5; arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); + arma::cube target = arma::zeros(1, 1, 5); RandomInitialization init(0.5, 0.5); // Create model with user defined rho parameter. @@ -924,7 +924,7 @@ BOOST_AUTO_TEST_CASE(GradientLSTMLayerTest) GradientFunction() { input = arma::randu(1, 1, 5); - target.ones(1, 1, 5); + target.zeros(1, 1, 5); const size_t rho = 5; model = new RNN >(rho); @@ -988,7 +988,7 @@ BOOST_AUTO_TEST_CASE(FastLSTMRrhoTest) { const size_t rho = 5; arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); + arma::cube target = arma::zeros(1, 1, 5); RandomInitialization init(0.5, 0.5); // Create model with user defined rho parameter. @@ -1029,7 +1029,7 @@ BOOST_AUTO_TEST_CASE(GradientFastLSTMLayerTest) GradientFunction() { input = arma::randu(1, 1, 5); - target = arma::ones(1, 1, 5); + target = arma::zeros(1, 1, 5); const size_t rho = 5; model = new RNN >(rho); @@ -1298,7 +1298,7 @@ BOOST_AUTO_TEST_CASE(GradientGRULayerTest) GradientFunction() { input = arma::randu(1, 1, 5); - target = arma::ones(1, 1, 5); + target = arma::zeros(1, 1, 5); const size_t rho = 5; model = new RNN >(rho); @@ -1537,7 +1537,7 @@ BOOST_AUTO_TEST_CASE(GradientConcatLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -1606,7 +1606,7 @@ BOOST_AUTO_TEST_CASE(GradientConcatenateLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -1961,7 +1961,7 @@ BOOST_AUTO_TEST_CASE(GradientBatchNormTest) { input = arma::randn(32, 2048); arma::mat target; - target.ones(1, 2048); + target.zeros(1, 2048); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -2037,7 +2037,7 @@ BOOST_AUTO_TEST_CASE(GradientVirtualBatchNormTest) input = arma::randn(5, 256); arma::mat referenceBatch = arma::mat(input.memptr(), input.n_rows, 16); arma::mat target; - target.ones(1, 256); + target.zeros(1, 256); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -2099,7 +2099,7 @@ BOOST_AUTO_TEST_CASE(MiniBatchDiscriminationTest) { input = arma::randn(5, 4); arma::mat target; - target.ones(1, 4); + target.zeros(1, 4); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -2278,7 +2278,7 @@ BOOST_AUTO_TEST_CASE(GradientTransposedConvolutionLayerTest) GradientFunction() { input = arma::linspace(0, 35, 36); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, RandomInitialization>(); model->Predictors() = input; @@ -2395,7 +2395,7 @@ BOOST_AUTO_TEST_CASE(GradientAtrousConvolutionLayerTest) GradientFunction() { input = arma::linspace(0, 35, 36); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, RandomInitialization>(); model->Predictors() = input; @@ -2578,7 +2578,7 @@ BOOST_AUTO_TEST_CASE(GradientLayerNormTest) { input = arma::randn(10, 256); arma::mat target; - target.ones(1, 256); + target.zeros(1, 256); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -2899,7 +2899,7 @@ BOOST_AUTO_TEST_CASE(GradientReparametrizationLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -2943,7 +2943,7 @@ BOOST_AUTO_TEST_CASE(GradientReparametrizationLayerBetaTest) GradientFunction() { input = arma::randu(10, 2); - target = arma::mat("1 1"); + target = arma::mat("0 0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -3099,7 +3099,7 @@ BOOST_AUTO_TEST_CASE(GradientHighwayLayerTest) GradientFunction() { input = arma::randu(5, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -3151,7 +3151,7 @@ BOOST_AUTO_TEST_CASE(GradientSequentialLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -3202,7 +3202,7 @@ BOOST_AUTO_TEST_CASE(GradientWeightNormLayerTest) GradientFunction() { input = arma::randu(10, 1); - target = arma::mat("1"); + target = arma::mat("0"); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; @@ -4037,7 +4037,7 @@ BOOST_AUTO_TEST_CASE(GradientBatchNormWithMiniBatchesTest) { input = arma::randn(16, 1024); arma::mat target; - target.ones(1, 1024); + target.zeros(1, 1024); model = new FFN, NguyenWidrowInitialization>(); model->Predictors() = input; diff --git a/src/mlpack/tests/callback_test.cpp b/src/mlpack/tests/callback_test.cpp index a62ede95a8..6483a11890 100644 --- a/src/mlpack/tests/callback_test.cpp +++ b/src/mlpack/tests/callback_test.cpp @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(RNNCallbackTest) { const size_t rho = 5; arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); + arma::cube target = arma::zeros(1, 1, 5); RandomInitialization init(0.5, 0.5); // Create model with user defined rho parameter. @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(RNNWithOptimizerCallbackTest) { const size_t rho = 5; arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); + arma::cube target = arma::zeros(1, 1, 5); RandomInitialization init(0.5, 0.5); // Create model with user defined rho parameter. diff --git a/src/mlpack/tests/convolutional_network_test.cpp b/src/mlpack/tests/convolutional_network_test.cpp index 39a7e161c3..c266e2b28b 100644 --- a/src/mlpack/tests/convolutional_network_test.cpp +++ b/src/mlpack/tests/convolutional_network_test.cpp @@ -47,13 +47,13 @@ BOOST_AUTO_TEST_CASE(VanillaNetworkTest) { if (i < nPoints / 2) { - // Assign label "1" to all samples with digit = 4 - Y(i) = 1; + // Assign label "0" to all samples with digit = 4 + Y(i) = 0; } else { - // Assign label "2" to all samples with digit = 9 - Y(i) = 2; + // Assign label "1" to all samples with digit = 9 + Y(i) = 1; } } @@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(VanillaNetworkTest) for (size_t i = 0; i < predictionTemp.n_cols; ++i) { prediction(i) = arma::as_scalar(arma::find( - arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)) + 1; + arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)); } size_t correct = arma::accu(prediction == Y); diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 47842204e6..c853962f10 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -52,7 +52,7 @@ void TestNetwork(ModelType& model, for (size_t i = 0; i < predictionTemp.n_cols; ++i) { prediction(i) = arma::as_scalar(arma::find( - arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)) + 1; + arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)); } size_t correct = arma::accu(prediction == testLabels); @@ -71,12 +71,14 @@ BOOST_AUTO_TEST_CASE(VanillaNetworkTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // Labels should be from 0 to numClasses - 1. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // Labels should be from 0 to numClasses - 1. /* * Construct a feed forward network with trainData.n_rows input nodes, @@ -120,7 +122,6 @@ BOOST_AUTO_TEST_CASE(VanillaNetworkTest) arma::mat labels = arma::zeros(1, dataset.n_cols); labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(1); - labels += 1; FFN > model1; model1.Add >(dataset.n_rows, 10); @@ -142,7 +143,6 @@ BOOST_AUTO_TEST_CASE(ForwardBackwardTest) arma::mat labels = arma::zeros(1, dataset.n_cols); labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(1); - labels += 1; FFN > model; model.Add >(dataset.n_rows, 50); @@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(ForwardBackwardTest) for (size_t i = 0; i < currentResuls.n_cols; ++i) { prediction(i) = arma::as_scalar(arma::find( - arma::max(currentResuls.col(i)) == currentResuls.col(i), 1)) + 1; + arma::max(currentResuls.col(i)) == currentResuls.col(i), 1)); } size_t correct = arma::accu(prediction == currentLabels); @@ -218,12 +218,14 @@ BOOST_AUTO_TEST_CASE(DropoutNetworkTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // Labels should be from 0 to numClasses - 1. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // Labels should be from 0 to numClasses - 1. /* * Construct a feed forward network with trainData.n_rows input nodes, @@ -269,7 +271,6 @@ BOOST_AUTO_TEST_CASE(DropoutNetworkTest) arma::mat labels = arma::zeros(1, dataset.n_cols); labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(1); - labels += 1; FFN > model1; model1.Add >(dataset.n_rows, 10); @@ -295,7 +296,6 @@ BOOST_AUTO_TEST_CASE(HighwayNetworkTest) arma::mat labels = arma::zeros(1, dataset.n_cols); labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(1); - labels += 1; FFN > model; model.Add >(dataset.n_rows, 10); @@ -319,12 +319,14 @@ BOOST_AUTO_TEST_CASE(DropConnectNetworkTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // The range should be between 0 and numClasses - 1. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // The range should be between 0 and numClasses - 1. /* * Construct a feed forward network with trainData.n_rows input nodes, @@ -370,7 +372,6 @@ BOOST_AUTO_TEST_CASE(DropConnectNetworkTest) arma::mat labels = arma::zeros(1, dataset.n_cols); labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(1); - labels += 1; FFN > model1; model1.Add >(dataset.n_rows, 10); @@ -408,12 +409,14 @@ BOOST_AUTO_TEST_CASE(SerializationTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // The labels should be between 0 and numClasses - 1. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // The labels should be between 0 and numClasses - 1. // Vanilla neural net with logistic activation function. // Because 92% of the patients are not hyperthyroid the neural @@ -457,12 +460,14 @@ BOOST_AUTO_TEST_CASE(CustomLayerTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // The labels should be between 0 and numClasses - 1. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // The labels should be between 0 and numClasses - 1. FFN, RandomInitialization, CustomLayer<> > model; model.Add >(trainData.n_rows, 8); @@ -536,12 +541,14 @@ BOOST_AUTO_TEST_CASE(FFNTrainReturnObjective) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // The labels should be between 0 and numClasses. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // The labels should be between 0 and numClasses. // Vanilla neural net with logistic activation function. // Because 92% of the patients are not hyperthyroid the neural @@ -606,12 +613,14 @@ BOOST_AUTO_TEST_CASE(OptimizerTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // The labels should be between 0 and numClasses. arma::mat testData; data::Load("thyroid_test.csv", testData, true); arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // The labels should be between 0 and numClasses. FFN, RandomInitialization, CustomLayer<> > model; model.Add >(trainData.n_rows, 8); @@ -634,11 +643,12 @@ BOOST_AUTO_TEST_CASE(RBFNetworkTest) arma::mat trainLabels = trainData.row(trainData.n_rows - 1); trainData.shed_row(trainData.n_rows - 1); + trainLabels -= 1; // The labels should be between 0 and numClasses. arma::mat trainLabels1 = arma::zeros(3, trainData.n_cols); for (size_t i = 0; i < trainData.n_cols; i++) { - trainLabels1.col(i).row((trainLabels(i) - 1)) = 1; + trainLabels1.col(i).row(trainLabels(i)) = 1; } arma::mat testData; @@ -646,6 +656,7 @@ BOOST_AUTO_TEST_CASE(RBFNetworkTest) arma::mat testLabels = testData.row(testData.n_rows - 1); testData.shed_row(testData.n_rows - 1); + testLabels -= 1; // The labels should be between 0 and numClasses. /* * Construct a feed forward network with trainData.n_rows input nodes, @@ -681,7 +692,7 @@ BOOST_AUTO_TEST_CASE(RBFNetworkTest) } arma::mat labels = arma::zeros(1, dataset.n_cols); - labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(1); + labels.submat(0, labels.n_cols / 2, 0, labels.n_cols - 1).fill(0); arma::mat labels1 = arma::zeros(2, dataset.n_cols); @@ -689,7 +700,6 @@ BOOST_AUTO_TEST_CASE(RBFNetworkTest) { labels1.col(i).row(labels(i)) = 1; } - labels += 1; arma::mat centroids1; arma::Row assignments; diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 1bef406e26..4bd9fa25e1 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(SequenceClassificationBRNNTest) for (size_t i = 0; i < labelsTemp.n_cols; ++i) { const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; + arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)); labels.tube(0, i).fill(value); } @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(SequenceClassificationTest) for (size_t i = 0; i < labelsTemp.n_cols; ++i) { const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; + arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)); labels.tube(0, i).fill(value); } @@ -212,10 +212,10 @@ BOOST_AUTO_TEST_CASE(SequenceClassificationTest) { const int predictionValue = arma::as_scalar(arma::find( arma::max(prediction.slice(rho - 1).col(i)) == - prediction.slice(rho - 1).col(i), 1) + 1); + prediction.slice(rho - 1).col(i), 1)); const int targetValue = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; + arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)); if (predictionValue == targetValue) { @@ -1452,15 +1452,15 @@ BOOST_AUTO_TEST_CASE(LargeRhoValueRnnTest) { const auto strLen = strlen(line); // Responses for NegativeLogLikelihood should be - // non-one-hot-encoded class IDs (from 1 to num_classes). + // non-one-hot-encoded class IDs (from 0 to num_classes - 1). MatType result(1, 1, strLen, arma::fill::zeros); // The response is the *next* letter in the sequence. for (size_t i = 0; i < strLen - 1; ++i) { - result.at(0, 0, i) = static_cast(line[i + 1]) + 1.0; + result.at(0, 0, i) = static_cast(line[i + 1]); } // The final response is empty, so we set it to class 0. - result.at(0, 0, strLen - 1) = 1.0; + result.at(0, 0, strLen - 1) = 0.0; return result; }; From a0be23a6eb03180813318764aa74d111e1c8efff Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Wed, 12 Aug 2020 14:10:06 -0400 Subject: [PATCH 013/550] removed the t argument --- src/mlpack/methods/hmm/hmm.hpp | 22 ++++++++++------------ src/mlpack/methods/hmm/hmm_impl.hpp | 21 ++++++++++----------- src/mlpack/tests/hmm_test.cpp | 2 +- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index f7a20404be..d934a08ef2 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -295,36 +295,34 @@ class HMM /** * Compute the log-likelihood of the given emission probability up to time t * - * @param t time order * @param log emission probability at time t. - * @param logScale Log-likelihood of the given sequence of emission - * probability up to time t-1 + * @param logLikelihood Log-likelihood of the given sequence of emission + * probability up to time t-1 * @param prevForwardProb Vector in which forward probabilities for time t-1 - * will be saved. + * will be saved. Passing prevForwardProb as an empty vector indicates the + * start of sequence or time t=0 * @param forwardProb Vector in which forward probabilities for time t * will be saved. * @return Log-likelihood of the given sequence of emission up to time t. */ - double LogLikelihoodEmissionProb(size_t t, - const arma::vec& emissionLogProb, - double &logScale, + double LogLikelihoodEmissionProb(const arma::vec& emissionLogProb, + double &logLikelihood, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given data up to time t * - * @param t time order * @param data observation at time t. * @param logScale Log-likelihood of the given sequence of data up to time t-1 * @param prevForwardProb Vector in which forward probabilities for time t-1 - * will be saved. + * will be saved. Passing prevForwardProb as an empty vector indicates the + * start of sequence or time t=0 * @param forwardProb Vector in which forward probabilities for time t * will be saved. * @return Log-likelihood of the given sequence of data up to time t. */ - double LogLikelihood(size_t t, - const arma::vec &data, - double &logScale, + double LogLikelihood(const arma::vec &data, + double &logLikelihood, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index a447d7501e..565db517db 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -526,34 +526,33 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const * Compute the log-likelihood of the given emission probability up to time t */ template -double HMM::LogLikelihoodEmissionProb(size_t t, - const arma::vec& emissionLogProb, - double &logScale, +double HMM::LogLikelihoodEmissionProb(const arma::vec& emissionLogProb, + double &logLikelihood, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - if(t == 0){ - ForwardAtT0(emissionLogProb, logScale, forwardLogProb); + if(prevForwardLogProb.empty()){ + //start os sequence or time t=0 + ForwardAtT0(emissionLogProb, logLikelihood, forwardLogProb); } else{ double curLogSacle; ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); - logScale += curLogSacle; + logLikelihood += curLogSacle; } prevForwardLogProb = forwardLogProb; - return logScale; + return logLikelihood; } /** * Compute the log-likelihood of the given data up to time t */ template -double HMM::LogLikelihood(size_t t, - const arma::vec &data, - double &logScale, +double HMM::LogLikelihood(const arma::vec &data, + double &logLikelihood, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { @@ -564,7 +563,7 @@ double HMM::LogLikelihood(size_t t, emissionLogProb(state) = emission[state].LogProbability(data); } - return LogLikelihoodEmissionProb(t, emissionLogProb, logScale, + return LogLikelihoodEmissionProb(emissionLogProb, logLikelihood, prevForwardLogProb, forwardLogProb); } diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 6cda82d289..73b6866889 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -842,7 +842,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) arma::vec prevForwardLogProb; arma::vec forwardLogProb; for(size_t t = 0; t Date: Wed, 12 Aug 2020 18:38:08 -0400 Subject: [PATCH 014/550] added logScale() and LogScaleEmissionProb() --- src/mlpack/methods/hmm/hmm.hpp | 40 +++++++++++++++-- src/mlpack/methods/hmm/hmm_impl.hpp | 66 ++++++++++++++++++++++------- src/mlpack/tests/hmm_test.cpp | 38 ++++++++++++----- 3 files changed, 116 insertions(+), 28 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index d934a08ef2..8829768325 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -292,6 +292,23 @@ class HMM */ double LogLikelihood(const arma::mat& dataSeq) const; + /** + * Compute the log of the scaling factor of the given emission probability + * at time t. To calculate the log-likelihood for the whole sequence, + * accumulate log scale over the entire sequence + * + * @param log emission probability at time t. + * probability up to time t-1 + * @param prevForwardProb Vector in which forward probabilities for time t-1 + * will be saved. Passing prevForwardProb as an empty vector indicates the + * start of sequence or time t=0 + * @param forwardProb Vector in which forward probabilities for time t + * will be saved. + * @return Log scale factor of the given sequence of emission at time t. + */ + double LogScaleEmissionProb(const arma::vec& emissionLogProb, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given emission probability up to time t * @@ -309,11 +326,28 @@ class HMM double &logLikelihood, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; + /** + * Compute the log of the scaling factor of the given data at time t. + * To calculate the log-likelihood for the whole sequence, accumulate log + * scale over the entire sequence + * + * @param data observation at time t. + * @param prevForwardProb Vector in which forward probabilities for time t-1 + * will be saved. Passing prevForwardProb as an empty vector indicates the + * start of sequence or time t=0 + * @param forwardProb Vector in which forward probabilities for time t + * will be saved. + * @return Log scale factor of the given sequence of data up at time t. + */ + double LogScale(const arma::vec &data, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given data up to time t * * @param data observation at time t. - * @param logScale Log-likelihood of the given sequence of data up to time t-1 + * @param logLikelihood Log-likelihood of the given sequence of data + * up to time t-1 * @param prevForwardProb Vector in which forward probabilities for time t-1 * will be saved. Passing prevForwardProb as an empty vector indicates the * start of sequence or time t=0 @@ -423,7 +457,7 @@ class HMM * states and columns equal to the number of observations. * * @param dataSeq Data sequence to compute probabilities for. - * @param scales Vector in which scaling factors will be saved. + * @param logScales Vector in which the log of scaling factors will be saved. * @param forwardProb Matrix in which forward probabilities will be saved. */ void Forward(const arma::mat& dataSeq, @@ -438,7 +472,7 @@ class HMM * columns equal to the number of observations. * * @param dataSeq Data sequence to compute probabilities for. - * @param scales Vector of scaling factors. + * @param logScales Vector of log of scaling factors. * @param backwardProb Matrix in which backward probabilities will be saved. */ void Backward(const arma::mat& dataSeq, diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 565db517db..d998307912 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -523,30 +523,70 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const } /** - * Compute the log-likelihood of the given emission probability up to time t + * Compute the log of the scaling factor of the given emission probability + * at time t. To calculate the log-likelihood for the whole sequence, + * accumulate log scale over the entire sequence */ template -double HMM::LogLikelihoodEmissionProb(const arma::vec& emissionLogProb, - double &logLikelihood, +double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { + double curLogSacle; if(prevForwardLogProb.empty()){ //start os sequence or time t=0 - ForwardAtT0(emissionLogProb, logLikelihood, forwardLogProb); + ForwardAtT0(emissionLogProb, curLogSacle, forwardLogProb); } else{ - double curLogSacle; ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); - logLikelihood += curLogSacle; } prevForwardLogProb = forwardLogProb; + return curLogSacle; +} + +/** + * Compute the log-likelihood of the given emission probability up to time t + */ +template +double HMM::LogLikelihoodEmissionProb( + const arma::vec& emissionLogProb, + double &logLikelihood, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const +{ + auto curLogScale = LogScaleEmissionProb(emissionLogProb, + prevForwardLogProb, forwardLogProb); + + logLikelihood = prevForwardLogProb.empty() + ? curLogScale : curLogScale + logLikelihood; + return logLikelihood; } +/** + * Compute the log of the scaling factor of the given data at time t. + * To calculate the log-likelihood for the whole sequence, accumulate log + * scale over the entire sequence + */ +template +double HMM::LogScale(const arma::vec &data, + arma::vec& prevForwardLogProb, + arma::vec& forwardLogProb) const +{ + arma::vec emissionLogProb(logTransition.n_rows); + + for (size_t state = 0; state < logTransition.n_rows; state++) + { + emissionLogProb(state) = emission[state].LogProbability(data); + } + + return LogScaleEmissionProb(emissionLogProb, + prevForwardLogProb, forwardLogProb); +} + /** * Compute the log-likelihood of the given data up to time t */ @@ -556,15 +596,11 @@ double HMM::LogLikelihood(const arma::vec &data, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - arma::vec emissionLogProb(logTransition.n_rows); - - for (size_t state = 0; state < logTransition.n_rows; state++) - { - emissionLogProb(state) = emission[state].LogProbability(data); - } - - return LogLikelihoodEmissionProb(emissionLogProb, logLikelihood, - prevForwardLogProb, forwardLogProb); + auto curLogScale = LogScale(data, prevForwardLogProb, forwardLogProb); + + logLikelihood = prevForwardLogProb.empty() + ? curLogScale : curLogScale + logLikelihood; + return logLikelihood; } /** diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 73b6866889..49a8b067c3 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -835,16 +835,37 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) } }; - arma::Row stateSeq; - auto loglikelihood = hmm.LogLikelihood(obs); + const double loglikelihoodRef = -2734.43; - double loglikelihood2; - arma::vec prevForwardLogProb; - arma::vec forwardLogProb; - for(size_t t = 0; t stateSeq; hmm.Predict(obs, stateSeq); arma::Row stateSeqRef = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -853,9 +874,6 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; - BOOST_REQUIRE_CLOSE(loglikelihood, -2734.43, 1e-3); - BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihood2, 1e-5); - for (size_t i = 0; i < stateSeqRef.n_cols; ++i) { BOOST_REQUIRE_EQUAL(stateSeqRef.at(i), stateSeq.at(i)); From 51d210988a03d30f6c32540435c6e415269d5153 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Wed, 12 Aug 2020 19:06:32 -0400 Subject: [PATCH 015/550] fixed doxygen @param arguments --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 49ef018404..71904154cf 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -456,7 +456,7 @@ class HMM * * @param dataSeq Data sequence to compute probabilities for. * @param logScales Vector in which the log of scaling factors will be saved. - * @param forwardProb Matrix in which forward probabilities will be saved. + * @param forwardLogProb Matrix in which forward probabilities will be saved. */ void Forward(const arma::mat& dataSeq, arma::vec& logScales, @@ -471,7 +471,7 @@ class HMM * * @param dataSeq Data sequence to compute probabilities for. * @param logScales Vector of log of scaling factors. - * @param backwardProb Matrix in which backward probabilities will be saved. + * @param backwardLogProb Matrix in which backward probabilities will be saved. */ void Backward(const arma::mat& dataSeq, const arma::vec& logScales, From ffa6669c1195d2b8c89302045e164840763ca7fc Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Wed, 12 Aug 2020 19:11:27 -0400 Subject: [PATCH 016/550] fixed doxygen @param arguments --- src/mlpack/methods/hmm/hmm.hpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 71904154cf..ca732c7164 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -295,12 +295,12 @@ class HMM * at time t. To calculate the log-likelihood for the whole sequence, * accumulate log scale over the entire sequence * - * @param log emission probability at time t. + * @param emissionLogProb emission probability at time t. * probability up to time t-1 - * @param prevForwardProb Vector in which forward probabilities for time t-1 - * will be saved. Passing prevForwardProb as an empty vector indicates the + * @param prevForwardLogProb Vector in which forward probabilities for time + * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the * start of sequence or time t=0 - * @param forwardProb Vector in which forward probabilities for time t + * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log scale factor of the given sequence of emission at time t. */ @@ -310,13 +310,13 @@ class HMM /** * Compute the log-likelihood of the given emission probability up to time t * - * @param log emission probability at time t. + * @param emissionLogProb emission probability at time t. * @param logLikelihood Log-likelihood of the given sequence of emission * probability up to time t-1 - * @param prevForwardProb Vector in which forward probabilities for time t-1 - * will be saved. Passing prevForwardProb as an empty vector indicates the + * @param prevForwardLogProb Vector in which forward probabilities for time + * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the * start of sequence or time t=0 - * @param forwardProb Vector in which forward probabilities for time t + * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log-likelihood of the given sequence of emission up to time t. */ @@ -330,10 +330,10 @@ class HMM * scale over the entire sequence * * @param data observation at time t. - * @param prevForwardProb Vector in which forward probabilities for time t-1 - * will be saved. Passing prevForwardProb as an empty vector indicates the + * @param prevForwardLogProb Vector in which forward probabilities for time + * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the * start of sequence or time t=0 - * @param forwardProb Vector in which forward probabilities for time t + * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log scale factor of the given sequence of data up at time t. */ @@ -346,10 +346,10 @@ class HMM * @param data observation at time t. * @param logLikelihood Log-likelihood of the given sequence of data * up to time t-1 - * @param prevForwardProb Vector in which forward probabilities for time t-1 - * will be saved. Passing prevForwardProb as an empty vector indicates the + * @param prevForwardLogProb Vector in which forward probabilities for time + * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the * start of sequence or time t=0 - * @param forwardProb Vector in which forward probabilities for time t + * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log-likelihood of the given sequence of data up to time t. */ From e10669d130f31d0d86155af334c31c5dab7e1744 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Wed, 12 Aug 2020 19:22:09 -0400 Subject: [PATCH 017/550] fixed styles --- src/mlpack/methods/hmm/hmm.hpp | 8 ++++---- src/mlpack/methods/hmm/hmm_impl.hpp | 14 ++++++-------- src/mlpack/tests/hmm_test.cpp | 8 +++++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index ca732c7164..0229734dc5 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -299,7 +299,7 @@ class HMM * probability up to time t-1 * @param prevForwardLogProb Vector in which forward probabilities for time * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 + * start of sequence or time t=0 * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log scale factor of the given sequence of emission at time t. @@ -315,7 +315,7 @@ class HMM * probability up to time t-1 * @param prevForwardLogProb Vector in which forward probabilities for time * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 + * start of sequence or time t=0 * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log-likelihood of the given sequence of emission up to time t. @@ -332,7 +332,7 @@ class HMM * @param data observation at time t. * @param prevForwardLogProb Vector in which forward probabilities for time * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 + * start of sequence or time t=0 * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log scale factor of the given sequence of data up at time t. @@ -348,7 +348,7 @@ class HMM * up to time t-1 * @param prevForwardLogProb Vector in which forward probabilities for time * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 + * start of sequence or time t=0 * @param forwardLogProb Vector in which forward probabilities for time t * will be saved. * @return Log-likelihood of the given sequence of data up to time t. diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 62d9ee73d9..941d18e9ab 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -533,11 +533,12 @@ double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, arma::vec& forwardLogProb) const { double curLogSacle; - if(prevForwardLogProb.empty()){ - //start os sequence or time t=0 + if (prevForwardLogProb.empty()){ + // start os sequence or time t=0 ForwardAtT0(emissionLogProb, curLogSacle, forwardLogProb); } - else{ + else + { ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); } @@ -559,10 +560,8 @@ double HMM::LogLikelihoodEmissionProb( { auto curLogScale = LogScaleEmissionProb(emissionLogProb, prevForwardLogProb, forwardLogProb); - logLikelihood = prevForwardLogProb.empty() ? curLogScale : curLogScale + logLikelihood; - return logLikelihood; } @@ -583,7 +582,7 @@ double HMM::LogScale(const arma::vec &data, emissionLogProb(state) = emission[state].LogProbability(data); } - return LogScaleEmissionProb(emissionLogProb, + return LogScaleEmissionProb(emissionLogProb, prevForwardLogProb, forwardLogProb); } @@ -597,10 +596,9 @@ double HMM::LogLikelihood(const arma::vec &data, arma::vec& forwardLogProb) const { auto curLogScale = LogScale(data, prevForwardLogProb, forwardLogProb); - logLikelihood = prevForwardLogProb.empty() ? curLogScale : curLogScale + logLikelihood; - return logLikelihood; + return logLikelihood; } /** diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 381b73e550..490d789c15 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -837,7 +837,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) const double loglikelihoodRef = -2734.43; - { + { auto loglikelihood = hmm.LogLikelihood(obs); BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } @@ -846,7 +846,8 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) double loglikelihood; arma::vec prevForwardLogProb; arma::vec forwardLogProb; - for(size_t t = 0; t Date: Wed, 12 Aug 2020 19:27:30 -0400 Subject: [PATCH 018/550] fixed styles --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- src/mlpack/tests/hmm_test.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 941d18e9ab..acc17dd542 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -538,7 +538,7 @@ double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, ForwardAtT0(emissionLogProb, curLogSacle, forwardLogProb); } else - { + { ForwardAtTn(emissionLogProb, curLogSacle, prevForwardLogProb, forwardLogProb); } diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 490d789c15..fc4a6bf2b3 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -847,7 +847,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) arma::vec prevForwardLogProb; arma::vec forwardLogProb; for (size_t t = 0; t Date: Thu, 13 Aug 2020 15:46:09 -0400 Subject: [PATCH 019/550] fixed log-likelihood calculation --- src/mlpack/methods/hmm/hmm_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index acc17dd542..e2594ef8a5 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -558,10 +558,10 @@ double HMM::LogLikelihoodEmissionProb( arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { + auto isStartOfSeq = prevForwardLogProb.empty(); auto curLogScale = LogScaleEmissionProb(emissionLogProb, prevForwardLogProb, forwardLogProb); - logLikelihood = prevForwardLogProb.empty() - ? curLogScale : curLogScale + logLikelihood; + logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; } @@ -595,9 +595,9 @@ double HMM::LogLikelihood(const arma::vec &data, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { + auto isStartOfSeq = prevForwardLogProb.empty(); auto curLogScale = LogScale(data, prevForwardLogProb, forwardLogProb); - logLikelihood = prevForwardLogProb.empty() - ? curLogScale : curLogScale + logLikelihood; + logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; } From 4ab3ae1527f3ab27d7f7e7f2311832fa2cfacdc5 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Mon, 31 Aug 2020 13:31:53 -0400 Subject: [PATCH 020/550] fixed typo and style --- src/mlpack/methods/hmm/hmm_impl.hpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index e2594ef8a5..ffc8c4ede7 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -532,20 +532,21 @@ double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - double curLogSacle; - if (prevForwardLogProb.empty()){ - // start os sequence or time t=0 - ForwardAtT0(emissionLogProb, curLogSacle, forwardLogProb); + double curLogScale; + if (prevForwardLogProb.empty()) + { + // start of sequence or time t=0 + ForwardAtT0(emissionLogProb, curLogScale, forwardLogProb); } else { - ForwardAtTn(emissionLogProb, curLogSacle, - prevForwardLogProb, forwardLogProb); + ForwardAtTn(emissionLogProb, curLogScale, + prevForwardLogProb, forwardLogProb); } prevForwardLogProb = forwardLogProb; - return curLogSacle; + return curLogScale; } /** @@ -558,8 +559,8 @@ double HMM::LogLikelihoodEmissionProb( arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - auto isStartOfSeq = prevForwardLogProb.empty(); - auto curLogScale = LogScaleEmissionProb(emissionLogProb, + bool isStartOfSeq = prevForwardLogProb.empty(); + double curLogScale = LogScaleEmissionProb(emissionLogProb, prevForwardLogProb, forwardLogProb); logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; From 297169131c72868f8c68ad90a7dc433d93b6f648 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Mon, 31 Aug 2020 13:40:50 -0400 Subject: [PATCH 021/550] added comments for ForwardAtT0() and ForwardAtTn() --- src/mlpack/methods/hmm/hmm.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 0229734dc5..f2abbeb026 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -436,11 +436,31 @@ class HMM protected: + /** + * Given emission probabilities, computes forward probabilities at time t=0. + * The returned matrix has rows equal to the number of hidden + * states and columns equal to the number of observations. + * + * @param emissionLogProb emission probability at time t=0. + * @param logScales Vector in which the log of scaling factors will be saved. + * @param forwardLogProb Matrix in which forward probabilities will be saved. + */ void ForwardAtT0( const arma::vec& emissionLogProb, double& logScales, arma::vec& forwardLogProb) const; + /** + * Given emission probabilities, computes forward probabilities for time t>0. + * The returned matrix has rows equal to the number of hidden + * states and columns equal to the number of observations. + * + * @param emissionLogProb emission probability at time t>0. + * @param logScales Vector in which the log of scaling factors will be saved. + * @param prevForwardLogProb Vector in which forward probabilities for time + * t-1 will be saved. + * @param forwardLogProb Matrix in which forward probabilities will be saved. + */ void ForwardAtTn( const arma::vec& emissionLogProb, double& logScales, From ca6a46c8a4414f97fa03587a5397aa8143bdd7e6 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Mon, 31 Aug 2020 18:13:57 -0400 Subject: [PATCH 022/550] no need to keep the previous forward probabilities in a separate vector --- src/mlpack/methods/hmm/hmm.hpp | 75 +++++++++++++---------------- src/mlpack/methods/hmm/hmm_impl.hpp | 51 +++++++++----------- src/mlpack/tests/hmm_test.cpp | 7 +-- 3 files changed, 59 insertions(+), 74 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index f2abbeb026..5f39326018 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -294,68 +294,68 @@ class HMM * Compute the log of the scaling factor of the given emission probability * at time t. To calculate the log-likelihood for the whole sequence, * accumulate log scale over the entire sequence + * This is meant for incremental or streaming computation of the + * log-likelihood of a sequence. For the first data point, provide an empty + * forwardLogProb vector. * * @param emissionLogProb emission probability at time t. * probability up to time t-1 - * @param prevForwardLogProb Vector in which forward probabilities for time - * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 - * @param forwardLogProb Vector in which forward probabilities for time t - * will be saved. + * @param forwardLogProb Vector in which forward probabilities will be saved. + * Passing forwardLogProb as an empty vector indicates the start of sequence + * or time t=0 * @return Log scale factor of the given sequence of emission at time t. */ double LogScaleEmissionProb(const arma::vec& emissionLogProb, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given emission probability up to time t + * This is meant for incremental or streaming computation of the + * log-likelihood of a sequence. For the first data point, provide an empty + * forwardLogProb vector. * * @param emissionLogProb emission probability at time t. * @param logLikelihood Log-likelihood of the given sequence of emission * probability up to time t-1 - * @param prevForwardLogProb Vector in which forward probabilities for time - * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 - * @param forwardLogProb Vector in which forward probabilities for time t - * will be saved. + * @param forwardLogProb Vector in which forward probabilities will be saved. + * Passing forwardLogProb as an empty vector indicates the start of sequence + * or time t=0 * @return Log-likelihood of the given sequence of emission up to time t. */ double LogLikelihoodEmissionProb(const arma::vec& emissionLogProb, double &logLikelihood, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** * Compute the log of the scaling factor of the given data at time t. * To calculate the log-likelihood for the whole sequence, accumulate log - * scale over the entire sequence + * scale over the entire sequence. + * This is meant for incremental or streaming computation of the + * log-likelihood of a sequence. For the first data point, provide an empty + * forwardLogProb vector. * * @param data observation at time t. - * @param prevForwardLogProb Vector in which forward probabilities for time - * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 - * @param forwardLogProb Vector in which forward probabilities for time t - * will be saved. + * @param forwardLogProb Vector in which forward probabilities will be saved. + * Passing forwardLogProb as an empty vector indicates the start of sequence + * or time t=0 * @return Log scale factor of the given sequence of data up at time t. */ double LogScale(const arma::vec &data, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given data up to time t + * This is meant for incremental or streaming computation of the + * log-likelihood of a sequence. For the first data point, provide an empty + * forwardLogProb vector. * * @param data observation at time t. * @param logLikelihood Log-likelihood of the given sequence of data * up to time t-1 - * @param prevForwardLogProb Vector in which forward probabilities for time - * t-1 will be saved. Passing prevForwardProb as an empty vector indicates the - * start of sequence or time t=0 - * @param forwardLogProb Vector in which forward probabilities for time t - * will be saved. + * @param forwardLogProb Vector in which forward probabilities will be saved. + * Passing forwardLogProb as an empty vector indicates the start of sequence + * or time t=0 * @return Log-likelihood of the given sequence of data up to time t. */ double LogLikelihood(const arma::vec &data, double &logLikelihood, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const; /** * HMM filtering. Computes the k-step-ahead expected emission at each time @@ -438,34 +438,27 @@ class HMM protected: /** * Given emission probabilities, computes forward probabilities at time t=0. - * The returned matrix has rows equal to the number of hidden - * states and columns equal to the number of observations. * - * @param emissionLogProb emission probability at time t=0. + * @param emissionLogProb Emission probability at time t=0. * @param logScales Vector in which the log of scaling factors will be saved. - * @param forwardLogProb Matrix in which forward probabilities will be saved. + * @return Forward probabilities */ - void ForwardAtT0( + arma::vec ForwardAtT0( const arma::vec& emissionLogProb, - double& logScales, - arma::vec& forwardLogProb) const; + double& logScales) const; /** * Given emission probabilities, computes forward probabilities for time t>0. - * The returned matrix has rows equal to the number of hidden - * states and columns equal to the number of observations. * - * @param emissionLogProb emission probability at time t>0. + * @param emissionLogProb Emission probability at time t>0. * @param logScales Vector in which the log of scaling factors will be saved. - * @param prevForwardLogProb Vector in which forward probabilities for time - * t-1 will be saved. - * @param forwardLogProb Matrix in which forward probabilities will be saved. + * @param prevForwardLogProb Previous forward probabilities. + * @return Forward probabilities */ - void ForwardAtTn( + arma::vec ForwardAtTn( const arma::vec& emissionLogProb, double& logScales, - const arma::vec& prevForwardLogProb, - arma::vec& forwardLogProb) const; + const arma::vec& prevForwardLogProb) const; // Helper functions. /** diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index ffc8c4ede7..a4c2759377 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -529,23 +529,20 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const */ template double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { double curLogScale; - if (prevForwardLogProb.empty()) + if (forwardLogProb.empty()) { // start of sequence or time t=0 - ForwardAtT0(emissionLogProb, curLogScale, forwardLogProb); + forwardLogProb = ForwardAtT0(emissionLogProb, curLogScale); } else { - ForwardAtTn(emissionLogProb, curLogScale, - prevForwardLogProb, forwardLogProb); + forwardLogProb = ForwardAtTn(emissionLogProb, curLogScale, + forwardLogProb); } - prevForwardLogProb = forwardLogProb; - return curLogScale; } @@ -556,12 +553,10 @@ template double HMM::LogLikelihoodEmissionProb( const arma::vec& emissionLogProb, double &logLikelihood, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - bool isStartOfSeq = prevForwardLogProb.empty(); - double curLogScale = LogScaleEmissionProb(emissionLogProb, - prevForwardLogProb, forwardLogProb); + bool isStartOfSeq = forwardLogProb.empty(); + double curLogScale = LogScaleEmissionProb(emissionLogProb, forwardLogProb); logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; } @@ -573,7 +568,6 @@ double HMM::LogLikelihoodEmissionProb( */ template double HMM::LogScale(const arma::vec &data, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { arma::vec emissionLogProb(logTransition.n_rows); @@ -583,8 +577,7 @@ double HMM::LogScale(const arma::vec &data, emissionLogProb(state) = emission[state].LogProbability(data); } - return LogScaleEmissionProb(emissionLogProb, - prevForwardLogProb, forwardLogProb); + return LogScaleEmissionProb(emissionLogProb, forwardLogProb); } /** @@ -593,11 +586,10 @@ double HMM::LogScale(const arma::vec &data, template double HMM::LogLikelihood(const arma::vec &data, double &logLikelihood, - arma::vec& prevForwardLogProb, arma::vec& forwardLogProb) const { - auto isStartOfSeq = prevForwardLogProb.empty(); - auto curLogScale = LogScale(data, prevForwardLogProb, forwardLogProb); + auto isStartOfSeq = forwardLogProb.empty(); + auto curLogScale = LogScale(data, forwardLogProb); logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; } @@ -654,9 +646,8 @@ void HMM::Smooth(const arma::mat& dataSeq, * The Forward procedure (part of the Forward-Backward algorithm). */ template -void HMM::ForwardAtT0(const arma::vec& emissionLogProb, - double& logScales, - arma::vec& forwardLogProb) const +arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, + double& logScales) const { // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. @@ -664,7 +655,7 @@ void HMM::ForwardAtT0(const arma::vec& emissionLogProb, ConvertToLogSpace(); - forwardLogProb.resize(logTransition.n_rows); + arma::vec forwardLogProb(logTransition.n_rows); forwardLogProb.fill(-std::numeric_limits::infinity()); // The first entry in the forward algorithm uses the initial state // probabilities. Note that MATLAB assumes that the starting state (at @@ -680,21 +671,24 @@ void HMM::ForwardAtT0(const arma::vec& emissionLogProb, if (std::isfinite(logScales)){ forwardLogProb -= logScales; } + + return forwardLogProb; } /** * The Forward procedure (part of the Forward-Backward algorithm). */ template -void HMM::ForwardAtTn(const arma::vec& emissionLogProb, +arma::vec HMM::ForwardAtTn(const arma::vec& emissionLogProb, double& logScales, - const arma::vec& prevForwardLogProb, - arma::vec& forwardLogProb) const + const arma::vec& prevForwardLogProb) const { // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. + arma::vec forwardLogProb(logTransition.n_rows); + forwardLogProb.fill(-std::numeric_limits::infinity()); // Now compute the probabilities for each successive observation. for (size_t state = 0; state < logTransition.n_rows; state++) { // The forward probability of state j at time t is the sum over all @@ -708,6 +702,8 @@ void HMM::ForwardAtTn(const arma::vec& emissionLogProb, if (std::isfinite(logScales)){ forwardLogProb -= logScales; } + + return forwardLogProb; } /** @@ -738,8 +734,7 @@ void HMM::Forward(const arma::mat& dataSeq, emission[state].LogProbability(dataSeq.unsafe_col(0)); } - arma::vec col0(forwardLogProb.colptr(0), logTransition.n_rows, false); - ForwardAtT0(emissionLogProb, logScales(0), col0); + forwardLogProb.col(0) = ForwardAtT0(emissionLogProb, logScales(0)); // Now compute the probabilities for each successive observation. for (size_t t = 1; t < dataSeq.n_cols; t++) @@ -750,8 +745,8 @@ void HMM::Forward(const arma::mat& dataSeq, emission[state].LogProbability(dataSeq.unsafe_col(t)); } - arma::vec colt(forwardLogProb.colptr(t), logTransition.n_rows, false); - ForwardAtTn(emissionLogProb, logScales(t), forwardLogProb.col(t-1), colt); + forwardLogProb.col(t) = + ForwardAtTn(emissionLogProb, logScales(t), forwardLogProb.col(t-1)); } } diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index fc4a6bf2b3..c4aef1112b 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -844,24 +844,21 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) { double loglikelihood; - arma::vec prevForwardLogProb; arma::vec forwardLogProb; for (size_t t = 0; t Date: Mon, 31 Aug 2020 19:45:56 -0400 Subject: [PATCH 023/550] added comments for logLikelihood calculation test --- src/mlpack/tests/hmm_test.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index c4aef1112b..74fccae9bd 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -837,11 +837,14 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) const double loglikelihoodRef = -2734.43; + //test loglikelihood calculation for the whole data { auto loglikelihood = hmm.LogLikelihood(obs); BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } + //test loglikelihoosd calculation in incremental way. + //It simulates the case where we have a stream of data. { double loglikelihood; arma::vec forwardLogProb; @@ -853,6 +856,8 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } + //test loglikelihoosd calculation in incremental way. + //It simulates the case where we have a stream of data. { double loglikelihood = 0; arma::vec forwardLogProb; From a4ead122498b39a71f1d0e41127c75ec73af3b04 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:16:31 -0400 Subject: [PATCH 024/550] Update src/mlpack/methods/hmm/hmm.hpp Style fix Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 5f39326018..71d456a10a 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -444,8 +444,8 @@ class HMM * @return Forward probabilities */ arma::vec ForwardAtT0( - const arma::vec& emissionLogProb, - double& logScales) const; + const arma::vec& emissionLogProb, + double& logScales) const; /** * Given emission probabilities, computes forward probabilities for time t>0. From 797d245e2823b339e3ed74c1944edf8ddb350626 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:17:23 -0400 Subject: [PATCH 025/550] Update src/mlpack/methods/hmm/hmm.hpp style fix Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 71d456a10a..8baea018c6 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -456,9 +456,9 @@ class HMM * @return Forward probabilities */ arma::vec ForwardAtTn( - const arma::vec& emissionLogProb, - double& logScales, - const arma::vec& prevForwardLogProb) const; + const arma::vec& emissionLogProb, + double& logScales, + const arma::vec& prevForwardLogProb) const; // Helper functions. /** From e50ec28d3f77d86d9e9eace4c972bae3162d03c9 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:18:18 -0400 Subject: [PATCH 026/550] Update src/mlpack/methods/hmm/hmm_impl.hpp style fix Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index a4c2759377..ab64d65dc3 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -570,14 +570,14 @@ template double HMM::LogScale(const arma::vec &data, arma::vec& forwardLogProb) const { - arma::vec emissionLogProb(logTransition.n_rows); + arma::vec emissionLogProb(logTransition.n_rows); - for (size_t state = 0; state < logTransition.n_rows; state++) - { - emissionLogProb(state) = emission[state].LogProbability(data); - } + for (size_t state = 0; state < logTransition.n_rows; state++) + { + emissionLogProb(state) = emission[state].LogProbability(data); + } - return LogScaleEmissionProb(emissionLogProb, forwardLogProb); + return LogScaleEmissionProb(emissionLogProb, forwardLogProb); } /** From 5f7650a96bd0000ceb5754289c744650a866ad5b Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:20:01 -0400 Subject: [PATCH 027/550] Update src/mlpack/methods/hmm/hmm_impl.hpp fixed use of auto Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index ab64d65dc3..c3dd69f7a2 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -588,10 +588,10 @@ double HMM::LogLikelihood(const arma::vec &data, double &logLikelihood, arma::vec& forwardLogProb) const { - auto isStartOfSeq = forwardLogProb.empty(); - auto curLogScale = LogScale(data, forwardLogProb); - logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; - return logLikelihood; + bool isStartOfSeq = forwardLogProb.empty(); + double curLogScale = LogScale(data, forwardLogProb); + logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; + return logLikelihood; } /** From b66421248404d80fd8edb91aba2aca4c1291b012 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:21:15 -0400 Subject: [PATCH 028/550] Update src/mlpack/methods/hmm/hmm_impl.hpp use of Armadillo objects instead of looping to add Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index c3dd69f7a2..ed6a9d117f 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -662,9 +662,7 @@ arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, // t = -1) is state 0; this is not our assumption here. To force that // behavior, you could append a single starting state to every single data // sequence and that should produce results in line with MATLAB. - for (size_t state = 0; state < logTransition.n_rows; state++) { - forwardLogProb(state) = logInitial(state) + emissionLogProb(state); - } + forwardLogProb = logInitial + emissionLogProb; // Normalize probability. logScales = math::AccuLog(forwardLogProb); From 22a208597162b9b4e1565b00e7d9094f4fc0419e Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:21:38 -0400 Subject: [PATCH 029/550] Update src/mlpack/methods/hmm/hmm_impl.hpp style fix Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index ed6a9d117f..88efd691c7 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -666,9 +666,8 @@ arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, // Normalize probability. logScales = math::AccuLog(forwardLogProb); - if (std::isfinite(logScales)){ - forwardLogProb -= logScales; - } + if (std::isfinite(logScales)) + forwardLogProb -= logScales; return forwardLogProb; } From 8407aeee58d65657e3fee191ca7babe41e66a3b9 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:25:32 -0400 Subject: [PATCH 030/550] Update src/mlpack/methods/hmm/hmm_impl.hpp fixed a typo Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 88efd691c7..3cb5011402 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -785,7 +785,7 @@ void HMM::Backward(const arma::mat& dataSeq, /** * Make sure the variables in log space are in sync with the linear - * counter parts + * counterparts. */ template void HMM::ConvertToLogSpace() const From 1dffcea4f23e6011779ff1cd9d13b903b6cea275 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:26:19 -0400 Subject: [PATCH 031/550] Update src/mlpack/tests/hmm_test.cpp improved the comment Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 74fccae9bd..f102f45f88 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -843,8 +843,8 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } - //test loglikelihoosd calculation in incremental way. - //It simulates the case where we have a stream of data. + // Test loglikelihood calculation in an incremental way. + // It simulates the case where we have a stream of data. { double loglikelihood; arma::vec forwardLogProb; From 2da39288a9240819240a4479cc58e749654f19da Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 16 Sep 2020 12:26:42 -0400 Subject: [PATCH 032/550] Update src/mlpack/tests/hmm_test.cpp improved the comment Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index f102f45f88..2593c3f8a0 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -856,8 +856,8 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } - //test loglikelihoosd calculation in incremental way. - //It simulates the case where we have a stream of data. + // Test loglikelihood calculation in an incremental way. + // It simulates the case where we have a stream of data. { double loglikelihood = 0; arma::vec forwardLogProb; From e5c1f54abdfe64ec4dec8823ffdf6004b1f59196 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Wed, 16 Sep 2020 12:45:09 -0400 Subject: [PATCH 033/550] fixed style --- src/mlpack/methods/hmm/hmm_impl.hpp | 53 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 3cb5011402..56d915d9cf 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -653,23 +653,23 @@ arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. - ConvertToLogSpace(); + ConvertToLogSpace(); - arma::vec forwardLogProb(logTransition.n_rows); - forwardLogProb.fill(-std::numeric_limits::infinity()); - // The first entry in the forward algorithm uses the initial state - // probabilities. Note that MATLAB assumes that the starting state (at - // t = -1) is state 0; this is not our assumption here. To force that - // behavior, you could append a single starting state to every single data - // sequence and that should produce results in line with MATLAB. + arma::vec forwardLogProb(logTransition.n_rows); + forwardLogProb.fill(-std::numeric_limits::infinity()); + // The first entry in the forward algorithm uses the initial state + // probabilities. Note that MATLAB assumes that the starting state (at + // t = -1) is state 0; this is not our assumption here. To force that + // behavior, you could append a single starting state to every single data + // sequence and that should produce results in line with MATLAB. forwardLogProb = logInitial + emissionLogProb; - // Normalize probability. - logScales = math::AccuLog(forwardLogProb); + // Normalize probability. + logScales = math::AccuLog(forwardLogProb); if (std::isfinite(logScales)) forwardLogProb -= logScales; - return forwardLogProb; + return forwardLogProb; } /** @@ -684,23 +684,22 @@ arma::vec HMM::ForwardAtTn(const arma::vec& emissionLogProb, // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. - arma::vec forwardLogProb(logTransition.n_rows); - forwardLogProb.fill(-std::numeric_limits::infinity()); - // Now compute the probabilities for each successive observation. - for (size_t state = 0; state < logTransition.n_rows; state++) { - // The forward probability of state j at time t is the sum over all - // states of the probability of the previous state transitioning to - // the current state and emitting the given observation. - arma::vec tmp = prevForwardLogProb + logTransition.row(state).t(); - forwardLogProb(state) = math::AccuLog(tmp) + emissionLogProb(state); - } - // Normalize probability. - logScales = math::AccuLog(forwardLogProb); - if (std::isfinite(logScales)){ - forwardLogProb -= logScales; - } + arma::vec forwardLogProb(logTransition.n_rows); + forwardLogProb.fill(-std::numeric_limits::infinity()); + // Now compute the probabilities for each successive observation. + for (size_t state = 0; state < logTransition.n_rows; state++) { + // The forward probability of state j at time t is the sum over all + // states of the probability of the previous state transitioning to + // the current state and emitting the given observation. + arma::vec tmp = prevForwardLogProb + logTransition.row(state).t(); + forwardLogProb(state) = math::AccuLog(tmp) + emissionLogProb(state); + } + // Normalize probability. + logScales = math::AccuLog(forwardLogProb); + if (std::isfinite(logScales)) + forwardLogProb -= logScales; - return forwardLogProb; + return forwardLogProb; } /** From 87dff6df61c8fedbf5a147d6de5eedf6c3fca888 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 17 Sep 2020 09:05:16 +0530 Subject: [PATCH 034/550] Added Adjusted R2 --- src/mlpack/core/cv/metrics/r2_score.hpp | 5 ++++- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp index f565239ec1..35e528269c 100644 --- a/src/mlpack/core/cv/metrics/r2_score.hpp +++ b/src/mlpack/core/cv/metrics/r2_score.hpp @@ -53,12 +53,15 @@ class R2Score * @param data Column-major data containing test items. * @param responses Ground truth (correct) target values for the test items, * should be either a row vector or a column-major matrix. + * @param adjR2 Boolean value which specifies whether to calculate adjusted + * R2 or not * @return calculated R2 Score. */ template static double Evaluate(MLAlgorithm& model, const DataType& data, - const ResponsesType& responses); + const ResponsesType& responses, + const bool adjR2 = false); /** * Information for hyper-parameter tuning code. It indicates that we want diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index ef2733ff39..575d5efbd9 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -45,7 +45,14 @@ double R2Score::Evaluate(MLAlgorithm& model, // Handling undefined R2 Score when both denominator and numerator is 0.0. if (residualSumSquared == 0.0) return totalSumSquared ? 1.0 : DBL_MIN; - + // Returning adjusted R-squared + if(adjR2){ + double rsq = 1 - (residualSumSquared / totalSumSquared); + double n = data.n_cols; // number of observations + double k = data.n_rows; + return (1 - ((1 - rsq) * ((n - 1) / (n - k - 1)))); + } + // Returning R-squared return 1 - residualSumSquared / totalSumSquared; } From 726a15eb189b876f48086235941310944995af0e Mon Sep 17 00:00:00 2001 From: shawnbrar <59639827+shawnbrar@users.noreply.github.com> Date: Thu, 17 Sep 2020 12:35:31 +0530 Subject: [PATCH 035/550] Update src/mlpack/core/cv/metrics/r2_score_impl.hpp Suggested change by kartikdutt18 Co-authored-by: kartikdutt18 <39593019+kartikdutt18@users.noreply.github.com> --- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 575d5efbd9..86eb7a3375 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -46,13 +46,13 @@ double R2Score::Evaluate(MLAlgorithm& model, if (residualSumSquared == 0.0) return totalSumSquared ? 1.0 : DBL_MIN; // Returning adjusted R-squared - if(adjR2){ + if (adjR2) + { double rsq = 1 - (residualSumSquared / totalSumSquared); - double n = data.n_cols; // number of observations - double k = data.n_rows; - return (1 - ((1 - rsq) * ((n - 1) / (n - k - 1)))); + return (1 - ((1 - rsq) * ((data.n_cols - 1) / (data.n_cols - data.n_rows - 1)))); } - // Returning R-squared + + // Returning R-squared return 1 - residualSumSquared / totalSumSquared; } From 1668879bca4dfb5a908f879aab0eb95e1007dd05 Mon Sep 17 00:00:00 2001 From: shawnbrar <59639827+shawnbrar@users.noreply.github.com> Date: Sun, 20 Sep 2020 11:24:47 +0530 Subject: [PATCH 036/550] Update r2_score_impl.hpp Added adjR2 argumnet --- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 86eb7a3375..45892e6203 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -18,7 +18,8 @@ namespace cv { template double R2Score::Evaluate(MLAlgorithm& model, const DataType& data, - const ResponsesType& responses) + const ResponsesType& responses, + const bool adjR2) { if (data.n_cols != responses.n_cols) { From 786e5e9acea96ece4d3aa5f5e8e315f3ea6c470c Mon Sep 17 00:00:00 2001 From: shawnbrar <59639827+shawnbrar@users.noreply.github.com> Date: Fri, 25 Sep 2020 06:58:34 +0530 Subject: [PATCH 037/550] Added Test for Adjusted R squared --- src/mlpack/tests/cv_test.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index 48bb9a6481..7b6f6aa7ed 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -191,6 +191,28 @@ TEST_CASE("R2ScoreTest", "[CVTest]") == Approx(expectedR2).epsilon(1e-7)); } +/** + * Test the Adjusted R squared metric + */ +TEST_CASE("AdjR2ScoreTest", "[CVTest]") +{ + // Making two variables that define the linear function is + // f(x1, x2) = x1 + x2 + arma::mat X; + X << 1 << 2 << 3 << 4 << 5 << 6 << arma::endr + << 2 << 3 << 4 << 5 << 6 << 7 << arma::endr; + arma::rowvec Y; + y << 3 << 5 << 7 << 9 << 11 << 13; + + LinearRegression lr(X, Y); + + //Theoretically Adjusted R squared should be equal 1 + double expAdjR2 = 1; + REQUIRE(std::abs(R2Score::Evaluate(lr, X, y) - expAdjR2) + <= 1e-7); +} + + /** * Test the mean squared error with matrix responses. */ From cd9fbcdc5ac14e84847b3c0ff01ad3cb5bff0e71 Mon Sep 17 00:00:00 2001 From: shawnbrar <59639827+shawnbrar@users.noreply.github.com> Date: Fri, 25 Sep 2020 06:59:17 +0530 Subject: [PATCH 038/550] Update src/mlpack/core/cv/metrics/r2_score_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 45892e6203..75d2751e67 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -46,7 +46,7 @@ double R2Score::Evaluate(MLAlgorithm& model, // Handling undefined R2 Score when both denominator and numerator is 0.0. if (residualSumSquared == 0.0) return totalSumSquared ? 1.0 : DBL_MIN; - // Returning adjusted R-squared + // Returning adjusted R-squared. if (adjR2) { double rsq = 1 - (residualSumSquared / totalSumSquared); From a62c4fad2fb67091b3a462a80bb69c462a8473d0 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Fri, 25 Sep 2020 14:26:28 -0400 Subject: [PATCH 039/550] rename logScale() to logScaleFactor() --- src/mlpack/methods/hmm/hmm.hpp | 2 +- src/mlpack/methods/hmm/hmm_impl.hpp | 4 ++-- src/mlpack/tests/hmm_test.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 8baea018c6..37011eb249 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -338,7 +338,7 @@ class HMM * or time t=0 * @return Log scale factor of the given sequence of data up at time t. */ - double LogScale(const arma::vec &data, + double LogScaleFactor(const arma::vec &data, arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given data up to time t diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 56d915d9cf..6854923776 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -567,7 +567,7 @@ double HMM::LogLikelihoodEmissionProb( * scale over the entire sequence */ template -double HMM::LogScale(const arma::vec &data, +double HMM::LogScaleFactor(const arma::vec &data, arma::vec& forwardLogProb) const { arma::vec emissionLogProb(logTransition.n_rows); @@ -589,7 +589,7 @@ double HMM::LogLikelihood(const arma::vec &data, arma::vec& forwardLogProb) const { bool isStartOfSeq = forwardLogProb.empty(); - double curLogScale = LogScale(data, forwardLogProb); + double curLogScale = LogScaleFactor(data, forwardLogProb); logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; } diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 2593c3f8a0..8c1f11c233 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -863,7 +863,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) arma::vec forwardLogProb; for (size_t t = 0; t Date: Fri, 25 Sep 2020 14:35:10 -0400 Subject: [PATCH 040/550] renamed Emiision functions --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- src/mlpack/methods/hmm/hmm_impl.hpp | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 37011eb249..75f9dac519 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -305,7 +305,7 @@ class HMM * or time t=0 * @return Log scale factor of the given sequence of emission at time t. */ - double LogScaleEmissionProb(const arma::vec& emissionLogProb, + double EmissionLogScaleFactor(const arma::vec& emissionLogProb, arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given emission probability up to time t @@ -321,7 +321,7 @@ class HMM * or time t=0 * @return Log-likelihood of the given sequence of emission up to time t. */ - double LogLikelihoodEmissionProb(const arma::vec& emissionLogProb, + double EmissionLogLikelihood(const arma::vec& emissionLogProb, double &logLikelihood, arma::vec& forwardLogProb) const; /** diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 6854923776..92b3d3c16b 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -528,7 +528,8 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const * accumulate log scale over the entire sequence */ template -double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, +double HMM::EmissionLogScaleFactor( + const arma::vec& emissionLogProb, arma::vec& forwardLogProb) const { double curLogScale; @@ -550,13 +551,14 @@ double HMM::LogScaleEmissionProb(const arma::vec& emissionLogProb, * Compute the log-likelihood of the given emission probability up to time t */ template -double HMM::LogLikelihoodEmissionProb( +double HMM::EmissionLogLikelihood( const arma::vec& emissionLogProb, double &logLikelihood, arma::vec& forwardLogProb) const { bool isStartOfSeq = forwardLogProb.empty(); - double curLogScale = LogScaleEmissionProb(emissionLogProb, forwardLogProb); + double curLogScale = EmissionLogScaleFactor(emissionLogProb, + forwardLogProb); logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; return logLikelihood; } @@ -577,7 +579,7 @@ double HMM::LogScaleFactor(const arma::vec &data, emissionLogProb(state) = emission[state].LogProbability(data); } - return LogScaleEmissionProb(emissionLogProb, forwardLogProb); + return EmissionLogScaleFactor(emissionLogProb, forwardLogProb); } /** From 337b3f9833aad15e3f9df569cb21c329a7a2fe2f Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Fri, 25 Sep 2020 16:24:20 -0400 Subject: [PATCH 041/550] added a test case for EmissionLogLikelihood() --- src/mlpack/tests/hmm_test.cpp | 220 +++++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 1 deletion(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 8c1f11c233..486b4b635f 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -802,6 +802,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) emission.Covariance(cov.at(i)); } + //100 2D observations arma::mat obs = { { -0.0424, -0.0395, -0.0336, -0.0294, -0.0299, -0.032, -0.0289, -0.0148, @@ -834,7 +835,211 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) 0.0521, 0.0313, 0.0188, 0.0113, 0.0068, 0.0042, 0.0026, 0.0018, 0.0014 } }; - + + //100 pre-calculated emission probabilities each for 10 states + std::vector emissionProb={ + { -2.7301e+03, 1.7874e+00, -1.9428e+00, -3.6365e+00, -4.0397e-01, + -1.5115e-01, -1.0328e+00, -1.1071e+00, 5.2876e-01, -1.0643e-01 }, + { -2.3684e+03, 1.8059e+00, -2.2058e+00, -4.0514e+00, -5.0935e-01, + -2.1126e-01, -1.1962e+00, -1.2567e+00, 4.1247e-01, -3.0199e-01 }, + { -1.7117e+03, 1.7981e+00, -2.5275e+00, -4.5634e+00, -6.4839e-01, + -2.9579e-01, -1.4000e+00, -1.4461e+00, 2.3795e-01, -5.5622e-01 }, + { -1.3089e+03, 1.7393e+00, -2.8685e+00, -5.0996e+00, -8.0288e-01, + -3.9863e-01, -1.6229e+00, -1.6478e+00, 2.3300e-02, -8.6617e-01 }, + { -1.3541e+03, 1.6414e+00, -3.1971e+00, -5.6043e+00, -9.5605e-01, + -5.1013e-01, -1.8460e+00, -1.8395e+00, -2.0603e-01, -1.2176e+00 }, + { -1.5521e+03, 1.5367e+00, -3.4806e+00, -6.0349e+00, -1.0924e+00, + -6.1426e-01, -2.0436e+00, -2.0051e+00, -4.2045e-01, -1.5500e+00 }, + { -1.2647e+03, 1.4680e+00, -3.6577e+00, -6.3144e+00, -1.1823e+00, + -6.8009e-01, -2.1646e+00, -2.1147e+00, -5.6512e-01, -1.7360e+00 }, + { -3.2650e+02, 1.4646e+00, -3.6693e+00, -6.3649e+00, -1.1957e+00, + -6.7711e-01, -2.1592e+00, -2.1377e+00, -5.8400e-01, -1.6543e+00 }, + { -1.3035e+02, 1.5123e+00, -3.5018e+00, -6.1593e+00, -1.1254e+00, + -6.0037e-01, -2.0181e+00, -2.0646e+00, -4.6413e-01, -1.3011e+00 }, + { -2.6279e+03, 1.5809e+00, -3.1559e+00, -5.6861e+00, -9.7699e-01, + -4.5903e-01, -1.7490e+00, -1.8956e+00, -2.2135e-01, -7.2772e-01 }, + { -9.6164e+03, 1.6193e+00, -2.6708e+00, -4.9944e+00, -7.8159e-01, + -2.8441e-01, -1.3909e+00, -1.6574e+00, 7.8411e-02, -5.0595e-02 }, + { -2.0944e+04, 1.5980e+00, -2.1094e+00, -4.1681e+00, -5.8143e-01, + -1.2105e-01, -1.0055e+00, -1.3879e+00, 3.4591e-01, 5.6464e-01 }, + { -3.3843e+04, 1.5241e+00, -1.5331e+00, -3.2977e+00, -4.1342e-01, + -8.0772e-03, -6.5026e-01, -1.1226e+00, 5.0244e-01, 9.8522e-01 }, + { -4.6678e+04, 1.3796e+00, -9.8223e-01, -2.4507e+00, -3.0368e-01, + 3.0609e-02, -3.5787e-01, -8.8913e-01, 4.9234e-01, 1.1530e+00 }, + { -6.0839e+04, 1.1013e+00, -4.8302e-01, -1.6712e+00, -2.7541e-01, + -2.2814e-02, -1.4691e-01, -7.1095e-01, 2.6698e-01, 1.0338e+00 }, + { -7.8940e+04, 6.2341e-01, -6.4826e-02, -1.0034e+00, -3.5198e-01, + -1.8517e-01, -3.7803e-02, -6.1240e-01, -2.1704e-01, 5.8353e-01 }, + { -1.0182e+05, -8.9362e-02, 2.5888e-01, -4.6429e-01, -5.5297e-01, + -4.7752e-01, -4.9871e-02, -6.0739e-01, -1.0089e+00, -2.6587e-01 }, + { -1.2437e+05, -9.8625e-01, 4.7236e-01, -8.1256e-02, -8.8097e-01, + -9.0979e-01, -2.0039e-01, -6.9837e-01, -2.1229e+00, -1.5424e+00 }, + { -1.3878e+05, -1.9546e+00, 5.6976e-01, 1.2361e-01, -1.3043e+00, + -1.4534e+00, -4.7690e-01, -8.6807e-01, -3.4831e+00, -3.1393e+00 }, + { -1.3979e+05, -2.8896e+00, 5.6962e-01, 1.6577e-01, -1.7631e+00, + -2.0456e+00, -8.3102e-01, -1.0792e+00, -4.9380e+00, -4.8430e+00 }, + { -1.2717e+05, -3.7474e+00, 5.0493e-01, 9.2444e-02, -2.1969e+00, + -2.6201e+00, -1.2028e+00, -1.2907e+00, -6.3319e+00, -6.4416e+00 }, + { -1.0548e+05, -4.5565e+00, 4.0397e-01, -4.5775e-02, -2.5711e+00, + -3.1354e+00, -1.5493e+00, -1.4771e+00, -7.5697e+00, -7.8170e+00 }, + { -8.0621e+04, -5.3691e+00, 2.8365e-01, -2.1252e-01, -2.8783e+00, + -3.5784e+00, -1.8523e+00, -1.6312e+00, -8.6245e+00, -8.9480e+00 }, + { -5.6310e+04, -6.2411e+00, 1.5008e-01, -3.9022e-01, -3.1294e+00, + -3.9597e+00, -2.1142e+00, -1.7569e+00, -9.5239e+00, -9.8785e+00 }, + { -3.4173e+04, -7.2306e+00, 3.0396e-03, -5.7242e-01, -3.3347e+00, + -4.2928e+00, -2.3417e+00, -1.8583e+00, -1.0301e+01, -1.0652e+01 }, + { -1.5877e+04, -8.3900e+00, -1.5871e-01, -7.5362e-01, -3.4959e+00, + -4.5816e+00, -2.5356e+00, -1.9353e+00, -1.0963e+01, -1.1284e+01 }, + { -3.3829e+03, -9.7572e+00, -3.3006e-01, -9.1554e-01, -3.5912e+00, + -4.8035e+00, -2.6770e+00, -1.9722e+00, -1.1452e+01, -1.1714e+01 }, + { -5.6088e+02, -1.1394e+01, -5.0305e-01, -1.0261e+00, -3.5777e+00, + -4.9138e+00, -2.7301e+00, -1.9403e+00, -1.1653e+01, -1.1829e+01 }, + { -1.4303e+04, -1.3346e+01, -6.7336e-01, -1.0564e+00, -3.4266e+00, + -4.8757e+00, -2.6690e+00, -1.8219e+00, -1.1470e+01, -1.1561e+01 }, + { -4.9066e+04, -1.5534e+01, -8.4176e-01, -1.0079e+00, -3.1636e+00, + -4.7028e+00, -2.5116e+00, -1.6369e+00, -1.0937e+01, -1.0995e+01 }, + { -9.9717e+04, -1.7702e+01, -1.0039e+00, -9.1443e-01, -2.8597e+00, + -4.4595e+00, -2.3138e+00, -1.4339e+00, -1.0224e+01, -1.0331e+01 }, + { -1.5886e+05, -1.9676e+01, -1.1535e+00, -7.9762e-01, -2.5479e+00, + -4.1805e+00, -2.1039e+00, -1.2332e+00, -9.4233e+00, -9.6530e+00 }, + { -2.2947e+05, -2.1635e+01, -1.3117e+00, -6.6325e-01, -2.2133e+00, + -3.8587e+00, -1.8780e+00, -1.0253e+00, -8.5051e+00, -8.9416e+00 }, + { -3.1968e+05, -2.3792e+01, -1.5095e+00, -5.1672e-01, -1.8381e+00, + -3.4770e+00, -1.6312e+00, -8.0190e-01, -7.4108e+00, -8.1836e+00 }, + { -4.3323e+05, -2.6183e+01, -1.7728e+00, -3.8390e-01, -1.4394e+00, + -3.0487e+00, -1.3857e+00, -5.7953e-01, -6.1647e+00, -7.4521e+00 }, + { -5.6473e+05, -2.8589e+01, -2.1061e+00, -3.0168e-01, -1.0547e+00, + -2.6054e+00, -1.1773e+00, -3.8708e-01, -4.8475e+00, -6.8476e+00 }, + { -6.9974e+05, -3.0612e+01, -2.4921e+00, -3.0913e-01, -7.2535e-01, + -2.1849e+00, -1.0419e+00, -2.5359e-01, -3.5677e+00, -6.4479e+00 }, + { -8.0655e+05, -3.1539e+01, -2.8524e+00, -4.2185e-01, -4.8692e-01, + -1.8260e+00, -9.9484e-01, -1.9514e-01, -2.4629e+00, -6.2373e+00 }, + { -8.5216e+05, -3.0655e+01, -3.0833e+00, -6.1881e-01, -3.3169e-01, + -1.5249e+00, -1.0091e+00, -1.9595e-01, -1.5717e+00, -6.0513e+00 }, + { -8.2392e+05, -2.7811e+01, -3.1362e+00, -8.7526e-01, -2.3459e-01, + -1.2631e+00, -1.0480e+00, -2.3278e-01, -8.7344e-01, -5.7341e+00 }, + { -7.3612e+05, -2.3582e+01, -3.0425e+00, -1.1744e+00, -1.7841e-01, + -1.0351e+00, -1.0893e+00, -2.9210e-01, -3.4780e-01, -5.2495e+00 }, + { -6.1397e+05, -1.8706e+01, -2.8744e+00, -1.5195e+00, -1.5516e-01, + -8.3816e-01, -1.1304e+00, -3.7330e-01, 3.7744e-02, -4.6424e+00 }, + { -4.8041e+05, -1.3799e+01, -2.7054e+00, -1.9262e+00, -1.6637e-01, + -6.7558e-01, -1.1810e+00, -4.8405e-01, 3.0197e-01, -3.9898e+00 }, + { -3.4790e+05, -9.2300e+00, -2.5518e+00, -2.3683e+00, -2.0524e-01, + -5.4582e-01, -1.2297e+00, -6.1666e-01, 4.5657e-01, -3.3063e+00 }, + { -2.2370e+05, -5.1887e+00, -2.3941e+00, -2.7911e+00, -2.5500e-01, + -4.3560e-01, -1.2487e+00, -7.5224e-01, 5.3161e-01, -2.5570e+00 }, + { -1.1273e+05, -1.7195e+00, -2.2258e+00, -3.1794e+00, -3.0915e-01, + -3.2974e-01, -1.2221e+00, -8.8867e-01, 5.5755e-01, -1.7017e+00 }, + { -2.8363e+04, 9.0588e-01, -2.0601e+00, -3.5233e+00, -3.7171e-01, + -2.2162e-01, -1.1370e+00, -1.0334e+00, 5.4434e-01, -7.3209e-01 }, + { -1.2122e+03, 1.9784e+00, -1.9455e+00, -3.7971e+00, -4.5862e-01, + -1.2081e-01, -9.8979e-01, -1.2000e+00, 4.7839e-01, 2.5783e-01 }, + { -7.1694e+04, 5.6327e-01, -2.0051e+00, -4.0345e+00, -6.1306e-01, + -6.6602e-02, -8.2833e-01, -1.4287e+00, 3.0684e-01, 1.0022e+00 }, + { -2.6198e+05, -3.8345e+00, -2.3396e+00, -4.2798e+00, -8.6900e-01, + -9.8822e-02, -7.1489e-01, -1.7486e+00, -1.6219e-02, 1.2358e+00 }, + { -5.5328e+05, -1.0687e+01, -2.9124e+00, -4.5058e+00, -1.2121e+00, + -2.2259e-01, -6.7273e-01, -2.1347e+00, -4.7585e-01, 8.8080e-01 }, + { -8.9436e+05, -1.8602e+01, -3.5518e+00, -4.6037e+00, -1.5911e+00, + -4.1140e-01, -6.7958e-01, -2.5173e+00, -1.0137e+00, 3.7886e-02 }, + { -1.2162e+06, -2.5781e+01, -4.0541e+00, -4.4848e+00, -1.9485e+00, + -6.3137e-01, -7.0903e-01, -2.8240e+00, -1.5699e+00, -1.1063e+00 }, + { -1.4436e+06, -3.0414e+01, -4.2395e+00, -4.1197e+00, -2.2265e+00, + -8.4654e-01, -7.3852e-01, -2.9921e+00, -2.0869e+00, -2.2970e+00 }, + { -1.5227e+06, -3.1337e+01, -3.9989e+00, -3.5197e+00, -2.3836e+00, + -1.0315e+00, -7.4887e-01, -2.9823e+00, -2.5313e+00, -3.3017e+00 }, + { -1.4386e+06, -2.8472e+01, -3.3472e+00, -2.7563e+00, -2.4087e+00, + -1.1801e+00, -7.3524e-01, -2.7971e+00, -2.9034e+00, -3.9803e+00 }, + { -1.2257e+06, -2.2958e+01, -2.4364e+00, -1.9521e+00, -2.3275e+00, + -1.3043e+00, -7.0875e-01, -2.4858e+00, -3.2295e+00, -4.3252e+00 }, + { -9.4813e+05, -1.6527e+01, -1.4675e+00, -1.2121e+00, -2.1965e+00, + -1.4367e+00, -6.9389e-01, -2.1228e+00, -3.5740e+00, -4.4844e+00 }, + { -6.6589e+05, -1.0680e+01, -6.1313e-01, -6.1440e-01, -2.0638e+00, + -1.5984e+00, -7.0917e-01, -1.7727e+00, -3.9726e+00, -4.5979e+00 }, + { -4.1809e+05, -6.2975e+00, 3.1651e-02, -1.8731e-01, -1.9586e+00, + -1.7982e+00, -7.6241e-01, -1.4730e+00, -4.4365e+00, -4.7645e+00 }, + { -2.2534e+05, -3.7546e+00, 4.3188e-01, 7.1872e-02, -1.8959e+00, + -2.0366e+00, -8.5455e-01, -1.2417e+00, -4.9637e+00, -5.0424e+00 }, + { -9.4330e+04, -3.0403e+00, 5.9517e-01, 1.8422e-01, -1.8702e+00, + -2.2952e+00, -9.7314e-01, -1.0776e+00, -5.5109e+00, -5.4155e+00 }, + { -2.1454e+04, -3.9202e+00, 5.5647e-01, 1.8381e-01, -1.8704e+00, + -2.5578e+00, -1.1056e+00, -9.6899e-01, -6.0419e+00, -5.8579e+00 }, + { -31.4830, -6.0953, 0.3567, 0.1044, -1.8840, -2.8086, -1.2397, + -0.9026, -6.5224, -6.3374 }, + { -2.2442e+04, -9.2735e+00, 3.4960e-02, -2.1605e-02, -1.8931e+00, + -3.0282e+00, -1.3611e+00, -8.6066e-01, -6.9076e+00, -6.8075e+00 }, + { -8.1676e+04, -1.3138e+01, -3.6831e-01, -1.6104e-01, -1.8763e+00, + -3.1905e+00, -1.4522e+00, -8.2511e-01, -7.1362e+00, -7.2081e+00 }, + { -1.6865e+05, -1.7287e+01, -8.0643e-01, -2.8264e-01, -1.8178e+00, + -3.2726e+00, -1.4987e+00, -7.8144e-01, -7.1585e+00, -7.4877e+00 }, + { -2.7001e+05, -2.1213e+01, -1.2247e+00, -3.6116e-01, -1.7095e+00, + -3.2596e+00, -1.4928e+00, -7.2002e-01, -6.9485e+00, -7.6058e+00 }, + { -3.7506e+05, -2.4628e+01, -1.5962e+00, -3.9394e-01, -1.5583e+00, + -3.1610e+00, -1.4428e+00, -6.4101e-01, -6.5350e+00, -7.5763e+00 }, + { -4.7871e+05, -2.7455e+01, -1.9194e+00, -3.9090e-01, -1.3720e+00, + -2.9900e+00, -1.3606e+00, -5.4763e-01, -5.9492e+00, -7.4279e+00 }, + { -5.7329e+05, -2.9501e+01, -2.1830e+00, -3.6323e-01, -1.1594e+00, + -2.7564e+00, -1.2564e+00, -4.4501e-01, -5.2194e+00, -7.1738e+00 }, + { -6.4968e+05, -3.0560e+01, -2.3747e+00, -3.2775e-01, -9.3375e-01, + -2.4742e+00, -1.1428e+00, -3.4141e-01, -4.3880e+00, -6.8281e+00 }, + { -6.9933e+05, -3.0501e+01, -2.4875e+00, -3.0631e-01, -7.1262e-01, + -2.1653e+00, -1.0343e+00, -2.4789e-01, -3.5174e+00, -6.4120e+00 }, + { -7.1802e+05, -2.9350e+01, -2.5271e+00, -3.2061e-01, -5.1194e-01, + -1.8521e+00, -9.4328e-01, -1.7450e-01, -2.6686e+00, -5.9486e+00 }, + { -7.0553e+05, -2.7236e+01, -2.5060e+00, -3.8730e-01, -3.4217e-01, + -1.5515e+00, -8.7707e-01, -1.2819e-01, -1.8857e+00, -5.4542e+00 }, + { -6.6569e+05, -2.4393e+01, -2.4435e+00, -5.1663e-01, -2.1031e-01, + -1.2775e+00, -8.3941e-01, -1.1339e-01, -1.2023e+00, -4.9470e+00 }, + { -6.1301e+05, -2.1269e+01, -2.3992e+00, -7.3370e-01, -1.2064e-01, + -1.0383e+00, -8.4300e-01, -1.3855e-01, -6.1878e-01, -4.4864e+00 }, + { -5.6195e+05, -1.8233e+01, -2.4507e+00, -1.0921e+00, -8.5743e-02, + -8.4467e-01, -9.1749e-01, -2.2378e-01, -1.3441e-01, -4.1677e+00 }, + { -5.0308e+05, -1.5078e+01, -2.5824e+00, -1.6122e+00, -1.1850e-01, + -7.0720e-01, -1.0690e+00, -3.7916e-01, 2.0948e-01, -3.9737e+00 }, + { -4.2417e+05, -1.1613e+01, -2.7333e+00, -2.2592e+00, -2.1392e-01, + -6.2529e-01, -1.2691e+00, -5.9232e-01, 3.8196e-01, -3.8021e+00 }, + { -3.4311e+05, -8.4490e+00, -2.9262e+00, -2.9840e+00, -3.6201e-01, + -6.0612e-01, -1.5036e+00, -8.4657e-01, 3.8172e-01, -3.6994e+00 }, + { -2.6553e+05, -5.7959e+00, -3.0657e+00, -3.6135e+00, -5.0450e-01, + -6.1056e-01, -1.6893e+00, -1.0726e+00, 2.9263e-01, -3.5310e+00 }, + { -1.6581e+05, -2.8806e+00, -2.9242e+00, -3.9480e+00, -5.5108e-01, + -5.3603e-01, -1.6743e+00, -1.1832e+00, 2.8121e-01, -2.8215e+00 }, + { -6.3112e+04, -4.4355e-02, -2.4673e+00, -3.8848e+00, -4.8010e-01, + -3.5415e-01, -1.4075e+00, -1.1547e+00, 4.0803e-01, -1.5227e+00 }, + { -5.4196e+03, 1.6750e+00, -1.9272e+00, -3.5655e+00, -3.8433e-01, + -1.5578e-01, -1.0312e+00, -1.0745e+00, 5.4628e-01, -1.8838e-01 }, + { -7.9742e+03, 1.9542e+00, -1.5297e+00, -3.2224e+00, -3.5023e-01, + -2.9557e-02, -7.1541e-01, -1.0340e+00, 5.7335e-01, 7.0234e-01 }, + { -4.6838e+04, 1.3383e+00, -1.2840e+00, -2.9202e+00, -3.6943e-01, + 2.1035e-02, -4.9879e-01, -1.0295e+00, 5.0388e-01, 1.1296e+00 }, + { -9.2965e+04, 5.0293e-01, -1.1033e+00, -2.6251e+00, -4.0461e-01, + 2.4992e-02, -3.5062e-01, -1.0246e+00, 3.8909e-01, 1.2595e+00 }, + { -1.3250e+05, -2.3738e-01, -9.9398e-01, -2.4136e+00, -4.4740e-01, + 6.0968e-03, -2.6559e-01, -1.0308e+00, 2.6684e-01, 1.2440e+00 }, + { -1.7149e+05, -9.7999e-01, -9.1698e-01, -2.2384e+00, -4.9912e-01, + -2.5475e-02, -2.0762e-01, -1.0468e+00, 1.3078e-01, 1.1599e+00 }, + { -2.2091e+05, -1.9350e+00, -8.5497e-01, -2.0582e+00, -5.7508e-01, + -7.7816e-02, -1.6138e-01, -1.0794e+00, -5.6045e-02, 9.8875e-01 }, + { -2.8140e+05, -3.1219e+00, -8.2568e-01, -1.8962e+00, -6.7862e-01, + -1.5242e-01, -1.3554e-01, -1.1353e+00, -2.9320e-01, 7.2082e-01 }, + { -3.4167e+05, -4.3171e+00, -8.2824e-01, -1.7733e+00, -7.8907e-01, + -2.3483e-01, -1.3167e-01, -1.2015e+00, -5.3627e-01, 4.0854e-01 }, + { -3.7868e+05, -5.0537e+00, -8.3691e-01, -1.7046e+00, -8.6035e-01, + -2.9036e-01, -1.3690e-01, -1.2447e+00, -6.9304e-01, 1.9260e-01 }, + { -3.7429e+05, -4.9406e+00, -7.8456e-01, -1.6323e+00, -8.6203e-01, + -3.0644e-01, -1.3159e-01, -1.2267e+00, -7.3358e-01, 1.3468e-01 }, + { -3.3293e+05, -4.0758e+00, -6.6873e-01, -1.5416e+00, -8.0032e-01, + -2.8877e-01, -1.1346e-01, -1.1498e+00, -6.7458e-01, 2.1365e-01 }, + { -2.7541e+05, -2.9085e+00, -5.3210e-01, -1.4470e+00, -7.0706e-01, + -2.5517e-01, -9.1435e-02, -1.0445e+00, -5.6402e-01, 3.5113e-01 }, + { -2.2010e+05, -1.8209e+00, -4.1116e-01, -1.3627e+00, -6.1220e-01, + -2.2144e-01, -7.3319e-02, -9.4005e-01, -4.4660e-01, 4.7992e-01 }, + { -1.7809e+05, -1.0242e+00, -3.2646e-01, -1.3011e+00, -5.3612e-01, + -1.9567e-01, -6.2291e-02, -8.5731e-01, -3.5032e-01, 5.7022e-01 }, + { -1.5426e+05, -5.8691e-01, -2.8121e-01, -1.2660e+00, -4.9111e-01, + -1.8141e-01, -5.7387e-02, -8.0842e-01, -2.9317e-01, 6.1601e-01 }, + }; + const double loglikelihoodRef = -2734.43; //test loglikelihood calculation for the whole data @@ -869,6 +1074,19 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } + // Test loglikelihood calculation in an incremental way. + // It simulates the case where we have emission probabilities pre-calculated. + { + double loglikelihood = 0; + arma::vec forwardLogProb; + for (size_t t = 0; t stateSeq; hmm.Predict(obs, stateSeq); From a9f23ad4798d84b9e5ff37dcf001d4d1526c3823 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Thu, 1 Oct 2020 10:26:10 -0400 Subject: [PATCH 042/550] updated HISTORY.md --- HISTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.md b/HISTORY.md index d7a2437e9e..d3fa680e73 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,6 @@ ### mlpack ?.?.? ###### ????-??-?? + * HMM: calculate likelihood for data stream with/without pre-calculated emission probability * Added Mean Absolute Percentage Error. ### mlpack 3.4.1 From 3ef602006210d20a2cc9e0540d9289916e598f31 Mon Sep 17 00:00:00 2001 From: shawnbrar <59639827+shawnbrar@users.noreply.github.com> Date: Wed, 7 Oct 2020 08:01:12 +0530 Subject: [PATCH 043/550] Update cv_test.cpp --- src/mlpack/tests/cv_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index 7b6f6aa7ed..44b169b64d 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -202,7 +202,7 @@ TEST_CASE("AdjR2ScoreTest", "[CVTest]") X << 1 << 2 << 3 << 4 << 5 << 6 << arma::endr << 2 << 3 << 4 << 5 << 6 << 7 << arma::endr; arma::rowvec Y; - y << 3 << 5 << 7 << 9 << 11 << 13; + Y << 3 << 5 << 7 << 9 << 11 << 13; LinearRegression lr(X, Y); From 2886ed5697c86dbb9d71892a06608fbd20f0d638 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 8 Oct 2020 18:55:44 -0400 Subject: [PATCH 044/550] Attempt to use Azure to build the MSI. --- .ci/windows-steps.yaml | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 69a33520a3..8cf26046fe 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -122,6 +122,95 @@ steps: replaceExistingArchive: true displayName: 'Build artifacts' +# Build MSI installer. +- powershell: | + # Pull the documentation for the installer. + try { + (new-object net.webclient).DownloadFile(${env:JENKINS_DOC_DOWNLOAD}, + 'dist\win-installer\jenkinsdoc.zip') + } + catch { + Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!" + } + try { + (Add-Type -AssemblyName System.IO.Compression.FileSystem); + [System.IO.Compression.ZipFile]::ExtractToDirectory(${env:JENKINS_DOC}, + 'dist\win-installer\staging\doc') + } + catch { + Write-Output "Unable to add doc to installer, skipping!" + } + # Preparing installer staging. + mkdir dist\win-installer\staging\lib + cp build\Release\*.lib dist\win-installer\staging\lib\ + cp build\Release\*.exp dist\win-installer\staging\lib\ + cp build\Release\*.dll dist\win-installer\staging\ + cp build\Release\*.exe dist\win-installer\staging\ + cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\staging\ + cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\staging\ + cp build\include\mlpack dist\win-installer\staging -recurse + cp doc\examples dist\win-installer\staging -recurse + cp src\mlpack\tests\data\german.csv dist\win-installer\staging\examples\sample-ml-app\sample-ml-app\data\ + # Check current git version or mlpack version. + $ver = (Get-Content + "src\mlpack\core\util\version.hpp" | + where {$_ -like "*MLPACK_VERSION*"}); + $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; + $env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.'; + $env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1); + + if (Test-Path "src/mlpack/core/util/gitversion.hpp") + { + $ver = (Get-Content ${env:GIT_VERSION_FILE}); + $env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1]; + } + else + { + $env:INSTALL_VERSION = $env:MLPACK_VERSION; + } + # Build the MSI installer. + cd dist\win-installer\mlpack-win-installer + heat dir ..\staging + -cg HeatGenerated + -dr INSTALLFOLDER + -sreg + -srd + -var var.HarvestPath + -ag + -sfrag + -out HeatGeneratedFileList.wxs + candle + -dHarvestPath=..\staging + -dConfiguration=Release + -dOutDir=bin\x64\Release\ + -dPlatform=x64 + -dProjectDir=. + -dProjectExt=.wixproj + -dProjectFileName=mlpack-win-installer.wixproj + -dProjectName=mlpack-win-installer + -dProjectPath=mlpack-win-installer.wixproj + -dTargetDir=.\bin\x64\Release\ + -dTargetExt=.msi + -dTargetFileName=mlpack-windows.msi + -dTargetName=mlpack-windows + -dTargetPath=.\bin\x64\Release\mlpack-windows.msi + -out obj\x64\Release\ + -arch x64 + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" + Product.wxs HeatGeneratedFileList.wxs + light + -out .\bin\x64\Release\mlpack-%INSTALL_VERSION%.msi + -pdbout .\bin\x64\Release\mlpack-windows.wixpdb + -cultures:null + -loc mlpack-localization.wxl + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" + -contentsfile obj\x64\Release\mlpack-win-installer.wixproj.BindContentsFileListnull.txt + -outputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindOutputsFileListnull.txt + -builtoutputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt + -wixprojectfile mlpack-win-installer.wixproj + obj\x64\Release\Product.wixobj obj\x64\Release\HeatGeneratedFileList.wixobj + displayName: 'Build MSI Windows installer' + # Publish artifacts to Azure Pipelines - task: PublishBuildArtifacts@1 inputs: @@ -138,6 +227,11 @@ steps: pathtoPublish: 'build/Testing/' artifactName: 'Tests' displayName: 'Publish artifacts test results' +- task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\x64\Release\*.msi' + artifactName: mlpack-windows-installer + displayName: 'Publish Windows MSI installer' # Publish test results to Azure Pipelines - task: PublishTestResults@2 From 0a8928d4cc44eab60e20aa4150ed76412f63bc72 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 8 Oct 2020 18:55:55 -0400 Subject: [PATCH 045/550] Remove the AppVeyor configuration entirely. --- .appveyor.yml | 258 -------------------------------------------------- 1 file changed, 258 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 633d0c120f..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,258 +0,0 @@ -clone_depth: 10 - -environment: - BOOST_PROG_OPTION : "C:/projects/mlpack/\ - boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - BOOST_MATH : "C:/projects/mlpack/\ - boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - BOOST_RANDOM : "C:/projects/mlpack/\ - boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - BOOST_SERIALIZATION : "C:/projects/mlpack/\ - boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - BOOST_UNIT_TEST : "C:/projects/mlpack/\ - boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - ARMADILLO_DOWNLOAD : "https://data.kurg.org/armadillo-8.400.0.tar.xz" - ARMADILLO_LIBRARY : "C:/projects/mlpack/armadillo-8.400.0/\ - build/Debug/armadillo.lib" - BLAS_LIBRARY : "%APPVEYOR_BUILD_FOLDER%/OpenBLAS.0.2.14.1/lib/native/lib/x64/\ - libopenblas.dll.a" - BOOST_INCLUDE : "C:/projects/mlpack/boost.1.60.0.0/lib/native/include" - JENKINS_DOC_DOWNLOAD : "http://ci.mlpack.org/job/mlpack%20-%20doxygen%20\ - build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip" - JENKINS_DOC : "C:/projects/mlpack/dist/win-installer/jenkinsdoc.zip" - GIT_VERSION_FILE : "C:/projects/mlpack/src/mlpack/core/util/gitversion.hpp" - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - VSVER: Visual Studio 14 2015 Win64 - MSBUILD: C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - VSVER: Visual Studio 15 2017 Win64 - MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe -# Currently, the VS2019 build seems to always time out. This seems to be an -# AppVeyor issue. -# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 -# VSVER: Visual Studio 16 2019 -# MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe - - -configuration: Release - -os: Visual Studio 2015 - -install: - - ps: nuget install boost -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_unit_test_framework-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_program_options-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_random-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_serialization-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_math_c99-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: nuget install OpenBLAS -o "${env:APPVEYOR_BUILD_FOLDER}" - - set path=C:\Program Files (x86)\WiX Toolset v3.11\bin;%path% - -build_script: - - mkdir boost_libs - - ps: cp ${env:BOOST_PROG_OPTION} C:\projects\mlpack\boost_libs\ - - ps: cp ${env:BOOST_MATH} C:\projects\mlpack\boost_libs\ - - ps: cp ${env:BOOST_RANDOM} C:\projects\mlpack\boost_libs\ - - ps: cp ${env:BOOST_SERIALIZATION} C:\projects\mlpack\boost_libs\ - - ps: cp ${env:BOOST_UNIT_TEST} C:\projects\mlpack\boost_libs\ - - echo TEST_ARMA is %ARMADILLO_DOWNLOAD% - - > - appveyor DownloadFile %ARMADILLO_DOWNLOAD% - -FileName armadillo.tar.xz - - 7z x armadillo.tar.xz -so -txz | 7z x -si -ttar > nul - - cd armadillo-8.400.0 && mkdir build && cd build - - > - cmake -G "%VSVER%" - -DBLAS_LIBRARY:FILEPATH=%BLAS_LIBRARY% - -DLAPACK_LIBRARY:FILEPATH=%BLAS_LIBRARY% - -DCMAKE_PREFIX:FILEPATH="%APPVEYOR_BUILD_FOLDER%/armadillo" - -DBUILD_SHARED_LIBS=OFF - -DCMAKE_BUILD_TYPE=Release .. - - > - "%MSBUILD%" "C:\projects\mlpack\armadillo-8.400.0\build\armadillo.sln" - /m /verbosity:quiet /p:Configuration=Release;Platform=x64 - - cd C:\projects\mlpack && mkdir build && cd build - - > - cmake -G "%VSVER%" - -DBLAS_LIBRARIES:FILEPATH=%BLAS_LIBRARY% - -DLAPACK_LIBRARIES:FILEPATH=%BLAS_LIBRARY% - -DARMADILLO_INCLUDE_DIR="C:/projects/mlpack/armadillo-8.400.0/include" - -DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY% - -DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE% - -DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs" - -DDEBUG=OFF - -DPROFILE=OFF - -DBUILD_PYTHON_BINDINGS=OFF - -DBUILD_GO_BINDINGS=OFF - -DBUILD_R_BINDINGS=OFF - -DCMAKE_BUILD_TYPE=Release .. - - > - "%MSBUILD%" "C:\projects\mlpack\build\mlpack.sln" - /m /verbosity:minimal /nologo /p:BuildInParallel=true - /p:Configuration=Release;Platform=x64 - - # Zip Artifacts. - - > - 7z a mlpack-windows-no-libs.zip - "%APPVEYOR_BUILD_FOLDER%\build\Release\*.exe" - - > - 7z a mlpack-windows.zip - "%APPVEYOR_BUILD_FOLDER%\build\Release\*.*" - "%APPVEYOR_BUILD_FOLDER%/OpenBLAS.0.2.14.1/lib/native/lib/x64/*.*" - - # Pulling documentation for the installer. - - ps: > - try{(new-object net.webclient).DownloadFile(${env:JENKINS_DOC_DOWNLOAD}, - 'C:\projects\mlpack\dist\win-installer\jenkinsdoc.zip')} - catch{Write-Output "Unable to pull jenkins doc, skipping!"} - - ps: > - try{(Add-Type -AssemblyName System.IO.Compression.FileSystem); - [System.IO.Compression.ZipFile]::ExtractToDirectory(${env:JENKINS_DOC}, - 'C:\projects\mlpack\dist\win-installer\staging\doc')} - catch{Write-Output "Unable to add doc to installer, skipping!"} - - # Preparing installer staging. - - cd C:\projects\mlpack\dist\win-installer\staging && mkdir lib - - ps: > - cp C:\projects\mlpack\build\Release\*.lib - C:\projects\mlpack\dist\win-installer\staging\lib\ - - ps: > - cp C:\projects\mlpack\build\Release\*.exp - C:\projects\mlpack\dist\win-installer\staging\lib\ - - ps: > - cp C:\projects\mlpack\build\Release\*.dll - C:\projects\mlpack\dist\win-installer\staging\ - - ps: > - cp C:\projects\mlpack\build\Release\*.exe - C:\projects\mlpack\dist\win-installer\staging\ - - ps: > - cp C:\projects\mlpack\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll - C:\projects\mlpack\dist\win-installer\staging\ - - ps: > - cp C:\projects\mlpack\boost_libs\boost_unit_test_framework-vc*.dll - C:\projects\mlpack\dist\win-installer\staging\ - - ps: > - cp C:\projects\mlpack\build\include\mlpack - C:\projects\mlpack\dist\win-installer\staging -recurse - - ps: > - cp C:\projects\mlpack\doc\examples - C:\projects\mlpack\dist\win-installer\staging -recurse - - ps: > - cp C:\projects\mlpack\src\mlpack\tests\data\german.csv - C:\projects\mlpack\dist\win-installer\staging\examples\sample-ml-app\sample-ml-app\data\ - - # Checking current gitversion or mlpack version. - - ps: > - $ver = (Get-Content - "${env:APPVEYOR_BUILD_FOLDER}\src\mlpack\core\util\version.hpp" | - where {$_ -like "*MLPACK_VERSION*"}); - $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; - $env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.'; - $env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1); - - if (Test-Path ${env:GIT_VERSION_FILE}) - { - $ver = (Get-Content ${env:GIT_VERSION_FILE}); - $env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1]; - } - else - { - $env:INSTALL_VERSION = $env:MLPACK_VERSION; - } - - echo INSTALL_VERSION is %INSTALL_VERSION% - - # Building MSI installer. - - cd C:\projects\mlpack\dist\win-installer\mlpack-win-installer - - > - heat dir ..\staging - -cg HeatGenerated - -dr INSTALLFOLDER - -sreg - -srd - -var var.HarvestPath - -ag - -sfrag - -out HeatGeneratedFileList.wxs - - > - candle -dHarvestPath=..\staging - -dConfiguration=Release - -dOutDir=bin\x64\Release\ - -dPlatform=x64 - -dProjectDir=. - -dProjectExt=.wixproj - -dProjectFileName=mlpack-win-installer.wixproj - -dProjectName=mlpack-win-installer - -dProjectPath=mlpack-win-installer.wixproj - -dTargetDir=.\bin\x64\Release\ - -dTargetExt=.msi - -dTargetFileName=mlpack-windows.msi - -dTargetName=mlpack-windows - -dTargetPath=.\bin\x64\Release\mlpack-windows.msi - -out obj\x64\Release\ - -arch x64 - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" - Product.wxs HeatGeneratedFileList.wxs - - > - light -out .\bin\x64\Release\mlpack-%INSTALL_VERSION%.msi - -pdbout .\bin\x64\Release\mlpack-windows.wixpdb - -cultures:null - -loc mlpack-localization.wxl - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" - -contentsfile - obj\x64\Release\mlpack-win-installer.wixproj.BindContentsFileListnull.txt - -outputsfile - obj\x64\Release\mlpack-win-installer.wixproj.BindOutputsFileListnull.txt - -builtoutputsfile - obj\x64\Release\mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt - -wixprojectfile - mlpack-win-installer.wixproj - obj\x64\Release\Product.wixobj - obj\x64\Release\HeatGeneratedFileList.wixobj - -artifacts: - - path: 'build\*.zip' - name: mlpack-windows-zip - - - path: 'dist\win-installer\mlpack-win-installer\bin\x64\Release\*.msi' - name: mlpack-windows-installer - -notifications: -- provider: Email - to: - - mlpack-git@lists.mlpack.org - on_build_success: true - on_build_failure: true - on_build_status_changed: true - -cache: - - packages -> **\packages.config - - armadillo.tar.xz -> appveyor.yaml - -test_script: - # Copy all DLLs into the right place before running the test. - - ps: cp C:\projects\mlpack\boost_libs\*.* C:\projects\mlpack\build\ - - ps: > - cp C:\projects\mlpack\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.* - C:\projects\mlpack\build\ - - cd "%APPVEYOR_BUILD_FOLDER%/build/" - - > - Release\mlpack_test.exe - --report_level=detailed - --log_level=test_suite --log_format=XML > mlpack_test.xml & exit 0 - # Attempt to upload results to AppVeyor. - - ps: > - $wc = New-Object 'System.Net.WebClient'; - $wc.UploadFile( - "https://ci.appveyor.com/api/testresults/xunit/$($env:APPVEYOR_JOB_ID)", - (Resolve-Path .\mlpack_test.xml)); From 45f80112eb4c438db835715ca6650685250bb571 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 8 Oct 2020 18:56:14 -0400 Subject: [PATCH 046/550] Temporarily disable Linux and OS X jobs. --- .ci/ci.yaml | 118 ++++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/.ci/ci.yaml b/.ci/ci.yaml index 89adaec398..6354363894 100644 --- a/.ci/ci.yaml +++ b/.ci/ci.yaml @@ -8,65 +8,65 @@ pr: - '*' jobs: -- job: Linux - timeoutInMinutes: 360 - pool: - vmImage: ubuntu-16.04 - strategy: - matrix: - Plain: - CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - Python: - binding: 'python' - python.version: '3.7' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - Julia: - julia.version: '1.3.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia -DBUILD_R_BINDINGS=OFF' - Go: - binding: 'go' - go.version: '1.11.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' - R: - binding: 'R' - R.version: '4.0.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON' - Markdown: - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - - steps: - - template: linux-steps.yaml - -- job: macOS - timeoutInMinutes: 360 - pool: - vmImage: macOS-10.14 - strategy: - matrix: - Plain: - CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - python.version: '2.7' - Python: - binding: 'python' - python.version: '3.7' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - Julia: - python.version: '2.7' - julia.version: '1.3.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - Go: - binding: 'go' - python.version: '2.7' - go.version: '1.11.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' - R: - binding: 'R' - python.version: '2.7' - R.version: '4.0.0' - CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON' - - steps: - - template: macos-steps.yaml +#- job: Linux +# timeoutInMinutes: 360 +# pool: +# vmImage: ubuntu-16.04 +# strategy: +# matrix: +# Plain: +# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# Python: +# binding: 'python' +# python.version: '3.7' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# Julia: +# julia.version: '1.3.0' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia -DBUILD_R_BINDINGS=OFF' +# Go: +# binding: 'go' +# go.version: '1.11.0' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' +# R: +# binding: 'R' +# R.version: '4.0.0' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON' +# Markdown: +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# +# steps: +# - template: linux-steps.yaml +# +#- job: macOS +# timeoutInMinutes: 360 +# pool: +# vmImage: macOS-10.14 +# strategy: +# matrix: +# Plain: +# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# python.version: '2.7' +# Python: +# binding: 'python' +# python.version: '3.7' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# Julia: +# python.version: '2.7' +# julia.version: '1.3.0' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# Go: +# binding: 'go' +# python.version: '2.7' +# go.version: '1.11.0' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' +# R: +# binding: 'R' +# python.version: '2.7' +# R.version: '4.0.0' +# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON' +# +# steps: +# - template: macos-steps.yaml - job: WindowsVS15 timeoutInMinutes: 360 From 7aaf1d74820bb3e4959440dc9402a5ad6b486790 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 8 Oct 2020 21:39:09 -0400 Subject: [PATCH 047/550] Try to fix syntax. --- .ci/windows-steps.yaml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 8cf26046fe..18bd50a0e5 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -152,12 +152,10 @@ steps: cp doc\examples dist\win-installer\staging -recurse cp src\mlpack\tests\data\german.csv dist\win-installer\staging\examples\sample-ml-app\sample-ml-app\data\ # Check current git version or mlpack version. - $ver = (Get-Content - "src\mlpack\core\util\version.hpp" | - where {$_ -like "*MLPACK_VERSION*"}); - $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; - $env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.'; - $env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1); + $ver = (Get-Content "src\mlpack\core\util\version.hpp" where {$_ -like "*MLPACK_VERSION*"}); + $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; + $env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.'; + $env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1); if (Test-Path "src/mlpack/core/util/gitversion.hpp") { From 58edc52e7047dec05e8a8903b8770fa7aafe4f0f Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 9 Oct 2020 10:49:06 -0400 Subject: [PATCH 048/550] Maybe we need the pipe? --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 18bd50a0e5..fc5d5f9ab7 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -152,7 +152,7 @@ steps: cp doc\examples dist\win-installer\staging -recurse cp src\mlpack\tests\data\german.csv dist\win-installer\staging\examples\sample-ml-app\sample-ml-app\data\ # Check current git version or mlpack version. - $ver = (Get-Content "src\mlpack\core\util\version.hpp" where {$_ -like "*MLPACK_VERSION*"}); + $ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"}); $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; $env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.'; $env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1); From f36060d47d6556aab1328390a592e52b2b7a1eee Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 9 Oct 2020 19:56:56 -0400 Subject: [PATCH 049/550] Try to fix a few bugs. --- .ci/windows-steps.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index fc5d5f9ab7..d644f6345f 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -126,7 +126,7 @@ steps: - powershell: | # Pull the documentation for the installer. try { - (new-object net.webclient).DownloadFile(${env:JENKINS_DOC_DOWNLOAD}, + (new-object net.webclient).DownloadFile('http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip'), 'dist\win-installer\jenkinsdoc.zip') } catch { @@ -134,7 +134,7 @@ steps: } try { (Add-Type -AssemblyName System.IO.Compression.FileSystem); - [System.IO.Compression.ZipFile]::ExtractToDirectory(${env:JENKINS_DOC}, + [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\staging\doc') } catch { @@ -159,7 +159,7 @@ steps: if (Test-Path "src/mlpack/core/util/gitversion.hpp") { - $ver = (Get-Content ${env:GIT_VERSION_FILE}); + $ver = (Get-Content "src/mlpack/core/util/gitversion.hpp" $env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1]; } else From 332c0c56d751a14147da90f03f98153af3059351 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 9 Oct 2020 23:11:38 -0400 Subject: [PATCH 050/550] Some additional syntax fixes (I hope...). --- .ci/windows-steps.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index d644f6345f..b317a0497c 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -126,8 +126,7 @@ steps: - powershell: | # Pull the documentation for the installer. try { - (new-object net.webclient).DownloadFile('http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip'), - 'dist\win-installer\jenkinsdoc.zip') + (new-object net.webclient).DownloadFile('http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip'), 'dist\win-installer\jenkinsdoc.zip') } catch { Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!" @@ -159,7 +158,7 @@ steps: if (Test-Path "src/mlpack/core/util/gitversion.hpp") { - $ver = (Get-Content "src/mlpack/core/util/gitversion.hpp" + $ver = (Get-Content "src/mlpack/core/util/gitversion.hpp"); $env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1]; } else From 7fdc820181e70a2d14c330980ac19ebc498aabfc Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 10 Oct 2020 13:59:50 -0400 Subject: [PATCH 051/550] Okay, does it all need to be on one line? --- .ci/windows-steps.yaml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index b317a0497c..82343803d1 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -125,20 +125,10 @@ steps: # Build MSI installer. - powershell: | # Pull the documentation for the installer. - try { - (new-object net.webclient).DownloadFile('http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip'), 'dist\win-installer\jenkinsdoc.zip') - } - catch { - Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!" - } - try { - (Add-Type -AssemblyName System.IO.Compression.FileSystem); - [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', - 'dist\win-installer\staging\doc') - } - catch { - Write-Output "Unable to add doc to installer, skipping!" - } + try{(new-object net.webclient).DownloadFile('http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip'), 'dist\win-installer\jenkinsdoc.zip')} + catch{Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!"} + try {(Add-Type -AssemblyName System.IO.Compression.FileSystem); [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\staging\doc')} + catch{Write-Output "Unable to add doc to installer, skipping!"} # Preparing installer staging. mkdir dist\win-installer\staging\lib cp build\Release\*.lib dist\win-installer\staging\lib\ From f63615c458b677b2ad33e6559f968afa701c82da Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 10 Oct 2020 17:01:54 -0400 Subject: [PATCH 052/550] Okay, maybe this syntax is okay? --- .ci/windows-steps.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 82343803d1..69734a9d1a 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -125,9 +125,17 @@ steps: # Build MSI installer. - powershell: | # Pull the documentation for the installer. - try{(new-object net.webclient).DownloadFile('http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip'), 'dist\win-installer\jenkinsdoc.zip')} - catch{Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!"} - try {(Add-Type -AssemblyName System.IO.Compression.FileSystem); [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\staging\doc')} + try { + $url = "http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip" + (new-object net.webclient).DownloadFile($url), 'dist\win-installer\jenkinsdoc.zip') + } + catch { + Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!" + } + try { + (Add-Type -AssemblyName System.IO.Compression.FileSystem); + [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\staging\doc') + } catch{Write-Output "Unable to add doc to installer, skipping!"} # Preparing installer staging. mkdir dist\win-installer\staging\lib From 989ce6c911be499aa1a2e0f6546163355fbc5b5e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 11 Oct 2020 10:12:54 -0400 Subject: [PATCH 053/550] Ok, oops, I had one too many ); that should have been obvious... --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 69734a9d1a..4cc616dd30 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -127,7 +127,7 @@ steps: # Pull the documentation for the installer. try { $url = "http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip" - (new-object net.webclient).DownloadFile($url), 'dist\win-installer\jenkinsdoc.zip') + (new-object net.webclient).DownloadFile($url, 'dist\win-installer\jenkinsdoc.zip') } catch { Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!" From 8ef8f94ce59b699bfe95711771a9d17ba26b6ac7 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 11 Oct 2020 13:10:17 -0400 Subject: [PATCH 054/550] Hey, getting somewhere! Now there is a path issue. --- .ci/windows-steps.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 4cc616dd30..7ec2c38120 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -164,6 +164,8 @@ steps: $env:INSTALL_VERSION = $env:MLPACK_VERSION; } # Build the MSI installer. + dir C:\Program Files (x86)\ + set path=C:\Program Files (x86)\WiX Toolset v3.11\bin;%path% cd dist\win-installer\mlpack-win-installer heat dir ..\staging -cg HeatGenerated From 4435692182cd45db2717006be4b0b436e37d4ad2 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 11 Oct 2020 20:25:15 -0400 Subject: [PATCH 055/550] Try escaping the string. --- .ci/windows-steps.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 7ec2c38120..e45fb26eb6 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -164,8 +164,8 @@ steps: $env:INSTALL_VERSION = $env:MLPACK_VERSION; } # Build the MSI installer. - dir C:\Program Files (x86)\ - set path=C:\Program Files (x86)\WiX Toolset v3.11\bin;%path% + dir "C:\Program Files (x86)\" + set path="C:\Program Files (x86)\WiX Toolset v3.11\bin";%path% cd dist\win-installer\mlpack-win-installer heat dir ..\staging -cg HeatGenerated From c333b69ecc8e84a651db2c7cf579cf40259de3bb Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 12 Oct 2020 09:50:00 -0400 Subject: [PATCH 056/550] Maybe with powershell I get the path with $path not %path%? --- .ci/windows-steps.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index e45fb26eb6..f86cf73d1d 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -164,8 +164,7 @@ steps: $env:INSTALL_VERSION = $env:MLPACK_VERSION; } # Build the MSI installer. - dir "C:\Program Files (x86)\" - set path="C:\Program Files (x86)\WiX Toolset v3.11\bin";%path% + set path="C:\Program Files (x86)\WiX Toolset v3.11\bin";$path cd dist\win-installer\mlpack-win-installer heat dir ..\staging -cg HeatGenerated From 17a5777263bf244d811fb0722a41e32eb262fdd3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 12 Oct 2020 12:50:44 -0400 Subject: [PATCH 057/550] Maybe this gets us closer with the path? --- .ci/windows-steps.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index f86cf73d1d..7d1c267821 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -164,8 +164,10 @@ steps: $env:INSTALL_VERSION = $env:MLPACK_VERSION; } # Build the MSI installer. - set path="C:\Program Files (x86)\WiX Toolset v3.11\bin";$path + $env:Path += "C:\Program Files (x86)\WiX Toolset v3.11\bin" cd dist\win-installer\mlpack-win-installer + dir "C:\Program Files (x86)\WiX Toolset v3.11\" + dir "C:\Program Files (x86)\WiX Toolset v3.11\bin\" heat dir ..\staging -cg HeatGenerated -dr INSTALLFOLDER From 4cb5e7ffce1ddc7d30ace5e8d83a63349c64cb93 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 12 Oct 2020 15:09:37 -0400 Subject: [PATCH 058/550] Ok, forget the path, just specify directly. --- .ci/windows-steps.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 7d1c267821..9519ef4699 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -164,11 +164,8 @@ steps: $env:INSTALL_VERSION = $env:MLPACK_VERSION; } # Build the MSI installer. - $env:Path += "C:\Program Files (x86)\WiX Toolset v3.11\bin" cd dist\win-installer\mlpack-win-installer - dir "C:\Program Files (x86)\WiX Toolset v3.11\" - dir "C:\Program Files (x86)\WiX Toolset v3.11\bin\" - heat dir ..\staging + "C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe" dir ..\staging -cg HeatGenerated -dr INSTALLFOLDER -sreg @@ -177,7 +174,7 @@ steps: -ag -sfrag -out HeatGeneratedFileList.wxs - candle + "C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" -dHarvestPath=..\staging -dConfiguration=Release -dOutDir=bin\x64\Release\ @@ -196,7 +193,7 @@ steps: -arch x64 -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" Product.wxs HeatGeneratedFileList.wxs - light + "C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" -out .\bin\x64\Release\mlpack-%INSTALL_VERSION%.msi -pdbout .\bin\x64\Release\mlpack-windows.wixpdb -cultures:null From 42aae59d1071f7c302c8eb2318a8db1c855afd7c Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 12 Oct 2020 19:00:42 -0400 Subject: [PATCH 059/550] Seriously? Backticks for line continuation? --- .ci/windows-steps.yaml | 72 +++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 9519ef4699..37908bc2be 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -165,44 +165,44 @@ steps: } # Build the MSI installer. cd dist\win-installer\mlpack-win-installer - "C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe" dir ..\staging - -cg HeatGenerated - -dr INSTALLFOLDER - -sreg - -srd - -var var.HarvestPath - -ag - -sfrag + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ..\staging ` + -cg HeatGenerated ` + -dr INSTALLFOLDER ` + -sreg ` + -srd ` + -var var.HarvestPath ` + -ag ` + -sfrag ` -out HeatGeneratedFileList.wxs - "C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" - -dHarvestPath=..\staging - -dConfiguration=Release - -dOutDir=bin\x64\Release\ - -dPlatform=x64 - -dProjectDir=. - -dProjectExt=.wixproj - -dProjectFileName=mlpack-win-installer.wixproj - -dProjectName=mlpack-win-installer - -dProjectPath=mlpack-win-installer.wixproj - -dTargetDir=.\bin\x64\Release\ - -dTargetExt=.msi - -dTargetFileName=mlpack-windows.msi - -dTargetName=mlpack-windows - -dTargetPath=.\bin\x64\Release\mlpack-windows.msi - -out obj\x64\Release\ - -arch x64 - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -dHarvestPath=..\staging ` + -dConfiguration=Release ` + -dOutDir=bin\x64\Release\ ` + -dPlatform=x64 ` + -dProjectDir=. ` + -dProjectExt=.wixproj ` + -dProjectFileName=mlpack-win-installer.wixproj ` + -dProjectName=mlpack-win-installer ` + -dProjectPath=mlpack-win-installer.wixproj ` + -dTargetDir=.\bin\x64\Release\ ` + -dTargetExt=.msi ` + -dTargetFileName=mlpack-windows.msi ` + -dTargetName=mlpack-windows ` + -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` + -out obj\x64\Release\ ` + -arch x64 ` + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` Product.wxs HeatGeneratedFileList.wxs - "C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" - -out .\bin\x64\Release\mlpack-%INSTALL_VERSION%.msi - -pdbout .\bin\x64\Release\mlpack-windows.wixpdb - -cultures:null - -loc mlpack-localization.wxl - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" - -contentsfile obj\x64\Release\mlpack-win-installer.wixproj.BindContentsFileListnull.txt - -outputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindOutputsFileListnull.txt - -builtoutputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt - -wixprojectfile mlpack-win-installer.wixproj + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` + -out .\bin\x64\Release\mlpack-%INSTALL_VERSION%.msi ` + -pdbout .\bin\x64\Release\mlpack-windows.wixpdb ` + -cultures:null ` + -loc mlpack-localization.wxl ` + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` + -contentsfile obj\x64\Release\mlpack-win-installer.wixproj.BindContentsFileListnull.txt ` + -outputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindOutputsFileListnull.txt ` + -builtoutputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt ` + -wixprojectfile mlpack-win-installer.wixproj ` obj\x64\Release\Product.wixobj obj\x64\Release\HeatGeneratedFileList.wixobj displayName: 'Build MSI Windows installer' From abd258eceeda09beea5acb8ad92fba43d1fbd2f0 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 13 Oct 2020 08:32:48 -0400 Subject: [PATCH 060/550] Maybe the directory did not exist? --- .ci/windows-steps.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 37908bc2be..a602584a4f 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -164,7 +164,10 @@ steps: $env:INSTALL_VERSION = $env:MLPACK_VERSION; } # Build the MSI installer. + dir + mkdir dist\win-installer\mlpack-win-installer cd dist\win-installer\mlpack-win-installer + dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ..\staging ` -cg HeatGenerated ` -dr INSTALLFOLDER ` From 6432d576e5ffa4745f1e41d26edebd1f80944439 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 13 Oct 2020 11:08:21 -0400 Subject: [PATCH 061/550] Ok, the directory already exists. --- .ci/windows-steps.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index a602584a4f..3198f90a6a 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -165,7 +165,6 @@ steps: } # Build the MSI installer. dir - mkdir dist\win-installer\mlpack-win-installer cd dist\win-installer\mlpack-win-installer dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ..\staging ` From 31750b1786b6332b43d805f0511113699f271ff5 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 13 Oct 2020 15:18:06 -0400 Subject: [PATCH 062/550] Could this be a \ vs. / issue? --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 3198f90a6a..40b4652901 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -167,7 +167,7 @@ steps: dir cd dist\win-installer\mlpack-win-installer dir - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ..\staging ` + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ../staging ` -cg HeatGenerated ` -dr INSTALLFOLDER ` -sreg ` From cc7431f019d7fbd99f3e91e9dee7c651fb4720d6 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 13 Oct 2020 21:49:19 -0400 Subject: [PATCH 063/550] More \ vs. / nonsense. --- .ci/windows-steps.yaml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 40b4652901..72e1d99597 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -177,35 +177,35 @@ steps: -sfrag ` -out HeatGeneratedFileList.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - -dHarvestPath=..\staging ` + -dHarvestPath=../staging ` -dConfiguration=Release ` - -dOutDir=bin\x64\Release\ ` + -dOutDir=bin/x64/Release/ ` -dPlatform=x64 ` -dProjectDir=. ` -dProjectExt=.wixproj ` -dProjectFileName=mlpack-win-installer.wixproj ` -dProjectName=mlpack-win-installer ` -dProjectPath=mlpack-win-installer.wixproj ` - -dTargetDir=.\bin\x64\Release\ ` + -dTargetDir=./bin/x64/Release/ ` -dTargetExt=.msi ` -dTargetFileName=mlpack-windows.msi ` -dTargetName=mlpack-windows ` - -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` - -out obj\x64\Release\ ` + -dTargetPath=./bin/x64/Release/mlpack-windows.msi ` + -out obj/x64/Release/ ` -arch x64 ` -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` Product.wxs HeatGeneratedFileList.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` - -out .\bin\x64\Release\mlpack-%INSTALL_VERSION%.msi ` - -pdbout .\bin\x64\Release\mlpack-windows.wixpdb ` + -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` + -pdbout ./bin/x64/Release/mlpack-windows.wixpdb ` -cultures:null ` -loc mlpack-localization.wxl ` -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` - -contentsfile obj\x64\Release\mlpack-win-installer.wixproj.BindContentsFileListnull.txt ` - -outputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindOutputsFileListnull.txt ` - -builtoutputsfile obj\x64\Release\mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt ` + -contentsfile obj/x64/Release/mlpack-win-installer.wixproj.BindContentsFileListnull.txt ` + -outputsfile obj/x64/Release/mlpack-win-installer.wixproj.BindOutputsFileListnull.txt ` + -builtoutputsfile obj/x64/Release/mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt ` -wixprojectfile mlpack-win-installer.wixproj ` - obj\x64\Release\Product.wixobj obj\x64\Release\HeatGeneratedFileList.wixobj + obj/x64/Release/Product.wixobj obj\x64\Release\HeatGeneratedFileList.wixobj displayName: 'Build MSI Windows installer' # Publish artifacts to Azure Pipelines From 24a5f8b1a3b57c8384de3fc697db201e8e09d5c9 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 14 Oct 2020 09:59:23 -0400 Subject: [PATCH 064/550] Okay, maybe I can get some documentation on candle.exe? --- .ci/windows-steps.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 72e1d99597..473d9fbfab 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -176,6 +176,7 @@ steps: -ag ` -sfrag ` -out HeatGeneratedFileList.wxs + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` -dHarvestPath=../staging ` -dConfiguration=Release ` From 51814aa34a9f50bdf28e520bb425cd770bbea1b3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 14 Oct 2020 17:00:25 -0400 Subject: [PATCH 065/550] What files are in the directory? --- .ci/windows-steps.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 473d9fbfab..c78530f62b 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -177,6 +177,7 @@ steps: -sfrag ` -out HeatGeneratedFileList.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? + dir ../staging & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` -dHarvestPath=../staging ` -dConfiguration=Release ` From 5b1104ad49bc85025d8ded72d9ccf0962b624941 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 15 Oct 2020 10:49:21 -0400 Subject: [PATCH 066/550] What if I just remove HarvestPath? --- .ci/windows-steps.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index c78530f62b..5748e4da71 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -179,7 +179,6 @@ steps: & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? dir ../staging & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - -dHarvestPath=../staging ` -dConfiguration=Release ` -dOutDir=bin/x64/Release/ ` -dPlatform=x64 ` From 9d313b77ae84cae503b1c637aa6590cc5c8d19fc Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 15 Oct 2020 13:53:37 -0400 Subject: [PATCH 067/550] I dunno, this is just a random guess... --- .ci/windows-steps.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 5748e4da71..18f91135eb 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -179,6 +179,8 @@ steps: & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? dir ../staging & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + mlpack-wix-installer.wixproj Product.wxs HeatGeneratedFileList.wxs ` + -dHarvestPath=../staging/ ` -dConfiguration=Release ` -dOutDir=bin/x64/Release/ ` -dPlatform=x64 ` @@ -194,8 +196,7 @@ steps: -dTargetPath=./bin/x64/Release/mlpack-windows.msi ` -out obj/x64/Release/ ` -arch x64 ` - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` - Product.wxs HeatGeneratedFileList.wxs + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` -pdbout ./bin/x64/Release/mlpack-windows.wixpdb ` From 7487eb6c7efef9e3ae05ce9d3b1eb49bd647f0d7 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 16 Oct 2020 11:00:10 -0400 Subject: [PATCH 068/550] Fix the spelling... --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 18f91135eb..c5ddef9926 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -179,7 +179,7 @@ steps: & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? dir ../staging & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - mlpack-wix-installer.wixproj Product.wxs HeatGeneratedFileList.wxs ` + mlpack-win-installer.wixproj Product.wxs HeatGeneratedFileList.wxs ` -dHarvestPath=../staging/ ` -dConfiguration=Release ` -dOutDir=bin/x64/Release/ ` From dac38224a7e348e22f98b41e36378eb330d8430e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 16 Oct 2020 17:10:45 -0400 Subject: [PATCH 069/550] Try removing HarvestPath again. --- .ci/windows-steps.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index c5ddef9926..0edae83723 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -180,7 +180,6 @@ steps: dir ../staging & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` mlpack-win-installer.wixproj Product.wxs HeatGeneratedFileList.wxs ` - -dHarvestPath=../staging/ ` -dConfiguration=Release ` -dOutDir=bin/x64/Release/ ` -dPlatform=x64 ` From bbfab574bf030ece756dc1059ba16bab5f8d87f8 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 16 Oct 2020 19:53:34 -0400 Subject: [PATCH 070/550] Maybe this gets us closer? I really have no idea. --- .ci/windows-steps.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 0edae83723..08b0da9394 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -184,7 +184,6 @@ steps: -dOutDir=bin/x64/Release/ ` -dPlatform=x64 ` -dProjectDir=. ` - -dProjectExt=.wixproj ` -dProjectFileName=mlpack-win-installer.wixproj ` -dProjectName=mlpack-win-installer ` -dProjectPath=mlpack-win-installer.wixproj ` From 2f3a8d7ff1bf4416153e54a68ff3abcf0e5eefbb Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 16 Oct 2020 19:54:13 -0400 Subject: [PATCH 071/550] Disable VS15 build. --- .ci/ci.yaml | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/.ci/ci.yaml b/.ci/ci.yaml index 09357c716e..7a02c0de62 100644 --- a/.ci/ci.yaml +++ b/.ci/ci.yaml @@ -59,21 +59,22 @@ jobs: # steps: # - template: macos-steps.yaml -- job: WindowsVS15 - timeoutInMinutes: 360 - displayName: Windows VS15 - pool: - vmImage: vs2017-win2016 - strategy: - matrix: - Plain: - CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - python.version: '2.7' - CMakeGenerator: '-G "Visual Studio 15 2017 Win64"' - MSBuildVersion: '15.0' - ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip' - ArchiveLibs: 'mlpack-windows-vs15.zip' - ArchiveTests: 'mlpack_test-vs15.xml' +# Typically gives a C1060... +#- job: WindowsVS15 +# timeoutInMinutes: 360 +# displayName: Windows VS15 +# pool: +# vmImage: vs2017-win2016 +# strategy: +# matrix: +# Plain: +# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# python.version: '2.7' +# CMakeGenerator: '-G "Visual Studio 15 2017 Win64"' +# MSBuildVersion: '15.0' +# ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip' +# ArchiveLibs: 'mlpack-windows-vs15.zip' +# ArchiveTests: 'mlpack_test-vs15.xml' steps: - template: windows-steps.yaml From fd7af11d2c0a660ff5a5e719d93948e09a117504 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 17 Oct 2020 14:28:13 -0400 Subject: [PATCH 072/550] What is even in this file? --- .ci/windows-steps.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 08b0da9394..cfc7ce5fd8 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -178,6 +178,7 @@ steps: -out HeatGeneratedFileList.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? dir ../staging + type Product.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` mlpack-win-installer.wixproj Product.wxs HeatGeneratedFileList.wxs ` -dConfiguration=Release ` From 133405989800bad0f876d611b042e6136bf210c5 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 17 Oct 2020 18:09:16 -0400 Subject: [PATCH 073/550] At this point it's just genetic algorithms. --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index cfc7ce5fd8..5fbd4c25c0 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -180,7 +180,7 @@ steps: dir ../staging type Product.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - mlpack-win-installer.wixproj Product.wxs HeatGeneratedFileList.wxs ` + Product.wxs HeatGeneratedFileList.wxs ` -dConfiguration=Release ` -dOutDir=bin/x64/Release/ ` -dPlatform=x64 ` From 497957346b73665cad135ce5ec5f58e254d2bdd4 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 17 Oct 2020 21:46:36 -0400 Subject: [PATCH 074/550] Try following some tutorial I found a little bit. --- .ci/windows-steps.yaml | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 5fbd4c25c0..77486cb3a1 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -168,34 +168,16 @@ steps: cd dist\win-installer\mlpack-win-installer dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ../staging ` - -cg HeatGenerated ` -dr INSTALLFOLDER ` - -sreg ` - -srd ` - -var var.HarvestPath ` - -ag ` - -sfrag ` - -out HeatGeneratedFileList.wxs - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' -? + -cg HeatGenerated ` + -g1 -gg -sf -srd -scom -sreg ` + -out fragment.wxs dir ../staging - type Product.wxs + dir + type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - Product.wxs HeatGeneratedFileList.wxs ` - -dConfiguration=Release ` - -dOutDir=bin/x64/Release/ ` - -dPlatform=x64 ` - -dProjectDir=. ` - -dProjectFileName=mlpack-win-installer.wixproj ` - -dProjectName=mlpack-win-installer ` - -dProjectPath=mlpack-win-installer.wixproj ` - -dTargetDir=./bin/x64/Release/ ` - -dTargetExt=.msi ` - -dTargetFileName=mlpack-windows.msi ` - -dTargetName=mlpack-windows ` - -dTargetPath=./bin/x64/Release/mlpack-windows.msi ` + Product.wxs fragment.wxs ` -out obj/x64/Release/ ` - -arch x64 ` - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` -pdbout ./bin/x64/Release/mlpack-windows.wixpdb ` From 54b5172c064fce5c4d5046101bb52f0e2403b0a6 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Sun, 18 Oct 2020 11:16:31 -0400 Subject: [PATCH 075/550] made loglikelihood const Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 486b4b635f..e9f8498837 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -1044,7 +1044,7 @@ BOOST_AUTO_TEST_CASE(GaussianHMMPredictTest) //test loglikelihood calculation for the whole data { - auto loglikelihood = hmm.LogLikelihood(obs); + const double loglikelihood = hmm.LogLikelihood(obs); BOOST_REQUIRE_CLOSE(loglikelihood, loglikelihoodRef, 1e-3); } From 78888bbbc3c97b85a6aca6b2a44cd0d1dda26759 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 18 Oct 2020 11:43:26 -0400 Subject: [PATCH 076/550] Oops, remove accidental backtick. --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 77486cb3a1..bc021fe5db 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -177,7 +177,7 @@ steps: type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` Product.wxs fragment.wxs ` - -out obj/x64/Release/ ` + -out obj/x64/Release/ & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` -pdbout ./bin/x64/Release/mlpack-windows.wixpdb ` From c6a8f796e447b307662a37d36ef32f3e0e91af17 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 19 Oct 2020 11:51:29 -0400 Subject: [PATCH 077/550] I wonder what will happen now? --- .ci/windows-steps.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index bc021fe5db..e0fd98d7d0 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -178,6 +178,7 @@ steps: & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` Product.wxs fragment.wxs ` -out obj/x64/Release/ + dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` -pdbout ./bin/x64/Release/mlpack-windows.wixpdb ` @@ -188,7 +189,7 @@ steps: -outputsfile obj/x64/Release/mlpack-win-installer.wixproj.BindOutputsFileListnull.txt ` -builtoutputsfile obj/x64/Release/mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt ` -wixprojectfile mlpack-win-installer.wixproj ` - obj/x64/Release/Product.wixobj obj\x64\Release\HeatGeneratedFileList.wixobj + obj/x64/Release/Product.wixobj obj\x64\Release\fragment.wixobj displayName: 'Build MSI Windows installer' # Publish artifacts to Azure Pipelines From 2667a564f56f417019f5eea31d3efb38e7ffa6d5 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 20 Oct 2020 09:27:28 -0400 Subject: [PATCH 078/550] Try to use the default "SourceDir". --- .ci/windows-steps.yaml | 26 +++++++++---------- .../mlpack-win-installer.wixproj | 5 +--- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index e0fd98d7d0..26d66754ab 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -134,20 +134,20 @@ steps: } try { (Add-Type -AssemblyName System.IO.Compression.FileSystem); - [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\staging\doc') + [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\SourceDir\doc') } catch{Write-Output "Unable to add doc to installer, skipping!"} # Preparing installer staging. - mkdir dist\win-installer\staging\lib - cp build\Release\*.lib dist\win-installer\staging\lib\ - cp build\Release\*.exp dist\win-installer\staging\lib\ - cp build\Release\*.dll dist\win-installer\staging\ - cp build\Release\*.exe dist\win-installer\staging\ - cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\staging\ - cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\staging\ - cp build\include\mlpack dist\win-installer\staging -recurse - cp doc\examples dist\win-installer\staging -recurse - cp src\mlpack\tests\data\german.csv dist\win-installer\staging\examples\sample-ml-app\sample-ml-app\data\ + mkdir dist\win-installer\SourceDir\lib + cp build\Release\*.lib dist\win-installer\SourceDir\lib\ + cp build\Release\*.exp dist\win-installer\SourceDir\lib\ + cp build\Release\*.dll dist\win-installer\SourceDir\ + cp build\Release\*.exe dist\win-installer\SourceDir\ + cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\SourceDir\ + cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\SourceDir\ + cp build\include\mlpack dist\win-installer\SourceDir -recurse + cp doc\examples dist\win-installer\SourceDir -recurse + cp src\mlpack\tests\data\german.csv dist\win-installer\SourceDir\examples\sample-ml-app\sample-ml-app\data\ # Check current git version or mlpack version. $ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"}); $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; @@ -167,12 +167,12 @@ steps: dir cd dist\win-installer\mlpack-win-installer dir - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ../staging ` + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ../SourceDir ` -dr INSTALLFOLDER ` -cg HeatGenerated ` -g1 -gg -sf -srd -scom -sreg ` -out fragment.wxs - dir ../staging + dir ../SourceDir dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 8795a920eb..c0e9d9fd0d 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -28,9 +28,6 @@ bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ - - HarvestPath=..\staging - @@ -56,4 +53,4 @@ --> - \ No newline at end of file + From d4fe9f7c937f5845505ca0ec98e0aba6514338b3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 21 Oct 2020 09:14:23 -0400 Subject: [PATCH 079/550] Try making SourceDir a subdirectory of mlpack-win-installer. --- .ci/windows-steps.yaml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 26d66754ab..0a8729c5b9 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -134,20 +134,20 @@ steps: } try { (Add-Type -AssemblyName System.IO.Compression.FileSystem); - [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\SourceDir\doc') + [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\mlpack-win-installer\SourceDir\doc') } catch{Write-Output "Unable to add doc to installer, skipping!"} # Preparing installer staging. - mkdir dist\win-installer\SourceDir\lib - cp build\Release\*.lib dist\win-installer\SourceDir\lib\ - cp build\Release\*.exp dist\win-installer\SourceDir\lib\ - cp build\Release\*.dll dist\win-installer\SourceDir\ - cp build\Release\*.exe dist\win-installer\SourceDir\ - cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\SourceDir\ - cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\SourceDir\ - cp build\include\mlpack dist\win-installer\SourceDir -recurse - cp doc\examples dist\win-installer\SourceDir -recurse - cp src\mlpack\tests\data\german.csv dist\win-installer\SourceDir\examples\sample-ml-app\sample-ml-app\data\ + mkdir dist\win-installer\mlpack-win-installer\SourceDir\lib + cp build\Release\*.lib dist\win-installer\mlpack-win-installer\SourceDir\lib\ + cp build\Release\*.exp dist\win-installer\mlpack-win-installer\SourceDir\lib\ + cp build\Release\*.dll dist\win-installer\mlpack-win-installer\SourceDir\ + cp build\Release\*.exe dist\win-installer\mlpack-win-installer\SourceDir\ + cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\SourceDir\ + cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\mlpack-win-installer\SourceDir\ + cp build\include\mlpack dist\win-installer\mlpack-win-installer\SourceDir -recurse + cp doc\examples dist\win-installer\mlpack-win-installer\SourceDir -recurse + cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\SourceDir\examples\sample-ml-app\sample-ml-app\data\ # Check current git version or mlpack version. $ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"}); $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; @@ -167,12 +167,12 @@ steps: dir cd dist\win-installer\mlpack-win-installer dir - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir ../SourceDir ` + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir SourceDir ` -dr INSTALLFOLDER ` -cg HeatGenerated ` -g1 -gg -sf -srd -scom -sreg ` -out fragment.wxs - dir ../SourceDir + dir SourceDir dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` From c59467e1a692e6bd976f2d4e8c380bc48fa2b979 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Tue, 27 Oct 2020 11:14:29 -0400 Subject: [PATCH 080/550] added more comment for LogScaleFactor() test case --- src/mlpack/tests/hmm_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 142b8c9bdc..69fe66e756 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -1061,6 +1061,8 @@ TEST_CASE("GaussianHMMPredictTest", "[HMMTest]") // Test loglikelihood calculation in an incremental way. // It simulates the case where we have a stream of data. + // In this case the accumulation of the log scales factor to calculate + // the logkielihood value is done outside of the loop { double loglikelihood = 0; arma::vec forwardLogProb; From af3bab25c6e005e74ee86c1c37c207ff5852bba8 Mon Sep 17 00:00:00 2001 From: Arash Abghari Date: Tue, 27 Oct 2020 11:42:04 -0400 Subject: [PATCH 081/550] updated the comments for EmissionLogLikelihood() and LogLikelihood() --- src/mlpack/methods/hmm/hmm.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 75f9dac519..726b60ca47 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -308,7 +308,8 @@ class HMM double EmissionLogScaleFactor(const arma::vec& emissionLogProb, arma::vec& forwardLogProb) const; /** - * Compute the log-likelihood of the given emission probability up to time t + * Compute the log-likelihood of the given emission probability up to time t, + * storing the result in logLikelihood. * This is meant for incremental or streaming computation of the * log-likelihood of a sequence. For the first data point, provide an empty * forwardLogProb vector. @@ -341,7 +342,8 @@ class HMM double LogScaleFactor(const arma::vec &data, arma::vec& forwardLogProb) const; /** - * Compute the log-likelihood of the given data up to time t + * Compute the log-likelihood of the given data up to time t, storing the + * result in logLikelihood. * This is meant for incremental or streaming computation of the * log-likelihood of a sequence. For the first data point, provide an empty * forwardLogProb vector. From 7d81636848921a6953dfd5c76bc36472f20f50b2 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 27 Oct 2020 14:07:42 -0400 Subject: [PATCH 082/550] Try re-adding HarvestPath. --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index c0e9d9fd0d..f677291fb9 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -43,6 +43,9 @@ + + HarvestPath=.\SourceDir + From 66c21a9511a2358e8b871ce211b066a5fe63a90c Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 31 Oct 2020 10:48:59 -0400 Subject: [PATCH 083/550] Just try simplifying some things... --- .ci/windows-steps.yaml | 29 +++++---- .../mlpack-win-installer.wixproj | 59 ------------------- 2 files changed, 16 insertions(+), 72 deletions(-) delete mode 100644 dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 0a8729c5b9..17171592b8 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -169,27 +169,30 @@ steps: dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir SourceDir ` -dr INSTALLFOLDER ` - -cg HeatGenerated ` - -g1 -gg -sf -srd -scom -sreg ` + -ag ` + -cg DynamicFragment ` + -ke ` + -srd ` + -sfrag ` + -nologo ` -out fragment.wxs dir SourceDir dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - Product.wxs fragment.wxs ` - -out obj/x64/Release/ + -out obj/x64/Release/Product.wixobj ` + Product.wxs + & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -out obj/x64/Release/fragment.wixobj ` + fragment.wxs dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` + -b SourceDir ` + obj/x64/Release/Product.wixobj ` + obj\x64\Release\fragment.wixobj ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` - -pdbout ./bin/x64/Release/mlpack-windows.wixpdb ` - -cultures:null ` - -loc mlpack-localization.wxl ` - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` - -contentsfile obj/x64/Release/mlpack-win-installer.wixproj.BindContentsFileListnull.txt ` - -outputsfile obj/x64/Release/mlpack-win-installer.wixproj.BindOutputsFileListnull.txt ` - -builtoutputsfile obj/x64/Release/mlpack-win-installer.wixproj.BindBuiltOutputsFileListnull.txt ` - -wixprojectfile mlpack-win-installer.wixproj ` - obj/x64/Release/Product.wixobj obj\x64\Release\fragment.wixobj + -loc mlpack-localization.wxl + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" displayName: 'Build MSI Windows installer' # Publish artifacts to Azure Pipelines diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj deleted file mode 100644 index f677291fb9..0000000000 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - Debug - x86 - 3.10 - 5409c191-c4b0-4caf-954c-001bb5c1d136 - 2.0 - mlpack-windows - Package - mlpack-win-installer - - - bin\$(Configuration)\ - obj\$(Configuration)\ - Debug - - - bin\$(Configuration)\ - obj\$(Configuration)\ - - - Debug - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - - - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - - - - - - - - $(WixExtDir)\WixUIExtension.dll - WixUIExtension - - - - - - - - - HarvestPath=.\SourceDir - - - - - - - From 7176f998bd2868f3b5927471dd10872714091f79 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 31 Oct 2020 11:18:13 -0400 Subject: [PATCH 084/550] Try an older version of Julia. I'm not sure if this will work. --- .ci/macos-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index c437344050..406f2fd68e 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -22,7 +22,7 @@ steps: fi if [ "a$(julia.version)" != "a" ]; then - brew cask install julia + brew cask install julia@1.5.1 fi git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf From cf1f70261343c0a4c4a78ebb33260328060a955b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 2 Nov 2020 08:53:45 -0500 Subject: [PATCH 085/550] Re-add .wixproj file... will it do anything? --- .../mlpack-win-installer.wixproj | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj new file mode 100644 index 0000000000..b82fa1b8f1 --- /dev/null +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -0,0 +1,59 @@ + + + + Debug + x86 + 3.10 + 5409c191-c4b0-4caf-954c-001bb5c1d136 + 2.0 + mlpack-windows + Package + mlpack-win-installer + + + bin\$(Configuration)\ + obj\$(Configuration)\ + Debug + + + bin\$(Configuration)\ + obj\$(Configuration)\ + + + Debug + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + + + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + + + HarvestPath=.\SourceDir + + + + + + + + $(WixExtDir)\WixUIExtension.dll + WixUIExtension + + + + + + + + + + + + + From ebc78e59c42ba0eab7515349338dad5cc4fa288b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 2 Nov 2020 08:53:55 -0500 Subject: [PATCH 086/550] Wrap line correctly. --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 02606c48fd..fb8a7435dd 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -187,7 +187,7 @@ steps: obj/x64/Release/Product.wixobj ` obj\x64\Release\fragment.wixobj ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` - -loc mlpack-localization.wxl + -loc mlpack-localization.wxl ` -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" displayName: 'Build MSI Windows installer' From 12f247fb617f6c0f6b71a79a7e4360342d43860a Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 4 Nov 2020 17:29:25 -0500 Subject: [PATCH 087/550] Try referencing the .wixproj file. --- .ci/windows-steps.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index fb8a7435dd..c6359297be 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -176,14 +176,21 @@ steps: dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -dProjectFileName=mlpack-win-installer.wixproj ` + -dProjectName=mlpack-win-installer ` + -dProjectPath=mlpack-win-installer.wixproj ` -out obj/x64/Release/Product.wixobj ` Product.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -dProjectFileName=mlpack-win-installer.wixproj ` + -dProjectName=mlpack-win-installer ` + -dProjectPath=mlpack-win-installer.wixproj ` -out obj/x64/Release/fragment.wixobj ` fragment.wxs dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` -b SourceDir ` + mlpack-win-installer.wixproj ` obj/x64/Release/Product.wixobj ` obj\x64\Release\fragment.wixobj ` -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` From d1e36633a66cd6c19a546300f14569f09333950b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 4 Nov 2020 17:34:48 -0500 Subject: [PATCH 088/550] Try to install Julia manually. --- .ci/macos-steps.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 406f2fd68e..e9901f0dcc 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -21,9 +21,11 @@ steps: pip install cython numpy pandas zipp configparser fi - if [ "a$(julia.version)" != "a" ]; then - brew cask install julia@1.5.1 - fi + # Install Julia manually. + wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.2-mac64.dmg + sudo hdiutil mount julia-1.5.2-mac64.dmg + sudo cp -R /Volumes/julia-1.5.2-mac64/julia-1.5.2-mac64.app /Applications + sudo ln -s /Applications/julia-1.5.2-mac64.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From 11e8e46e8b5494ba3aea6376dbbd8bb8fe994b70 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 6 Nov 2020 18:00:59 -0500 Subject: [PATCH 089/550] Try adding all the old options. --- .ci/windows-steps.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index c6359297be..104002c79a 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -169,6 +169,7 @@ steps: -cg DynamicFragment ` -ke ` -srd ` + -sreg ` -sfrag ` -nologo ` -out fragment.wxs @@ -176,15 +177,35 @@ steps: dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -dConfiguration=Release ` + -dOutDir=bin\x64\Release\ ` + -dPlatform=x64 ` + -dProjectDir=. ` + -dProjectExt=.wixproj ` -dProjectFileName=mlpack-win-installer.wixproj ` -dProjectName=mlpack-win-installer ` -dProjectPath=mlpack-win-installer.wixproj ` + -dTargetDir=.\bin\x64\Release\ ` + -dTargetExt=.msi ` + -dTargetFileName=mlpack-windows.msi ` + -dTargetName=mlpack-windows ` + -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` -out obj/x64/Release/Product.wixobj ` Product.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -dConfiguration=Release ` + -dOutDir=bin\x64\Release\ ` + -dPlatform=x64 ` + -dProjectDir=. ` + -dProjectExt=.wixproj ` -dProjectFileName=mlpack-win-installer.wixproj ` -dProjectName=mlpack-win-installer ` -dProjectPath=mlpack-win-installer.wixproj ` + -dTargetDir=.\bin\x64\Release\ ` + -dTargetExt=.msi ` + -dTargetFileName=mlpack-windows.msi ` + -dTargetName=mlpack-windows ` + -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` -out obj/x64/Release/fragment.wixobj ` fragment.wxs dir From fa2dca78fbeb51298ae4c70c3ff2d4f9b52d9ae3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 6 Nov 2020 18:02:21 -0500 Subject: [PATCH 090/550] Fix paths for manually installed Julia (hopefully). --- .ci/macos-steps.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index e9901f0dcc..22fe146323 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -24,8 +24,8 @@ steps: # Install Julia manually. wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.2-mac64.dmg sudo hdiutil mount julia-1.5.2-mac64.dmg - sudo cp -R /Volumes/julia-1.5.2-mac64/julia-1.5.2-mac64.app /Applications - sudo ln -s /Applications/julia-1.5.2-mac64.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia + sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.2.app /Applications + sudo ln -s /Applications/Julia-1.5.2.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From ada403b382d81457c75e264bbc79849504ce10b1 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 6 Nov 2020 19:06:16 -0500 Subject: [PATCH 091/550] Ok, what's in the directory? --- .ci/macos-steps.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 22fe146323..4f62d8e6a3 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -24,6 +24,7 @@ steps: # Install Julia manually. wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.2-mac64.dmg sudo hdiutil mount julia-1.5.2-mac64.dmg + ls /Volumes/Julia-1.5.2/ sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.2.app /Applications sudo ln -s /Applications/Julia-1.5.2.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia From e08afec48b26ea218706161bbb5277778923d193 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 10:22:44 -0500 Subject: [PATCH 092/550] Ok, getting closer to the right path... --- .ci/macos-steps.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 4f62d8e6a3..fa4fac9f8b 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -24,9 +24,9 @@ steps: # Install Julia manually. wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.2-mac64.dmg sudo hdiutil mount julia-1.5.2-mac64.dmg - ls /Volumes/Julia-1.5.2/ - sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.2.app /Applications - sudo ln -s /Applications/Julia-1.5.2.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia + ls /Volumes/Julia-1.5.2/Julia-1.5.app/ + sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.app /Applications + sudo ln -s /Applications/Julia-1.5.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From ed88a5759675903a42323097a15e300db0d8ccc3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 10:27:59 -0500 Subject: [PATCH 093/550] Wait... it's already linked? --- .ci/macos-steps.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index fa4fac9f8b..d8bdb2edd9 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -26,6 +26,7 @@ steps: sudo hdiutil mount julia-1.5.2-mac64.dmg ls /Volumes/Julia-1.5.2/Julia-1.5.app/ sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.app /Applications + ls -l /usr/local/bin/ sudo ln -s /Applications/Julia-1.5.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf From 74dc3e2255794294ea0fc2766ac851182b35b051 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 10:32:39 -0500 Subject: [PATCH 094/550] Apparently it's automatically linked? --- .ci/macos-steps.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index d8bdb2edd9..957c668e98 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -26,8 +26,6 @@ steps: sudo hdiutil mount julia-1.5.2-mac64.dmg ls /Volumes/Julia-1.5.2/Julia-1.5.app/ sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.app /Applications - ls -l /usr/local/bin/ - sudo ln -s /Applications/Julia-1.5.app/Contents/Resources/julia/bin/julia /usr/local/bin/julia git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From e1d3e4da16a4990d6eca222c44aa714ad223762f Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 10:52:57 -0500 Subject: [PATCH 095/550] Maybe HarvestPath helps? --- .ci/windows-steps.yaml | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 104002c79a..8767a2be71 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -177,6 +177,7 @@ steps: dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` + -dHarvestPath=.\Source ` -dConfiguration=Release ` -dOutDir=bin\x64\Release\ ` -dPlatform=x64 ` @@ -190,24 +191,10 @@ steps: -dTargetFileName=mlpack-windows.msi ` -dTargetName=mlpack-windows ` -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` - -out obj/x64/Release/Product.wixobj ` - Product.wxs - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - -dConfiguration=Release ` - -dOutDir=bin\x64\Release\ ` - -dPlatform=x64 ` - -dProjectDir=. ` - -dProjectExt=.wixproj ` - -dProjectFileName=mlpack-win-installer.wixproj ` - -dProjectName=mlpack-win-installer ` - -dProjectPath=mlpack-win-installer.wixproj ` - -dTargetDir=.\bin\x64\Release\ ` - -dTargetExt=.msi ` - -dTargetFileName=mlpack-windows.msi ` - -dTargetName=mlpack-windows ` - -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` - -out obj/x64/Release/fragment.wixobj ` - fragment.wxs + -out obj/x64/Release/ ` + -arch x64 ` + -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` + Product.wxs fragment.wxs dir & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` -b SourceDir ` From c8ff4d621c9c874ef0b8495ac1ce9ee9b5fd1bb7 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 13:58:36 -0500 Subject: [PATCH 096/550] Try a slightly older version of Julia. --- .ci/macos-steps.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 957c668e98..60e7aac60d 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -22,10 +22,10 @@ steps: fi # Install Julia manually. - wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.2-mac64.dmg - sudo hdiutil mount julia-1.5.2-mac64.dmg - ls /Volumes/Julia-1.5.2/Julia-1.5.app/ - sudo cp -R /Volumes/Julia-1.5.2/Julia-1.5.app /Applications + wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.1-mac64.dmg + sudo hdiutil mount julia-1.5.1-mac64.dmg + ls /Volumes/Julia-1.5.1/Julia-1.5.app/ + sudo cp -R /Volumes/Julia-1.5.1/Julia-1.5.app /Applications git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From 2a93e2c92a7ca394db32935f18dbd2a91422200f Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 16:00:00 -0500 Subject: [PATCH 097/550] Try another old version of Julia. --- .ci/macos-steps.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 60e7aac60d..7b98eb3d05 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -22,10 +22,10 @@ steps: fi # Install Julia manually. - wget https://julialang-s3.julialang.org/bin/mac/x64/1.5/julia-1.5.1-mac64.dmg - sudo hdiutil mount julia-1.5.1-mac64.dmg - ls /Volumes/Julia-1.5.1/Julia-1.5.app/ - sudo cp -R /Volumes/Julia-1.5.1/Julia-1.5.app /Applications + wget https://julialang-s3.julialang.org/bin/mac/x64/1.4/julia-1.4.2-mac64.dmg + sudo hdiutil mount julia-1.4.2-mac64.dmg + ls /Volumes/Julia-1.4.2/Julia-1.4.app/ + sudo cp -R /Volumes/Julia-1.4.2/Julia-1.4.app /Applications git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From 23e4bd022332ff9bf7d80179b6d9eb7dd7f4a550 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 7 Nov 2020 16:29:41 -0500 Subject: [PATCH 098/550] Oops, typo in the directory name. --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 8767a2be71..47e85a6b45 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -177,7 +177,7 @@ steps: dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - -dHarvestPath=.\Source ` + -dHarvestPath=.\SourceDir ` -dConfiguration=Release ` -dOutDir=bin\x64\Release\ ` -dPlatform=x64 ` From 9076b35d87168f974504c39b7f314718dc1747a9 Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Sun, 8 Nov 2020 11:00:59 +0530 Subject: [PATCH 099/550] Adding Copy and Move constructors in Dropout Layer --- src/mlpack/methods/ann/layer/dropout.hpp | 12 ++++ src/mlpack/methods/ann/layer/dropout_impl.hpp | 48 ++++++++++++++++ src/mlpack/tests/feedforward_network_test.cpp | 56 +++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/src/mlpack/methods/ann/layer/dropout.hpp b/src/mlpack/methods/ann/layer/dropout.hpp index 56734a9ca0..f3fb8f18b4 100644 --- a/src/mlpack/methods/ann/layer/dropout.hpp +++ b/src/mlpack/methods/ann/layer/dropout.hpp @@ -60,6 +60,18 @@ class Dropout */ Dropout(const double ratio = 0.5); + //! Copy Constructor + Dropout(const Dropout& layer); + + //! Move Constructor + Dropout(const Dropout&&); + + //! Copy assignment operator + Dropout& operator=(const Dropout& layer); + + //! Move assignment operator + Dropout& operator=(Dropout&& layer); + /** * Ordinary feed forward pass of the dropout layer. * diff --git a/src/mlpack/methods/ann/layer/dropout_impl.hpp b/src/mlpack/methods/ann/layer/dropout_impl.hpp index dbc6a92e59..80f0d81fec 100644 --- a/src/mlpack/methods/ann/layer/dropout_impl.hpp +++ b/src/mlpack/methods/ann/layer/dropout_impl.hpp @@ -29,6 +29,54 @@ Dropout::Dropout( // Nothing to do here. } +template +Dropout::Dropout( + const Dropout& layer) : + ratio(layer.ratio), + scale(layer.scale), + deterministic(layer.deterministic) +{ + // Nothing to do here. +} + +template +Dropout::Dropout( + const Dropout&& layer) : + ratio(std::move(layer.ratio)), + scale(std::move(scale)), + deterministic(std::move(deterministic)) +{ + // Nothing to do here. +} + +template +Dropout& +Dropout:: +operator=(const Dropout& layer) +{ + if (this != &layer) + { + ratio = layer.ratio; + scale = layer.scale; + deterministic = layer.deterministic; + } + return *this; +} + +template +Dropout& +Dropout:: +operator=(Dropout&& layer) +{ + if (this != &layer) + { + ratio = std::move(layer.ratio); + scale = std::move(layer.scale); + deterministic = std::move(layer.deterministic); + } + return *this; +} + template template void Dropout::Forward( diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 7188f69f50..5e088276f9 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -153,6 +153,62 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } +/** + * Check whether copying and moving network with dropout is working or not. + */ +TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]") +{ + // Load the dataset. + arma::mat trainData; + data::Load("thyroid_train.csv", trainData, true); + + arma::mat trainLabels = trainData.row(trainData.n_rows - 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 + * +-----+ +-----+ +-----+ + * | | | | | | + * | +------>| +------>| | + * | | +>| | +>| | + * +-----+ | +--+--+ | +-----+ + * | | + * Bias | Bias | + * Layer | Layer | + * +-----+ | +-----+ | + * | | | | | | + * | +-----+ | +-----+ + * | | | | + * +-----+ +-----+ + */ + + FFN > *model = new FFN >; + model->Add >(trainData.n_rows, 8); + model->Add >(); + model->Add >(0.3); + model->Add >(8, 3); + model->Add >(); + + FFN > *model1 = new FFN >; + model1->Add >(trainData.n_rows, 8); + model1->Add >(); + model1->Add >(0.3); + 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); +} + + /** * Train the vanilla network on a larger dataset. */ From 30bb69d9017009f7027fe37c1783d5a07be6185a Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Mon, 9 Nov 2020 01:13:22 +0530 Subject: [PATCH 100/550] Added copy and move constructors to linear3d layer --- src/mlpack/methods/ann/layer/linear3d.hpp | 12 ++++ .../methods/ann/layer/linear3d_impl.hpp | 56 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/mlpack/methods/ann/layer/linear3d.hpp b/src/mlpack/methods/ann/layer/linear3d.hpp index 9562074cf7..a32b694f06 100644 --- a/src/mlpack/methods/ann/layer/linear3d.hpp +++ b/src/mlpack/methods/ann/layer/linear3d.hpp @@ -54,6 +54,18 @@ class Linear3D const size_t outSize, RegularizerType regularizer = RegularizerType()); + //! Copy constructor. + Linear3D(const Linear3D& layer); + + //! Move constructor. + Linear3D(Linear3D&&); + + //! Copy assignment operator. + Linear3D& operator=(const Linear3D& layer); + + //! Move assignment operator. + Linear3D& operator=(Linear3D&& layer); + /* * Reset the layer parameter. */ diff --git a/src/mlpack/methods/ann/layer/linear3d_impl.hpp b/src/mlpack/methods/ann/layer/linear3d_impl.hpp index 97df023e37..ab7434c6c7 100644 --- a/src/mlpack/methods/ann/layer/linear3d_impl.hpp +++ b/src/mlpack/methods/ann/layer/linear3d_impl.hpp @@ -40,6 +40,62 @@ Linear3D::Linear3D( weights.set_size(outSize * inSize + outSize, 1); } +template +Linear3D::Linear3D( + const Linear3D& layer) : + inSize(layer.inSize), + outSize(layer.outSize), + weights(layer.weights), + regularizer(layer.regularizer) +{ + // Nothing to do here. +} + +template +Linear3D::Linear3D( + Linear3D&& layer) : + inSize(0), + outSize(0), + weights(std::move(layer.weights)), + regularizer(std::move(layer.regularizer)); +{ + // Nothing to do here. +} + +template +Linear3D& +Linear3D:: +operator=(const Linear3D& layer) +{ + if (this != &layer) + { + inSize = layer.inSize; + outSize = layer.outSize; + weights = layer.weights; + regularizer = layer.regularizer; + } + return *this; +} + +template +Linear3D& +Linear3D:: +operator=(Linear3D&& layer) +P + if (this != &layer) + { + inSize = 0; + outSize = 0; + weights = std::move(layer.weights); + regularizer = std::move(layer.regularizer); + } + return *this; +} + template void Linear3D::Reset() From 836b3efa9628edb71900d46dbfb7c1e24b4c9397 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 8 Nov 2020 19:36:24 -0500 Subject: [PATCH 101/550] Surely it's not that I just have to specify it as a directory? --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 47e85a6b45..fb40fe895e 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -177,7 +177,7 @@ steps: dir type fragment.wxs & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - -dHarvestPath=.\SourceDir ` + -dHarvestPath=.\SourceDir\ ` -dConfiguration=Release ` -dOutDir=bin\x64\Release\ ` -dPlatform=x64 ` From 591665fa5d8071977748f2c0097b1c1d71748d2a Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Mon, 9 Nov 2020 14:40:02 +0530 Subject: [PATCH 102/550] Updated all matrix and vector initializations to use c++11 braced initializer --- src/mlpack/tests/binarize_test.cpp | 12 +- src/mlpack/tests/convolution_test.cpp | 132 ++++++++-------- src/mlpack/tests/cv_test.cpp | 6 +- src/mlpack/tests/decision_stump_test.cpp | 73 ++++----- src/mlpack/tests/det_test.cpp | 142 +++++++++--------- src/mlpack/tests/distribution_test.cpp | 9 +- src/mlpack/tests/facilities_test.cpp | 6 +- src/mlpack/tests/linear_regression_test.cpp | 8 +- src/mlpack/tests/logistic_regression_test.cpp | 6 +- src/mlpack/tests/lsh_test.cpp | 29 ++-- .../main_tests/logistic_regression_test.cpp | 30 ++-- .../tests/main_tests/perceptron_test.cpp | 10 +- src/mlpack/tests/maximal_inputs_test.cpp | 24 ++- src/mlpack/tests/perceptron_test.cpp | 62 ++++---- src/mlpack/tests/recurrent_network_test.cpp | 16 +- 15 files changed, 273 insertions(+), 292 deletions(-) diff --git a/src/mlpack/tests/binarize_test.cpp b/src/mlpack/tests/binarize_test.cpp index 8991515724..ba17f31787 100644 --- a/src/mlpack/tests/binarize_test.cpp +++ b/src/mlpack/tests/binarize_test.cpp @@ -23,9 +23,9 @@ using namespace mlpack::data; TEST_CASE("BinarizeOneDimension", "[BinarizeTest]") { mat input; - input << 1 << 2 << 3 << endr - << 4 << 5 << 6 << endr // this row will be tested - << 7 << 8 << 9; + input = { {1, 2, 3}, + {4, 5, 6}, // this row will be tested + {7, 8, 9} }; mat output; const double threshold = 5.0; @@ -46,9 +46,9 @@ TEST_CASE("BinarizeOneDimension", "[BinarizeTest]") TEST_CASE("BinerizeAll", "[BinarizeTest]") { mat input; - input << 1 << 2 << 3 << endr - << 4 << 5 << 6 << endr // this row will be tested - << 7 << 8 << 9; + input = { {1, 2, 3}, + {4, 5, 6}, // this row will be tested + {7, 8, 9} }; mat output; const double threshold = 5.0; diff --git a/src/mlpack/tests/convolution_test.cpp b/src/mlpack/tests/convolution_test.cpp index f60b8cf033..0b6023e4be 100644 --- a/src/mlpack/tests/convolution_test.cpp +++ b/src/mlpack/tests/convolution_test.cpp @@ -124,17 +124,17 @@ TEST_CASE("ValidConvolution2DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input << 1 << 2 << 3 << 4 << arma::endr - << 4 << 1 << 2 << 3 << arma::endr - << 3 << 4 << 1 << 2 << arma::endr - << 2 << 3 << 4 << 1; + input = { {1, 2, 3, 4}, + {4, 1, 2, 3}, + {3, 4, 1, 2}, + {2, 3, 4, 1} }; - filter << 1 << 0 << -1 << arma::endr - << 0 << 1 << 0 << arma::endr - << -1 << 0 << 1; + filter = { {1, 0, -1}, + {0, 1, 0}, + {-1, 0, 1} }; - output << -3 << -2 << arma::endr - << 8 << -3; + output = { {-3, -2}, + {8, -3} }; // Perform the naive convolution approach. Convolution2DMethodTest >(input, filter, @@ -157,21 +157,21 @@ TEST_CASE("FullConvolution2DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input << 1 << 2 << 3 << 4 << arma::endr - << 4 << 1 << 2 << 3 << arma::endr - << 3 << 4 << 1 << 2 << arma::endr - << 2 << 3 << 4 << 1; + input = { {1, 2, 3, 4}, + {4, 1, 2, 3}, + {3, 4, 1, 2}, + {2, 3, 4, 1} }; - filter << 1 << 0 << -1 << arma::endr - << 1 << 1 << 1 << arma::endr - << -1 << 0 << 1; + filter = { {1, 0, -1}, + {1, 1, 1} + {-1, 0, 1} }; - output << 1 << 2 << 2 << 2 << -3 << -4 << arma::endr - << 5 << 4 << 4 << 11 << 5 << 1 << arma::endr - << 6 << 7 << 3 << 2 << 7 << 5 << arma::endr - << 1 << 9 << 12 << 3 << 1 << 4 << arma::endr - << -1 << 1 << 11 << 10 << 6 << 3 << arma::endr - << -2 << -3 << -2 << 2 << 4 << 1; + output = { {1, 2, 2, 2, -3, -4}, + {5, 4, 4, 11, 5, 1}, + {6, 7, 3, 2, 7, 5}, + {1, 9, 12, 3, 1, 4}, + {-1, 1, 11, 10, 6, 3}, + {-2, -3, -2, 2, 4, 1} }; // Perform the naive convolution approach. Convolution2DMethodTest >(input, filter, @@ -194,17 +194,17 @@ TEST_CASE("ValidConvolution3DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input << 1 << 2 << 3 << 4 << arma::endr - << 4 << 1 << 2 << 3 << arma::endr - << 3 << 4 << 1 << 2 << arma::endr - << 2 << 3 << 4 << 1; + input = { {1, 2, 3, 4}, + {4, 1, 2, 3}, + {3, 4, 1, 2}, + {2, 3, 4, 1} }; - filter << 1 << 0 << -1 << arma::endr - << 0 << 1 << 0 << arma::endr - << -1 << 0 << 1; + filter = { {1, 0, -1}, + {0, 1, 0}, + {-1, 0, 1} }; - output << -3 << -2 << arma::endr - << 8 << -3; + output = { {-3, -2}, + {8, -3} }; arma::cube inputCube(input.n_rows, input.n_cols, 2); inputCube.slice(0) = input; @@ -239,21 +239,21 @@ TEST_CASE("FullConvolution3DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input << 1 << 2 << 3 << 4 << arma::endr - << 4 << 1 << 2 << 3 << arma::endr - << 3 << 4 << 1 << 2 << arma::endr - << 2 << 3 << 4 << 1; + input = { {1, 2, 3, 4}, + {4, 1, 2, 3}, + {3, 4, 1, 2}, + {2, 3, 4, 1} }; - filter << 1 << 0 << -1 << arma::endr - << 1 << 1 << 1 << arma::endr - << -1 << 0 << 1; + filter = { {1, 0, -1}, + {1, 1, 1}, + {-1, 0, 1} }; - output << 1 << 2 << 2 << 2 << -3 << -4 << arma::endr - << 5 << 4 << 4 << 11 << 5 << 1 << arma::endr - << 6 << 7 << 3 << 2 << 7 << 5 << arma::endr - << 1 << 9 << 12 << 3 << 1 << 4 << arma::endr - << -1 << 1 << 11 << 10 << 6 << 3 << arma::endr - << -2 << -3 << -2 << 2 << 4 << 1; + output = { {1, 2, 2, 2, -3, -4}, + {5, 4, 4, 11, 5, 1}, + {6, 7, 3, 2, 7, 5}, + {1, 9, 12, 3, 1, 4}, + {-1, 1, 11, 10, 6, 3}, + {-2, -3, -2, 2, 4, 1} }; arma::cube inputCube(input.n_rows, input.n_cols, 2); inputCube.slice(0) = input; @@ -289,17 +289,17 @@ TEST_CASE("ValidConvolutionBatchTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input << 1 << 2 << 3 << 4 << arma::endr - << 4 << 1 << 2 << 3 << arma::endr - << 3 << 4 << 1 << 2 << arma::endr - << 2 << 3 << 4 << 1; + input = { {1, 2, 3, 4}, + {4, 1, 2, 3}, + {3, 4, 1, 2}, + {2, 3, 4, 1} }; - filter << 1 << 0 << -1 << arma::endr - << 0 << 1 << 0 << arma::endr - << -1 << 0 << 1; + filter = { {1, 0, -1}, + {0, 1, 0}, + {-1, 0, 1} }; - output << -3 << -2 << arma::endr - << 8 << -3; + output = { {-3, -2}, + {8, -3} }; arma::cube filterCube(filter.n_rows, filter.n_cols, 2); filterCube.slice(0) = filter; @@ -331,21 +331,21 @@ TEST_CASE("FullConvolutionBatchTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input << 1 << 2 << 3 << 4 << arma::endr - << 4 << 1 << 2 << 3 << arma::endr - << 3 << 4 << 1 << 2 << arma::endr - << 2 << 3 << 4 << 1; + input = { {1, 2, 3, 4}, + {4, 1, 2, 3}, + {3, 4, 1, 2}, + {2, 3, 4, 1} }; - filter << 1 << 0 << -1 << arma::endr - << 1 << 1 << 1 << arma::endr - << -1 << 0 << 1; + filter = { {1, 0, -1}, + {1, 1, 1}, + {-1, 0, 1} }; - output << 1 << 2 << 2 << 2 << -3 << -4 << arma::endr - << 5 << 4 << 4 << 11 << 5 << 1 << arma::endr - << 6 << 7 << 3 << 2 << 7 << 5 << arma::endr - << 1 << 9 << 12 << 3 << 1 << 4 << arma::endr - << -1 << 1 << 11 << 10 << 6 << 3 << arma::endr - << -2 << -3 << -2 << 2 << 4 << 1; + output = { {1, 2, 2, 2, -3, -4}, + {5, 4, 4, 11, 5, 1}, + {6, 7, 3, 2, 7, 5}, + {1, 9, 12, 3, 1, 4}, + {-1, 1, 11, 10, 6, 3}, + {-2, -3, -2, 2, 4, 1} }; arma::cube filterCube(filter.n_rows, filter.n_cols, 2); filterCube.slice(0) = filter; diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index 48bb9a6481..a611ce2d4b 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -750,9 +750,9 @@ TEST_CASE("KFoldCVWithDTTestUnevenBinsWeighted", "[CVTest]") TEST_CASE("SilhouetteScoreTest", "[CVTest]") { arma::mat X; - X << 0 << 1 << 1 << 0 << 0 << arma::endr - << 0 << 1 << 2 << 0 << 0 << arma::endr - << 1 << 1 << 3 << 2 << 0 << arma::endr; + X = { {0, 1, 1, 0, 0}, + {0, 1, 2, 0, 0}, + {1, 1, 3, 2, 0} }; arma::Row labels = {0, 1, 2, 0, 0}; metric::EuclideanDistance metric; double silhouetteScore = SilhouetteScore::Overall(X, labels, metric); diff --git a/src/mlpack/tests/decision_stump_test.cpp b/src/mlpack/tests/decision_stump_test.cpp index d2fe36cc08..b250306976 100644 --- a/src/mlpack/tests/decision_stump_test.cpp +++ b/src/mlpack/tests/decision_stump_test.cpp @@ -30,16 +30,16 @@ TEST_CASE("OneClass", "[DecisionStumpTest]") const size_t inpBucketSize = 6; mat trainingData; - trainingData << 2.4 << 3.8 << 3.8 << endr - << 1 << 1 << 2 << endr - << 1.3 << 1.9 << 1.3 << endr; + trainingData = { {2.4, 3.8, 3.8}, + {1, 1, 2}, + {1.3, 1.9, 1.3} }; // No need to normalize labels here. Mat labelsIn; - labelsIn << 1 << 1 << 1; + labelsIn = {1, 1, 1}; mat testingData; - testingData << 2.4 << 2.5 << 2.6; + testingData = {2.4, 2.5, 2.6}; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -65,17 +65,13 @@ TEST_CASE("CorrectDimensionChosen", "[DecisionStumpTest]") // found on page 176 (and a description of the correct splitting dimension is // given below that). mat trainingData; - trainingData << 0 << 0 << 0 << 0 << 0 << 1 << 1 << 1 << 1 - << 2 << 2 << 2 << 2 << 2 << endr - << 70 << 90 << 85 << 95 << 70 << 90 << 78 << 65 << 75 - << 80 << 70 << 80 << 80 << 96 << endr - << 1 << 1 << 0 << 0 << 0 << 1 << 0 << 1 << 0 - << 1 << 1 << 0 << 0 << 0 << endr; + trainingData = { {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2}, + {70, 90, 85, 95, 70, 90, 78, 65, 75, 80, 70, 80, 80, 96}, + {1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0} }; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 1 << 1 << 1 << 0 << 0 << 0 << 0 - << 0 << 1 << 1 << 0 << 0 << 0; + labelsIn = {0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -96,14 +92,14 @@ TEST_CASE("PerfectSplitOnZero", "[DecisionStumpTest]") const size_t inpBucketSize = 2; mat trainingData; - trainingData << -1 << 1 << -2 << 2 << -3 << 3; + trainingData = {-1, 1, -2, 2, -3, 3}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 1 << 0 << 1 << 0 << 1; + labelsIn = {0, 1, 0, 1, 0, 1}; mat testingData; - testingData << -4 << 7 << -7 << -5 << 6; + testingData = {-4, 7, -7, -5, 6}; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -127,14 +123,14 @@ TEST_CASE("BinningTesting", "[DecisionStumpTest]") const size_t inpBucketSize = 10; mat trainingData; - trainingData << -1 << 1 << -2 << 2 << -3 << 3 << -4; + trainingData = {-1, 1, -2, 2, -3, 3, -4}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 1 << 0 << 1 << 0 << 1 << 0; + labelsIn = {0, 1, 0, 1, 0, 1, 0}; mat testingData; - testingData << 5; + testingData = {5}; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -155,16 +151,14 @@ TEST_CASE("PerfectMultiClassSplit", "[DecisionStumpTest]") const size_t inpBucketSize = 3; mat trainingData; - trainingData << -8 << -7 << -6 << -5 << -4 << -3 << -2 << -1 - << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7; + trainingData = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 1 << 1 - << 2 << 2 << 2 << 2 << 3 << 3 << 3 << 3; + labelsIn = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}; mat testingData; - testingData << -6.1 << -2.1 << 1.1 << 5.1; + testingData = {-6.1, -2.1, 1.1, 5.1}; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -189,17 +183,16 @@ TEST_CASE("MultiClassSplit", "[DecisionStumpTest]") const size_t inpBucketSize = 3; mat trainingData; - trainingData << -7 << -6 << -5 << -4 << -3 << -2 << -1 << 0 << 1 - << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10; + trainingData , = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 0 << 0 - << 1 << 1 << 1 << 2 << 1 << 2 << 2 << 2 << 2 << 2; + labelsIn = {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2}; mat testingData; - testingData << -6.1 << -5.9 << -2.1 << -0.7 << 2.5 << 4.7 << 7.2 << 9.1; + testingData = {-6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1}; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -327,17 +320,16 @@ TEST_CASE("EmptyConstructorTest", "[DecisionStumpTest]") // Now train on another dataset and make sure something kind of makes sense. mat trainingData; - trainingData << -7 << -6 << -5 << -4 << -3 << -2 << -1 << 0 << 1 - << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10; + trainingData = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 0 << 0 - << 1 << 1 << 1 << 2 << 1 << 2 << 2 << 2 << 2 << 2; + labelsIn = {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2}; mat testingData; - testingData << -6.1 << -5.9 << -2.1 << -0.7 << 2.5 << 4.7 << 7.2 << 9.1; + testingData = {-6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1}; DecisionStump<> ds(trainingData, labelsIn.row(0), 4, 3); @@ -362,18 +354,17 @@ TEST_CASE("IntTest", "[DecisionStumpTest]") { // Train on a dataset and make sure something kind of makes sense. imat trainingData; - trainingData << -7 << -6 << -5 << -4 << -3 << -2 << -1 << 0 << 1 - << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10; + trainingData = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 0 << 0 << 0 << 1 << 1 << 0 << 0 - << 1 << 1 << 1 << 2 << 1 << 2 << 2 << 2 << 2 << 2; + labelsIn = {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2}; DecisionStump ds(trainingData, labelsIn.row(0), 4, 3); imat testingData; - testingData << -6 << -6 << -2 << -1 << 3 << 5 << 7 << 9; + testingData = {-6, -6, -2, -1, 3, 5, 7, 9}; arma::Row predictedLabels; ds.Classify(testingData, predictedLabels); @@ -397,11 +388,11 @@ TEST_CASE("DecisionStumpTrainReturnEntropy", "[DecisionStumpTest]") const size_t inpBucketSize = 2; mat trainingData; - trainingData << -1 << 1 << -2 << 2 << -3 << 3; + trainingData = {-1, 1, -2, 2, -3, 3}; // No need to normalize labels here. Mat labelsIn; - labelsIn << 0 << 1 << 0 << 1 << 0 << 1; + labelsIn = {0, 1, 0, 1, 0, 1}; arma::Row weights = arma::ones>(labelsIn.n_elem); diff --git a/src/mlpack/tests/det_test.cpp b/src/mlpack/tests/det_test.cpp index c0989768eb..9a5b2b7c68 100644 --- a/src/mlpack/tests/det_test.cpp +++ b/src/mlpack/tests/det_test.cpp @@ -40,9 +40,9 @@ TEST_CASE("TestGetMaxMinVals", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; DTree tree(testData); @@ -81,11 +81,11 @@ TEST_CASE("TestWithinRange", "[DETTest]") DTree testDTree(maxVals, minVals, 5); arma::vec testQuery(3); - testQuery << 4.5 << 2.5 << 2; + testQuery = {4.5, 2.5, 2}; REQUIRE(testDTree.WithinRange(testQuery) == true); - testQuery << 8.5 << 2.5 << 2; + testQuery = {8.5, 2.5, 2}; REQUIRE(testDTree.WithinRange(testQuery) == false); } @@ -94,9 +94,9 @@ TEST_CASE("TestFindSplit", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; DTree testDTree(testData); @@ -124,14 +124,14 @@ TEST_CASE("TestSplitData", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; DTree testDTree(testData); arma::Col oTest(5); - oTest << 1 << 2 << 3 << 4 << 5; + oTest = {1, 2, 3, 4, 5}; size_t splitDim = 2; double trueSplitVal = 5.5; @@ -152,10 +152,10 @@ TEST_CASE("TestSparseFindSplit", "[DETTest]") { arma::mat realData(4, 7); - realData << .0 << 4 << 5 << 7 << 0 << 5 << 0 << arma::endr - << .0 << 5 << 0 << 0 << 1 << 7 << 1 << arma::endr - << .0 << 5 << 6 << 7 << 1 << 0 << 8 << arma::endr - << -1 << 2 << 5 << 0 << 0 << 0 << 0 << arma::endr; + realData = { {.0, 4, 5, 7, 0, 5, 0}, + {.0, 5, 0, 0, 1, 7, 1}, + {.0, 5, 6, 7, 1, 0, 8}, + {-1, 2, 5, 0, 0, 0, 0} }; arma::sp_mat testData(realData); @@ -186,17 +186,17 @@ TEST_CASE("TestSparseSplitData", "[DETTest]") { arma::mat realData(4, 7); - realData << .0 << 4 << 5 << 7 << 0 << 5 << 0 << arma::endr - << .0 << 5 << 0 << 0 << 1 << 7 << 1 << arma::endr - << .0 << 5 << 6 << 7 << 1 << 0 << 8 << arma::endr - << -1 << 2 << 5 << 0 << 0 << 0 << 0 << arma::endr; + realData = { {.0, 4, 5, 7, 0, 5, 0}, + {.0, 5, 0, 0, 1, 7, 1}, + {.0, 5, 6, 7, 1, 0, 8}, + {-1, 2, 5, 0, 0, 0, 0} }; arma::sp_mat testData(realData); DTree testDTree(testData); arma::Col oTest(7); - oTest << 1 << 2 << 3 << 4 << 5 << 6 << 7; + oTest = {1, 2, 3, 4, 5, 6, 7}; size_t splitDim = 1; double trueSplitVal = .5; @@ -223,12 +223,12 @@ TEST_CASE("TestGrow", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; double rootError, lError, rError, rlError, rrError; @@ -289,12 +289,12 @@ TEST_CASE("TestPruneAndUpdate", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); alpha = testDTree.PruneAndUpdate(alpha, testData.n_cols, false); @@ -315,19 +315,19 @@ TEST_CASE("TestComputeValue", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; arma::vec q1(3), q2(3), q3(3), q4(3); - q1 << 4 << 2 << 2; - q2 << 5 << 0.25 << 6; - q3 << 5 << 3 << 7; - q4 << 2 << 3 << 3; + q1 = {4, 2, 2}; + q2 = {5, 0.25, 6}; + q3 = {5, 3, 7}; + q4 = {2, 3, 3; arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); @@ -355,9 +355,9 @@ TEST_CASE("TestVariableImportance", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; double rootError, lError, rError, rlError, rrError; @@ -370,7 +370,7 @@ TEST_CASE("TestVariableImportance", "[DETTest]") rrError = -1.0 * exp(2 * log(2.0 / 5.0) - (log(6.5) + log(4.0) + log(2.5))); arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree testDTree(testData); testDTree.Grow(testData, oTest, false, 2, 1); @@ -390,14 +390,14 @@ TEST_CASE("TestSparsePruneAndUpdate", "[DETTest]") { arma::mat realData(3, 5); - realData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + realData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; arma::sp_mat testData(realData); arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); @@ -419,22 +419,22 @@ TEST_CASE("TestSparseComputeValue", "[DETTest]") { arma::mat realData(3, 5); - realData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + realData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; arma::vec q1d(3), q2d(3), q3d(3), q4d(3); - q1d << 4 << 2 << 2; - q2d << 5 << 0.25 << 6; - q3d << 5 << 3 << 7; - q4d << 2 << 3 << 3; + q1d = {4, 2, 2}; + q2d = {5, 0.25, 6}; + q3d = {5, 3, 7}; + q4d = {2, 3, 3; arma::sp_mat testData(realData); arma::sp_vec q1(q1d), q2(q2d), q3(q3d), q4(q4d); arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); @@ -465,9 +465,9 @@ TEST_CASE("TestTagTree", "[DETTest]") { MatType testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; DTree<>* testDTree = new DTree<>(&testData); @@ -478,9 +478,9 @@ TEST_CASE("TestFindBucket", "[DETTest]") { MatType testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; DTree<>* testDTree = new DTree<>(&testData); @@ -510,13 +510,13 @@ TEST_CASE("CopyConstructorAndOperatorTest", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; // Construct another DTree for testing the children. arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree *testDTree = new DTree(testData); testDTree->Grow(testData, oTest, false, 2, 1); @@ -622,13 +622,13 @@ TEST_CASE("MoveConstructorTest", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; // Construct another DTree for testing the children. arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree *testDTree = new DTree(testData); testDTree->Grow(testData, oTest, false, 2, 1); @@ -705,13 +705,13 @@ TEST_CASE("MoveOperatorTest", "[DETTest]") { arma::mat testData(3, 5); - testData << 4 << 5 << 7 << 3 << 5 << arma::endr - << 5 << 0 << 1 << 7 << 1 << arma::endr - << 5 << 6 << 7 << 1 << 8 << arma::endr; + testData = { {4, 5, 7, 3, 5}, + {5, 0, 1, 7, 1}, + {5, 6, 7, 1, 8} }; // Construct another DTree for testing the children. arma::Col oTest(5); - oTest << 0 << 1 << 2 << 3 << 4; + oTest = {0, 1, 2, 3, 4}; DTree *testDTree = new DTree(testData); testDTree->Grow(testData, oTest, false, 2, 1); diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index ab7d606a9f..5970277da1 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -981,8 +981,8 @@ TEST_CASE("GammaDistributionProbabilityTest", "[DistributionTest]") // Combine into one 2-dimensional distribution. const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); arma::mat x3(2, 2); - x3 << 2.0 << 2.94 << arma::endr - << 2.0 << 2.94; + x3 = { {2.0, 2.94}, + {2.0, 2.94} }; arma::vec prob3; // Expect that the 2-dimensional distribution returns the product of the @@ -1017,9 +1017,8 @@ TEST_CASE("GammaDistributionLogProbabilityTest", "[DistributionTest]") // Combine into one 2-dimensional distribution. const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); arma::mat x3(2, 2); - x3 - << 2.0 << 2.94 << arma::endr - << 2.0 << 2.94; + x3 = { {2.0, 2.94}, + {2.0, 2.94} }; arma::vec logprob3; // Expect that the 2-dimensional distribution returns the product of the diff --git a/src/mlpack/tests/facilities_test.cpp b/src/mlpack/tests/facilities_test.cpp index b50279fe9e..fa5b651338 100644 --- a/src/mlpack/tests/facilities_test.cpp +++ b/src/mlpack/tests/facilities_test.cpp @@ -47,9 +47,9 @@ BOOST_AUTO_TEST_CASE(AssertSizesTest) BOOST_AUTO_TEST_CASE(PairwiseDistanceTest) { arma::mat X; - X << 0 << 1 << 1 << 0 << 0 << arma::endr - << 0 << 1 << 2 << 0 << 0 << arma::endr - << 1 << 1 << 3 << 2 << 0 << arma::endr; + X = { {0, 1, 1, 0, 0}, + {0, 1, 2, 0, 0}, + {1, 1, 3, 2, 0} }; metric::EuclideanDistance metric; arma::mat dist = PairwiseDistances(X, metric); BOOST_REQUIRE_EQUAL(dist(0, 0), 0); diff --git a/src/mlpack/tests/linear_regression_test.cpp b/src/mlpack/tests/linear_regression_test.cpp index 8ec1ed8740..aea8532905 100644 --- a/src/mlpack/tests/linear_regression_test.cpp +++ b/src/mlpack/tests/linear_regression_test.cpp @@ -73,8 +73,8 @@ TEST_CASE("LinearRegressionTestCase", "[LinearRegressionTest]") TEST_CASE("ComputeErrorTest", "[LinearRegressionTest]") { arma::mat predictors; - predictors << 0 << 1 << 2 << 4 << 8 << 16 << arma::endr - << 16 << 8 << 4 << 2 << 1 << 0 << arma::endr; + predictors = { {0, 1, 2, 4, 8, 16}, + {16, 8, 4, 2, 1, 0} }; arma::rowvec responses = "0 2 4 3 8 8"; // http://www.mlpack.org/trac/ticket/298 @@ -92,8 +92,8 @@ TEST_CASE("ComputeErrorPerfectFitTest", "[LinearRegressionTest]") { // Linear regression should perfectly model this dataset. arma::mat predictors; - predictors << 0 << 1 << 2 << 1 << 6 << 2 << arma::endr - << 0 << 1 << 2 << 2 << 2 << 6 << arma::endr; + predictors = { {0, 1, 2, 1, 6, 2}, + {0, 1, 2, 2, 2, 6} }; arma::rowvec responses = "0 2 4 3 8 8"; LinearRegression lr(predictors, responses); diff --git a/src/mlpack/tests/logistic_regression_test.cpp b/src/mlpack/tests/logistic_regression_test.cpp index 38f7a966c8..3b08619216 100644 --- a/src/mlpack/tests/logistic_regression_test.cpp +++ b/src/mlpack/tests/logistic_regression_test.cpp @@ -1011,9 +1011,9 @@ BOOST_AUTO_TEST_CASE(ConstructionThenTraining) arma::mat myMatrix; // Four points, three dimensions. - myMatrix << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr - << 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr - << 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr; + myMatrix = { {0.555950, 0.274690, 0.540605, 0.798938}, + {0.948014, 0.973234, 0.216504, 0.883152}, + {0.023787, 0.675382, 0.231751, 0.450332} }; arma::Row myTargets("1 0 1 0"); diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 49c3f4dde9..0e88ff6aac 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -39,16 +39,16 @@ void GetPointset(const size_t N, arma::mat& rdata) arma::mat c4(d, N / 4, arma::fill::randu); arma::colvec offset1; - offset1 << 0 << arma::endr - << 3 << arma::endr; + offset1 = { {0}, + {3} }; arma::colvec offset2; - offset2 << 3 << arma::endr - << 3 << arma::endr; + offset2 = { {3}, + {3} }; arma::colvec offset4; - offset4 << 3 << arma::endr - << 0 << arma::endr; + offset4 = { {3}, + {0} }; // Spread points in plane. for (size_t p = 0; p < N / 4; ++p) @@ -589,12 +589,14 @@ BOOST_AUTO_TEST_CASE(MultiprobeDeterministicTest) // Construct q1 so it is hashed directly under C2. arma::mat q1; - q1 << 3.9 << arma::endr << 2.99; + q1 = { {3.9}, + {2.99} }; q1 -= offsets; // Construct q2 so it is hashed near the center of C2. arma::mat q2; - q2 << 3.6 << arma::endr << 3.6; + q2 = { {3.6}, + {3.6} }; q2 -= offsets; arma::Mat neighbors; @@ -689,12 +691,11 @@ BOOST_AUTO_TEST_CASE(RecallTestPartiallyCorrect) // be 0 but recall should not be. arma::Mat q2; q2.set_size(k, numQueries); - q2 << - 2 << arma::endr << - 3 << arma::endr << - 4 << arma::endr << - 6 << arma::endr << - 7 << arma::endr; + q2 = { {2}, + {3}, + {4}, + {6}, + {7} }; BOOST_REQUIRE_CLOSE(LSHSearch<>::ComputeRecall(base, q2), 0.6, 0.0001); } diff --git a/src/mlpack/tests/main_tests/logistic_regression_test.cpp b/src/mlpack/tests/main_tests/logistic_regression_test.cpp index cfe24c6b26..e81a695bc3 100644 --- a/src/mlpack/tests/main_tests/logistic_regression_test.cpp +++ b/src/mlpack/tests/main_tests/logistic_regression_test.cpp @@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(LRNoTrainingData) { arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; SetInputParam("labels", std::move(trainY)); @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(LRPridictionSizeCheck) arma::mat trainX = arma::randu(D, N); arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; arma::mat testX = arma::randu(D, M); SetInputParam("training", std::move(trainX)); @@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(LRWrongResponseSizeTest) arma::Row trainY; // Response vector with wrong size. // 8 responses - incorrect size. - trainY << 0 << 0 << 1 << 0 << 1 << 1 << 1 << 0 << arma::endr; + trainY = {0, 0, 1, 0, 1, 1, 1, 0}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(LRModelReload) arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; arma::mat testX = arma::randu(D, M); @@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(LRWrongDimOfTestData) arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; // Test data with wrong dimensionality. arma::mat testX = arma::randu(D-1, N); @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(LRWrongDimOfTestData2) arma::mat trainX = arma::randu(D, N); arma::Row trainY; // 10 responses - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -308,7 +308,7 @@ BOOST_AUTO_TEST_CASE(LRTrainWithMoreThanTwoClasses) arma::Row trainY; // 8 responses containing more than two classes. - trainY << 0 << 1 << 0 << 1 << 2 << 1 << 3 << 1 << arma::endr; + trainY = {0, 1, 0, 1, 2, 1, 3, 1}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(LRNonNegativeMaxIterationTest) arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -356,7 +356,7 @@ BOOST_AUTO_TEST_CASE(LRNonNegativeStepSizeTest) arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(LRNonNegativeToleranceTest) arma::Row trainY; // 10 responses. - trainY << 1 << 1 << 0 << 1 << 0 << 0 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {1, 1, 0, 1, 0, 0, 0, 1, 0, 1}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -405,7 +405,7 @@ BOOST_AUTO_TEST_CASE(LRMaxIterationsChangeTest) arma::Row trainY; // 10 responses. - trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -454,7 +454,7 @@ BOOST_AUTO_TEST_CASE(LRLambdaChangeTest) arma::Row trainY; // 10 responses. - trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -503,7 +503,7 @@ BOOST_AUTO_TEST_CASE(LRStepSizeChangeTest) arma::Row trainY; // 10 responses. - trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -554,7 +554,7 @@ BOOST_AUTO_TEST_CASE(LROptimizerChangeTest) arma::Row trainY; // 10 responses. - trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -606,7 +606,7 @@ BOOST_AUTO_TEST_CASE(LRDecisionBoundaryTest) arma::Row trainY; // 10 responses. - trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr; + trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; arma::mat testX = arma::randu(D, M); diff --git a/src/mlpack/tests/main_tests/perceptron_test.cpp b/src/mlpack/tests/main_tests/perceptron_test.cpp index 025f9f68da..d29e999cc4 100644 --- a/src/mlpack/tests/main_tests/perceptron_test.cpp +++ b/src/mlpack/tests/main_tests/perceptron_test.cpp @@ -308,7 +308,7 @@ BOOST_AUTO_TEST_CASE(PerceptronReTrainWithWrongClasses) arma::Row labelsX2; // 10 responses. - labelsX2 << 0 << 1 << 4 << 1 << 2 << 1 << 0 << 3 << 3 << 0 << endr; + labelsX2 = {0, 1, 4, 1, 2, 1, 0, 3, 3, 0}; // Last column of trainX2 contains the class labels. SetInputParam("training", std::move(trainX2)); @@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(PerceptronWrongDimOfTestData) arma::Row trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << endr; + trainY = {0 , 1, 0, 1, 1, 1, 0, 1, 0, 0}; // Test data with wrong dimensionality. arma::mat testX = arma::randu(D-3, M); @@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE(PerceptronWrongResponseSizeTest) arma::Row trainY; // Response vector with wrong size. // 8 responses. - trainY << 0 << 0 << 1 << 0 << 1 << 1 << 1 << 0 << endr; + trainY = {0, 0, 1, 0, 1, 1, 1, 0}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(PerceptronNoResponsesTest) BOOST_AUTO_TEST_CASE(PerceptronNoTrainingDataTest) { arma::Row trainY; - trainY << 1 << 1 << 0 << 1 << 0 << 0 < trainY; // 10 responses. - trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << endr; + trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); diff --git a/src/mlpack/tests/maximal_inputs_test.cpp b/src/mlpack/tests/maximal_inputs_test.cpp index 8af1d9aaaa..95ce8a1025 100644 --- a/src/mlpack/tests/maximal_inputs_test.cpp +++ b/src/mlpack/tests/maximal_inputs_test.cpp @@ -21,8 +21,8 @@ using namespace mlpack; arma::mat CreateMaximalInput() { arma::mat w1(2, 4); - w1 << 0 << 1 << 2 << 3 << arma::endr - << 4 << 5 << 6 << 7; + w1 = { {0, 1, 2, 3}, + {4, 5, 6, 7} }; arma::mat input(5, 5); input.submat(0, 0, 1, 3) = w1; @@ -53,12 +53,10 @@ BOOST_AUTO_TEST_CASE(ColumnToBlocksEvaluate) ctb.Transform(CreateMaximalInput(), output); arma::mat matlabResults; - matlabResults << -1 << -1 << -1 << -1 << -1 << -1 << -1 << arma::endr - << -1 << -1<< -0.42857 << -1 << 0.14286 << 0.71429 << -1 - << arma::endr - << -1 << -0.71429 << -0.14286 << -1 << 0.42857 << 1 << -1 - << arma::endr - << -1 << -1 << -1 << -1 << -1 << -1 << -1; + matlabResults = { {-1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -0.42857, -1, 0.14286, 0.71429, -1}, + {-1, -0.71429, -0.14286, -1, 0.42857, 1, -1}, + {-1, -1, -1, -1, -1, -1, -1} }; TestResults(output, matlabResults); } @@ -73,12 +71,10 @@ BOOST_AUTO_TEST_CASE(ColumnToBlocksChangeBlockSize) ctb.Transform(CreateMaximalInput(), output); arma::mat matlabResults; - matlabResults<< -3 << -3 << -3 << -3 << -3 - << -3 << -3 << -3 << -3 << -3 << -3 << arma::endr - << -3 << -1 << -0.71429 << -0.42857 << -0.14286 - << -3 << 0.14286 << 0.42857 << 0.71429 << 1 << -3 << arma::endr - << -3 << -3 << -3 << -3 << -3 << -3 << -3 << -3 << -3 << -3 - << -3 << arma::endr; + matlabResults = { {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3} + {-3, -1, -0.71429, -0.42857, -0.14286, -3, 0.14286, + 0.42857, 0.71429, 1, -3}, + {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3} }; TestResults(output, matlabResults); } diff --git a/src/mlpack/tests/perceptron_test.cpp b/src/mlpack/tests/perceptron_test.cpp index bcb64cc9d6..5039c7fbd6 100644 --- a/src/mlpack/tests/perceptron_test.cpp +++ b/src/mlpack/tests/perceptron_test.cpp @@ -110,16 +110,16 @@ TEST_CASE("SimpleWeightUpdateInstanceWeight", "[PerceptronTest]") TEST_CASE("And", "[PerceptronTest]") { mat trainData; - trainData << 0 << 1 << 1 << 0 << endr - << 1 << 0 << 1 << 0 << endr; + trainData = { {0, 1, 1, 0}, + {1, 0, 1, 0} }; Mat labels; - labels << 0 << 0 << 1 << 0; + labels = {0, 0, 1, 0}; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData << 0 << 1 << 1 << 0 << endr - << 1 << 0 << 1 << 0 << endr; + testData = { {0, 1, 1, 0}, + {1, 0, 1, 0} }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -135,17 +135,17 @@ TEST_CASE("And", "[PerceptronTest]") TEST_CASE("Or", "[PerceptronTest]") { mat trainData; - trainData << 0 << 1 << 1 << 0 << endr - << 1 << 0 << 1 << 0 << endr; + trainData = { {0, 1, 1, 0}, + {1, 0, 1, 0} }; Mat labels; - labels << 1 << 1 << 1 << 0; + labels = {1, 1, 1, 0}; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData << 0 << 1 << 1 << 0 << endr - << 1 << 0 << 1 << 0 << endr; + testData = { {0, 1, 1, 0}, + {1, 0, 1, 0} }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -162,17 +162,17 @@ TEST_CASE("Or", "[PerceptronTest]") TEST_CASE("Random3", "[PerceptronTest]") { mat trainData; - trainData << 0 << 1 << 1 << 4 << 5 << 4 << 1 << 2 << 1 << endr - << 1 << 0 << 1 << 1 << 1 << 2 << 4 << 5 << 4 << endr; + trainData = { {0, 1, 1, 4, 5, 4, 1, 2, 1}, + {1, 0, 1, 1, 1, 2, 4, 5, 4} }; Mat labels; - labels << 0 << 0 << 0 << 1 << 1 << 1 << 2 << 2 << 2; + labels = {0, 0, 0, 1, 1, 1, 2, 2, 2}; Perceptron<> p(trainData, labels.row(0), 3, 1000); mat testData; - testData << 0 << 1 << 1 << endr - << 1 << 0 << 1 << endr; + testData = { {0, 1, 1}, + {1, 0, 1} }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -187,17 +187,17 @@ TEST_CASE("Random3", "[PerceptronTest]") TEST_CASE("TwoPoints", "[PerceptronTest]") { mat trainData; - trainData << 0 << 1 << endr - << 1 << 0 << endr; + trainData = { {0, 1}, + {1, 0} }; Mat labels; - labels << 0 << 1; + labels = {0, 1}; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData << 0 << 1 << endr - << 1 << 0 << endr; + testData = { {0, 1}, + {1, 0} }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -212,20 +212,17 @@ TEST_CASE("TwoPoints", "[PerceptronTest]") TEST_CASE("NonLinearlySeparableDataset", "[PerceptronTest]") { mat trainData; - trainData << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 - << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << endr - << 1 << 1 << 1 << 1 << 1 << 1 << 1 << 1 - << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << endr; + trainData = { {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, + {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2} }; Mat labels; - labels << 0 << 0 << 0 << 1 << 0 << 1 << 1 << 1 - << 0 << 0 << 0 << 1 << 0 << 1 << 1 << 1; + labels = {0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData << 3 << 4 << 5 << 6 << endr - << 3 << 2.3 << 1.7 << 1.5 << endr; + testData = { {3, 4, 5, 6}, + {3, 2.3, 1.7, 1.5} }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -238,14 +235,11 @@ TEST_CASE("NonLinearlySeparableDataset", "[PerceptronTest]") TEST_CASE("SecondaryConstructor", "[PerceptronTest]") { mat trainData; - trainData << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 - << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << endr - << 1 << 1 << 1 << 1 << 1 << 1 << 1 << 1 - << 2 << 2 << 2 << 2 << 2 << 2 << 2 << 2 << endr; + trainData = { {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, + {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2} }; Mat labels; - labels << 0 << 0 << 0 << 1 << 0 << 1 << 1 << 1 - << 0 << 0 << 0 << 1 << 0 << 1 << 1 << 1; + labels = {0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}; Perceptron<> p1(trainData, labels.row(0), 2, 1000); diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 5bedcbd3cc..8197fe2dd3 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -309,7 +309,7 @@ template void ReberReverseTranslation(const MatType& translation, char& symbol) { arma::Col symbols; - symbols << 'B' << 'T' << 'S' << 'X' << 'P' << 'V' << 'E' << arma::endr; + symbols = {'B', 'T', 'S', 'X', 'P', 'V', 'E'}; const int idx = arma::as_scalar(arma::find(translation == 1, 1, "first")); symbol = symbols(idx); @@ -324,7 +324,7 @@ void ReberReverseTranslation(const MatType& translation, char& symbol) void ReberTranslation(const char symbol, arma::colvec& translation) { arma::Col symbols; - symbols << 'B' << 'T' << 'S' << 'X' << 'P' << 'V' << 'E' << arma::endr; + symbols = {'B', 'T', 'S', 'X', 'P', 'V', 'E'}; const int idx = arma::as_scalar(arma::find(symbols == symbol, 1, "first")); translation = arma::zeros(7); @@ -464,12 +464,12 @@ arma::Mat GenerateReberGrammarData( // Reber state transition matrix. (The last two columns are the indices to the // next path). arma::Mat transitions; - transitions << 'T' << 'P' << '1' << '2' << arma::endr - << 'X' << 'S' << '3' << '1' << arma::endr - << 'V' << 'T' << '4' << '2' << arma::endr - << 'X' << 'S' << '2' << '5' << arma::endr - << 'P' << 'V' << '3' << '5' << arma::endr - << 'E' << 'E' << '0' << '0' << arma::endr; + transitions = { {'T', 'P', '1', '2'}, + {'X', 'S', '3', '1'}, + {'V', 'T', '4', '2'}, + {'X', 'S', '2', '5'}, + {'P', 'V', '3', '5'}, + {'E', 'E', '0', '0'} }; std::string trainReber, testReber; From 15dbadd71e1daefc5a0d1cc1f3e62a250b9044c8 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Mon, 9 Nov 2020 15:19:35 +0530 Subject: [PATCH 103/550] Fixed typo --- src/mlpack/tests/convolution_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/convolution_test.cpp b/src/mlpack/tests/convolution_test.cpp index 0b6023e4be..7a579568bf 100644 --- a/src/mlpack/tests/convolution_test.cpp +++ b/src/mlpack/tests/convolution_test.cpp @@ -163,7 +163,7 @@ TEST_CASE("FullConvolution2DTest", "[ConvolutionTest]") {2, 3, 4, 1} }; filter = { {1, 0, -1}, - {1, 1, 1} + {1, 1, 1}, {-1, 0, 1} }; output = { {1, 2, 2, 2, -3, -4}, From 341feceae5253ffb02c44208bb4e140aa5d53e28 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Mon, 9 Nov 2020 15:50:42 +0530 Subject: [PATCH 104/550] Fixed another typo --- src/mlpack/tests/decision_stump_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/decision_stump_test.cpp b/src/mlpack/tests/decision_stump_test.cpp index b250306976..debdf1586f 100644 --- a/src/mlpack/tests/decision_stump_test.cpp +++ b/src/mlpack/tests/decision_stump_test.cpp @@ -183,7 +183,7 @@ TEST_CASE("MultiClassSplit", "[DecisionStumpTest]") const size_t inpBucketSize = 3; mat trainingData; - trainingData , = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + trainingData = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // No need to normalize labels here. From 8070f12e6e242168d0becfb272e021c5e5824c71 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Mon, 9 Nov 2020 17:53:04 +0530 Subject: [PATCH 105/550] Fixed some typos and changed initializer in columns_to_blocks.hpp --- src/mlpack/tests/det_test.cpp | 4 ++-- src/mlpack/tests/lsh_test.cpp | 18 +++++++++--------- src/mlpack/tests/maximal_inputs_test.cpp | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/mlpack/tests/det_test.cpp b/src/mlpack/tests/det_test.cpp index 9a5b2b7c68..c3f6170c9c 100644 --- a/src/mlpack/tests/det_test.cpp +++ b/src/mlpack/tests/det_test.cpp @@ -324,7 +324,7 @@ TEST_CASE("TestComputeValue", "[DETTest]") q1 = {4, 2, 2}; q2 = {5, 0.25, 6}; q3 = {5, 3, 7}; - q4 = {2, 3, 3; + q4 = {2, 3, 3}; arma::Col oTest(5); oTest = {0, 1, 2, 3, 4}; @@ -428,7 +428,7 @@ TEST_CASE("TestSparseComputeValue", "[DETTest]") q1d = {4, 2, 2}; q2d = {5, 0.25, 6}; q3d = {5, 3, 7}; - q4d = {2, 3, 3; + q4d = {2, 3, 3}; arma::sp_mat testData(realData); arma::sp_vec q1(q1d), q2(q2d), q3(q3d), q4(q4d); diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 0e88ff6aac..0bdae315dc 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -589,14 +589,14 @@ BOOST_AUTO_TEST_CASE(MultiprobeDeterministicTest) // Construct q1 so it is hashed directly under C2. arma::mat q1; - q1 = { {3.9}, - {2.99} }; + q1 << 3.9 << arma::endr + << 2.99 << arma::endr; q1 -= offsets; // Construct q2 so it is hashed near the center of C2. arma::mat q2; - q2 = { {3.6}, - {3.6} }; + q2 << 3.6 << arma::endr + << 3.6 << arma::endr; q2 -= offsets; arma::Mat neighbors; @@ -691,11 +691,11 @@ BOOST_AUTO_TEST_CASE(RecallTestPartiallyCorrect) // be 0 but recall should not be. arma::Mat q2; q2.set_size(k, numQueries); - q2 = { {2}, - {3}, - {4}, - {6}, - {7} }; + q2 << 2 << arma::endr + << 3 << arma::endr + << 4 << arma::endr + << 6 << arma::endr + << 7 << arma::endr; BOOST_REQUIRE_CLOSE(LSHSearch<>::ComputeRecall(base, q2), 0.6, 0.0001); } diff --git a/src/mlpack/tests/maximal_inputs_test.cpp b/src/mlpack/tests/maximal_inputs_test.cpp index 95ce8a1025..57b6136135 100644 --- a/src/mlpack/tests/maximal_inputs_test.cpp +++ b/src/mlpack/tests/maximal_inputs_test.cpp @@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(ColumnToBlocksChangeBlockSize) ctb.Transform(CreateMaximalInput(), output); arma::mat matlabResults; - matlabResults = { {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3} + matlabResults = { {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, {-3, -1, -0.71429, -0.42857, -0.14286, -3, 0.14286, 0.42857, 0.71429, 1, -3}, {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3} }; From d39590accae9779d43598250442aa06071888b16 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 9 Nov 2020 09:24:20 -0500 Subject: [PATCH 106/550] Try letting MSBuild build the whole thing. --- .ci/windows-steps.yaml | 52 +++----------- .../mlpack-win-installer/Product.wxs | 70 ++++++++----------- .../mlpack-win-installer.wixproj | 21 +++--- 3 files changed, 47 insertions(+), 96 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index fb40fe895e..8d19763bb3 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -159,51 +159,15 @@ steps: { $env:INSTALL_VERSION = $env:MLPACK_VERSION; } + # Build the MSI installer. - dir - cd dist\win-installer\mlpack-win-installer - dir - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\heat.exe' dir SourceDir ` - -dr INSTALLFOLDER ` - -ag ` - -cg DynamicFragment ` - -ke ` - -srd ` - -sreg ` - -sfrag ` - -nologo ` - -out fragment.wxs - dir SourceDir - dir - type fragment.wxs - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe' ` - -dHarvestPath=.\SourceDir\ ` - -dConfiguration=Release ` - -dOutDir=bin\x64\Release\ ` - -dPlatform=x64 ` - -dProjectDir=. ` - -dProjectExt=.wixproj ` - -dProjectFileName=mlpack-win-installer.wixproj ` - -dProjectName=mlpack-win-installer ` - -dProjectPath=mlpack-win-installer.wixproj ` - -dTargetDir=.\bin\x64\Release\ ` - -dTargetExt=.msi ` - -dTargetFileName=mlpack-windows.msi ` - -dTargetName=mlpack-windows ` - -dTargetPath=.\bin\x64\Release\mlpack-windows.msi ` - -out obj/x64/Release/ ` - -arch x64 ` - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" ` - Product.wxs fragment.wxs - dir - & 'C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe' ` - -b SourceDir ` - mlpack-win-installer.wixproj ` - obj/x64/Release/Product.wixobj ` - obj\x64\Release\fragment.wixobj ` - -out ./bin/x64/Release/mlpack-%INSTALL_VERSION%.msi ` - -loc mlpack-localization.wxl ` - -ext "C:\Program Files (x86)\WiX Toolset v3.11\bin\\WixUIExtension.dll" + dir 'C:\Program Files (x86)\' + dir 'C:\Program Files (x86)\MSBuild\' + & 'C:\Program Files (x86)\MSBuild\15.0\Bin\MSBuild.exe' ` + -t:rebuild + -p:Configuration=Release ` + -p:TreatWarningsAsErrors=True ` + mlpack-win-installer.wixproj displayName: 'Build MSI Windows installer' # Publish artifacts to Azure Pipelines diff --git a/dist/win-installer/mlpack-win-installer/Product.wxs b/dist/win-installer/mlpack-win-installer/Product.wxs index 4adafc2a23..f05d12eff4 100644 --- a/dist/win-installer/mlpack-win-installer/Product.wxs +++ b/dist/win-installer/mlpack-win-installer/Product.wxs @@ -2,47 +2,39 @@ - - - + + - - - + + - - - - $(env.MLPACK_VERSION) - - - - - - + + + + + + + - - - - - - - - - - - - - - + + + + + $(env.MLPACK_VERSION) + + + + + + diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index b82fa1b8f1..16d0572fb6 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -33,27 +33,22 @@ - - - + + SourcesDir + Sources + var.SourcesDir + $(WixExtDir)\WixUIExtension.dll WixUIExtension + + + - - - - - From d964c1773793ec855f2e588401a4f1adb6ac6727 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 9 Nov 2020 17:44:20 -0500 Subject: [PATCH 107/550] Try a different path for MSBuild. --- .ci/windows-steps.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 8d19763bb3..61200a5f24 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -163,7 +163,10 @@ steps: # Build the MSI installer. dir 'C:\Program Files (x86)\' dir 'C:\Program Files (x86)\MSBuild\' - & 'C:\Program Files (x86)\MSBuild\15.0\Bin\MSBuild.exe' ` + dir 'C:\Program Files (x86)\MSBuild\15.0\' + dir 'C:\Program Files (x86)\MSBuild\15.0\Bin\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\' + & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild -p:Configuration=Release ` -p:TreatWarningsAsErrors=True ` From e188a1add693bbe62fa9636ac536bf68013eac62 Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Tue, 10 Nov 2020 12:53:10 +0530 Subject: [PATCH 108/550] Added WeightSize() to transposed convolution --- src/mlpack/methods/ann/layer/transposed_convolution.hpp | 6 ++++++ .../methods/ann/layer/transposed_convolution_impl.hpp | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/transposed_convolution.hpp b/src/mlpack/methods/ann/layer/transposed_convolution.hpp index a7a89b1dbc..87644ad7e9 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution.hpp @@ -274,6 +274,12 @@ class TransposedConvolution //! Modify the right padding width. size_t& PadWRight() { return padWRight; } + //! Get the size of the weight matrix. + size_t WeightSize() const + { + return (outSize * inSize * kernelWidth * kernelHeight) + outSize; + } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp b/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp index 03770c9095..5a63a097f5 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp @@ -124,8 +124,8 @@ TransposedConvolution< outputWidth(outputWidth), outputHeight(outputHeight) { - weights.set_size((outSize * inSize * kernelWidth * kernelHeight) + outSize, - 1); + weights.set_size(WeightSize(), 1); + // Transform paddingType to lowercase. std::string paddingTypeLow = paddingType; util::ToLower(paddingType, paddingTypeLow); From 9a7a773512e999e623cdfc63f6bd7484bc92d847 Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Tue, 10 Nov 2020 13:48:04 +0530 Subject: [PATCH 109/550] Added WeightSize() to c_relu, celu, leaky_relu, noisy_linear --- src/mlpack/methods/ann/layer/c_relu.hpp | 3 +++ src/mlpack/methods/ann/layer/celu.hpp | 3 +++ src/mlpack/methods/ann/layer/leaky_relu.hpp | 3 +++ src/mlpack/methods/ann/layer/noisylinear.hpp | 3 +++ src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 2 +- src/mlpack/methods/ann/layer/parametric_relu.hpp | 3 +++ src/mlpack/methods/ann/layer/parametric_relu_impl.hpp | 2 +- 7 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/c_relu.hpp b/src/mlpack/methods/ann/layer/c_relu.hpp index da317918ae..365111a7d7 100644 --- a/src/mlpack/methods/ann/layer/c_relu.hpp +++ b/src/mlpack/methods/ann/layer/c_relu.hpp @@ -88,6 +88,9 @@ class CReLU //! Modify the delta. OutputDataType& Delta() { return delta; } + //! Get size of weights. + size_t WeightSize() const { return 0; } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/celu.hpp b/src/mlpack/methods/ann/layer/celu.hpp index 45bdc01321..ae508703ad 100644 --- a/src/mlpack/methods/ann/layer/celu.hpp +++ b/src/mlpack/methods/ann/layer/celu.hpp @@ -111,6 +111,9 @@ class CELU //! Modify the value of deterministic parameter. bool& Deterministic() { return deterministic; } + //! Get size of weights. + size_t WeightSize() { return 0; } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/leaky_relu.hpp b/src/mlpack/methods/ann/layer/leaky_relu.hpp index a8c9f5e591..52b2896fca 100644 --- a/src/mlpack/methods/ann/layer/leaky_relu.hpp +++ b/src/mlpack/methods/ann/layer/leaky_relu.hpp @@ -90,6 +90,9 @@ class LeakyReLU //! Modify the non zero gradient. double& Alpha() { return alpha; } + //! Get size of weights. + size_t WeightSize() const { return 0; } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/noisylinear.hpp b/src/mlpack/methods/ann/layer/noisylinear.hpp index 34ca70193b..e41b6522af 100644 --- a/src/mlpack/methods/ann/layer/noisylinear.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear.hpp @@ -133,6 +133,9 @@ class NoisyLinear //! Modify the bias weights of the layer. arma::mat& Bias() { return bias; } + //! Get size of weights. + size_t WeightSize() const { return (outSize * inSize + outSize) * 2; } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index 82a3a35fc6..529c34a668 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -43,7 +43,7 @@ NoisyLinear::NoisyLinear( inSize(inSize), outSize(outSize) { - weights.set_size((outSize * inSize + outSize) * 2, 1); + weights.set_size(WeightSize(), 1); weightEpsilon.set_size(outSize, inSize); biasEpsilon.set_size(outSize, 1); } diff --git a/src/mlpack/methods/ann/layer/parametric_relu.hpp b/src/mlpack/methods/ann/layer/parametric_relu.hpp index 728b6c5db9..f40be33b2a 100644 --- a/src/mlpack/methods/ann/layer/parametric_relu.hpp +++ b/src/mlpack/methods/ann/layer/parametric_relu.hpp @@ -119,6 +119,9 @@ class PReLU //! Modify the non zero gradient. double& Alpha() { return alpha(0); } + //! Get size of weights. + size_t WeightSize() const { return 1; } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/parametric_relu_impl.hpp b/src/mlpack/methods/ann/layer/parametric_relu_impl.hpp index 2650c5d863..6636e776b7 100644 --- a/src/mlpack/methods/ann/layer/parametric_relu_impl.hpp +++ b/src/mlpack/methods/ann/layer/parametric_relu_impl.hpp @@ -25,7 +25,7 @@ template PReLU::PReLU( const double userAlpha) : userAlpha(userAlpha) { - alpha.set_size(1, 1); + alpha.set_size(WeightSize(), 1); alpha(0) = userAlpha; } From 04f767b207b96da4c888b579f3091bbca077b633 Mon Sep 17 00:00:00 2001 From: NippunSharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 10 Nov 2020 16:45:50 +0530 Subject: [PATCH 110/550] Update src/mlpack/methods/ann/layer/noisylinear.hpp Co-authored-by: Anush Kini <33577829+Abilityguy@users.noreply.github.com> --- src/mlpack/methods/ann/layer/noisylinear.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear.hpp b/src/mlpack/methods/ann/layer/noisylinear.hpp index e41b6522af..78af47b83f 100644 --- a/src/mlpack/methods/ann/layer/noisylinear.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear.hpp @@ -135,7 +135,6 @@ class NoisyLinear //! Get size of weights. size_t WeightSize() const { return (outSize * inSize + outSize) * 2; } - /** * Serialize the layer */ From 2cea4e7e3be1e1958f3dca1723ad570b0a3acf75 Mon Sep 17 00:00:00 2001 From: NippunSharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 10 Nov 2020 16:46:07 +0530 Subject: [PATCH 111/550] Update src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp Co-authored-by: Anush Kini <33577829+Abilityguy@users.noreply.github.com> --- src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp b/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp index 5a63a097f5..47cf2cd6c8 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution_impl.hpp @@ -125,7 +125,6 @@ TransposedConvolution< outputHeight(outputHeight) { weights.set_size(WeightSize(), 1); - // Transform paddingType to lowercase. std::string paddingTypeLow = paddingType; util::ToLower(paddingType, paddingTypeLow); From 38994240c4fb995d97f8ff4b43d3a0476fc07bfb Mon Sep 17 00:00:00 2001 From: NippunSharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 10 Nov 2020 16:46:23 +0530 Subject: [PATCH 112/550] Update src/mlpack/methods/ann/layer/transposed_convolution.hpp Co-authored-by: Anush Kini <33577829+Abilityguy@users.noreply.github.com> --- src/mlpack/methods/ann/layer/transposed_convolution.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/transposed_convolution.hpp b/src/mlpack/methods/ann/layer/transposed_convolution.hpp index 87644ad7e9..04ec5c7cc5 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution.hpp @@ -279,7 +279,6 @@ class TransposedConvolution { return (outSize * inSize * kernelWidth * kernelHeight) + outSize; } - /** * Serialize the layer. */ From 70ba3ad131b7fe7be8613e771252eb725c6d0f89 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 10 Nov 2020 21:06:54 +0530 Subject: [PATCH 113/550] added tests for transposed_conv and noisy_linear --- src/mlpack/tests/ann_visitor_test.cpp | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index f42a0a367e..030b9f8c0a 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -186,3 +186,36 @@ TEST_CASE("WeightSizeVisitorTestForBatchNormLayer", "[ANNVisitorTest]") LayerTypes<> batchNorm = new BatchNorm<>(randomSize); CheckCorrectnessOfWeightSize(batchNorm); } + +/** + * Test that WeightSizeVisitor works properly for Transposed Convolution layer. + */ +TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") +{ + size_t randomInSize = arma::randi(arma::distr_param(1, 100)); + size_t randomOutSize = arma::randi(arma::distr_param(1, 100)); + size_t randomKernelWidth = arma::randi(arma::distr_param(1, 100)); + size_t randomKernelHeight = arma::randi(arma::distr_param(1, 100)); + + LayerTypes<> transposedConvLayer = new TransposedConvolution<>(randomInSize, randomOutSize, + randomKernelWidth, randomKernelHeight); + + size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), transposedConvLayer); + + CheckCorrectnessOfWeightSize(transposedConvLayer); +} + +/** + * Test that WeightSizeVisitor works properly for noisy linear layer. + */ +TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") +{ + size_t randomInSize = arma::randi(arma::distr_param(1, 100)); + size_t randomOutSize = arma::randi(arma::distr_param(1, 100)); + + LayerTypes<> noisyLinearLayer = new NoisyLinear<>(randomInSize, randomOutSize); + + size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), noisyLinearLayer); + + CheckCorrectnessOfWeightSize(noisyLinearLayer); +} \ No newline at end of file From 110d481ca7bd5c26a008a39414382349df79b235 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 10 Nov 2020 21:16:50 +0530 Subject: [PATCH 114/550] fixed style --- src/mlpack/tests/ann_visitor_test.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index 030b9f8c0a..2757bca23e 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -197,10 +197,11 @@ TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") size_t randomKernelWidth = arma::randi(arma::distr_param(1, 100)); size_t randomKernelHeight = arma::randi(arma::distr_param(1, 100)); - LayerTypes<> transposedConvLayer = new TransposedConvolution<>(randomInSize, randomOutSize, - randomKernelWidth, randomKernelHeight); - - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), transposedConvLayer); + LayerTypes<> transposedConvLayer = new TransposedConvolution<>(randomInSize, + randomOutSize, randomKernelWidth, randomKernelHeight); + + size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), + transposedConvLayer); CheckCorrectnessOfWeightSize(transposedConvLayer); } @@ -213,9 +214,11 @@ TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") size_t randomInSize = arma::randi(arma::distr_param(1, 100)); size_t randomOutSize = arma::randi(arma::distr_param(1, 100)); - LayerTypes<> noisyLinearLayer = new NoisyLinear<>(randomInSize, randomOutSize); + LayerTypes<> noisyLinearLayer = new NoisyLinear<>(randomInSize, + randomOutSize); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), noisyLinearLayer); + size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), + noisyLinearLayer); CheckCorrectnessOfWeightSize(noisyLinearLayer); -} \ No newline at end of file +} From 40be199ed781ab0022dd8ec530a5b97795ac95ff Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 10 Nov 2020 21:20:56 +0530 Subject: [PATCH 115/550] fixed style 2 --- src/mlpack/tests/ann_visitor_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index 2757bca23e..be37b4fda6 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -197,10 +197,10 @@ TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") size_t randomKernelWidth = arma::randi(arma::distr_param(1, 100)); size_t randomKernelHeight = arma::randi(arma::distr_param(1, 100)); - LayerTypes<> transposedConvLayer = new TransposedConvolution<>(randomInSize, + LayerTypes<> transposedConvLayer = new TransposedConvolution<>(randomInSize, randomOutSize, randomKernelWidth, randomKernelHeight); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), + size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), transposedConvLayer); CheckCorrectnessOfWeightSize(transposedConvLayer); @@ -214,10 +214,10 @@ TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") size_t randomInSize = arma::randi(arma::distr_param(1, 100)); size_t randomOutSize = arma::randi(arma::distr_param(1, 100)); - LayerTypes<> noisyLinearLayer = new NoisyLinear<>(randomInSize, + LayerTypes<> noisyLinearLayer = new NoisyLinear<>(randomInSize, randomOutSize); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), + size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), noisyLinearLayer); CheckCorrectnessOfWeightSize(noisyLinearLayer); From 6914e7b69d62c9bf8246400aab4f534229dc3799 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 11 Nov 2020 00:19:34 +0530 Subject: [PATCH 116/550] Made the spacing and columns consistent --- src/mlpack/core/math/columns_to_blocks.hpp | 8 +- src/mlpack/tests/binarize_test.cpp | 6 +- src/mlpack/tests/convolution_test.cpp | 132 ++++++++--------- src/mlpack/tests/cv_test.cpp | 8 +- src/mlpack/tests/decision_stump_test.cpp | 62 ++++---- src/mlpack/tests/det_test.cpp | 138 +++++++++--------- src/mlpack/tests/distribution_test.cpp | 8 +- src/mlpack/tests/facilities_test.cpp | 6 +- src/mlpack/tests/linear_regression_test.cpp | 8 +- src/mlpack/tests/logistic_regression_test.cpp | 6 +- src/mlpack/tests/lsh_test.cpp | 26 ++-- .../main_tests/logistic_regression_test.cpp | 30 ++-- .../tests/main_tests/perceptron_test.cpp | 10 +- src/mlpack/tests/maximal_inputs_test.cpp | 18 ++- src/mlpack/tests/perceptron_test.cpp | 56 +++---- src/mlpack/tests/recurrent_network_test.cpp | 18 +-- 16 files changed, 271 insertions(+), 269 deletions(-) diff --git a/src/mlpack/core/math/columns_to_blocks.hpp b/src/mlpack/core/math/columns_to_blocks.hpp index de482ee573..1b94a20679 100644 --- a/src/mlpack/core/math/columns_to_blocks.hpp +++ b/src/mlpack/core/math/columns_to_blocks.hpp @@ -66,10 +66,10 @@ namespace math { * @code * // This matrix has two columns. * arma::mat input; - * input << -1.0000 << 0.1429 << arma::endr - * << -0.7143 << 0.4286 << arma::endr - * << -0.4286 << 0.7143 << arma::endr - * << -0.1429 << 1.0000 << arma::endr; + * input = { {-1.0000, 0.1429}, + * {-0.7143, 0.4286}, + * {-0.4286, 0.7143}, + * {-0.1429, 1.0000} }; * * arma::mat output; * ColumnsToBlocks ctb(1, 2); diff --git a/src/mlpack/tests/binarize_test.cpp b/src/mlpack/tests/binarize_test.cpp index ba17f31787..f90fb0ad19 100644 --- a/src/mlpack/tests/binarize_test.cpp +++ b/src/mlpack/tests/binarize_test.cpp @@ -46,9 +46,9 @@ TEST_CASE("BinarizeOneDimension", "[BinarizeTest]") TEST_CASE("BinerizeAll", "[BinarizeTest]") { mat input; - input = { {1, 2, 3}, - {4, 5, 6}, // this row will be tested - {7, 8, 9} }; + input = { { 1, 2, 3 }, + { 4, 5, 6 }, // this row will be tested + { 7, 8, 9 } }; mat output; const double threshold = 5.0; diff --git a/src/mlpack/tests/convolution_test.cpp b/src/mlpack/tests/convolution_test.cpp index 7a579568bf..02d3cd800d 100644 --- a/src/mlpack/tests/convolution_test.cpp +++ b/src/mlpack/tests/convolution_test.cpp @@ -124,17 +124,17 @@ TEST_CASE("ValidConvolution2DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input = { {1, 2, 3, 4}, - {4, 1, 2, 3}, - {3, 4, 1, 2}, - {2, 3, 4, 1} }; + input = { { 1, 2, 3, 4 }, + { 4, 1, 2, 3 }, + { 3, 4, 1, 2 }, + { 2, 3, 4, 1 } }; - filter = { {1, 0, -1}, - {0, 1, 0}, - {-1, 0, 1} }; + filter = { { 1, 0, -1 }, + { 0, 1, 0 }, + { -1, 0, 1 } }; - output = { {-3, -2}, - {8, -3} }; + output = { { -3, -2 }, + { 8, -3 } }; // Perform the naive convolution approach. Convolution2DMethodTest >(input, filter, @@ -157,21 +157,21 @@ TEST_CASE("FullConvolution2DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input = { {1, 2, 3, 4}, - {4, 1, 2, 3}, - {3, 4, 1, 2}, - {2, 3, 4, 1} }; + input = { { 1, 2, 3, 4 }, + { 4, 1, 2, 3 }, + { 3, 4, 1, 2 }, + { 2, 3, 4, 1 } }; - filter = { {1, 0, -1}, - {1, 1, 1}, - {-1, 0, 1} }; + filter = { { 1, 0, -1 }, + { 1, 1, 1 }, + { -1, 0, 1 } }; - output = { {1, 2, 2, 2, -3, -4}, - {5, 4, 4, 11, 5, 1}, - {6, 7, 3, 2, 7, 5}, - {1, 9, 12, 3, 1, 4}, - {-1, 1, 11, 10, 6, 3}, - {-2, -3, -2, 2, 4, 1} }; + output = { { 1, 2, 2, 2, -3, -4 }, + { 5, 4, 4, 11, 5, 1 }, + { 6, 7, 3, 2, 7, 5 }, + { 1, 9, 12, 3, 1, 4 }, + { -1, 1, 11, 10, 6, 3 }, + { -2, -3, -2, 2, 4, 1 } }; // Perform the naive convolution approach. Convolution2DMethodTest >(input, filter, @@ -194,17 +194,17 @@ TEST_CASE("ValidConvolution3DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input = { {1, 2, 3, 4}, - {4, 1, 2, 3}, - {3, 4, 1, 2}, - {2, 3, 4, 1} }; + input = { { 1, 2, 3, 4 }, + { 4, 1, 2, 3 }, + { 3, 4, 1, 2 }, + { 2, 3, 4, 1 } }; - filter = { {1, 0, -1}, - {0, 1, 0}, - {-1, 0, 1} }; + filter = { { 1, 0, -1 }, + { 0, 1, 0 }, + { -1, 0, 1 } }; - output = { {-3, -2}, - {8, -3} }; + output = { { -3, -2 }, + { 8, -3 } }; arma::cube inputCube(input.n_rows, input.n_cols, 2); inputCube.slice(0) = input; @@ -239,21 +239,21 @@ TEST_CASE("FullConvolution3DTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input = { {1, 2, 3, 4}, - {4, 1, 2, 3}, - {3, 4, 1, 2}, - {2, 3, 4, 1} }; + input = { { 1, 2, 3, 4 }, + { 4, 1, 2, 3 }, + { 3, 4, 1, 2 }, + { 2, 3, 4, 1 } }; - filter = { {1, 0, -1}, - {1, 1, 1}, - {-1, 0, 1} }; + filter = { { 1, 0, -1 }, + { 1, 1, 1 }, + { -1, 0, 1 } }; - output = { {1, 2, 2, 2, -3, -4}, - {5, 4, 4, 11, 5, 1}, - {6, 7, 3, 2, 7, 5}, - {1, 9, 12, 3, 1, 4}, - {-1, 1, 11, 10, 6, 3}, - {-2, -3, -2, 2, 4, 1} }; + output = { { 1, 2, 2, 2, -3, -4 }, + { 5, 4, 4, 11, 5, 1 }, + { 6, 7, 3, 2, 7, 5 }, + { 1, 9, 12, 3, 1, 4 }, + { -1, 1, 11, 10, 6, 3 }, + { -2, -3, -2, 2, 4, 1 } }; arma::cube inputCube(input.n_rows, input.n_cols, 2); inputCube.slice(0) = input; @@ -289,17 +289,17 @@ TEST_CASE("ValidConvolutionBatchTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input = { {1, 2, 3, 4}, - {4, 1, 2, 3}, - {3, 4, 1, 2}, - {2, 3, 4, 1} }; + input = { { 1, 2, 3, 4 }, + { 4, 1, 2, 3 }, + { 3, 4, 1, 2 }, + { 2, 3, 4, 1 } }; - filter = { {1, 0, -1}, - {0, 1, 0}, - {-1, 0, 1} }; + filter = { { 1, 0, -1 }, + { 0, 1, 0 }, + { -1, 0, 1 } }; - output = { {-3, -2}, - {8, -3} }; + output = { { -3, -2 }, + { 8, -3 } }; arma::cube filterCube(filter.n_rows, filter.n_cols, 2); filterCube.slice(0) = filter; @@ -331,21 +331,21 @@ TEST_CASE("FullConvolutionBatchTest", "[ConvolutionTest]") { // Generate dataset for convolution function tests. arma::mat input, filter, output; - input = { {1, 2, 3, 4}, - {4, 1, 2, 3}, - {3, 4, 1, 2}, - {2, 3, 4, 1} }; + input = { { 1, 2, 3, 4 }, + { 4, 1, 2, 3 }, + { 3, 4, 1, 2 }, + { 2, 3, 4, 1 } }; - filter = { {1, 0, -1}, - {1, 1, 1}, - {-1, 0, 1} }; + filter = { { 1, 0, -1 }, + { 1, 1, 1 }, + { -1, 0, 1 } }; - output = { {1, 2, 2, 2, -3, -4}, - {5, 4, 4, 11, 5, 1}, - {6, 7, 3, 2, 7, 5}, - {1, 9, 12, 3, 1, 4}, - {-1, 1, 11, 10, 6, 3}, - {-2, -3, -2, 2, 4, 1} }; + output = { { 1, 2, 2, 2, -3, -4 }, + { 5, 4, 4, 11, 5, 1 }, + { 6, 7, 3, 2, 7, 5 }, + { 1, 9, 12, 3, 1, 4 }, + { -1, 1, 11, 10, 6, 3 }, + { -2, -3, -2, 2, 4, 1 } }; arma::cube filterCube(filter.n_rows, filter.n_cols, 2); filterCube.slice(0) = filter; diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index a611ce2d4b..d053d46f4a 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -750,10 +750,10 @@ TEST_CASE("KFoldCVWithDTTestUnevenBinsWeighted", "[CVTest]") TEST_CASE("SilhouetteScoreTest", "[CVTest]") { arma::mat X; - X = { {0, 1, 1, 0, 0}, - {0, 1, 2, 0, 0}, - {1, 1, 3, 2, 0} }; - arma::Row labels = {0, 1, 2, 0, 0}; + X = { { 0, 1, 1, 0, 0 }, + { 0, 1, 2, 0, 0 }, + { 1, 1, 3, 2, 0 } }; + arma::Row labels = { 0, 1, 2, 0, 0 }; metric::EuclideanDistance metric; double silhouetteScore = SilhouetteScore::Overall(X, labels, metric); REQUIRE(silhouetteScore == Approx(0.1121684822489150).epsilon(1e-7)); diff --git a/src/mlpack/tests/decision_stump_test.cpp b/src/mlpack/tests/decision_stump_test.cpp index debdf1586f..d9d633fe3e 100644 --- a/src/mlpack/tests/decision_stump_test.cpp +++ b/src/mlpack/tests/decision_stump_test.cpp @@ -30,16 +30,16 @@ TEST_CASE("OneClass", "[DecisionStumpTest]") const size_t inpBucketSize = 6; mat trainingData; - trainingData = { {2.4, 3.8, 3.8}, - {1, 1, 2}, - {1.3, 1.9, 1.3} }; + trainingData = { { 2.4, 3.8, 3.8 }, + { 1, 1, 2 }, + { 1.3, 1.9, 1.3 } }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {1, 1, 1}; + labelsIn = { 1, 1, 1 }; mat testingData; - testingData = {2.4, 2.5, 2.6}; + testingData = { 2.4, 2.5, 2.6 }; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -65,13 +65,13 @@ TEST_CASE("CorrectDimensionChosen", "[DecisionStumpTest]") // found on page 176 (and a description of the correct splitting dimension is // given below that). mat trainingData; - trainingData = { {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2}, - {70, 90, 85, 95, 70, 90, 78, 65, 75, 80, 70, 80, 80, 96}, - {1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0} }; + trainingData = { { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2 }, + { 70, 90, 85, 95, 70, 90, 78, 65, 75, 80, 70, 80, 80, 96 }, + { 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0 } }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}; + labelsIn = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -92,14 +92,14 @@ TEST_CASE("PerfectSplitOnZero", "[DecisionStumpTest]") const size_t inpBucketSize = 2; mat trainingData; - trainingData = {-1, 1, -2, 2, -3, 3}; + trainingData = { -1, 1, -2, 2, -3, 3 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 1, 0, 1, 0, 1}; + labelsIn = { 0, 1, 0, 1, 0, 1 }; mat testingData; - testingData = {-4, 7, -7, -5, 6}; + testingData = { -4, 7, -7, -5, 6 }; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -123,11 +123,11 @@ TEST_CASE("BinningTesting", "[DecisionStumpTest]") const size_t inpBucketSize = 10; mat trainingData; - trainingData = {-1, 1, -2, 2, -3, 3, -4}; + trainingData = { -1, 1, -2, 2, -3, 3, -4 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 1, 0, 1, 0, 1, 0}; + labelsIn = { 0, 1, 0, 1, 0, 1, 0 }; mat testingData; testingData = {5}; @@ -151,14 +151,14 @@ TEST_CASE("PerfectMultiClassSplit", "[DecisionStumpTest]") const size_t inpBucketSize = 3; mat trainingData; - trainingData = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; + trainingData = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3}; + labelsIn = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 }; mat testingData; - testingData = {-6.1, -2.1, 1.1, 5.1}; + testingData = { -6.1, -2.1, 1.1, 5.1 }; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -183,16 +183,16 @@ TEST_CASE("MultiClassSplit", "[DecisionStumpTest]") const size_t inpBucketSize = 3; mat trainingData; - trainingData = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10}; + trainingData = { -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2}; + labelsIn = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2 }; mat testingData; - testingData = {-6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1}; + testingData = { -6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1 }; DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); @@ -320,16 +320,16 @@ TEST_CASE("EmptyConstructorTest", "[DecisionStumpTest]") // Now train on another dataset and make sure something kind of makes sense. mat trainingData; - trainingData = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10}; + trainingData = { -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2}; + labelsIn = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2 }; mat testingData; - testingData = {-6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1}; + testingData = { -6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1 }; DecisionStump<> ds(trainingData, labelsIn.row(0), 4, 3); @@ -354,17 +354,17 @@ TEST_CASE("IntTest", "[DecisionStumpTest]") { // Train on a dataset and make sure something kind of makes sense. imat trainingData; - trainingData = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10}; + trainingData = { -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2}; + labelsIn = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2 }; DecisionStump ds(trainingData, labelsIn.row(0), 4, 3); imat testingData; - testingData = {-6, -6, -2, -1, 3, 5, 7, 9}; + testingData = { -6, -6, -2, -1, 3, 5, 7, 9 }; arma::Row predictedLabels; ds.Classify(testingData, predictedLabels); @@ -388,11 +388,11 @@ TEST_CASE("DecisionStumpTrainReturnEntropy", "[DecisionStumpTest]") const size_t inpBucketSize = 2; mat trainingData; - trainingData = {-1, 1, -2, 2, -3, 3}; + trainingData = { -1, 1, -2, 2, -3, 3 }; // No need to normalize labels here. Mat labelsIn; - labelsIn = {0, 1, 0, 1, 0, 1}; + labelsIn = { 0, 1, 0, 1, 0, 1 }; arma::Row weights = arma::ones>(labelsIn.n_elem); diff --git a/src/mlpack/tests/det_test.cpp b/src/mlpack/tests/det_test.cpp index c3f6170c9c..ab55a541cd 100644 --- a/src/mlpack/tests/det_test.cpp +++ b/src/mlpack/tests/det_test.cpp @@ -40,9 +40,9 @@ TEST_CASE("TestGetMaxMinVals", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; DTree tree(testData); @@ -81,11 +81,11 @@ TEST_CASE("TestWithinRange", "[DETTest]") DTree testDTree(maxVals, minVals, 5); arma::vec testQuery(3); - testQuery = {4.5, 2.5, 2}; + testQuery = { 4.5, 2.5, 2 }; REQUIRE(testDTree.WithinRange(testQuery) == true); - testQuery = {8.5, 2.5, 2}; + testQuery = { 8.5, 2.5, 2 }; REQUIRE(testDTree.WithinRange(testQuery) == false); } @@ -94,9 +94,9 @@ TEST_CASE("TestFindSplit", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; DTree testDTree(testData); @@ -124,14 +124,14 @@ TEST_CASE("TestSplitData", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; DTree testDTree(testData); arma::Col oTest(5); - oTest = {1, 2, 3, 4, 5}; + oTest = { 1, 2, 3, 4, 5 }; size_t splitDim = 2; double trueSplitVal = 5.5; @@ -152,10 +152,10 @@ TEST_CASE("TestSparseFindSplit", "[DETTest]") { arma::mat realData(4, 7); - realData = { {.0, 4, 5, 7, 0, 5, 0}, - {.0, 5, 0, 0, 1, 7, 1}, - {.0, 5, 6, 7, 1, 0, 8}, - {-1, 2, 5, 0, 0, 0, 0} }; + realData = { { .0, 4, 5, 7, 0, 5, 0 }, + { .0, 5, 0, 0, 1, 7, 1 }, + { .0, 5, 6, 7, 1, 0, 8 }, + { -1, 2, 5, 0, 0, 0, 0 } }; arma::sp_mat testData(realData); @@ -186,17 +186,17 @@ TEST_CASE("TestSparseSplitData", "[DETTest]") { arma::mat realData(4, 7); - realData = { {.0, 4, 5, 7, 0, 5, 0}, - {.0, 5, 0, 0, 1, 7, 1}, - {.0, 5, 6, 7, 1, 0, 8}, - {-1, 2, 5, 0, 0, 0, 0} }; + realData = { { .0, 4, 5, 7, 0, 5, 0 }, + { .0, 5, 0, 0, 1, 7, 1 }, + { .0, 5, 6, 7, 1, 0, 8 }, + { -1, 2, 5, 0, 0, 0, 0 } }; arma::sp_mat testData(realData); DTree testDTree(testData); arma::Col oTest(7); - oTest = {1, 2, 3, 4, 5, 6, 7}; + oTest = { 1, 2, 3, 4, 5, 6, 7 }; size_t splitDim = 1; double trueSplitVal = .5; @@ -223,12 +223,12 @@ TEST_CASE("TestGrow", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; double rootError, lError, rError, rlError, rrError; @@ -289,9 +289,9 @@ TEST_CASE("TestPruneAndUpdate", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; arma::Col oTest(5); oTest = {0, 1, 2, 3, 4}; @@ -315,19 +315,19 @@ TEST_CASE("TestComputeValue", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; arma::vec q1(3), q2(3), q3(3), q4(3); - q1 = {4, 2, 2}; - q2 = {5, 0.25, 6}; - q3 = {5, 3, 7}; - q4 = {2, 3, 3}; + q1 = { 4, 2, 2 }; + q2 = { 5, 0.25, 6 }; + q3 = { 5, 3, 7 }; + q4 = { 2, 3, 3 }; arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); @@ -355,9 +355,9 @@ TEST_CASE("TestVariableImportance", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; double rootError, lError, rError, rlError, rrError; @@ -370,7 +370,7 @@ TEST_CASE("TestVariableImportance", "[DETTest]") rrError = -1.0 * exp(2 * log(2.0 / 5.0) - (log(6.5) + log(4.0) + log(2.5))); arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; DTree testDTree(testData); testDTree.Grow(testData, oTest, false, 2, 1); @@ -390,14 +390,14 @@ TEST_CASE("TestSparsePruneAndUpdate", "[DETTest]") { arma::mat realData(3, 5); - realData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + realData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; arma::sp_mat testData(realData); arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); @@ -419,22 +419,22 @@ TEST_CASE("TestSparseComputeValue", "[DETTest]") { arma::mat realData(3, 5); - realData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + realData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; arma::vec q1d(3), q2d(3), q3d(3), q4d(3); - q1d = {4, 2, 2}; - q2d = {5, 0.25, 6}; - q3d = {5, 3, 7}; - q4d = {2, 3, 3}; + q1d = { 4, 2, 2 }; + q2d = { 5, 0.25, 6 }; + q3d = { 5, 3, 7 }; + q4d = { 2, 3, 3 }; arma::sp_mat testData(realData); arma::sp_vec q1(q1d), q2(q2d), q3(q3d), q4(q4d); arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; DTree testDTree(testData); double alpha = testDTree.Grow(testData, oTest, false, 2, 1); @@ -465,9 +465,9 @@ TEST_CASE("TestTagTree", "[DETTest]") { MatType testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; DTree<>* testDTree = new DTree<>(&testData); @@ -478,9 +478,9 @@ TEST_CASE("TestFindBucket", "[DETTest]") { MatType testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; DTree<>* testDTree = new DTree<>(&testData); @@ -510,13 +510,13 @@ TEST_CASE("CopyConstructorAndOperatorTest", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; // Construct another DTree for testing the children. arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; DTree *testDTree = new DTree(testData); testDTree->Grow(testData, oTest, false, 2, 1); @@ -622,13 +622,13 @@ TEST_CASE("MoveConstructorTest", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; // Construct another DTree for testing the children. arma::Col oTest(5); - oTest = {0, 1, 2, 3, 4}; + oTest = { 0, 1, 2, 3, 4 }; DTree *testDTree = new DTree(testData); testDTree->Grow(testData, oTest, false, 2, 1); @@ -705,9 +705,9 @@ TEST_CASE("MoveOperatorTest", "[DETTest]") { arma::mat testData(3, 5); - testData = { {4, 5, 7, 3, 5}, - {5, 0, 1, 7, 1}, - {5, 6, 7, 1, 8} }; + testData = { { 4, 5, 7, 3, 5 }, + { 5, 0, 1, 7, 1 }, + { 5, 6, 7, 1, 8 } }; // Construct another DTree for testing the children. arma::Col oTest(5); diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index 5970277da1..bdb023341f 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -981,8 +981,8 @@ TEST_CASE("GammaDistributionProbabilityTest", "[DistributionTest]") // Combine into one 2-dimensional distribution. const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); arma::mat x3(2, 2); - x3 = { {2.0, 2.94}, - {2.0, 2.94} }; + x3 = { { 2.0, 2.94 }, + { 2.0, 2.94 } }; arma::vec prob3; // Expect that the 2-dimensional distribution returns the product of the @@ -1017,8 +1017,8 @@ TEST_CASE("GammaDistributionLogProbabilityTest", "[DistributionTest]") // Combine into one 2-dimensional distribution. const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); arma::mat x3(2, 2); - x3 = { {2.0, 2.94}, - {2.0, 2.94} }; + x3 = { { 2.0, 2.94 }, + { 2.0, 2.94 } }; arma::vec logprob3; // Expect that the 2-dimensional distribution returns the product of the diff --git a/src/mlpack/tests/facilities_test.cpp b/src/mlpack/tests/facilities_test.cpp index fa5b651338..b5115dc23f 100644 --- a/src/mlpack/tests/facilities_test.cpp +++ b/src/mlpack/tests/facilities_test.cpp @@ -47,9 +47,9 @@ BOOST_AUTO_TEST_CASE(AssertSizesTest) BOOST_AUTO_TEST_CASE(PairwiseDistanceTest) { arma::mat X; - X = { {0, 1, 1, 0, 0}, - {0, 1, 2, 0, 0}, - {1, 1, 3, 2, 0} }; + X = { { 0, 1, 1, 0, 0 }, + { 0, 1, 2, 0, 0 }, + { 1, 1, 3, 2, 0 } }; metric::EuclideanDistance metric; arma::mat dist = PairwiseDistances(X, metric); BOOST_REQUIRE_EQUAL(dist(0, 0), 0); diff --git a/src/mlpack/tests/linear_regression_test.cpp b/src/mlpack/tests/linear_regression_test.cpp index aea8532905..ae341cb243 100644 --- a/src/mlpack/tests/linear_regression_test.cpp +++ b/src/mlpack/tests/linear_regression_test.cpp @@ -73,8 +73,8 @@ TEST_CASE("LinearRegressionTestCase", "[LinearRegressionTest]") TEST_CASE("ComputeErrorTest", "[LinearRegressionTest]") { arma::mat predictors; - predictors = { {0, 1, 2, 4, 8, 16}, - {16, 8, 4, 2, 1, 0} }; + predictors = { { 0, 1, 2, 4, 8, 16 }, + { 16, 8, 4, 2, 1, 0 } }; arma::rowvec responses = "0 2 4 3 8 8"; // http://www.mlpack.org/trac/ticket/298 @@ -92,8 +92,8 @@ TEST_CASE("ComputeErrorPerfectFitTest", "[LinearRegressionTest]") { // Linear regression should perfectly model this dataset. arma::mat predictors; - predictors = { {0, 1, 2, 1, 6, 2}, - {0, 1, 2, 2, 2, 6} }; + predictors = { { 0, 1, 2, 1, 6, 2 }, + { 0, 1, 2, 2, 2, 6 } }; arma::rowvec responses = "0 2 4 3 8 8"; LinearRegression lr(predictors, responses); diff --git a/src/mlpack/tests/logistic_regression_test.cpp b/src/mlpack/tests/logistic_regression_test.cpp index 3b08619216..ff1ee1820d 100644 --- a/src/mlpack/tests/logistic_regression_test.cpp +++ b/src/mlpack/tests/logistic_regression_test.cpp @@ -1011,9 +1011,9 @@ BOOST_AUTO_TEST_CASE(ConstructionThenTraining) arma::mat myMatrix; // Four points, three dimensions. - myMatrix = { {0.555950, 0.274690, 0.540605, 0.798938}, - {0.948014, 0.973234, 0.216504, 0.883152}, - {0.023787, 0.675382, 0.231751, 0.450332} }; + myMatrix = { { 0.555950, 0.274690, 0.540605, 0.798938 }, + { 0.948014, 0.973234, 0.216504, 0.883152 }, + { 0.023787, 0.675382, 0.231751, 0.450332 } }; arma::Row myTargets("1 0 1 0"); diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 0bdae315dc..48259ad0eb 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -39,16 +39,16 @@ void GetPointset(const size_t N, arma::mat& rdata) arma::mat c4(d, N / 4, arma::fill::randu); arma::colvec offset1; - offset1 = { {0}, - {3} }; + offset1 = { { 0 }, + { 3 } }; arma::colvec offset2; - offset2 = { {3}, - {3} }; + offset2 = { { 3 }, + { 3 } }; arma::colvec offset4; - offset4 = { {3}, - {0} }; + offset4 = { { 3 }, + { 0 } }; // Spread points in plane. for (size_t p = 0; p < N / 4; ++p) @@ -132,8 +132,8 @@ BOOST_AUTO_TEST_CASE(NumTablesTest) fail = false; const int lSize = 6; // Number of runs. - const int lValue[] = {1, 8, 16, 32, 64, 128}; // Number of tables. - double lValueRecall[lSize] = {0.0}; // Recall of each LSH run. + const int lValue[] = { 1, 8, 16, 32, 64, 128 }; // Number of tables. + double lValueRecall[lSize] = { 0.0 }; // Recall of each LSH run. for (size_t l = 0; l < lSize; ++l) { @@ -198,8 +198,8 @@ BOOST_AUTO_TEST_CASE(HashWidthTest) arma::mat groundDistances; knn.Search(qdata, k, groundTruth, groundDistances); const int hSize = 7; // Number of runs. - const double hValue[] = {0.1, 0.5, 1, 5, 10, 50, 500}; // Hash width. - double hValueRecall[hSize] = {0.0}; // Recall of each run. + const double hValue[] = { 0.1, 0.5, 1, 5, 10, 50, 500 }; // Hash width. + double hValueRecall[hSize] = { 0.0 }; // Recall of each run. for (size_t h = 0; h < hSize; ++h) { @@ -260,8 +260,8 @@ BOOST_AUTO_TEST_CASE(NumProjTest) // LSH test parameters for numProj. const int pSize = 5; // Number of runs. - const int pValue[] = {1, 10, 20, 50, 100}; // Number of projections. - double pValueRecall[pSize] = {0.0}; // Recall of each run. + const int pValue[] = { 1, 10, 20, 50, 100 }; // Number of projections. + double pValueRecall[pSize] = { 0.0 }; // Recall of each run. for (size_t p = 0; p < pSize; ++p) { @@ -490,7 +490,7 @@ BOOST_AUTO_TEST_CASE(MultiprobeTest) const size_t repetitions = 5; // Train five objects. const size_t probeTrials = 5; - const size_t numProbes[probeTrials] = {0, 1, 2, 3, 4}; + const size_t numProbes[probeTrials] = { 0, 1, 2, 3, 4 }; // Algorithm parameters. const int k = 4; diff --git a/src/mlpack/tests/main_tests/logistic_regression_test.cpp b/src/mlpack/tests/main_tests/logistic_regression_test.cpp index e81a695bc3..5490da10d4 100644 --- a/src/mlpack/tests/main_tests/logistic_regression_test.cpp +++ b/src/mlpack/tests/main_tests/logistic_regression_test.cpp @@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(LRNoTrainingData) { arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; SetInputParam("labels", std::move(trainY)); @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(LRPridictionSizeCheck) arma::mat trainX = arma::randu(D, N); arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; arma::mat testX = arma::randu(D, M); SetInputParam("training", std::move(trainX)); @@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(LRWrongResponseSizeTest) arma::Row trainY; // Response vector with wrong size. // 8 responses - incorrect size. - trainY = {0, 0, 1, 0, 1, 1, 1, 0}; + trainY = { 0, 0, 1, 0, 1, 1, 1, 0 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(LRModelReload) arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; arma::mat testX = arma::randu(D, M); @@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(LRWrongDimOfTestData) arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; // Test data with wrong dimensionality. arma::mat testX = arma::randu(D-1, N); @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(LRWrongDimOfTestData2) arma::mat trainX = arma::randu(D, N); arma::Row trainY; // 10 responses - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -308,7 +308,7 @@ BOOST_AUTO_TEST_CASE(LRTrainWithMoreThanTwoClasses) arma::Row trainY; // 8 responses containing more than two classes. - trainY = {0, 1, 0, 1, 2, 1, 3, 1}; + trainY = { 0, 1, 0, 1, 2, 1, 3, 1 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(LRNonNegativeMaxIterationTest) arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -356,7 +356,7 @@ BOOST_AUTO_TEST_CASE(LRNonNegativeStepSizeTest) arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + trainY = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(LRNonNegativeToleranceTest) arma::Row trainY; // 10 responses. - trainY = {1, 1, 0, 1, 0, 0, 0, 1, 0, 1}; + trainY = { 1, 1, 0, 1, 0, 0, 0, 1, 0, 1 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -405,7 +405,7 @@ BOOST_AUTO_TEST_CASE(LRMaxIterationsChangeTest) arma::Row trainY; // 10 responses. - trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; + trainY = { 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 }; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -454,7 +454,7 @@ BOOST_AUTO_TEST_CASE(LRLambdaChangeTest) arma::Row trainY; // 10 responses. - trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; + trainY = { 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 }; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -503,7 +503,7 @@ BOOST_AUTO_TEST_CASE(LRStepSizeChangeTest) arma::Row trainY; // 10 responses. - trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; + trainY = { 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 }; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -554,7 +554,7 @@ BOOST_AUTO_TEST_CASE(LROptimizerChangeTest) arma::Row trainY; // 10 responses. - trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; + trainY = { 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 }; SetInputParam("training", trainX); SetInputParam("labels", trainY); @@ -606,7 +606,7 @@ BOOST_AUTO_TEST_CASE(LRDecisionBoundaryTest) arma::Row trainY; // 10 responses. - trainY = {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}; + trainY = { 1, 0, 0, 1, 0, 1, 0, 1, 0, 1 }; arma::mat testX = arma::randu(D, M); diff --git a/src/mlpack/tests/main_tests/perceptron_test.cpp b/src/mlpack/tests/main_tests/perceptron_test.cpp index d29e999cc4..c290c59448 100644 --- a/src/mlpack/tests/main_tests/perceptron_test.cpp +++ b/src/mlpack/tests/main_tests/perceptron_test.cpp @@ -308,7 +308,7 @@ BOOST_AUTO_TEST_CASE(PerceptronReTrainWithWrongClasses) arma::Row labelsX2; // 10 responses. - labelsX2 = {0, 1, 4, 1, 2, 1, 0, 3, 3, 0}; + labelsX2 = { 0, 1, 4, 1, 2, 1, 0, 3, 3, 0 }; // Last column of trainX2 contains the class labels. SetInputParam("training", std::move(trainX2)); @@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(PerceptronWrongDimOfTestData) arma::Row trainY; // 10 responses. - trainY = {0 , 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0 , 1, 0, 1, 1, 1, 0, 1, 0, 0 }; // Test data with wrong dimensionality. arma::mat testX = arma::randu(D-3, M); @@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE(PerceptronWrongResponseSizeTest) arma::Row trainY; // Response vector with wrong size. // 8 responses. - trainY = {0, 0, 1, 0, 1, 1, 1, 0}; + trainY = { 0, 0, 1, 0, 1, 1, 1, 0 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); @@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(PerceptronNoResponsesTest) BOOST_AUTO_TEST_CASE(PerceptronNoTrainingDataTest) { arma::Row trainY; - trainY = {1, 1, 0, 1, 0, 0}; + trainY = { 1, 1, 0, 1, 0, 0 }; SetInputParam("labels", std::move(trainY)); @@ -418,7 +418,7 @@ BOOST_AUTO_TEST_CASE(PerceptronWrongDimOfTestData2) arma::Row trainY; // 10 responses. - trainY = {0, 1, 0, 1, 1, 1, 0, 1, 0, 0}; + trainY = { 0, 1, 0, 1, 1, 1, 0, 1, 0, 0 }; SetInputParam("training", std::move(trainX)); SetInputParam("labels", std::move(trainY)); diff --git a/src/mlpack/tests/maximal_inputs_test.cpp b/src/mlpack/tests/maximal_inputs_test.cpp index 57b6136135..f324f2304a 100644 --- a/src/mlpack/tests/maximal_inputs_test.cpp +++ b/src/mlpack/tests/maximal_inputs_test.cpp @@ -53,10 +53,10 @@ BOOST_AUTO_TEST_CASE(ColumnToBlocksEvaluate) ctb.Transform(CreateMaximalInput(), output); arma::mat matlabResults; - matlabResults = { {-1, -1, -1, -1, -1, -1, -1}, - {-1, -1, -0.42857, -1, 0.14286, 0.71429, -1}, - {-1, -0.71429, -0.14286, -1, 0.42857, 1, -1}, - {-1, -1, -1, -1, -1, -1, -1} }; + matlabResults = { { -1, -1, -1, -1, -1, -1, -1 }, + { -1, -1, -0.42857, -1, 0.14286, 0.71429, -1 }, + { -1, -0.71429, -0.14286, -1, 0.42857, 1, -1 }, + { -1, -1, -1, -1, -1, -1, -1 } }; TestResults(output, matlabResults); } @@ -71,10 +71,12 @@ BOOST_AUTO_TEST_CASE(ColumnToBlocksChangeBlockSize) ctb.Transform(CreateMaximalInput(), output); arma::mat matlabResults; - matlabResults = { {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, - {-3, -1, -0.71429, -0.42857, -0.14286, -3, 0.14286, - 0.42857, 0.71429, 1, -3}, - {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3} }; + matlabResults = { { -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3 }, + { -3, -1, -0.71429, -0.42857, -0.14286, -3, 0.14286, + 0.42857, 0.71429, 1, -3 }, + { -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3 } }; TestResults(output, matlabResults); } diff --git a/src/mlpack/tests/perceptron_test.cpp b/src/mlpack/tests/perceptron_test.cpp index 5039c7fbd6..d53903c259 100644 --- a/src/mlpack/tests/perceptron_test.cpp +++ b/src/mlpack/tests/perceptron_test.cpp @@ -110,16 +110,16 @@ TEST_CASE("SimpleWeightUpdateInstanceWeight", "[PerceptronTest]") TEST_CASE("And", "[PerceptronTest]") { mat trainData; - trainData = { {0, 1, 1, 0}, - {1, 0, 1, 0} }; + trainData = { { 0, 1, 1, 0 }, + { 1, 0, 1, 0 } }; Mat labels; - labels = {0, 0, 1, 0}; + labels = { 0, 0, 1, 0 }; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData = { {0, 1, 1, 0}, - {1, 0, 1, 0} }; + testData = { { 0, 1, 1, 0 }, + { 1, 0, 1, 0 } }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -135,17 +135,17 @@ TEST_CASE("And", "[PerceptronTest]") TEST_CASE("Or", "[PerceptronTest]") { mat trainData; - trainData = { {0, 1, 1, 0}, - {1, 0, 1, 0} }; + trainData = { { 0, 1, 1, 0 }, + { 1, 0, 1, 0 } }; Mat labels; - labels = {1, 1, 1, 0}; + labels = { 1, 1, 1, 0 }; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData = { {0, 1, 1, 0}, - {1, 0, 1, 0} }; + testData = { { 0, 1, 1, 0 }, + { 1, 0, 1, 0 } }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -162,17 +162,17 @@ TEST_CASE("Or", "[PerceptronTest]") TEST_CASE("Random3", "[PerceptronTest]") { mat trainData; - trainData = { {0, 1, 1, 4, 5, 4, 1, 2, 1}, - {1, 0, 1, 1, 1, 2, 4, 5, 4} }; + trainData = { { 0, 1, 1, 4, 5, 4, 1, 2, 1 }, + { 1, 0, 1, 1, 1, 2, 4, 5, 4 } }; Mat labels; - labels = {0, 0, 0, 1, 1, 1, 2, 2, 2}; + labels = { 0, 0, 0, 1, 1, 1, 2, 2, 2 }; Perceptron<> p(trainData, labels.row(0), 3, 1000); mat testData; - testData = { {0, 1, 1}, - {1, 0, 1} }; + testData = { { 0, 1, 1 }, + { 1, 0, 1 } }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -187,17 +187,17 @@ TEST_CASE("Random3", "[PerceptronTest]") TEST_CASE("TwoPoints", "[PerceptronTest]") { mat trainData; - trainData = { {0, 1}, - {1, 0} }; + trainData = { { 0, 1 }, + { 1, 0 } }; Mat labels; - labels = {0, 1}; + labels = { 0, 1 }; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData = { {0, 1}, - {1, 0} }; + testData = { { 0, 1 }, + { 1, 0 } }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -212,17 +212,17 @@ TEST_CASE("TwoPoints", "[PerceptronTest]") TEST_CASE("NonLinearlySeparableDataset", "[PerceptronTest]") { mat trainData; - trainData = { {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, - {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2} }; + trainData = { { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 } }; Mat labels; - labels = {0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}; + labels = { 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1 }; Perceptron<> p(trainData, labels.row(0), 2, 1000); mat testData; - testData = { {3, 4, 5, 6}, - {3, 2.3, 1.7, 1.5} }; + testData = { { 3, 4, 5, 6 }, + { 3, 2.3, 1.7, 1.5 } }; Row predictedLabels(testData.n_cols); p.Classify(testData, predictedLabels); @@ -235,11 +235,11 @@ TEST_CASE("NonLinearlySeparableDataset", "[PerceptronTest]") TEST_CASE("SecondaryConstructor", "[PerceptronTest]") { mat trainData; - trainData = { {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}, - {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2} }; + trainData = { { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 } }; Mat labels; - labels = {0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}; + labels = { 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1 }; Perceptron<> p1(trainData, labels.row(0), 2, 1000); diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 8197fe2dd3..e734d41890 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -309,7 +309,7 @@ template void ReberReverseTranslation(const MatType& translation, char& symbol) { arma::Col symbols; - symbols = {'B', 'T', 'S', 'X', 'P', 'V', 'E'}; + symbols = { 'B', 'T', 'S', 'X', 'P', 'V', 'E' }; const int idx = arma::as_scalar(arma::find(translation == 1, 1, "first")); symbol = symbols(idx); @@ -324,7 +324,7 @@ void ReberReverseTranslation(const MatType& translation, char& symbol) void ReberTranslation(const char symbol, arma::colvec& translation) { arma::Col symbols; - symbols = {'B', 'T', 'S', 'X', 'P', 'V', 'E'}; + symbols = { 'B', 'T', 'S', 'X', 'P', 'V', 'E' }; const int idx = arma::as_scalar(arma::find(symbols == symbol, 1, "first")); translation = arma::zeros(7); @@ -464,12 +464,12 @@ arma::Mat GenerateReberGrammarData( // Reber state transition matrix. (The last two columns are the indices to the // next path). arma::Mat transitions; - transitions = { {'T', 'P', '1', '2'}, - {'X', 'S', '3', '1'}, - {'V', 'T', '4', '2'}, - {'X', 'S', '2', '5'}, - {'P', 'V', '3', '5'}, - {'E', 'E', '0', '0'} }; + transitions = { { 'T', 'P', '1', '2' }, + { 'X', 'S', '3', '1' }, + { 'V', 'T', '4', '2' }, + { 'X', 'S', '2', '5' }, + { 'P', 'V', '3', '5' }, + { 'E', 'E', '0', '0' } }; std::string trainReber, testReber; @@ -1422,7 +1422,7 @@ TEST_CASE("LargeRhoValueRnnTest", "[RecurrentNetworkTest]") using MatType = arma::cube; std::vectortrainingData = { "THIS IS THE INPUT 0" , "THIS IS THE INPUT 1" , - "THIS IS THE INPUT 3"}; + "THIS IS THE INPUT 3" }; RNN<> model(rho); From 27fc4e2eb131e02b312bc0d522c182b0d464edaf Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 10 Nov 2020 16:27:40 -0500 Subject: [PATCH 117/550] Well, evidently, that's not where MSBuild is. --- .ci/windows-steps.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 61200a5f24..59331e3b74 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -161,10 +161,6 @@ steps: } # Build the MSI installer. - dir 'C:\Program Files (x86)\' - dir 'C:\Program Files (x86)\MSBuild\' - dir 'C:\Program Files (x86)\MSBuild\15.0\' - dir 'C:\Program Files (x86)\MSBuild\15.0\Bin\' dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\' & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild From 081a653faf2259fef54ecc55f9ff15082a08570c Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 10 Nov 2020 19:54:39 -0500 Subject: [PATCH 118/550] This has to be the most inefficient possible way of searching for a file. --- .ci/windows-steps.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 59331e3b74..84549e1246 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -161,6 +161,16 @@ steps: } # Build the MSI installer. + dir 'C:\Program Files (x86)\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\' + dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\' dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\' & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild From 4e98d324d484335a6b92736cc01893ceeec83730 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 11 Nov 2020 09:23:45 +0530 Subject: [PATCH 119/550] Trying to restart checks From 412b881ce63e2c39b481059c27e51bf2af1b1afb Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 11 Nov 2020 18:12:26 +0530 Subject: [PATCH 120/550] Fixed some spacing and initializations --- src/mlpack/core/math/columns_to_blocks.hpp | 8 +- src/mlpack/tests/binarize_test.cpp | 6 +- src/mlpack/tests/lsh_test.cpp | 6 +- src/mlpack/tests/recurrent_network_test.cpp | 1257 +------------------ src/mlpack/tests/rnn_reber_test.cpp | 16 +- 5 files changed, 18 insertions(+), 1275 deletions(-) diff --git a/src/mlpack/core/math/columns_to_blocks.hpp b/src/mlpack/core/math/columns_to_blocks.hpp index 1b94a20679..a6d7e3a391 100644 --- a/src/mlpack/core/math/columns_to_blocks.hpp +++ b/src/mlpack/core/math/columns_to_blocks.hpp @@ -66,10 +66,10 @@ namespace math { * @code * // This matrix has two columns. * arma::mat input; - * input = { {-1.0000, 0.1429}, - * {-0.7143, 0.4286}, - * {-0.4286, 0.7143}, - * {-0.1429, 1.0000} }; + * input = { { -1.0000, 0.1429 }, + * { -0.7143, 0.4286 }, + * { -0.4286, 0.7143 }, + * { -0.1429, 1.0000 } }; * * arma::mat output; * ColumnsToBlocks ctb(1, 2); diff --git a/src/mlpack/tests/binarize_test.cpp b/src/mlpack/tests/binarize_test.cpp index f90fb0ad19..e050f65ca4 100644 --- a/src/mlpack/tests/binarize_test.cpp +++ b/src/mlpack/tests/binarize_test.cpp @@ -23,9 +23,9 @@ using namespace mlpack::data; TEST_CASE("BinarizeOneDimension", "[BinarizeTest]") { mat input; - input = { {1, 2, 3}, - {4, 5, 6}, // this row will be tested - {7, 8, 9} }; + input = { { 1, 2, 3 }, + { 4, 5, 6 }, // this row will be tested + { 7, 8, 9 } }; mat output; const double threshold = 5.0; diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 48259ad0eb..606bf19e84 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -589,14 +589,12 @@ BOOST_AUTO_TEST_CASE(MultiprobeDeterministicTest) // Construct q1 so it is hashed directly under C2. arma::mat q1; - q1 << 3.9 << arma::endr - << 2.99 << arma::endr; + q1 = arma::mat( { 3.9, 2.99 } ).t(); q1 -= offsets; // Construct q2 so it is hashed near the center of C2. arma::mat q2; - q2 << 3.6 << arma::endr - << 3.6 << arma::endr; + q2 = arma::mat( { 3.6, 3.6 } ); q2 -= offsets; arma::Mat neighbors; diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 403f797953..987c808ef2 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -69,1261 +69,6 @@ void GenerateNoisySines(arma::cube& data, } } -/** - * Train the BRNN on a larger dataset. - */ -TEST_CASE("SequenceClassificationBRNNTest", "[RecurrentNetworkTest]") -{ - // Using same test for RNN below. - size_t successes = 0; - const size_t rho = 10; - - for (size_t trial = 0; trial < 6; ++trial) - { - // Generate 12 (2 * 6) noisy sines. A single sine contains rho - // points/features. - arma::cube input; - arma::mat labelsTemp; - GenerateNoisySines(input, labelsTemp, rho, 6); - - arma::cube labels = arma::zeros(1, labelsTemp.n_cols, rho); - for (size_t i = 0; i < labelsTemp.n_cols; ++i) - { - const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - labels.tube(0, i).fill(value); - } - - Add<> add(4); - Linear<> lookup(1, 4); - SigmoidLayer<> sigmoidLayer; - Linear<> linear(4, 4); - Recurrent<>* recurrent = new Recurrent<>( - add, lookup, linear, sigmoidLayer, rho); - - BRNN<> model(rho); - model.Add >(); - model.Add(recurrent); - model.Add >(4, 5); - - StandardSGD opt(0.1, 1, 500 * input.n_cols, -100); - model.Train(input, labels, opt); - INFO("Training over"); - arma::cube prediction; - model.Predict(input, prediction); - INFO("Prediction over"); - - size_t error = 0; - for (size_t i = 0; i < prediction.n_cols; ++i) - { - const int predictionValue = arma::as_scalar(arma::find( - arma::max(prediction.slice(rho - 1).col(i)) == - prediction.slice(rho - 1).col(i), 1) + 1); - - const int targetValue = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - - if (predictionValue == targetValue) - { - error++; - } - } - - double classificationError = 1 - double(error) / prediction.n_cols; - INFO(classificationError); - if (classificationError <= 0.2) - { - ++successes; - break; - } - } - - REQUIRE(successes >= 1); -} - -/** - * Train the vanilla network on a larger dataset. - */ -TEST_CASE("SequenceClassificationTest", "[RecurrentNetworkTest]") -{ - // It isn't guaranteed that the recurrent network will converge in the - // specified number of iterations using random weights. If this works 1 of 6 - // times, I'm fine with that. All I want to know is that the network is able - // to escape from local minima and to solve the task. - size_t successes = 0; - const size_t rho = 10; - - for (size_t trial = 0; trial < 6; ++trial) - { - // Generate 12 (2 * 6) noisy sines. A single sine contains rho - // points/features. - arma::cube input; - arma::mat labelsTemp; - GenerateNoisySines(input, labelsTemp, rho, 6); - - arma::cube labels = arma::zeros(1, labelsTemp.n_cols, rho); - for (size_t i = 0; i < labelsTemp.n_cols; ++i) - { - const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - labels.tube(0, i).fill(value); - } - - /** - * Construct a network with 1 input unit, 4 hidden units and 10 output - * units. The hidden layer is connected to itself. The network structure - * looks like: - * - * Input Hidden Output - * Layer(1) Layer(4) Layer(10) - * +-----+ +-----+ +-----+ - * | | | | | | - * | +------>| +------>| | - * | | ..>| | | | - * +-----+ . +--+--+ +-----+ - * . . - * . . - * ....... - */ - Add<> add(4); - Linear<> lookup(1, 4); - SigmoidLayer<> sigmoidLayer; - Linear<> linear(4, 4); - Recurrent<>* recurrent = new Recurrent<>( - add, lookup, linear, sigmoidLayer, rho); - - RNN<> model(rho); - model.Add >(); - model.Add(recurrent); - model.Add >(4, 10); - model.Add >(); - - StandardSGD opt(0.1, 1, 500 * input.n_cols, -100); - model.Train(input, labels, opt); - - arma::cube prediction; - model.Predict(input, prediction); - - size_t error = 0; - for (size_t i = 0; i < prediction.n_cols; ++i) - { - const int predictionValue = arma::as_scalar(arma::find( - arma::max(prediction.slice(rho - 1).col(i)) == - prediction.slice(rho - 1).col(i), 1) + 1); - - const int targetValue = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - - if (predictionValue == targetValue) - { - error++; - } - } - - double classificationError = 1 - double(error) / prediction.n_cols; - if (classificationError <= 0.2) - { - ++successes; - break; - } - } - - REQUIRE(successes >= 1); -} - -/** - * Generate a random Reber grammar. - * - * For more information, see the following thesis. - * - * @code - * @misc{Gers2001, - * author = {Felix Gers}, - * title = {Long Short-Term Memory in Recurrent Neural Networks}, - * year = {2001} - * } - * @endcode - * - * @param transitions Reber grammar transition matrix. - * @param reber The generated Reber grammar string. - */ -void GenerateReber(const arma::Mat& transitions, std::string& reber) -{ - size_t idx = 0; - reber = "B"; - - do - { - const int grammerIdx = rand() % 2; - reber += arma::as_scalar(transitions.submat(idx, grammerIdx, idx, - grammerIdx)); - - idx = arma::as_scalar(transitions.submat(idx, grammerIdx + 2, idx, - grammerIdx + 2)) - '0'; - } while (idx != 0); -} - -/** - * Generate a random recursive Reber grammar. - * - * @param transitions Recursive Reber grammar transition matrix. - * @param averageRecursion Average recursive depth of the reber grammar. - * @param maxRecursion Maximum recursive depth of reber grammar. - * @param reber The generated embedded Reber grammar string. - * @param addEnd Add ending 'E' to the generated grammar. - */ -void GenerateRecursiveReber(const arma::Mat& transitions, - size_t averageRecursion, - size_t maxRecursion, - std::string& reber, - bool addEnd = true) -{ - char c = (rand() % averageRecursion) == 1 ? 'P' : 'T'; - - if (maxRecursion == 1 || c == 'T') - { - c = 'T'; - GenerateReber(transitions, reber); - } - else - { - GenerateRecursiveReber(transitions, averageRecursion, --maxRecursion, - reber, false); - } - - reber = c + reber + c; - - if (addEnd) - { - reber = "B" + reber + "E"; - } -} - -/** - * Convert a unit vector to a Reber symbol. - * - * @param translation The unit vector to be converted. - * @param symbol The converted unit vector stored as Reber symbol. - */ -template -void ReberReverseTranslation(const MatType& translation, char& symbol) -{ - arma::Col symbols; - symbols = { 'B', 'T', 'S', 'X', 'P', 'V', 'E' }; - const int idx = arma::as_scalar(arma::find(translation == 1, 1, "first")); - - symbol = symbols(idx); -} - -/** - * Convert a Reber symbol to a unit vector. - * - * @param symbol Reber symbol to be converted. - * @param translation The converted symbol stored as unit vector. - */ -void ReberTranslation(const char symbol, arma::colvec& translation) -{ - arma::Col symbols; - symbols = { 'B', 'T', 'S', 'X', 'P', 'V', 'E' }; - const int idx = arma::as_scalar(arma::find(symbols == symbol, 1, "first")); - - translation = arma::zeros(7); - translation(idx) = 1; -} - -/** - * Given a Reber string, return a Reber string with all reachable next symbols. - * - * @param transitions The Reber transistion matrix. - * @param reber The Reber string used to generate all reachable next symbols. - * @param nextReber All reachable next symbols. - */ -void GenerateNextReber(const arma::Mat& transitions, - const std::string& reber, std::string& nextReber) -{ - size_t idx = 0; - - for (size_t grammer = 1; grammer < reber.length(); grammer++) - { - const int grammerIdx = arma::as_scalar(arma::find( - transitions.row(idx) == reber[grammer], 1, "first")); - - idx = arma::as_scalar(transitions.submat(idx, grammerIdx + 2, idx, - grammerIdx + 2)) - '0'; - } - - nextReber = arma::as_scalar(transitions.submat(idx, 0, idx, 0)); - nextReber += arma::as_scalar(transitions.submat(idx, 1, idx, 1)); -} - -/** - * Given a recursive Reber string, return a Reber string with all - * reachable next symbols. - * - * @param transitions The Reber transistion matrix. - * @param reber The Reber string used to generate all reachable next symbols. - * @param nextReber All reachable next symbols. - */ -void GenerateNextRecursiveReber(const arma::Mat& transitions, - const std::string& reber, - std::string& nextReber) -{ - size_t state = 0; - size_t numPs = 0; - - for (size_t cIndex = 0; cIndex < reber.length(); cIndex++) - { - char c = reber[cIndex]; - - if (c == 'B' && state == 0) - { - state = 1; - } - else if (c == 'P' && state == 1) - { - numPs++; - state = 1; - } - else if (c == 'T' && state == 1) - { - state = 2; - } - else if (c == 'B' && state == 2) - { - size_t pos = reber.find('E'); - if (pos != std::string::npos) - { - cIndex = pos; - state = 4; - } - else - { - GenerateNextReber(transitions, reber.substr(cIndex), nextReber); - state = 3; - } - } - else if (c == 'T' && state == 4) - { - state = 5; - } - else if (c == 'P' && state == 5) - { - numPs--; - state = 5; - } - } - - if (state == 0 || state == 2) - { - nextReber = "B"; - } - else if (state == 1) - { - nextReber = "PT"; - } - else if (state == 4) - { - nextReber = "T"; - } - else if (state == 5) - { - if (numPs == 0) - { - nextReber = "E"; - } - else - { - nextReber = "P"; - } - } -} - -/** - * @brief Creates the reber grammar data for tests. - * - * @param trainInput The train data - * @param trainLabels The train labels - * @param testInput The test input - * @param recursive whether recursive Reber - * @param trainReberGrammarCount The number of training set - * @param testReberGrammarCount The number of test set - * @param averageRecursion Average recursion - * @param maxRecursion Max recursion - * @return arma::Mat The Reber state translation to be used. - */ -arma::Mat GenerateReberGrammarData( - arma::field& trainInput, - arma::field& trainLabels, - arma::field& testInput, - bool recursive = false, - const size_t trainReberGrammarCount = 700, - const size_t testReberGrammarCount = 250, - const size_t averageRecursion = 3, - const size_t maxRecursion = 5) -{ - // Reber state transition matrix. (The last two columns are the indices to the - // next path). - arma::Mat transitions; - transitions = { { 'T', 'P', '1', '2' }, - { 'X', 'S', '3', '1' }, - { 'V', 'T', '4', '2' }, - { 'X', 'S', '2', '5' }, - { 'P', 'V', '3', '5' }, - { 'E', 'E', '0', '0' } }; - - - std::string trainReber, testReber; - - arma::colvec translation; - - // Generate the training data. - for (size_t i = 0; i < trainReberGrammarCount; ++i) - { - if (recursive) - GenerateRecursiveReber(transitions, 3, 5, trainReber); - else - GenerateReber(transitions, trainReber); - - for (size_t j = 0; j < trainReber.length() - 1; ++j) - { - ReberTranslation(trainReber[j], translation); - trainInput(0, i) = arma::join_cols(trainInput(0, i), translation); - - ReberTranslation(trainReber[j + 1], translation); - trainLabels(0, i) = arma::join_cols(trainLabels(0, i), translation); - } - } - - // Generate the test data. - for (size_t i = 0; i < testReberGrammarCount; ++i) - { - if (recursive) - GenerateRecursiveReber(transitions, averageRecursion, maxRecursion, - testReber); - else - GenerateReber(transitions, testReber); - - for (size_t j = 0; j < testReber.length() - 1; ++j) - { - ReberTranslation(testReber[j], translation); - testInput(0, i) = arma::join_cols(testInput(0, i), translation); - } - } - - return transitions; -} - -/** - * Train the specified network and the construct a Reber grammar dataset. - */ -template -void ReberGrammarTestNetwork(ModelType& model, - const bool recursive = false, - const size_t averageRecursion = 3, - const size_t maxRecursion = 5, - const size_t iterations = 10, - const size_t trials = 5) -{ - const size_t trainReberGrammarCount = 700; - const size_t testReberGrammarCount = 250; - - arma::field trainInput(1, trainReberGrammarCount); - arma::field trainLabels(1, trainReberGrammarCount); - arma::field testInput(1, testReberGrammarCount); - - arma::Mat transitions = - GenerateReberGrammarData(trainInput, - trainLabels, - testInput, - recursive, - trainReberGrammarCount, - testReberGrammarCount, - averageRecursion, - maxRecursion); - - /* - * Construct a network with 7 input units, layerSize hidden units and 7 output - * units. The hidden layer is connected to itself. The network structure looks - * like: - * - * Input Hidden Output - * Layer(7) Layer(layerSize) Layer(7) - * +-----+ +-----+ +-----+ - * | | | | | | - * | +------>| +------>| | - * | | ..>| | | | - * +-----+ . +--+--+ +-- ---+ - * . . - * . . - * ....... - */ - // It isn't guaranteed that the recurrent network will converge in the - // specified number of iterations using random weights. If this works 1 of 5 - // times, I'm fine with that. All I want to know is that the network is able - // to escape from local minima and to solve the task. - size_t successes = 0; - size_t offset = 0; - const size_t inputSize = 7; - for (size_t trial = 0; trial < trials; ++trial) - { - // Reset model before using for next trial. - model.Reset(); - MomentumSGD opt(0.06, 50, 2, -50000); - - arma::cube inputTemp, labelsTemp; - for (size_t iteration = 0; iteration < (iterations + offset); iteration++) - { - for (size_t j = 0; j < trainReberGrammarCount; ++j) - { - // Each sequence may be a different length, so we need to extract them - // manually. We will reshape them into a cube with each slice equal to - // a time step. - inputTemp = arma::cube(trainInput.at(0, j).memptr(), inputSize, 1, - trainInput.at(0, j).n_elem / inputSize, false, true); - labelsTemp = arma::cube(trainLabels.at(0, j).memptr(), inputSize, 1, - trainInput.at(0, j).n_elem / inputSize, false, true); - - model.Rho() = inputTemp.n_elem / inputSize; - model.Train(inputTemp, labelsTemp, opt); - opt.ResetPolicy() = false; - } - } - - double error = 0; - - // Ask the network to predict the next Reber grammar in the given sequence. - for (size_t i = 0; i < testReberGrammarCount; ++i) - { - arma::cube prediction; - arma::cube input(testInput.at(0, i).memptr(), inputSize, 1, - testInput.at(0, i).n_elem / inputSize, false, true); - - model.Rho() = input.n_elem / inputSize; - model.Predict(input, prediction); - - const size_t reberGrammerSize = 7; - std::string inputReber = ""; - - size_t reberError = 0; - - for (size_t j = 0; j < (prediction.n_elem / reberGrammerSize); ++j) - { - char predictedSymbol, inputSymbol; - std::string reberChoices; - - arma::umat output = (prediction.slice(j) == (arma::ones( - reberGrammerSize, 1) * - arma::as_scalar(arma::max(prediction.slice(j))))); - - ReberReverseTranslation(output, predictedSymbol); - ReberReverseTranslation(input.slice(j), inputSymbol); - inputReber += inputSymbol; - - if (recursive) - GenerateNextRecursiveReber(transitions, inputReber, reberChoices); - else - GenerateNextReber(transitions, inputReber, reberChoices); - - if (reberChoices.find(predictedSymbol) != std::string::npos) - reberError++; - } - - if (reberError != (prediction.n_elem / reberGrammerSize)) - error += 1; - } - - error /= testReberGrammarCount; - if (error <= 0.3) - { - ++successes; - break; - } - - offset += 3; - } - - REQUIRE(successes >= 1); -} - -/** - * Train the specified networks on an embedded Reber grammar dataset. - */ -TEST_CASE("LSTMReberGrammarTest", "[RecurrentNetworkTest]") -{ - RNN > model(5); - model.Add >(7, 10); - model.Add >(10, 10); - model.Add >(10, 7); - model.Add >(); - ReberGrammarTestNetwork(model, false); -} - -/** - * Train the specified networks on an embedded Reber grammar dataset. - */ -TEST_CASE("FastLSTMReberGrammarTest", "[RecurrentNetworkTest]") -{ - RNN > model(5); - model.Add >(7, 8); - model.Add >(8, 8); - model.Add >(8, 7); - model.Add >(); - ReberGrammarTestNetwork(model, false); -} - -/** - * Train the specified networks on an embedded Reber grammar dataset. - */ -TEST_CASE("GRURecursiveReberGrammarTest", "[RecurrentNetworkTest]") -{ - RNN > model(5); - model.Add >(7, 16); - model.Add >(16, 16); - model.Add >(16, 7); - model.Add >(); - ReberGrammarTestNetwork(model, true, 3, 5, 10, 7); -} - -/** - * Train BLSTM on an embedded Reber grammar dataset. - */ -TEST_CASE("BRNNReberGrammarTest", "[RecurrentNetworkTest]") -{ - BRNN, AddMerge<>, SigmoidLayer<> > model(5); - model.Add >(7, 10); - model.Add >(10, 10); - model.Add >(10, 7); - ReberGrammarTestNetwork(model, false, 3, 5, 1); -} - -||||||| c889cd06d -/** - * Train the BRNN on a larger dataset. - */ -TEST_CASE("SequenceClassificationBRNNTest", "[RecurrentNetworkTest]") -{ - // Using same test for RNN below. - size_t successes = 0; - const size_t rho = 10; - - for (size_t trial = 0; trial < 6; ++trial) - { - // Generate 12 (2 * 6) noisy sines. A single sine contains rho - // points/features. - arma::cube input; - arma::mat labelsTemp; - GenerateNoisySines(input, labelsTemp, rho, 6); - - arma::cube labels = arma::zeros(1, labelsTemp.n_cols, rho); - for (size_t i = 0; i < labelsTemp.n_cols; ++i) - { - const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - labels.tube(0, i).fill(value); - } - - Add<> add(4); - Linear<> lookup(1, 4); - SigmoidLayer<> sigmoidLayer; - Linear<> linear(4, 4); - Recurrent<>* recurrent = new Recurrent<>( - add, lookup, linear, sigmoidLayer, rho); - - BRNN<> model(rho); - model.Add >(); - model.Add(recurrent); - model.Add >(4, 5); - - StandardSGD opt(0.1, 1, 500 * input.n_cols, -100); - model.Train(input, labels, opt); - INFO("Training over"); - arma::cube prediction; - model.Predict(input, prediction); - INFO("Prediction over"); - - size_t error = 0; - for (size_t i = 0; i < prediction.n_cols; ++i) - { - const int predictionValue = arma::as_scalar(arma::find( - arma::max(prediction.slice(rho - 1).col(i)) == - prediction.slice(rho - 1).col(i), 1) + 1); - - const int targetValue = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - - if (predictionValue == targetValue) - { - error++; - } - } - - double classificationError = 1 - double(error) / prediction.n_cols; - INFO(classificationError); - if (classificationError <= 0.2) - { - ++successes; - break; - } - } - - REQUIRE(successes >= 1); -} - -/** - * Train the vanilla network on a larger dataset. - */ -TEST_CASE("SequenceClassificationTest", "[RecurrentNetworkTest]") -{ - // It isn't guaranteed that the recurrent network will converge in the - // specified number of iterations using random weights. If this works 1 of 6 - // times, I'm fine with that. All I want to know is that the network is able - // to escape from local minima and to solve the task. - size_t successes = 0; - const size_t rho = 10; - - for (size_t trial = 0; trial < 6; ++trial) - { - // Generate 12 (2 * 6) noisy sines. A single sine contains rho - // points/features. - arma::cube input; - arma::mat labelsTemp; - GenerateNoisySines(input, labelsTemp, rho, 6); - - arma::cube labels = arma::zeros(1, labelsTemp.n_cols, rho); - for (size_t i = 0; i < labelsTemp.n_cols; ++i) - { - const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - labels.tube(0, i).fill(value); - } - - /** - * Construct a network with 1 input unit, 4 hidden units and 10 output - * units. The hidden layer is connected to itself. The network structure - * looks like: - * - * Input Hidden Output - * Layer(1) Layer(4) Layer(10) - * +-----+ +-----+ +-----+ - * | | | | | | - * | +------>| +------>| | - * | | ..>| | | | - * +-----+ . +--+--+ +-----+ - * . . - * . . - * ....... - */ - Add<> add(4); - Linear<> lookup(1, 4); - SigmoidLayer<> sigmoidLayer; - Linear<> linear(4, 4); - Recurrent<>* recurrent = new Recurrent<>( - add, lookup, linear, sigmoidLayer, rho); - - RNN<> model(rho); - model.Add >(); - model.Add(recurrent); - model.Add >(4, 10); - model.Add >(); - - StandardSGD opt(0.1, 1, 500 * input.n_cols, -100); - model.Train(input, labels, opt); - - arma::cube prediction; - model.Predict(input, prediction); - - size_t error = 0; - for (size_t i = 0; i < prediction.n_cols; ++i) - { - const int predictionValue = arma::as_scalar(arma::find( - arma::max(prediction.slice(rho - 1).col(i)) == - prediction.slice(rho - 1).col(i), 1) + 1); - - const int targetValue = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; - - if (predictionValue == targetValue) - { - error++; - } - } - - double classificationError = 1 - double(error) / prediction.n_cols; - if (classificationError <= 0.2) - { - ++successes; - break; - } - } - - REQUIRE(successes >= 1); -} - -/** - * Generate a random Reber grammar. - * - * For more information, see the following thesis. - * - * @code - * @misc{Gers2001, - * author = {Felix Gers}, - * title = {Long Short-Term Memory in Recurrent Neural Networks}, - * year = {2001} - * } - * @endcode - * - * @param transitions Reber grammar transition matrix. - * @param reber The generated Reber grammar string. - */ -void GenerateReber(const arma::Mat& transitions, std::string& reber) -{ - size_t idx = 0; - reber = "B"; - - do - { - const int grammerIdx = rand() % 2; - reber += arma::as_scalar(transitions.submat(idx, grammerIdx, idx, - grammerIdx)); - - idx = arma::as_scalar(transitions.submat(idx, grammerIdx + 2, idx, - grammerIdx + 2)) - '0'; - } while (idx != 0); -} - -/** - * Generate a random recursive Reber grammar. - * - * @param transitions Recursive Reber grammar transition matrix. - * @param averageRecursion Average recursive depth of the reber grammar. - * @param maxRecursion Maximum recursive depth of reber grammar. - * @param reber The generated embedded Reber grammar string. - * @param addEnd Add ending 'E' to the generated grammar. - */ -void GenerateRecursiveReber(const arma::Mat& transitions, - size_t averageRecursion, - size_t maxRecursion, - std::string& reber, - bool addEnd = true) -{ - char c = (rand() % averageRecursion) == 1 ? 'P' : 'T'; - - if (maxRecursion == 1 || c == 'T') - { - c = 'T'; - GenerateReber(transitions, reber); - } - else - { - GenerateRecursiveReber(transitions, averageRecursion, --maxRecursion, - reber, false); - } - - reber = c + reber + c; - - if (addEnd) - { - reber = "B" + reber + "E"; - } -} - -/** - * Convert a unit vector to a Reber symbol. - * - * @param translation The unit vector to be converted. - * @param symbol The converted unit vector stored as Reber symbol. - */ -template -void ReberReverseTranslation(const MatType& translation, char& symbol) -{ - arma::Col symbols; - symbols << 'B' << 'T' << 'S' << 'X' << 'P' << 'V' << 'E' << arma::endr; - const int idx = arma::as_scalar(arma::find(translation == 1, 1, "first")); - - symbol = symbols(idx); -} - -/** - * Convert a Reber symbol to a unit vector. - * - * @param symbol Reber symbol to be converted. - * @param translation The converted symbol stored as unit vector. - */ -void ReberTranslation(const char symbol, arma::colvec& translation) -{ - arma::Col symbols; - symbols << 'B' << 'T' << 'S' << 'X' << 'P' << 'V' << 'E' << arma::endr; - const int idx = arma::as_scalar(arma::find(symbols == symbol, 1, "first")); - - translation = arma::zeros(7); - translation(idx) = 1; -} - -/** - * Given a Reber string, return a Reber string with all reachable next symbols. - * - * @param transitions The Reber transistion matrix. - * @param reber The Reber string used to generate all reachable next symbols. - * @param nextReber All reachable next symbols. - */ -void GenerateNextReber(const arma::Mat& transitions, - const std::string& reber, std::string& nextReber) -{ - size_t idx = 0; - - for (size_t grammer = 1; grammer < reber.length(); grammer++) - { - const int grammerIdx = arma::as_scalar(arma::find( - transitions.row(idx) == reber[grammer], 1, "first")); - - idx = arma::as_scalar(transitions.submat(idx, grammerIdx + 2, idx, - grammerIdx + 2)) - '0'; - } - - nextReber = arma::as_scalar(transitions.submat(idx, 0, idx, 0)); - nextReber += arma::as_scalar(transitions.submat(idx, 1, idx, 1)); -} - -/** - * Given a recursive Reber string, return a Reber string with all - * reachable next symbols. - * - * @param transitions The Reber transistion matrix. - * @param reber The Reber string used to generate all reachable next symbols. - * @param nextReber All reachable next symbols. - */ -void GenerateNextRecursiveReber(const arma::Mat& transitions, - const std::string& reber, - std::string& nextReber) -{ - size_t state = 0; - size_t numPs = 0; - - for (size_t cIndex = 0; cIndex < reber.length(); cIndex++) - { - char c = reber[cIndex]; - - if (c == 'B' && state == 0) - { - state = 1; - } - else if (c == 'P' && state == 1) - { - numPs++; - state = 1; - } - else if (c == 'T' && state == 1) - { - state = 2; - } - else if (c == 'B' && state == 2) - { - size_t pos = reber.find('E'); - if (pos != std::string::npos) - { - cIndex = pos; - state = 4; - } - else - { - GenerateNextReber(transitions, reber.substr(cIndex), nextReber); - state = 3; - } - } - else if (c == 'T' && state == 4) - { - state = 5; - } - else if (c == 'P' && state == 5) - { - numPs--; - state = 5; - } - } - - if (state == 0 || state == 2) - { - nextReber = "B"; - } - else if (state == 1) - { - nextReber = "PT"; - } - else if (state == 4) - { - nextReber = "T"; - } - else if (state == 5) - { - if (numPs == 0) - { - nextReber = "E"; - } - else - { - nextReber = "P"; - } - } -} - -/** - * @brief Creates the reber grammar data for tests. - * - * @param trainInput The train data - * @param trainLabels The train labels - * @param testInput The test input - * @param recursive whether recursive Reber - * @param trainReberGrammarCount The number of training set - * @param testReberGrammarCount The number of test set - * @param averageRecursion Average recursion - * @param maxRecursion Max recursion - * @return arma::Mat The Reber state translation to be used. - */ -arma::Mat GenerateReberGrammarData( - arma::field& trainInput, - arma::field& trainLabels, - arma::field& testInput, - bool recursive = false, - const size_t trainReberGrammarCount = 700, - const size_t testReberGrammarCount = 250, - const size_t averageRecursion = 3, - const size_t maxRecursion = 5) -{ - // Reber state transition matrix. (The last two columns are the indices to the - // next path). - arma::Mat transitions; - transitions << 'T' << 'P' << '1' << '2' << arma::endr - << 'X' << 'S' << '3' << '1' << arma::endr - << 'V' << 'T' << '4' << '2' << arma::endr - << 'X' << 'S' << '2' << '5' << arma::endr - << 'P' << 'V' << '3' << '5' << arma::endr - << 'E' << 'E' << '0' << '0' << arma::endr; - - - std::string trainReber, testReber; - - arma::colvec translation; - - // Generate the training data. - for (size_t i = 0; i < trainReberGrammarCount; ++i) - { - if (recursive) - GenerateRecursiveReber(transitions, 3, 5, trainReber); - else - GenerateReber(transitions, trainReber); - - for (size_t j = 0; j < trainReber.length() - 1; ++j) - { - ReberTranslation(trainReber[j], translation); - trainInput(0, i) = arma::join_cols(trainInput(0, i), translation); - - ReberTranslation(trainReber[j + 1], translation); - trainLabels(0, i) = arma::join_cols(trainLabels(0, i), translation); - } - } - - // Generate the test data. - for (size_t i = 0; i < testReberGrammarCount; ++i) - { - if (recursive) - GenerateRecursiveReber(transitions, averageRecursion, maxRecursion, - testReber); - else - GenerateReber(transitions, testReber); - - for (size_t j = 0; j < testReber.length() - 1; ++j) - { - ReberTranslation(testReber[j], translation); - testInput(0, i) = arma::join_cols(testInput(0, i), translation); - } - } - - return transitions; -} - -/** - * Train the specified network and the construct a Reber grammar dataset. - */ -template -void ReberGrammarTestNetwork(ModelType& model, - const bool recursive = false, - const size_t averageRecursion = 3, - const size_t maxRecursion = 5, - const size_t iterations = 10, - const size_t trials = 5) -{ - const size_t trainReberGrammarCount = 700; - const size_t testReberGrammarCount = 250; - - arma::field trainInput(1, trainReberGrammarCount); - arma::field trainLabels(1, trainReberGrammarCount); - arma::field testInput(1, testReberGrammarCount); - - arma::Mat transitions = - GenerateReberGrammarData(trainInput, - trainLabels, - testInput, - recursive, - trainReberGrammarCount, - testReberGrammarCount, - averageRecursion, - maxRecursion); - - /* - * Construct a network with 7 input units, layerSize hidden units and 7 output - * units. The hidden layer is connected to itself. The network structure looks - * like: - * - * Input Hidden Output - * Layer(7) Layer(layerSize) Layer(7) - * +-----+ +-----+ +-----+ - * | | | | | | - * | +------>| +------>| | - * | | ..>| | | | - * +-----+ . +--+--+ +-- ---+ - * . . - * . . - * ....... - */ - // It isn't guaranteed that the recurrent network will converge in the - // specified number of iterations using random weights. If this works 1 of 5 - // times, I'm fine with that. All I want to know is that the network is able - // to escape from local minima and to solve the task. - size_t successes = 0; - size_t offset = 0; - const size_t inputSize = 7; - for (size_t trial = 0; trial < trials; ++trial) - { - // Reset model before using for next trial. - model.Reset(); - MomentumSGD opt(0.06, 50, 2, -50000); - - arma::cube inputTemp, labelsTemp; - for (size_t iteration = 0; iteration < (iterations + offset); iteration++) - { - for (size_t j = 0; j < trainReberGrammarCount; ++j) - { - // Each sequence may be a different length, so we need to extract them - // manually. We will reshape them into a cube with each slice equal to - // a time step. - inputTemp = arma::cube(trainInput.at(0, j).memptr(), inputSize, 1, - trainInput.at(0, j).n_elem / inputSize, false, true); - labelsTemp = arma::cube(trainLabels.at(0, j).memptr(), inputSize, 1, - trainInput.at(0, j).n_elem / inputSize, false, true); - - model.Rho() = inputTemp.n_elem / inputSize; - model.Train(inputTemp, labelsTemp, opt); - opt.ResetPolicy() = false; - } - } - - double error = 0; - - // Ask the network to predict the next Reber grammar in the given sequence. - for (size_t i = 0; i < testReberGrammarCount; ++i) - { - arma::cube prediction; - arma::cube input(testInput.at(0, i).memptr(), inputSize, 1, - testInput.at(0, i).n_elem / inputSize, false, true); - - model.Rho() = input.n_elem / inputSize; - model.Predict(input, prediction); - - const size_t reberGrammerSize = 7; - std::string inputReber = ""; - - size_t reberError = 0; - - for (size_t j = 0; j < (prediction.n_elem / reberGrammerSize); ++j) - { - char predictedSymbol, inputSymbol; - std::string reberChoices; - - arma::umat output = (prediction.slice(j) == (arma::ones( - reberGrammerSize, 1) * - arma::as_scalar(arma::max(prediction.slice(j))))); - - ReberReverseTranslation(output, predictedSymbol); - ReberReverseTranslation(input.slice(j), inputSymbol); - inputReber += inputSymbol; - - if (recursive) - GenerateNextRecursiveReber(transitions, inputReber, reberChoices); - else - GenerateNextReber(transitions, inputReber, reberChoices); - - if (reberChoices.find(predictedSymbol) != std::string::npos) - reberError++; - } - - if (reberError != (prediction.n_elem / reberGrammerSize)) - error += 1; - } - - error /= testReberGrammarCount; - if (error <= 0.3) - { - ++successes; - break; - } - - offset += 3; - } - - REQUIRE(successes >= 1); -} - -/** - * Train the specified networks on an embedded Reber grammar dataset. - */ -TEST_CASE("LSTMReberGrammarTest", "[RecurrentNetworkTest]") -{ - RNN > model(5); - model.Add >(7, 10); - model.Add >(10, 10); - model.Add >(10, 7); - model.Add >(); - ReberGrammarTestNetwork(model, false); -} - -/** - * Train the specified networks on an embedded Reber grammar dataset. - */ -TEST_CASE("FastLSTMReberGrammarTest", "[RecurrentNetworkTest]") -{ - RNN > model(5); - model.Add >(7, 8); - model.Add >(8, 8); - model.Add >(8, 7); - model.Add >(); - ReberGrammarTestNetwork(model, false); -} - -/** - * Train the specified networks on an embedded Reber grammar dataset. - */ -TEST_CASE("GRURecursiveReberGrammarTest", "[RecurrentNetworkTest]") -{ - RNN > model(5); - model.Add >(7, 16); - model.Add >(16, 16); - model.Add >(16, 7); - model.Add >(); - ReberGrammarTestNetwork(model, true, 3, 5, 10, 7); -} - -/** - * Train BLSTM on an embedded Reber grammar dataset. - */ -TEST_CASE("BRNNReberGrammarTest", "[RecurrentNetworkTest]") -{ - BRNN, AddMerge<>, SigmoidLayer<> > model(5); - model.Add >(7, 10); - model.Add >(10, 10); - model.Add >(10, 7); - ReberGrammarTestNetwork(model, false, 3, 5, 1); -} - /* * This sample is a simplified version of Derek D. Monner's Distracted Sequence * Recall task, which involves 10 symbols: @@ -2073,7 +818,7 @@ TEST_CASE("LargeRhoValueRnnTest", "[RecurrentNetworkTest]") using MatType = arma::cube; std::vectortrainingData = { "THIS IS THE INPUT 0" , "THIS IS THE INPUT 1" , - "THIS IS THE INPUT 3" }; + "THIS IS THE INPUT 3"}; RNN<> model(rho); diff --git a/src/mlpack/tests/rnn_reber_test.cpp b/src/mlpack/tests/rnn_reber_test.cpp index b583a1c64a..a7e0ff3ef8 100644 --- a/src/mlpack/tests/rnn_reber_test.cpp +++ b/src/mlpack/tests/rnn_reber_test.cpp @@ -106,7 +106,7 @@ template void ReberReverseTranslation(const MatType& translation, char& symbol) { arma::Col symbols; - symbols << 'B' << 'T' << 'S' << 'X' << 'P' << 'V' << 'E' << arma::endr; + symbols = { 'B', 'T', 'S', 'X', 'P', 'V', 'E' }; const int idx = arma::as_scalar(arma::find(translation == 1, 1, "first")); symbol = symbols(idx); @@ -121,7 +121,7 @@ void ReberReverseTranslation(const MatType& translation, char& symbol) void ReberTranslation(const char symbol, arma::colvec& translation) { arma::Col symbols; - symbols << 'B' << 'T' << 'S' << 'X' << 'P' << 'V' << 'E' << arma::endr; + symbols = { 'B', 'T', 'S', 'X', 'P', 'V', 'E' }; const int idx = arma::as_scalar(arma::find(symbols == symbol, 1, "first")); translation = arma::zeros(7); @@ -261,12 +261,12 @@ arma::Mat GenerateReberGrammarData( // Reber state transition matrix. (The last two columns are the indices to the // next path). arma::Mat transitions; - transitions << 'T' << 'P' << '1' << '2' << arma::endr - << 'X' << 'S' << '3' << '1' << arma::endr - << 'V' << 'T' << '4' << '2' << arma::endr - << 'X' << 'S' << '2' << '5' << arma::endr - << 'P' << 'V' << '3' << '5' << arma::endr - << 'E' << 'E' << '0' << '0' << arma::endr; + transitions = { { 'T', 'P', '1', '2' }, + { 'X', 'S', '3', '1' }, + { 'V', 'T', '4', '2' }, + { 'X', 'S', '2', '5' }, + { 'P', 'V', '3', '5' }, + { 'E', 'E', '0', '0' } }; std::string trainReber, testReber; From 03e6c086c7c13c21df445e02f6a5f7fee22b7aa7 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 11 Nov 2020 18:29:27 +0530 Subject: [PATCH 121/550] Fixed styles in lsh_test.cpp --- src/mlpack/tests/lsh_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 606bf19e84..8063669c1f 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -589,12 +589,12 @@ BOOST_AUTO_TEST_CASE(MultiprobeDeterministicTest) // Construct q1 so it is hashed directly under C2. arma::mat q1; - q1 = arma::mat( { 3.9, 2.99 } ).t(); + q1 = arma::mat({ 3.9, 2.99 }).t(); q1 -= offsets; // Construct q2 so it is hashed near the center of C2. arma::mat q2; - q2 = arma::mat( { 3.6, 3.6 } ); + q2 = arma::mat({ 3.6, 3.6 }).t(); q2 -= offsets; arma::Mat neighbors; From 036b6af2dce90d0350f5750331c03560a769c204 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 11 Nov 2020 18:31:27 +0530 Subject: [PATCH 122/550] Fixed style of distribution_test.cpp --- src/mlpack/tests/distribution_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index bcbd0235fe..caf3540df1 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -1018,7 +1018,7 @@ TEST_CASE("GammaDistributionLogProbabilityTest", "[DistributionTest]") const arma::vec a3("2.0 3.1"), b3("0.9 1.4"); arma::mat x3(2, 2); x3 = { { 2.0, 2.94 }, - { 2.0, 2.94 } }; + { 2.0, 2.94 } }; arma::vec logprob3; // Expect that the 2-dimensional distribution returns the product of the From 2f7054a4957142d3bd0f705dea1ffca1558030bf Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 11 Nov 2020 18:35:16 +0530 Subject: [PATCH 123/550] Fixed style in lsh_test.cpp --- src/mlpack/tests/lsh_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 8063669c1f..972db2906a 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -44,7 +44,7 @@ void GetPointset(const size_t N, arma::mat& rdata) arma::colvec offset2; offset2 = { { 3 }, - { 3 } }; + { 3 } }; arma::colvec offset4; offset4 = { { 3 }, From 1bd61054f9799bbcc7959bd48e5841be57972103 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 11 Nov 2020 09:14:43 -0500 Subject: [PATCH 124/550] Got it! Now let's see if it works. --- .ci/windows-steps.yaml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 84549e1246..69d9b0d0a8 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -161,18 +161,7 @@ steps: } # Build the MSI installer. - dir 'C:\Program Files (x86)\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\' - dir 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\' - & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' ` + & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild -p:Configuration=Release ` -p:TreatWarningsAsErrors=True ` From 04d23250caa2232ca79428ce9bd7791b64e38658 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 11 Nov 2020 18:19:24 -0500 Subject: [PATCH 125/550] Ugh, forgot a backtick... --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 69d9b0d0a8..5414084fa3 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -162,7 +162,7 @@ steps: # Build the MSI installer. & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' ` - -t:rebuild + -t:rebuild ` -p:Configuration=Release ` -p:TreatWarningsAsErrors=True ` mlpack-win-installer.wixproj From 261cec6374e871d6047422dc3731ef4744f8e6e5 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 12 Nov 2020 14:28:11 +0530 Subject: [PATCH 126/550] deleted layers and added spaces --- src/mlpack/tests/ann_visitor_test.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index be37b4fda6..a0002ee445 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -198,12 +198,11 @@ TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") size_t randomKernelHeight = arma::randi(arma::distr_param(1, 100)); LayerTypes<> transposedConvLayer = new TransposedConvolution<>(randomInSize, - randomOutSize, randomKernelWidth, randomKernelHeight); - - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), - transposedConvLayer); + randomOutSize, randomKernelWidth, randomKernelHeight); CheckCorrectnessOfWeightSize(transposedConvLayer); + + delete transposedConvLayer; } /** @@ -215,10 +214,9 @@ TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") size_t randomOutSize = arma::randi(arma::distr_param(1, 100)); LayerTypes<> noisyLinearLayer = new NoisyLinear<>(randomInSize, - randomOutSize); - - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), - noisyLinearLayer); + randomOutSize); CheckCorrectnessOfWeightSize(noisyLinearLayer); + + delete noisyLinearLayer; } From c4580844499034bfacce19726054871e15e83bc9 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 12 Nov 2020 15:19:56 +0530 Subject: [PATCH 127/550] removing delete --- src/mlpack/tests/ann_visitor_test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index a0002ee445..d741b94328 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -201,8 +201,6 @@ TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") randomOutSize, randomKernelWidth, randomKernelHeight); CheckCorrectnessOfWeightSize(transposedConvLayer); - - delete transposedConvLayer; } /** @@ -217,6 +215,4 @@ TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") randomOutSize); CheckCorrectnessOfWeightSize(noisyLinearLayer); - - delete noisyLinearLayer; } From 6c8123e52d01a7891e477de108c175615c0276bf Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Fri, 13 Nov 2020 12:09:37 +0530 Subject: [PATCH 128/550] Added test for copy and move constructor of linear3d --- src/mlpack/tests/feedforward_network_test.cpp | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index bcffa4c8a8..dd8312813e 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -155,6 +155,59 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } +/** + * Check whether copying and moving network with linear3d is working or not. + */ +TEST_CASE("CheckCopyMovingLinear3DNetworkTest", "[FeedForwardNetworkTest]") +{ + // Load the dataset. + arma::mat trainData; + data::Load("thyroid_train.csv", trainData, true); + + arma::mat trainLabels = trainData.row(trainData.n_rows - 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 + * +-----+ +-----+ +-----+ + * | | | | | | + * | +------>| +------>| | + * | | +>| | +>| | + * +-----+ | +--+--+ | +-----+ + * | | + * Bias | Bias | + * 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); +} + /** * Train the vanilla network on a larger dataset. */ From 9a35092b8f52d7593f116c6c5480b8bcdce7acff Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Fri, 13 Nov 2020 15:43:23 +0530 Subject: [PATCH 129/550] Fixed typos --- src/mlpack/methods/ann/layer/linear3d_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/linear3d_impl.hpp b/src/mlpack/methods/ann/layer/linear3d_impl.hpp index ab7434c6c7..48ae77f749 100644 --- a/src/mlpack/methods/ann/layer/linear3d_impl.hpp +++ b/src/mlpack/methods/ann/layer/linear3d_impl.hpp @@ -59,7 +59,7 @@ Linear3D::Linear3D( inSize(0), outSize(0), weights(std::move(layer.weights)), - regularizer(std::move(layer.regularizer)); + regularizer(std::move(layer.regularizer)) { // Nothing to do here. } @@ -85,7 +85,7 @@ template& Linear3D:: operator=(Linear3D&& layer) -P +{ if (this != &layer) { inSize = 0; From 541e64c3b1e77781b6e8b41579f580b9755aad23 Mon Sep 17 00:00:00 2001 From: jeffin143 Date: Fri, 13 Nov 2020 22:51:04 +0530 Subject: [PATCH 130/550] some boost cleanup --- .appveyor.yml | 1 - CMakeLists.txt | 27 +++-------------------- src/mlpack/bindings/cli/CMakeLists.txt | 1 - src/mlpack/bindings/python/CMakeLists.txt | 9 -------- src/mlpack/bindings/python/setup.py.in | 3 +-- src/mlpack/tests/CMakeLists.txt | 1 - 6 files changed, 4 insertions(+), 38 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 08c8dc4468..722a597468 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -71,7 +71,6 @@ build_script: -DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY% -DCEREAL_INCLUDE_DIR="C:/projects/mlpack/unofficial-flayan-cereal.1.2.2/build/native/include" -DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE% - -DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs" -DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF diff --git a/CMakeLists.txt b/CMakeLists.txt index 10f126283a..056edaa52e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -288,7 +288,6 @@ endif() # ARMADILLO_INCLUDE_DIRS - directories necessary for Armadillo includes # BOOST_ROOT - root of Boost installation # BOOST_INCLUDEDIR - include directory for Boost -# BOOST_LIBRARYDIR - library directory for Boost # ENSMALLEN_INCLUDE_DIR - include directory for ensmallen # STB_IMAGE_INCLUDE_DIR - include directory for STB image library # MATHJAX_ROOT - root of MathJax installation @@ -442,31 +441,11 @@ set(Boost_ADDITIONAL_VERSIONS # TODO for the brave: transition all mlpack's CMake to 'target-based modern # CMake'. Good luck! You'll need it. set(Boost_NO_BOOST_CMAKE 1) -find_package(Boost "${BOOST_VERSION}" - COMPONENTS - REQUIRED -) - -link_directories(${Boost_LIBRARY_DIRS}) - -# In Visual Studio, automatic linking is performed, so we don't need to worry -# about it. Clear the list of libraries to link against and let Visual Studio -# handle it. -if (MSVC) - link_directories(${Boost_LIBRARY_DIRS}) - set(CMAKE_MSVCIDE_RUN_PATH ${CMAKE_MSVCIDE_RUN_PATH} ${Boost_LIBRARY_DIRS}) - message("boost lib dirs ${Boost_LIBRARY_DIRS}") - set(Boost_LIBRARIES "") -endif () +find_package(Boost "${BOOST_VERSION}") set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) -set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${Boost_LIBRARIES}) -set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS}) - -# For Boost testing framework (will have no effect on non-testing executables). -# This specifies to Boost that we are dynamically linking to the Boost test -# library. -add_definitions(-DBOOST_TEST_DYN_LINK) +set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES}) +set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS}) # Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags # to compile with OpenMP are returned and added and the HAS_OPENMP definition diff --git a/src/mlpack/bindings/cli/CMakeLists.txt b/src/mlpack/bindings/cli/CMakeLists.txt index 1083ec41f2..4b94805fe5 100644 --- a/src/mlpack/bindings/cli/CMakeLists.txt +++ b/src/mlpack/bindings/cli/CMakeLists.txt @@ -53,7 +53,6 @@ if (BUILD_CLI_EXECUTABLES) target_link_libraries(mlpack_${name} mlpack ${ARMADILLO_LIBRARIES} - ${Boost_LIBRARIES} ${COMPILER_SUPPORT_LIBRARIES} ) # Make sure that we set BINDING_TYPE to cli so the command-line program is diff --git a/src/mlpack/bindings/python/CMakeLists.txt b/src/mlpack/bindings/python/CMakeLists.txt index 180014ed3c..65490997c3 100644 --- a/src/mlpack/bindings/python/CMakeLists.txt +++ b/src/mlpack/bindings/python/CMakeLists.txt @@ -18,7 +18,6 @@ macro (post_python_bindings) -D GENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/setup.py.in -D GENERATE_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py -D PACKAGE_VERSION="${PACKAGE_VERSION}" - -D Boost_LIBRARY_DIRS="${Boost_LIBRARY_DIRS}" -D ARMADILLO_LIBRARIES="${ARMADILLO_LIBRARIES}" -D MLPACK_LIBRARY=$ -D MLPACK_LIBDIR=$ @@ -240,14 +239,6 @@ if (WIN32) foreach (dll ${DLL_COPY_LIBS}) file(COPY ${dll} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/) endforeach () - - # We also need to copy the boost DLLs over. - file(GLOB boost_ser_dll_files "${Boost_LIBRARY_DIRS}/*serialization*.dll") - file(COPY ${boost_ser_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/) - file(GLOB boost_po_dll_files "${Boost_LIBRARY_DIRS}/*program*options*.dll") - file(COPY ${boost_po_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/) - file(GLOB boost_utf_dll_files "${Boost_LIBRARY_DIRS}/*unit*test*framework*.dll") - file(COPY ${boost_utf_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/) endif () # Add a macro to build a python binding. diff --git a/src/mlpack/bindings/python/setup.py.in b/src/mlpack/bindings/python/setup.py.in index a69432f539..2d7d921a46 100644 --- a/src/mlpack/bindings/python/setup.py.in +++ b/src/mlpack/bindings/python/setup.py.in @@ -34,8 +34,7 @@ else: # directories with a (valid) space in the name will be given to us as '\ '; so, # in order to split these right, we first convert all spaces to ';', then # convert '\;' back to ' ', then split on ';'. -library_dirs = list(filter(None, ['${MLPACK_LIBDIR}'] + - '${Boost_LIBRARY_DIRS}'.replace(' ', ';').replace('\;', ' ').split(' '))) +library_dirs = list(filter(None, ['${MLPACK_LIBDIR}'])) # We'll link with the exact paths to each library using extra_objects, instead # of linking with 'libraries' and 'library_dirs', because of differences in diff --git a/src/mlpack/tests/CMakeLists.txt b/src/mlpack/tests/CMakeLists.txt index 48d05959cf..3b7ebb4b05 100644 --- a/src/mlpack/tests/CMakeLists.txt +++ b/src/mlpack/tests/CMakeLists.txt @@ -179,7 +179,6 @@ add_executable(mlpack_test target_link_libraries(mlpack_test mlpack ${ARMADILLO_LIBRARIES} - ${BOOST_LIBRARIES} ${COMPILER_SUPPORT_LIBRARIES} ) From cd1301c5d13a2a3de9b6cba823d30750efdd6471 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 14 Nov 2020 10:25:07 +0530 Subject: [PATCH 131/550] Improved variable names in MSE --- .../ann/loss_functions/mean_squared_error.hpp | 18 ++++++++++-------- .../loss_functions/mean_squared_error_impl.hpp | 16 ++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp index 3c36b33611..7df7eb3cf1 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp @@ -42,24 +42,26 @@ class MeanSquaredError /** * Computes the mean squared error function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/mean_squared_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/mean_squared_error_impl.hpp index 85cdbb3b45..ee4ae8c021 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_squared_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_squared_error_impl.hpp @@ -25,23 +25,23 @@ MeanSquaredError::MeanSquaredError() } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type MeanSquaredError::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - return arma::accu(arma::square(input - target)) / target.n_cols; + return arma::accu(arma::square(prediction - target)) / target.n_cols; } template -template +template void MeanSquaredError::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = 2 * (input - target) / target.n_cols; + loss = 2 * (prediction - target) / target.n_cols; } template From 05e21d9f59e2e3c9a37fdad0c7c440869f2f3668 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 14 Nov 2020 23:45:19 +0530 Subject: [PATCH 132/550] Made requested changes --- src/mlpack/tests/binarize_test.cpp | 2 +- src/mlpack/tests/lsh_test.cpp | 6 +----- src/mlpack/tests/maximal_inputs_test.cpp | 6 ++---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/mlpack/tests/binarize_test.cpp b/src/mlpack/tests/binarize_test.cpp index e050f65ca4..b6ae6b2885 100644 --- a/src/mlpack/tests/binarize_test.cpp +++ b/src/mlpack/tests/binarize_test.cpp @@ -47,7 +47,7 @@ TEST_CASE("BinerizeAll", "[BinarizeTest]") { mat input; input = { { 1, 2, 3 }, - { 4, 5, 6 }, // this row will be tested + { 4, 5, 6 }, // This row will be tested. { 7, 8, 9 } }; mat output; diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 972db2906a..0042c20255 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -689,11 +689,7 @@ BOOST_AUTO_TEST_CASE(RecallTestPartiallyCorrect) // be 0 but recall should not be. arma::Mat q2; q2.set_size(k, numQueries); - q2 << 2 << arma::endr - << 3 << arma::endr - << 4 << arma::endr - << 6 << arma::endr - << 7 << arma::endr; + q2 = arma::mat({ 2, 3, 4, 6, 7 }).t(); BOOST_REQUIRE_CLOSE(LSHSearch<>::ComputeRecall(base, q2), 0.6, 0.0001); } diff --git a/src/mlpack/tests/maximal_inputs_test.cpp b/src/mlpack/tests/maximal_inputs_test.cpp index f324f2304a..94a395b404 100644 --- a/src/mlpack/tests/maximal_inputs_test.cpp +++ b/src/mlpack/tests/maximal_inputs_test.cpp @@ -71,12 +71,10 @@ BOOST_AUTO_TEST_CASE(ColumnToBlocksChangeBlockSize) ctb.Transform(CreateMaximalInput(), output); arma::mat matlabResults; - matlabResults = { { -3, -3, -3, -3, -3, -3, -3, - -3, -3, -3, -3 }, + matlabResults = { { -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3 }, { -3, -1, -0.71429, -0.42857, -0.14286, -3, 0.14286, 0.42857, 0.71429, 1, -3 }, - { -3, -3, -3, -3, -3, -3, -3, - -3, -3, -3, -3 } }; + { -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3 } }; TestResults(output, matlabResults); } From fa26a28b583df75f94a568af0190cc4825679bc4 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 14 Nov 2020 23:55:17 +0530 Subject: [PATCH 133/550] Made requested changes --- src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp index 7df7eb3cf1..0cc3f6378d 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_squared_error.hpp @@ -43,12 +43,12 @@ class MeanSquaredError * Computes the mean squared error function. * * @param prediction Predictions used for evaluating the specified loss - * function. + * function. * @param target The target vector. */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. From fa33f7d5c1e500978e638ff1e6312249fb51ec9f Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sun, 15 Nov 2020 01:36:18 +0530 Subject: [PATCH 134/550] Fixed a small but in lsh_test --- src/mlpack/tests/lsh_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/lsh_test.cpp b/src/mlpack/tests/lsh_test.cpp index 0042c20255..f49d81f8e6 100644 --- a/src/mlpack/tests/lsh_test.cpp +++ b/src/mlpack/tests/lsh_test.cpp @@ -689,7 +689,7 @@ BOOST_AUTO_TEST_CASE(RecallTestPartiallyCorrect) // be 0 but recall should not be. arma::Mat q2; q2.set_size(k, numQueries); - q2 = arma::mat({ 2, 3, 4, 6, 7 }).t(); + q2 = arma::Mat({ 2, 3, 4, 6, 7 }).t(); BOOST_REQUIRE_CLOSE(LSHSearch<>::ComputeRecall(base, q2), 0.6, 0.0001); } From f6b5641381e9324d1dc17a3fd65158f88ace3632 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 15 Nov 2020 21:14:02 +0530 Subject: [PATCH 135/550] Restarting Checks From a705ca7d3fe03f1eb483873ec230cfb4b2731c17 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 16 Nov 2020 18:32:57 -0500 Subject: [PATCH 136/550] Make sure we are in the right directory before running. --- .ci/windows-steps.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 5414084fa3..b0a383271d 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -161,6 +161,8 @@ steps: } # Build the MSI installer. + cd dist\win-installer\mlpack-win-installer + dir & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild ` -p:Configuration=Release ` From 93b27f6ec08df3ac7549fd1c950036951f6991bf Mon Sep 17 00:00:00 2001 From: jeffin143 Date: Tue, 17 Nov 2020 23:08:24 +0530 Subject: [PATCH 137/550] cleanup boost furthermore --- doc/guide/build.hpp | 24 ++++++++++++------------ doc/guide/build_windows.hpp | 7 ------- doc/guide/sample_ml_app.hpp | 1 - 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 08068eaa73..9a133319c1 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -2,10 +2,10 @@ @section build_buildintro Introduction -This document discusses how to build mlpack from source. These build directions +This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, -FreeBSD etc). However, mlpack is in the repositories of many Linux distributions -and so it may be easier to use the package manager for your system. For example, +FreeBSD etc). However, mlpack is in the repositories of many Linux distributions +and so it may be easier to use the package manager for your system. For example, on Ubuntu, you can install mlpack with the following command: @code @@ -25,7 +25,7 @@ mlpack uses CMake as a build system and allows several flexible build configuration options. One can consult any of numerous CMake tutorials for further documentation, but this tutorial should be enough to get mlpack built and installed on most Linux and UNIX-like systems (including OS X). If you want -to build mlpack on Windows, see \ref build_windows (alternatively, you can read +to build mlpack on Windows, see \ref build_windows (alternatively, you can read Keon's excellent tutorial which is based on older versions). @@ -78,7 +78,7 @@ mlpack depends on the following libraries, which need to be installed on the system and have headers present: - Armadillo >= 8.400.0 (with LAPACK support) - - Boost (math_c99, unit_test_framework, heap, spirit) >= 1.58 + - Boost (math_c99, spirit) >= 1.58 - cereal >= 1.1.2 - ensmallen >= 2.10.0 (will be downloaded if not found) @@ -95,11 +95,11 @@ For Python bindings, the following packages are required: - pandas >= 0.15.0 - pytest-runner -In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be +In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be installed through apt: @code -# apt-get install libboost-math-dev libboost-test-dev libcereal-dev +# apt-get install libboost-math-dev libcereal-dev libarmadillo-dev binutils-dev python3-pandas python3-numpy cython3 python3-setuptools @endcode @@ -112,18 +112,18 @@ packages: # apt-get install libensmallen-dev libstb-dev @endcode -@note For older versions of Ubuntu and Debian, Armadillo needs to be built from -source as apt installs an older version. So you need to omit +@note For older versions of Ubuntu and Debian, Armadillo needs to be built from +source as apt installs an older version. So you need to omit \c libarmadillo-dev from the code snippet above and instead use this link - to download the required file. Extract this file and follow the README in the + to download the required file. Extract this file and follow the README in the uncompressed folder to build and install Armadillo. On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf: @code -# dnf install boost-devel boost-test boost-math armadillo-devel binutils-devel - python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel +# dnf install boost-devel boost-math armadillo-devel binutils-devel + python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel stbi-devel cereal-devel @endcode diff --git a/doc/guide/build_windows.hpp b/doc/guide/build_windows.hpp index 90fe93c0db..e150cc3b54 100644 --- a/doc/guide/build_windows.hpp +++ b/doc/guide/build_windows.hpp @@ -147,13 +147,6 @@ If you prefer to use cmake GUI, follow these instructions: following variables and reconfigure: - Name: `BOOST_INCLUDEDIR`; type `PATH`; value `C:/boost/` - Name: `BOOST_LIBRARYDIR`; type `PATH`; value `C:/boost/lib64-msvc-14.2` - - If Boost is still not found, try adding the following variables and - reconfigure: - - Name: `Boost_INCLUDE_DIR`; type `PATH`; value `C:/boost/` - - Name: `Boost_SERIALIZATION_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-gd-x64-1_71.lib` - - Name: `Boost_SERIALIZATION_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-x64-1_71.lib` - - Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-gd-x64-1_71.lib` - - Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-x64-1_71.lib` - Once CMake has configured successfully, hit "Generate" to create the `.sln` file. @section build_windows_additional_information Additional Information diff --git a/doc/guide/sample_ml_app.hpp b/doc/guide/sample_ml_app.hpp index 72a7253d5a..b8282a9ade 100644 --- a/doc/guide/sample_ml_app.hpp +++ b/doc/guide/sample_ml_app.hpp @@ -34,7 +34,6 @@ mlpack and dependencies in Release Mode). - Under Linker > Input > Additional Dependencies add: @code - C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib - - C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_serialization-vc142-mt-gd-x64-1_71.lib @endcode - Under Build Events > Post-Build Event > Command Line add: @code From 9b30b6f8268a19091aaffd3708d4ec9c04c109f5 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 17 Nov 2020 17:07:35 -0500 Subject: [PATCH 138/550] Suppress generation of registry elements. (Hopefully I read the documentation right for this part.) --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 16d0572fb6..087d03f6d5 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -33,7 +33,7 @@ - + SourcesDir Sources var.SourcesDir From 4f1d00ba12b1d13b8ccda7836260556d44b52eb7 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 17 Nov 2020 17:08:39 -0500 Subject: [PATCH 139/550] Oh, actually, I'm pretty sure I did that wrong. --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 087d03f6d5..2bb01f2d69 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -33,10 +33,11 @@ - + SourcesDir Sources var.SourcesDir + true $(WixExtDir)\WixUIExtension.dll From 099bf6532a819d9fd2f0f48c1bc02d1c52774b29 Mon Sep 17 00:00:00 2001 From: jeffin sam Date: Wed, 18 Nov 2020 16:34:36 +0530 Subject: [PATCH 140/550] Update src/mlpack/bindings/python/setup.py.in Co-authored-by: Ryan Curtin --- src/mlpack/bindings/python/setup.py.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/bindings/python/setup.py.in b/src/mlpack/bindings/python/setup.py.in index 2d7d921a46..4762f3194b 100644 --- a/src/mlpack/bindings/python/setup.py.in +++ b/src/mlpack/bindings/python/setup.py.in @@ -34,7 +34,7 @@ else: # directories with a (valid) space in the name will be given to us as '\ '; so, # in order to split these right, we first convert all spaces to ';', then # convert '\;' back to ' ', then split on ';'. -library_dirs = list(filter(None, ['${MLPACK_LIBDIR}'])) +library_dirs = ['${MLPACK_LIBDIR}'] # We'll link with the exact paths to each library using extra_objects, instead # of linking with 'libraries' and 'library_dirs', because of differences in From f7038098653406e8cb3e2eb3c930663a1bcdee41 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 18 Nov 2020 08:38:21 -0500 Subject: [PATCH 141/550] Try to set preprocessor variable value correctly. --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 2bb01f2d69..6f102c34f7 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -29,7 +29,7 @@ obj\$(Platform)\$(Configuration)\ - HarvestPath=.\SourceDir + HarvestPath=.\SourceDir;SourcesDir=SourceDir From 6a625192a06ad4f0f4944509833294bf3b68abca Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 22:02:21 +0530 Subject: [PATCH 142/550] cosine embedding loss --- .../loss_functions/cosine_embedding_loss.hpp | 20 ++++++----- .../cosine_embedding_loss_impl.hpp | 34 +++++++++---------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss.hpp b/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss.hpp index ab3296b41d..c7df95e4a4 100644 --- a/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss.hpp @@ -57,24 +57,26 @@ class CosineEmbeddingLoss /** * Ordinary feed forward pass of a neural network. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, - const TargetType& target); + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the input parameter. InputDataType& InputParameter() const { return inputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss_impl.hpp index 194d6a912a..129a12c26c 100644 --- a/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/cosine_embedding_loss_impl.hpp @@ -27,20 +27,20 @@ CosineEmbeddingLoss::CosineEmbeddingLoss( } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type CosineEmbeddingLoss::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - typedef typename InputType::elem_type ElemType; + typedef typename PredictionType::elem_type ElemType; - const size_t cols = input.n_cols; - const size_t batchSize = input.n_elem / cols; - if (arma::size(input) != arma::size(target)) + const size_t cols = prediction.n_cols; + const size_t batchSize = prediction.n_elem / cols; + if (arma::size(prediction) != arma::size(target)) Log::Fatal << "Input Tensors must have same dimensions." << std::endl; - arma::colvec inputTemp1 = arma::vectorise(input); + arma::colvec inputTemp1 = arma::vectorise(prediction); arma::colvec inputTemp2 = arma::vectorise(target); ElemType loss = 0.0; @@ -65,23 +65,23 @@ CosineEmbeddingLoss::Forward( } template -template +template void CosineEmbeddingLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - typedef typename InputType::elem_type ElemType; + typedef typename PredictionType::elem_type ElemType; - const size_t cols = input.n_cols; - if (arma::size(input) != arma::size(target)) + const size_t cols = prediction.n_cols; + if (arma::size(prediction) != arma::size(target)) Log::Fatal << "Input Tensors must have same dimensions." << std::endl; - arma::colvec inputTemp1 = arma::vectorise(input); + arma::colvec inputTemp1 = arma::vectorise(prediction); arma::colvec inputTemp2 = arma::vectorise(target); - output.set_size(arma::size(inputTemp1)); + loss.set_size(arma::size(inputTemp1)); - arma::colvec outputTemp(output.memptr(), inputTemp1.n_elem, + arma::colvec outputTemp(loss.memptr(), inputTemp1.n_elem, false, false); for (size_t i = 0; i < inputTemp1.n_elem; i += cols) { From 3996ea7c524dac1c676c64d0bdaa049ee9ab5bb8 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 22:02:46 +0530 Subject: [PATCH 143/550] cross entropy error --- .../ann/loss_functions/cross_entropy_error.hpp | 18 ++++++++++-------- .../cross_entropy_error_impl.hpp | 18 +++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp b/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp index 3696abb0ab..03e2be7572 100644 --- a/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp @@ -45,24 +45,26 @@ class CrossEntropyError /** * Computes the cross-entropy function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp index 6428714a52..cbd88e97da 100644 --- a/src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp @@ -26,24 +26,24 @@ CrossEntropyError::CrossEntropyError( } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type CrossEntropyError::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - return -arma::accu(target % arma::log(input + eps) + - (1. - target) % arma::log(1. - input + eps)); + return -arma::accu(target % arma::log(prediction + eps) + + (1. - target) % arma::log(1. - prediction + eps)); } template -template +template void CrossEntropyError::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = (1. - target) / (1. - input + eps) - target / (input + eps); + loss = (1. - target) / (1. - prediction + eps) - target / (prediction + eps); } template From 195c4978700a11604face855c096fceb3432c62f Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 22:13:26 +0530 Subject: [PATCH 144/550] dice loss --- .../methods/ann/loss_functions/dice_loss.hpp | 18 +++++++------ .../ann/loss_functions/dice_loss_impl.hpp | 26 +++++++++---------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/dice_loss.hpp b/src/mlpack/methods/ann/loss_functions/dice_loss.hpp index c4dd6da2d6..89f6903b83 100644 --- a/src/mlpack/methods/ann/loss_functions/dice_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/dice_loss.hpp @@ -60,24 +60,26 @@ class DiceLoss /** * Computes the dice loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/dice_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/dice_loss_impl.hpp index 3df59dee7a..2a1835dc70 100644 --- a/src/mlpack/methods/ann/loss_functions/dice_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/dice_loss_impl.hpp @@ -26,27 +26,27 @@ DiceLoss::DiceLoss( } template -template -typename InputType::elem_type DiceLoss::Forward( - const InputType& input, - const TargetType& target) +template +typename PredictionType::elem_type DiceLoss + ::Forward(const PredictionType& prediction, + const TargetType& target) { - return 1 - ((2 * arma::accu(target % input) + smooth) / + return 1 - ((2 * arma::accu(target % prediction) + smooth) / (arma::accu(target % target) + arma::accu( - input % input) + smooth)); + prediction % prediction) + smooth)); } template -template +template void DiceLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = -2 * (target * (arma::accu(input % input) + - arma::accu(target % target) + smooth) - input * - (2 * arma::accu(target % input) + smooth)) / std::pow( - arma::accu(target % target) + arma::accu(input % input) + loss = -2 * (target * (arma::accu(prediction % prediction) + + arma::accu(target % target) + smooth) - prediction * + (2 * arma::accu(target % prediction) + smooth)) / std::pow( + arma::accu(target % target) + arma::accu(prediction % prediction) + smooth, 2.0); } From aed121137b6454a1ed6ef9893b2a84f773656d18 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 22:20:09 +0530 Subject: [PATCH 145/550] earth mover distance --- .../loss_functions/earth_mover_distance.hpp | 18 ++++++++++-------- .../earth_mover_distance_impl.hpp | 16 ++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp b/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp index 7b4ebd479b..47bd60c6c3 100644 --- a/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp +++ b/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp @@ -41,24 +41,26 @@ class EarthMoverDistance /** * Ordinary feed forward pass of a neural network. * - * @param input Input data used for evaluating the specified function. + * @param prediction Prediction used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Prediction used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/earth_mover_distance_impl.hpp b/src/mlpack/methods/ann/loss_functions/earth_mover_distance_impl.hpp index 452a80ca99..8f6ab6f52e 100644 --- a/src/mlpack/methods/ann/loss_functions/earth_mover_distance_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/earth_mover_distance_impl.hpp @@ -25,23 +25,23 @@ EarthMoverDistance::EarthMoverDistance() } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type EarthMoverDistance::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - return -arma::accu(target % input); + return -arma::accu(target % prediction); } template -template +template void EarthMoverDistance::Backward( - const InputType& /* input */, + const PredictionType& /* prediction */, const TargetType& target, - OutputType& output) + LossType& loss) { - output = -target; + loss = -target; } template From 7f16688f4e9e2c27db75ebff607c234517ecb914 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 22:25:43 +0530 Subject: [PATCH 146/550] empty loss --- .../methods/ann/loss_functions/empty_loss.hpp | 18 ++++++++++-------- .../ann/loss_functions/empty_loss_impl.hpp | 12 ++++++------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/empty_loss.hpp b/src/mlpack/methods/ann/loss_functions/empty_loss.hpp index 4d44bcfcfe..8cc8caae9d 100644 --- a/src/mlpack/methods/ann/loss_functions/empty_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/empty_loss.hpp @@ -43,23 +43,25 @@ class EmptyLoss /** * Computes the Empty loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Prediction used for evaluating the specified loss + * function. * @param target The target vector. */ - template - double Forward(const InputType& input, const TargetType& target); + template + double Forward(const PredictionType& input, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Prediction used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); }; // class EmptyLoss } // namespace ann diff --git a/src/mlpack/methods/ann/loss_functions/empty_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/empty_loss_impl.hpp index 8af2c51655..190792030e 100644 --- a/src/mlpack/methods/ann/loss_functions/empty_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/empty_loss_impl.hpp @@ -27,21 +27,21 @@ EmptyLoss::EmptyLoss() } template -template +template double EmptyLoss::Forward( - const InputType& /* input */, const TargetType& /* target */) + const PredictionType& /* prediction */, const TargetType& /* target */) { return 0; } template -template +template void EmptyLoss::Backward( - const InputType& /* input */, + const PredictionType& /* prediction */, const TargetType& target, - OutputType& output) + LossType& loss) { - output = target; + loss = target; } } // namespace ann From 55cda72021ef18a85ad83a80ccdba2483f804af6 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 23:08:55 +0530 Subject: [PATCH 147/550] hinge embedding loss --- .../loss_functions/hinge_embedding_loss.hpp | 18 ++++++++++-------- .../hinge_embedding_loss_impl.hpp | 16 ++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp b/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp index b2a75502f2..892537ee34 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp @@ -44,24 +44,26 @@ class HingeEmbeddingLoss /** * Computes the Hinge Embedding loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Prediction used for evaluating the specified loss + * function. * @param target Target data to compare with. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Prediction used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss_impl.hpp index f0f48fb42a..1f6456c71f 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss_impl.hpp @@ -26,25 +26,25 @@ HingeEmbeddingLoss::HingeEmbeddingLoss() } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type HingeEmbeddingLoss::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { TargetType temp = target - (target == 0); - return (arma::accu(arma::max(1-input % temp, 0.))) / target.n_elem; + return (arma::accu(arma::max(1 - prediction % temp, 0.))) / target.n_elem; } template -template +template void HingeEmbeddingLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { TargetType temp = target - (target == 0); - output = (input < 1 / temp) % -temp; + loss = (prediction < 1 / temp) % -temp; } template From 51797fe0fc198bc712bcbc10b43d92748bc9d69e Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 18 Nov 2020 23:16:45 +0530 Subject: [PATCH 148/550] huber loss --- .../methods/ann/loss_functions/huber_loss.hpp | 18 +++++----- .../ann/loss_functions/huber_loss_impl.hpp | 34 +++++++++---------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/huber_loss.hpp b/src/mlpack/methods/ann/loss_functions/huber_loss.hpp index 29896f7ac3..5847931a30 100644 --- a/src/mlpack/methods/ann/loss_functions/huber_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/huber_loss.hpp @@ -48,24 +48,26 @@ class HuberLoss /** * Computes the Huber Loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/huber_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/huber_loss_impl.hpp index c97305d7b5..d692734754 100644 --- a/src/mlpack/methods/ann/loss_functions/huber_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/huber_loss_impl.hpp @@ -29,39 +29,39 @@ HuberLoss::HuberLoss( } template -template -typename InputType::elem_type -HuberLoss::Forward(const InputType& input, +template +typename PredictionType::elem_type +HuberLoss::Forward(const PredictionType& prediction, const TargetType& target) { - typedef typename InputType::elem_type ElemType; + typedef typename PredictionType::elem_type ElemType; ElemType loss = 0; - for (size_t i = 0; i < input.n_elem; ++i) + for (size_t i = 0; i < prediction.n_elem; ++i) { - const ElemType absError = std::abs(target[i] - input[i]); + const ElemType absError = std::abs(target[i] - prediction[i]); loss += absError > delta ? delta * (absError - 0.5 * delta) : 0.5 * std::pow(absError, 2); } - return mean ? loss / input.n_elem : loss; + return mean ? loss / prediction.n_elem : loss; } template -template +template void HuberLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - typedef typename InputType::elem_type ElemType; + typedef typename PredictionType::elem_type ElemType; - output.set_size(size(input)); - for (size_t i = 0; i < output.n_elem; ++i) + loss.set_size(size(prediction)); + for (size_t i = 0; i < loss.n_elem; ++i) { - const ElemType absError = std::abs(target[i] - input[i]); - output[i] = absError > delta - ? - delta * (target[i] - input[i]) / absError : input[i] - target[i]; + const ElemType absError = std::abs(target[i] - prediction[i]); + loss[i] = absError > delta + ? - delta * (target[i] - prediction[i]) / absError : prediction[i] - target[i]; if (mean) - output[i] /= output.n_elem; + loss[i] /= loss.n_elem; } } From 5a7118646f7c588a80bfb886e9ea27fc839b31d5 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 19 Nov 2020 16:42:56 +0530 Subject: [PATCH 149/550] Restarting Checks From b7bc1a15896ed076a26a5764663c3360991203f3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 19 Nov 2020 17:24:11 -0500 Subject: [PATCH 150/550] Maybe that part wasn't needed? --- dist/win-installer/mlpack-win-installer/Product.wxs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dist/win-installer/mlpack-win-installer/Product.wxs b/dist/win-installer/mlpack-win-installer/Product.wxs index f05d12eff4..f224e26ad5 100644 --- a/dist/win-installer/mlpack-win-installer/Product.wxs +++ b/dist/win-installer/mlpack-win-installer/Product.wxs @@ -25,8 +25,7 @@ - - + From 10f4c80bf843d5e7c6bb17ac11b68a43047c2232 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Fri, 20 Nov 2020 08:07:25 +0530 Subject: [PATCH 151/550] Update src/mlpack/tests/feedforward_network_test.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/feedforward_network_test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 5e088276f9..880106e8ce 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -208,7 +208,6 @@ TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } - /** * Train the vanilla network on a larger dataset. */ @@ -771,4 +770,3 @@ TEST_CASE("OptimizerTest", "[FeedForwardNetworkTest]") ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); model.Train(trainData, trainLabels, opt); } - From 7f38d5a696206759971df6e27778f41184244c58 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Fri, 20 Nov 2020 23:50:17 +0530 Subject: [PATCH 152/550] kl divergence --- .../ann/loss_functions/kl_divergence.hpp | 18 +++++++++-------- .../ann/loss_functions/kl_divergence_impl.hpp | 20 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp b/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp index 680343b803..f4c25d3aa8 100644 --- a/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp +++ b/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp @@ -56,24 +56,26 @@ class KLDivergence /** * Computes the Kullback–Leibler divergence error function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target Target data to compare with. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/kl_divergence_impl.hpp b/src/mlpack/methods/ann/loss_functions/kl_divergence_impl.hpp index 3c84345ee3..aa1a5c1b62 100644 --- a/src/mlpack/methods/ann/loss_functions/kl_divergence_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/kl_divergence_impl.hpp @@ -27,36 +27,36 @@ KLDivergence::KLDivergence(const bool takeMean) : } template -template -typename InputType::elem_type -KLDivergence::Forward(const InputType& input, +template +typename PredictionType::elem_type +KLDivergence::Forward(const PredictionType& prediction, const TargetType& target) { if (takeMean) { return arma::as_scalar(arma::mean( - arma::mean(input % (arma::log(input) - arma::log(target))))); + arma::mean(prediction % (arma::log(prediction) - arma::log(target))))); } else { - return arma::accu(input % (arma::log(input) - arma::log(target))); + return arma::accu(prediction % (arma::log(prediction) - arma::log(target))); } } template -template +template void KLDivergence::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { if (takeMean) { - output = arma::mean(arma::mean(arma::log(input) - arma::log(target) + 1)); + loss = arma::mean(arma::mean(arma::log(prediction) - arma::log(target) + 1)); } else { - output = arma::accu(arma::log(input) - arma::log(target) + 1); + loss = arma::accu(arma::log(prediction) - arma::log(target) + 1); } } From f1177eec8966a9c5437b475bae386f43ebd0c8c8 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:00:15 +0530 Subject: [PATCH 153/550] l1 loss --- .../methods/ann/loss_functions/l1_loss.hpp | 18 ++++++++++-------- .../ann/loss_functions/l1_loss_impl.hpp | 18 +++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/l1_loss.hpp b/src/mlpack/methods/ann/loss_functions/l1_loss.hpp index dadf1fe99b..c22361deba 100644 --- a/src/mlpack/methods/ann/loss_functions/l1_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/l1_loss.hpp @@ -44,24 +44,26 @@ class L1Loss /** * Computes the L1 Loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/l1_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/l1_loss_impl.hpp index d1ab0599cc..100823ad90 100644 --- a/src/mlpack/methods/ann/loss_functions/l1_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/l1_loss_impl.hpp @@ -26,26 +26,26 @@ L1Loss::L1Loss(const bool mean): } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type L1Loss::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { if (mean) - return arma::accu(arma::mean(input - target)); + return arma::accu(arma::mean(prediction - target)); - return arma::accu(input - target); + return arma::accu(prediction - target); } template -template +template void L1Loss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = arma::sign(input - target); + loss = arma::sign(prediction - target); } template From b065240d1c34fae7dea16a6e9284d4a0aac9b355 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:00:51 +0530 Subject: [PATCH 154/550] log cos loss --- .../ann/loss_functions/log_cosh_loss.hpp | 18 ++++++++++-------- .../ann/loss_functions/log_cosh_loss_impl.hpp | 19 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp b/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp index 9cc8172d33..3f7bb801a5 100644 --- a/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp @@ -51,24 +51,26 @@ class LogCoshLoss /** * Computes the Log-Hyperbolic-Cosine loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target Target data to compare with. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/log_cosh_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/log_cosh_loss_impl.hpp index f4c4da63fe..63a72cfa97 100644 --- a/src/mlpack/methods/ann/loss_functions/log_cosh_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/log_cosh_loss_impl.hpp @@ -27,22 +27,23 @@ LogCoshLoss::LogCoshLoss(const double a) : } template -template -typename InputType::elem_type -LogCoshLoss::Forward(const InputType& input, - const TargetType& target) +template +typename PredictionType::elem_type +LogCoshLoss::Forward( + const PredictionType& prediction, + const TargetType& target) { - return arma::accu(arma::log(arma::cosh(a * (target - input)))) / a; + return arma::accu(arma::log(arma::cosh(a * (target - prediction)))) / a; } template -template +template void LogCoshLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = arma::tanh(a * (target - input)); + loss = arma::tanh(a * (target - prediction)); } template From 6f299f38960244c209e18fdf0bfef4eeaa1392e3 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:01:16 +0530 Subject: [PATCH 155/550] margin ranking loss --- .../loss_functions/margin_ranking_loss.hpp | 21 +++++----- .../margin_ranking_loss_impl.hpp | 40 ++++++++++--------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp b/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp index a590cdf4d1..f288f5e43e 100644 --- a/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp @@ -45,29 +45,30 @@ class MarginRankingLoss /** * Computes the Margin Ranking Loss function. * - * @param input Concatenation of the two inputs for evaluating the specified - * function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The label vector which contains values of -1 or 1. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated concatenated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The label vector which contains -1 or 1 values. - * @param output The calculated error. + * @param loss The calculated error. */ template < - typename InputType, + typename PredictionType, typename TargetType, - typename OutputType + typename LossType > - void Backward(const InputType& input, + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/margin_ranking_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/margin_ranking_loss_impl.hpp index cb16e3f79f..17c63ca8e8 100644 --- a/src/mlpack/methods/ann/loss_functions/margin_ranking_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/margin_ranking_loss_impl.hpp @@ -26,37 +26,41 @@ MarginRankingLoss::MarginRankingLoss( } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type MarginRankingLoss::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - const int inputRows = input.n_rows; - const InputType& input1 = input.rows(0, inputRows / 2 - 1); - const InputType& input2 = input.rows(inputRows / 2, inputRows - 1); + const int predictionRows = prediction.n_rows; + const PredictionType& prediction1 = prediction.rows(0, + predictionRows / 2 - 1); + const PredictionType& prediction2 = prediction.rows(predictionRows / 2, + predictionRows - 1); return arma::accu(arma::max(arma::zeros(size(target)), - -target % (input1 - input2) + margin)) / target.n_cols; + -target % (prediction1 - prediction2) + margin)) / target.n_cols; } template template < - typename InputType, + typename PredictionType, typename TargetType, - typename OutputType + typename LossType > void MarginRankingLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - const int inputRows = input.n_rows; - const InputType& input1 = input.rows(0, inputRows / 2 - 1); - const InputType& input2 = input.rows(inputRows / 2, inputRows - 1); - output = -target % (input1 - input2) + margin; - output.elem(arma::find(output >= 0)).ones(); - output.elem(arma::find(output < 0)).zeros(); - output = (input2 - input1) % output / target.n_cols; + const int predictionRows = prediction.n_rows; + const PredictionType& prediction1 = prediction.rows(0, + predictionRows / 2 - 1); + const PredictionType& prediction2 = prediction.rows(predictionRows / 2, + predictionRows - 1); + loss = -target % (prediction1 - prediction2) + margin; + loss.elem(arma::find(loss >= 0)).ones(); + loss.elem(arma::find(loss < 0)).zeros(); + loss = (prediction2 - prediction1) % loss / target.n_cols; } template From 5321103dfad96f043f29eecedf8ed9bcd39a4eb7 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:02:10 +0530 Subject: [PATCH 156/550] mean absolute precentage error --- .../mean_absolute_percentage_error.hpp | 18 ++++++++++-------- .../mean_absolute_percentage_error_impl.hpp | 16 ++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp index 17a0f355e4..af72ca1d15 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp @@ -57,24 +57,26 @@ class MeanAbsolutePercentageError /** * Computes the mean absolute percentage error function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error_impl.hpp index 52b6281a18..b573654e7f 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error_impl.hpp @@ -26,25 +26,25 @@ MeanAbsolutePercentageError() } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type MeanAbsolutePercentageError::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - InputType loss = arma::abs((input - target) / target); + PredictionType loss = arma::abs((prediction - target) / target); return arma::accu(loss) * (100 / target.n_cols); } template -template +template void MeanAbsolutePercentageError::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = (((arma::conv_to::from(input < target) * -2) + 1) / + loss = (((arma::conv_to::from(prediction < target) * -2) + 1) / target) * (100 / target.n_cols); } From 7181af4051bb12c4de2f8c36e1de4920019a7771 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:02:42 +0530 Subject: [PATCH 157/550] mean bias error --- .../ann/loss_functions/mean_bias_error.hpp | 18 +++++++++------- .../loss_functions/mean_bias_error_impl.hpp | 21 ++++++++++--------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp index 043ff97d5b..c66304fa6a 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp @@ -41,24 +41,26 @@ class MeanBiasError /** * Computes the mean bias error function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/mean_bias_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/mean_bias_error_impl.hpp index 3a9f18b51f..0343558693 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_bias_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_bias_error_impl.hpp @@ -26,23 +26,24 @@ MeanBiasError::MeanBiasError() } template -template -typename InputType::elem_type -MeanBiasError::Forward(const InputType& input, - const TargetType& target) +template +typename PredictionType::elem_type +MeanBiasError::Forward( + const PredictionType& prediction, + const TargetType& target) { - return arma::accu(target - input) / target.n_cols; + return arma::accu(target - prediction) / target.n_cols; } template -template +template void MeanBiasError::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& /* target */, - OutputType& output) + LossType& loss) { - output.set_size(arma::size(input)); - output.fill(-1.0); + loss.set_size(arma::size(prediction)); + loss.fill(-1.0); } template From fd5231e04d56f35f4fcb0d9982456bff8da296bc Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:03:20 +0530 Subject: [PATCH 158/550] mean squared logarithmic error --- .../mean_squared_logarithmic_error.hpp | 20 ++++++++++--------- .../mean_squared_logarithmic_error_impl.hpp | 18 ++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error.hpp index 4e9ca3c4de..14a7a08ad0 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error.hpp @@ -41,24 +41,26 @@ class MeanSquaredLogarithmicError /** * Computes the mean squared logarithmic error function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - typename InputType::elem_type Forward(const InputType& input, - const TargetType& target); + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error_impl.hpp index b34c8019cb..ffb1ea7cd8 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error_impl.hpp @@ -26,25 +26,25 @@ MeanSquaredLogarithmicError } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type MeanSquaredLogarithmicError::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { return arma::accu(arma::square(arma::log(1. + target) - - arma::log(1. + input))) / target.n_cols; + arma::log(1. + prediction))) / target.n_cols; } template -template +template void MeanSquaredLogarithmicError::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = 2 * (arma::log(1. + input) - arma::log(1. + target)) / - ((1. + input) * target.n_cols); + loss = 2 * (arma::log(1. + prediction) - arma::log(1. + target)) / + ((1. + prediction) * target.n_cols); } template From f77a0d73ec7f87743a12f0067f7f3a01483c5ce6 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:03:45 +0530 Subject: [PATCH 159/550] negative log likelihood --- .../negative_log_likelihood.hpp | 20 +++++++------ .../negative_log_likelihood_impl.hpp | 28 +++++++++---------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood.hpp b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood.hpp index bd5ad313cb..4f97c152f5 100644 --- a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood.hpp +++ b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood.hpp @@ -43,13 +43,14 @@ class NegativeLogLikelihood /** * Computes the Negative log likelihood. * - * @param input Input data used for evaluating the specified function. + * @param iprediction Predictions used for evaluating the specified loss + * function. * @param target The target vector, that contains the class index in the range * between 1 and the number of classes. */ - template - typename InputType::elem_type Forward(const InputType& input, - const TargetType& target); + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. The negative log @@ -57,15 +58,16 @@ class NegativeLogLikelihood * each class. The layer also expects a class index, in the range between 1 * and the number of classes, as target when calling the Forward function. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector, that contains the class index in the range * between 1 and the number of classes. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the input parameter. InputDataType& InputParameter() const { return inputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp index 3634bc4738..870a840f4f 100644 --- a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp @@ -25,41 +25,41 @@ NegativeLogLikelihood::NegativeLogLikelihood() } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type NegativeLogLikelihood::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - typedef typename InputType::elem_type ElemType; + typedef typename PredictionType::elem_type ElemType; ElemType output = 0; - for (size_t i = 0; i < input.n_cols; ++i) + for (size_t i = 0; i < prediction.n_cols; ++i) { size_t currentTarget = target(i) - 1; - Log::Assert(currentTarget < input.n_rows, + Log::Assert(currentTarget < prediction.n_rows, "Target class out of range."); - output -= input(currentTarget, i); + output -= prediction(currentTarget, i); } return output; } template -template +template void NegativeLogLikelihood::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = arma::zeros(input.n_rows, input.n_cols); - for (size_t i = 0; i < input.n_cols; ++i) + loss = arma::zeros(prediction.n_rows, prediction.n_cols); + for (size_t i = 0; i < prediction.n_cols; ++i) { size_t currentTarget = target(i) - 1; - Log::Assert(currentTarget < input.n_rows, + Log::Assert(currentTarget < prediction.n_rows, "Target class out of range."); - output(currentTarget, i) = -1; + loss(currentTarget, i) = -1; } } From 59066efeedf17abba144b6cc3b5a50040e48e2b7 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:04:15 +0530 Subject: [PATCH 160/550] poisson nnl loss --- .../ann/loss_functions/poisson_nll_loss.hpp | 18 ++++++------ .../loss_functions/poisson_nll_loss_impl.hpp | 28 +++++++++---------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/poisson_nll_loss.hpp b/src/mlpack/methods/ann/loss_functions/poisson_nll_loss.hpp index 415deaa00a..31e1cb5620 100644 --- a/src/mlpack/methods/ann/loss_functions/poisson_nll_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/poisson_nll_loss.hpp @@ -55,12 +55,13 @@ class PoissonNLLLoss /** * Computes the Poisson negative log likelihood Loss. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector, that contains the class index in the range * between 1 and the number of classes. */ - template - typename InputDataType::elem_type Forward(const InputType& input, + template + typename InputDataType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** @@ -69,15 +70,16 @@ class PoissonNLLLoss * It expects a class index, in the range between 1 and the number of classes, * as target when calling the Forward function. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector, that contains the class index in the range * between 1 and the number of classes. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the input parameter. InputDataType& InputParameter() const { return inputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/poisson_nll_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/poisson_nll_loss_impl.hpp index a3233eff81..05d2d79886 100644 --- a/src/mlpack/methods/ann/loss_functions/poisson_nll_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/poisson_nll_loss_impl.hpp @@ -34,26 +34,26 @@ PoissonNLLLoss::PoissonNLLLoss( } template -template +template typename InputDataType::elem_type PoissonNLLLoss::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - InputType loss(arma::size(input)); + PredictionType loss(arma::size(prediction)); if (logInput) - loss = arma::exp(input) - target % input; + loss = arma::exp(prediction) - target % prediction; else { - CheckProbs(input); - loss = input - target % arma::log(input + eps); + CheckProbs(prediction); + loss = prediction - target % arma::log(prediction + eps); } if (full) { const auto mask = target > 1.0; - const InputType approx = target % arma::log(target) - target + const PredictionType approx = target % arma::log(target) - target + 0.5 * arma::log(2 * M_PI * target); loss.elem(arma::find(mask)) += approx.elem(arma::find(mask)); } @@ -62,21 +62,21 @@ PoissonNLLLoss::Forward( } template -template +template void PoissonNLLLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output.set_size(size(input)); + loss.set_size(size(prediction)); if (logInput) - output = (arma::exp(input) - target); + loss = (arma::exp(prediction) - target); else - output = (1 - target / (input + eps)); + loss = (1 - target / (prediction + eps)); if (mean) - output = output / output.n_elem; + loss = loss / loss.n_elem; } template From ed049588a62a0f97580440111df27a6b90ed828f Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:04:59 +0530 Subject: [PATCH 161/550] reconstruction loss --- .../loss_functions/reconstruction_loss.hpp | 20 ++++++++++--------- .../reconstruction_loss_impl.hpp | 18 ++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/reconstruction_loss.hpp b/src/mlpack/methods/ann/loss_functions/reconstruction_loss.hpp index 4ae46b125a..56f6f39cc3 100644 --- a/src/mlpack/methods/ann/loss_functions/reconstruction_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/reconstruction_loss.hpp @@ -45,24 +45,26 @@ class ReconstructionLoss /** * Computes the reconstruction loss. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target matrix. */ - template - typename InputType::elem_type Forward(const InputType& input, - const TargetType& target); + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target matrix. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/reconstruction_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/reconstruction_loss_impl.hpp index 1821ae2f5d..ca5c986f05 100644 --- a/src/mlpack/methods/ann/loss_functions/reconstruction_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/reconstruction_loss_impl.hpp @@ -29,24 +29,24 @@ ReconstructionLoss< } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type ReconstructionLoss::Forward( - const InputType& input, const TargetType& target) + const PredictionType& prediction, const TargetType& target) { - dist = DistType(input); + dist = DistType(prediction); return -dist.LogProbability(target); } template -template +template void ReconstructionLoss::Backward( - const InputType& /* input */, + const PredictionType& /* prediction */, const TargetType& target, - OutputType& output) + LossType& loss) { - dist.LogProbBackward(target, output); - output *= -1; + dist.LogProbBackward(target, loss); + loss *= -1; } template From 65ba175306d090eb35aeffbebdd1fc78738e293c Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:05:21 +0530 Subject: [PATCH 162/550] sigmoid crossentropy loss --- .../sigmoid_cross_entropy_error.hpp | 20 +++++++++------- .../sigmoid_cross_entropy_error_impl.hpp | 24 +++++++++---------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error.hpp b/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error.hpp index c577fc998e..2d0bed9721 100644 --- a/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error.hpp @@ -60,23 +60,25 @@ class SigmoidCrossEntropyError /** * Computes the Sigmoid CrossEntropy Error functions. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. */ - template - inline typename InputType::elem_type Forward(const InputType& input, - const TargetType& target); + template + inline typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - inline void Backward(const InputType& input, + template + inline void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error_impl.hpp index 3cfcb0b04f..93b3775e6a 100644 --- a/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error_impl.hpp @@ -28,31 +28,31 @@ SigmoidCrossEntropyError } template -template -inline typename InputType::elem_type +template +inline typename PredictionType::elem_type SigmoidCrossEntropyError::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - typedef typename InputType::elem_type ElemType; + typedef typename PredictionType::elem_type ElemType; ElemType maximum = 0; - for (size_t i = 0; i < input.n_elem; ++i) + for (size_t i = 0; i < prediction.n_elem; ++i) { - maximum += std::max(input[i], 0.0) + - std::log(1 + std::exp(-std::abs(input[i]))); + maximum += std::max(prediction[i], 0.0) + + std::log(1 + std::exp(-std::abs(prediction[i]))); } - return maximum - arma::accu(input % target); + return maximum - arma::accu(prediction % target); } template -template +template inline void SigmoidCrossEntropyError::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output = 1.0 / (1.0 + arma::exp(-input)) - target; + loss = 1.0 / (1.0 + arma::exp(-prediction)) - target; } template From 9f20637623c8b3f7683d9eb59522034623515e10 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:05:40 +0530 Subject: [PATCH 163/550] soft margin loss --- .../ann/loss_functions/soft_margin_loss.hpp | 20 +++++++------ .../loss_functions/soft_margin_loss_impl.hpp | 30 +++++++++---------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/soft_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/soft_margin_loss.hpp index 40b8965e83..a35db04d14 100644 --- a/src/mlpack/methods/ann/loss_functions/soft_margin_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/soft_margin_loss.hpp @@ -48,24 +48,26 @@ class SoftMarginLoss /** * Computes the Soft Margin Loss function. * - * @param input Input data used for evaluating the specified function. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector with same shape as input. */ - template - typename InputType::elem_type Forward(const InputType& input, - const TargetType& target); + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. + * @param prediction Predictions used for evaluating the specified loss + * function. * @param target The target vector. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/soft_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/soft_margin_loss_impl.hpp index d89c20170d..40453564a3 100644 --- a/src/mlpack/methods/ann/loss_functions/soft_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/soft_margin_loss_impl.hpp @@ -26,35 +26,35 @@ SoftMarginLoss(const bool reduction) : reduction(reduction) } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type SoftMarginLoss::Forward( - const InputType& input, const TargetType& target) + const PredictionType& prediction, const TargetType& target) { - InputType loss = arma::log(1 + arma::exp(-target % input)); - typename InputType::elem_type lossSum = arma::accu(loss); + PredictionType loss = arma::log(1 + arma::exp(-target % prediction)); + typename PredictionType::elem_type lossSum = arma::accu(loss); if (reduction) return lossSum; - return lossSum / input.n_elem; + return lossSum / prediction.n_elem; } template -template +template void SoftMarginLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - output.set_size(size(input)); - InputType temp = arma::exp(-target % input); - InputType numerator = -target % temp; - InputType denominator = 1 + temp; - output = numerator / denominator; + loss.set_size(size(prediction)); + PredictionType temp = arma::exp(-target % prediction); + PredictionType numerator = -target % temp; + PredictionType denominator = 1 + temp; + loss = numerator / denominator; if (!reduction) - output = output / input.n_elem; + loss = loss / prediction.n_elem; } template From 2dcd4dc353a95514b9ff7e8a8515ba0fb3a9731a Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Sat, 21 Nov 2020 01:11:10 +0530 Subject: [PATCH 164/550] fixed spacing --- src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp | 2 +- src/mlpack/methods/ann/loss_functions/dice_loss.hpp | 2 +- src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp | 2 +- src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp | 2 +- src/mlpack/methods/ann/loss_functions/huber_loss.hpp | 2 +- src/mlpack/methods/ann/loss_functions/kl_divergence.hpp | 2 +- src/mlpack/methods/ann/loss_functions/l1_loss.hpp | 2 +- src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp | 2 +- src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp | 2 +- .../ann/loss_functions/mean_absolute_percentage_error.hpp | 2 +- src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp b/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp index 03e2be7572..e6d077cb6c 100644 --- a/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp @@ -51,7 +51,7 @@ class CrossEntropyError */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/dice_loss.hpp b/src/mlpack/methods/ann/loss_functions/dice_loss.hpp index 89f6903b83..ce4a80f54d 100644 --- a/src/mlpack/methods/ann/loss_functions/dice_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/dice_loss.hpp @@ -66,7 +66,7 @@ class DiceLoss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp b/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp index 47bd60c6c3..a5afbf37c2 100644 --- a/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp +++ b/src/mlpack/methods/ann/loss_functions/earth_mover_distance.hpp @@ -47,7 +47,7 @@ class EarthMoverDistance */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp b/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp index 892537ee34..99e5d50ff2 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp @@ -50,7 +50,7 @@ class HingeEmbeddingLoss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/huber_loss.hpp b/src/mlpack/methods/ann/loss_functions/huber_loss.hpp index 5847931a30..f5ce03dba4 100644 --- a/src/mlpack/methods/ann/loss_functions/huber_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/huber_loss.hpp @@ -54,7 +54,7 @@ class HuberLoss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp b/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp index f4c25d3aa8..5eacb03b36 100644 --- a/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp +++ b/src/mlpack/methods/ann/loss_functions/kl_divergence.hpp @@ -62,7 +62,7 @@ class KLDivergence */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/l1_loss.hpp b/src/mlpack/methods/ann/loss_functions/l1_loss.hpp index c22361deba..552089bbd0 100644 --- a/src/mlpack/methods/ann/loss_functions/l1_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/l1_loss.hpp @@ -50,7 +50,7 @@ class L1Loss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp b/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp index 3f7bb801a5..db3090488e 100644 --- a/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/log_cosh_loss.hpp @@ -57,7 +57,7 @@ class LogCoshLoss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp b/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp index f288f5e43e..28971c89f0 100644 --- a/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp @@ -51,7 +51,7 @@ class MarginRankingLoss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp index af72ca1d15..d6eb6e5e89 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_absolute_percentage_error.hpp @@ -63,7 +63,7 @@ class MeanAbsolutePercentageError */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp b/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp index c66304fa6a..b9836f856f 100644 --- a/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/mean_bias_error.hpp @@ -47,7 +47,7 @@ class MeanBiasError */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. From fe563518d3770483b282cb86b75c65602e96b1f2 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 21 Nov 2020 11:39:07 -0500 Subject: [PATCH 165/550] Try to debug why we can't find the file. --- .ci/windows-steps.yaml | 3 +++ dist/win-installer/mlpack-win-installer/Product.wxs | 8 ++++---- .../mlpack-win-installer.wixproj | 13 ++++--------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index b0a383271d..ff8db4481c 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -163,6 +163,9 @@ steps: # Build the MSI installer. cd dist\win-installer\mlpack-win-installer dir + cd SourceDir + dir + cd .. & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild ` -p:Configuration=Release ` diff --git a/dist/win-installer/mlpack-win-installer/Product.wxs b/dist/win-installer/mlpack-win-installer/Product.wxs index f224e26ad5..fc2b19f544 100644 --- a/dist/win-installer/mlpack-win-installer/Product.wxs +++ b/dist/win-installer/mlpack-win-installer/Product.wxs @@ -6,11 +6,11 @@ UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662" Name="mlpack" Language="1033" - Version="$(env.MLPACK_VERSION)" + Version="$(env.MLPACK_VERSION)" Manufacturer="mlpack"> @@ -20,13 +20,13 @@ - + - + $(env.MLPACK_VERSION) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 6f102c34f7..4b35b09f08 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -9,6 +9,7 @@ mlpack-windows Package mlpack-win-installer + HarvestPath=.\SourceDir;SourceDir=SourceDir bin\$(Configuration)\ @@ -28,24 +29,18 @@ bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ - - HarvestPath=.\SourceDir;SourcesDir=SourceDir - - SourcesDir - Sources - var.SourcesDir + SourceDir + SourceDir + var.SourceDir true $(WixExtDir)\WixUIExtension.dll WixUIExtension - - - From 582ee39e683237c7a0113340de94b64efe25f7d4 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 22 Nov 2020 10:38:54 -0500 Subject: [PATCH 166/550] add copying and moving construcotr implementation --- src/mlpack/methods/ann/layer/concatenate.hpp | 14 ++++- .../methods/ann/layer/concatenate_impl.hpp | 56 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/concatenate.hpp b/src/mlpack/methods/ann/layer/concatenate.hpp index b27d92afee..cc50ad8514 100644 --- a/src/mlpack/methods/ann/layer/concatenate.hpp +++ b/src/mlpack/methods/ann/layer/concatenate.hpp @@ -41,6 +41,18 @@ class Concatenate */ Concatenate(); + //! Copy constructor + Concatenate(const Concatenate& layer); + + //! Move constructor + Concatenate(Concatenate&& layer); + + //! Copy operator constructor + Concatenate& operator=(const Concatenate& layer); + + //! move operator constructor + Concatenate& operator=(Concatenate&& layer); + /** * Ordinary feed forward pass of a neural network, evaluating the function * f(x) by propagating the activity forward through f. @@ -82,7 +94,7 @@ class Concatenate //! Get the concat matrix. OutputDataType const& Concat() const { return concat; } - //! Modify the delta. + //! Modify the concat. OutputDataType& Concat() { return concat; } /** diff --git a/src/mlpack/methods/ann/layer/concatenate_impl.hpp b/src/mlpack/methods/ann/layer/concatenate_impl.hpp index 20c7ba6d15..4dffc95609 100644 --- a/src/mlpack/methods/ann/layer/concatenate_impl.hpp +++ b/src/mlpack/methods/ann/layer/concatenate_impl.hpp @@ -25,6 +25,62 @@ Concatenate::Concatenate() // Nothing to do here. } +//! Copy constructor +template +Concatenate::Concatenate(const Concatenate& layer) : + inRows(layer.inRows), + weights(layer.weights), + delta(layer.delta), + concat(layer.concat) +{ + // Nothing to to here +} + +//! Move constructor +template +Concatenate::Concatenate(Concatenate&& layer) : + inRows(std::move(layer.inRows)), + weights(std::move(layer.weights)), + delta(std::move(layer.delta)), + concat(std::move(layer.concat)) +{ + // Nothing to do here +} + +template +Concatenate& +Concatenate:: +operator=(const Concatenate& layer) +{ + if (this != &layer) + { + inRows = layer.inRows; + weights = layer.weights; + delta = layer.delta; + concat = layer.concat; + } + return *this; +} + +template +Concatenate& +Concatenate:: +operator=(Concatenate&& layer) +{ + if (this != &layer) + { + inRows = std::move(layer.inRows); + layer.inRows = 0; + weights = std::move(layer.weights); + layer.weights = nullptr; + delta = std::move(layer.delta); + layer.delta = nullptr; + concat = std::move(layer.concat); + layer.concat = nullptr; + } + return *this; +} + template template void Concatenate::Forward( From fc0ac208c16fd90df995c2a0710f93605bdddc55 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 22 Nov 2020 10:39:45 -0500 Subject: [PATCH 167/550] add test case for copying and moving constructor for Concatenate layer --- src/mlpack/tests/feedforward_network_test.cpp | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 7188f69f50..b6b2d51e89 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -153,6 +153,56 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } +/** + * Concatenate layer constructor test. + */ +TEST_CASE("CheckCopyMovingConcatenateTest", "[FeedForwardNetworkTest]") +{ + // Create training input by 5x5 matrix + arma::mat input = arma::randu(10,1); + // Create training output by 1 matrix + arma::mat output = arma::mat("1"); + + // Check copying constructor + FFN> *model1 = new FFN>(); + model1->Predictors() = input; + model1->Responses() = output; + model1->Add>(); + model1->Add>(10, 5); + + // Create concatenate layer + arma::mat concatMatrix = arma::ones(5, 1); + Concatenate<>* concatLayer = new Concatenate<>(); + concatLayer->Concat() = concatMatrix; + + // Add concatenate layer to the current network + model1->Add(concatLayer); + model1->Add >(10, 5); + model1->Add>(); + + // Check whether copy constructor is working or not. + CheckCopyFunction<>(model1, input, output, 1); + + // check moving constructor + FFN> *model2 = new FFN>(); + model2->Predictors() = input; + model2->Responses() = output; + model2->Add>(); + model2->Add>(10, 5); + + // Create new concat layer + Concatenate<>* concatLayer2 = new Concatenate<>(); + concatLayer2->Concat() = concatMatrix; + + // Add concatenate layer to the current network + model2->Add(concatLayer2); + model2->Add >(10, 5); + model2->Add>(); + + // Check whether move constructor is working or not. + CheckMoveFunction<>(model2, input, output, 1); +} + /** * Train the vanilla network on a larger dataset. */ From 85556de42055faee0b3b7288b354a7ec54af9703 Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Sun, 22 Nov 2020 17:39:46 +0100 Subject: [PATCH 168/550] Added template parameter --- src/mlpack/core/cv/metrics/r2_score.hpp | 34 ++++++++++++--- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 46 ++++++++++++++++---- src/mlpack/tests/cv_test.cpp | 4 +- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp index 35e528269c..2e8f0b4bbf 100644 --- a/src/mlpack/core/cv/metrics/r2_score.hpp +++ b/src/mlpack/core/cv/metrics/r2_score.hpp @@ -43,7 +43,10 @@ namespace cv { * For example, a model having R2Score = 0.85, explains 85 \% variability of * the response data around its mean. */ -class R2Score + +template class R2Score; + +template<> class R2Score { public: /** @@ -53,15 +56,36 @@ class R2Score * @param data Column-major data containing test items. * @param responses Ground truth (correct) target values for the test items, * should be either a row vector or a column-major matrix. - * @param adjR2 Boolean value which specifies whether to calculate adjusted - * R2 or not * @return calculated R2 Score. */ template static double Evaluate(MLAlgorithm& model, const DataType& data, - const ResponsesType& responses, - const bool adjR2 = false); + const ResponsesType& responses); + + /** + * Information for hyper-parameter tuning code. It indicates that we want + * to maximize the measurement. + */ + static const bool NeedsMinimization = false; +}; + +template<> class R2Score +{ + public: + /** + * Run prediction and calculate the Adjusted R squared error. + * + * @param model A regression model. + * @param data Column-major data containing test items. + * @param responses Ground truth (correct) target values for the test items, + * should be either a row vector or a column-major matrix. + * @return calculated R2 Score. + */ + template + static double Evaluate(MLAlgorithm& model, + const DataType& data, + const ResponsesType& responses); /** * Information for hyper-parameter tuning code. It indicates that we want diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 75d2751e67..0d935f867d 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -16,10 +16,9 @@ namespace mlpack { namespace cv { template -double R2Score::Evaluate(MLAlgorithm& model, +double R2Score::Evaluate(MLAlgorithm& model, const DataType& data, - const ResponsesType& responses, - const bool adjR2) + const ResponsesType& responses) { if (data.n_cols != responses.n_cols) { @@ -46,16 +45,45 @@ double R2Score::Evaluate(MLAlgorithm& model, // Handling undefined R2 Score when both denominator and numerator is 0.0. if (residualSumSquared == 0.0) return totalSumSquared ? 1.0 : DBL_MIN; - // Returning adjusted R-squared. - if (adjR2) + + // Returning R-squared + return 1 - residualSumSquared / totalSumSquared; +} + +template + double R2Score::Evaluate(MLAlgorithm& model, + const DataType& data, + const ResponsesType& responses) { + if (data.n_cols != responses.n_cols) + { + std::ostringstream oss; + oss << "R2Score::Evaluate(): number of points (" << data.n_cols << ") " + << "does not match number of responses (" << responses.n_cols << ")!" + << std::endl; + throw std::invalid_argument(oss.str()); + } + + ResponsesType predictedResponses; + // Taking Predicted Output from the model. + model.Predict(data, predictedResponses); + // Mean value of response. + double meanResponses = arma::mean(responses); + + // Calculate the numerator i.e. residual sum of squares. + double residualSumSquared = arma::accu(arma::square(responses - + predictedResponses)); + + // Calculate the denominator i.e.total sum of squares. + double totalSumSquared = arma::accu(arma::square(responses - meanResponses)); + + // Handling undefined R2 Score when both denominator and numerator is 0.0. + if (residualSumSquared == 0.0) + return totalSumSquared ? 1.0 : DBL_MIN; + // Returning adjusted R-squared. double rsq = 1 - (residualSumSquared / totalSumSquared); return (1 - ((1 - rsq) * ((data.n_cols - 1) / (data.n_cols - data.n_rows - 1)))); } - - // Returning R-squared - return 1 - residualSumSquared / totalSumSquared; -} } // namespace cv } // namespace mlpack diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index 44b169b64d..d2bc7d7418 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -187,7 +187,7 @@ TEST_CASE("R2ScoreTest", "[CVTest]") double expectedR2 = 0.99999779; - REQUIRE(R2Score::Evaluate(lr, data, responses) + REQUIRE(R2Score::Evaluate(lr, data, responses) == Approx(expectedR2).epsilon(1e-7)); } @@ -208,7 +208,7 @@ TEST_CASE("AdjR2ScoreTest", "[CVTest]") //Theoretically Adjusted R squared should be equal 1 double expAdjR2 = 1; - REQUIRE(std::abs(R2Score::Evaluate(lr, X, y) - expAdjR2) + REQUIRE(std::abs(R2Score::Evaluate(lr, X, Y) - expAdjR2) <= 1e-7); } From 9a369251de9be72bf7298b92b006b31ef738a399 Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Sun, 22 Nov 2020 17:44:50 +0100 Subject: [PATCH 169/550] Added Documentation --- src/mlpack/core/cv/metrics/r2_score.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp index 2e8f0b4bbf..7fb733eb0c 100644 --- a/src/mlpack/core/cv/metrics/r2_score.hpp +++ b/src/mlpack/core/cv/metrics/r2_score.hpp @@ -80,7 +80,7 @@ template<> class R2Score * @param data Column-major data containing test items. * @param responses Ground truth (correct) target values for the test items, * should be either a row vector or a column-major matrix. - * @return calculated R2 Score. + * @return calculated Ajusted R2 Score. */ template static double Evaluate(MLAlgorithm& model, From 4312b15cde7c26a1c1d439994f1b645c4c4fe8c3 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 22 Nov 2020 13:18:06 -0500 Subject: [PATCH 170/550] minor edit --- src/mlpack/methods/ann/layer/concatenate.hpp | 8 ++++---- .../methods/ann/layer/concatenate_impl.hpp | 6 ++---- src/mlpack/tests/feedforward_network_test.cpp | 16 ++++++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/layer/concatenate.hpp b/src/mlpack/methods/ann/layer/concatenate.hpp index cc50ad8514..6dbcc54d1d 100644 --- a/src/mlpack/methods/ann/layer/concatenate.hpp +++ b/src/mlpack/methods/ann/layer/concatenate.hpp @@ -41,16 +41,16 @@ class Concatenate */ Concatenate(); - //! Copy constructor + //! Copy constructor. Concatenate(const Concatenate& layer); - //! Move constructor + //! Move constructor. Concatenate(Concatenate&& layer); - //! Copy operator constructor + //! Copy operator constructor. Concatenate& operator=(const Concatenate& layer); - //! move operator constructor + //! move operator constructor. Concatenate& operator=(Concatenate&& layer); /** diff --git a/src/mlpack/methods/ann/layer/concatenate_impl.hpp b/src/mlpack/methods/ann/layer/concatenate_impl.hpp index 4dffc95609..efa642f2b9 100644 --- a/src/mlpack/methods/ann/layer/concatenate_impl.hpp +++ b/src/mlpack/methods/ann/layer/concatenate_impl.hpp @@ -25,7 +25,6 @@ Concatenate::Concatenate() // Nothing to do here. } -//! Copy constructor template Concatenate::Concatenate(const Concatenate& layer) : inRows(layer.inRows), @@ -33,10 +32,9 @@ Concatenate::Concatenate(const Concatenate& layer delta(layer.delta), concat(layer.concat) { - // Nothing to to here + // Nothing to to here. } -//! Move constructor template Concatenate::Concatenate(Concatenate&& layer) : inRows(std::move(layer.inRows)), @@ -44,7 +42,7 @@ Concatenate::Concatenate(Concatenate&& layer) : delta(std::move(layer.delta)), concat(std::move(layer.concat)) { - // Nothing to do here + // Nothing to do here. } template diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index b6b2d51e89..68672423c1 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -158,24 +158,24 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") */ TEST_CASE("CheckCopyMovingConcatenateTest", "[FeedForwardNetworkTest]") { - // Create training input by 5x5 matrix + // Create training input by 5x5 matrix. arma::mat input = arma::randu(10,1); - // Create training output by 1 matrix + // Create training output by 1 matrix. arma::mat output = arma::mat("1"); - // Check copying constructor + // Check copying constructor. FFN> *model1 = new FFN>(); model1->Predictors() = input; model1->Responses() = output; model1->Add>(); model1->Add>(10, 5); - // Create concatenate layer + // Create concatenate layer. arma::mat concatMatrix = arma::ones(5, 1); Concatenate<>* concatLayer = new Concatenate<>(); concatLayer->Concat() = concatMatrix; - // Add concatenate layer to the current network + // Add concatenate layer to the current network. model1->Add(concatLayer); model1->Add >(10, 5); model1->Add>(); @@ -183,18 +183,18 @@ TEST_CASE("CheckCopyMovingConcatenateTest", "[FeedForwardNetworkTest]") // Check whether copy constructor is working or not. CheckCopyFunction<>(model1, input, output, 1); - // check moving constructor + // check moving constructor. FFN> *model2 = new FFN>(); model2->Predictors() = input; model2->Responses() = output; model2->Add>(); model2->Add>(10, 5); - // Create new concat layer + // Create new concat layer. Concatenate<>* concatLayer2 = new Concatenate<>(); concatLayer2->Concat() = concatMatrix; - // Add concatenate layer to the current network + // Add concatenate layer to the current network. model2->Add(concatLayer2); model2->Add >(10, 5); model2->Add>(); From 5e4d847595b1970b64b1ded88abe0adef7aba37f Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 22 Nov 2020 13:11:10 -0500 Subject: [PATCH 171/550] add copying and moving constructor --- src/mlpack/methods/ann/layer/noisylinear.hpp | 9 ++++ .../methods/ann/layer/noisylinear_impl.hpp | 42 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/mlpack/methods/ann/layer/noisylinear.hpp b/src/mlpack/methods/ann/layer/noisylinear.hpp index 34ca70193b..705b59bb75 100644 --- a/src/mlpack/methods/ann/layer/noisylinear.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear.hpp @@ -48,6 +48,15 @@ class NoisyLinear //! Copy constructor. NoisyLinear(const NoisyLinear&); + //! Move constructor + NoisyLinear(NoisyLinear&&); + + //! Operator= copy constructor + NoisyLinear& operator=(NoisyLinear const& layer); + + //! Operator= move constructor + NoisyLinear& operator=(NoisyLinear&& layer); + /* * Reset the layer parameter. */ diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index 82a3a35fc6..8bb7890bf9 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -48,6 +48,48 @@ NoisyLinear::NoisyLinear( biasEpsilon.set_size(outSize, 1); } +template +NoisyLinear::NoisyLinear( + NoisyLinear&& layer) : + inSize(std::move(layer.inSize)), + outSize(std::move(layer.outSize)), + weights(std::move(layer.weights)) +{ + layer.inSize = 0; + layer.outSize = 0; + layer.weights = nullptr; + Reset(); +} + +template +NoisyLinear& +NoisyLinear::operator=(NoisyLinear const& layer) +{ + if(this != &layer) { + inSize = layer.inSize; + outSize = layer.outSize; + weights = layer.weights; + Reset(); + } + return *this; +} + +template +NoisyLinear& +NoisyLinear::operator=(NoisyLinear&& layer) +{ + if(this != &layer) { + inSize = std::move(layer.inSize); + layer.inSize = 0; + outSize = std::move(layer.outSize); + layer.outSize = 0; + weights = std::move(layer.weights); + layer.weights = nullptr; + Reset(); + } + return *this; +} + template void NoisyLinear::Reset() { From f151fccce7252410e486bb5cf83a58385e1ad2ba Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 22 Nov 2020 13:11:34 -0500 Subject: [PATCH 172/550] add test for copy and move constructor of noisy linear layer --- src/mlpack/tests/feedforward_network_test.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 7188f69f50..d828bb4075 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -153,6 +153,41 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } +/** + * Noisy Linear layer constructor test. + */ +TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") +{ + // Create training input by 5x5 matrix + arma::mat input = arma::randu(10,1); + // Create training output by 1 matrix + arma::mat output = arma::mat("1"); + + // Check copying constructor + FFN> *model1 = new FFN>(); + model1->Predictors() = input; + model1->Responses() = output; + model1->Add>(); + model1->Add>(10, 5); + model1->Add >(5, 1); + model1->Add>(); + + // Check whether copy constructor is working or not. + CheckCopyFunction<>(model1, input, output, 1); + + // Check moving constructor + FFN> *model2 = new FFN>(); + model2->Predictors() = input; + model2->Responses() = output; + model2->Add>(); + model2->Add>(10, 5); + model2->Add >(5, 1); + model2->Add>(); + + // Check whether move constructor is working or not. + CheckMoveFunction<>(model2, input, output, 1); +} + /** * Train the vanilla network on a larger dataset. */ From 1cae18a9de15ebac2eb2d7867e9a51ebd9d18618 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 22 Nov 2020 14:03:45 -0500 Subject: [PATCH 173/550] minor edit --- src/mlpack/methods/ann/layer/noisylinear.hpp | 6 +++--- src/mlpack/tests/feedforward_network_test.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear.hpp b/src/mlpack/methods/ann/layer/noisylinear.hpp index 705b59bb75..625f7d6c6c 100644 --- a/src/mlpack/methods/ann/layer/noisylinear.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear.hpp @@ -48,13 +48,13 @@ class NoisyLinear //! Copy constructor. NoisyLinear(const NoisyLinear&); - //! Move constructor + //! Move constructor. NoisyLinear(NoisyLinear&&); - //! Operator= copy constructor + //! Operator= copy constructor. NoisyLinear& operator=(NoisyLinear const& layer); - //! Operator= move constructor + //! Operator= move constructor. NoisyLinear& operator=(NoisyLinear&& layer); /* diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index d828bb4075..9d6ff13f6a 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -158,12 +158,12 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") */ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") { - // Create training input by 5x5 matrix + // Create training input by 5x5 matrix. arma::mat input = arma::randu(10,1); - // Create training output by 1 matrix + // Create training output by 1 matrix. arma::mat output = arma::mat("1"); - // Check copying constructor + // Check copying constructor. FFN> *model1 = new FFN>(); model1->Predictors() = input; model1->Responses() = output; @@ -175,7 +175,7 @@ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") // Check whether copy constructor is working or not. CheckCopyFunction<>(model1, input, output, 1); - // Check moving constructor + // Check moving constructor. FFN> *model2 = new FFN>(); model2->Predictors() = input; model2->Responses() = output; From 2df4a238c37294384892d9fc6a5709351295b2f6 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 22 Nov 2020 15:08:37 -0500 Subject: [PATCH 174/550] Add BUILD_DOCS option to enable/disable building documentation. --- CMakeLists.txt | 73 ++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10f126283a..0804d28039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ option(DISABLE_DOWNLOADS "Disable downloads of dependencies during build." OFF) option(DOWNLOAD_ENSMALLEN "If ensmallen is not found, download it." ON) option(DOWNLOAD_STB_IMAGE "Download stb_image for image loading." ON) option(BUILD_GO_SHLIB "Build Go shared library." OFF) +option(BUILD_DOCS "Build doxygen documentation (if doxygen is available)." ON) # Set minimum library version required by mlpack. set(ARMADILLO_VERSION "8.400.0") @@ -617,43 +618,45 @@ add_dependencies(mlpack_headers mlpack_arma_config) # Make a target to generate the documentation. If Doxygen isn't installed, then # I guess this option will just be unavailable. -find_package(Doxygen) -if (DOXYGEN_FOUND) - if (MATHJAX) - find_package(MathJax) - if (NOT MATHJAX_FOUND) - message(STATUS "Using MathJax at the MathJax Content Delivery Network. " - "Be careful, formulas will not be shown without the internet.") +if (BUILD_DOCS) + find_package(Doxygen) + if (DOXYGEN_FOUND) + if (MATHJAX) + find_package(MathJax) + if (NOT MATHJAX_FOUND) + message(STATUS "Using MathJax at the MathJax Content Delivery Network. " + "Be careful, formulas will not be shown without the internet.") + endif () endif () + # Preprocess the Doxyfile. This is done before 'make doc'. + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile + PRE_BUILD + COMMAND ${CMAKE_COMMAND} + -D DESTDIR=${CMAKE_BINARY_DIR} + -D MATHJAX="${MATHJAX}" + -D MATHJAX_FOUND="${MATHJAX_FOUND}" + -D MATHJAX_PATH="${MATHJAX_PATH}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile" + COMMENT "Creating Doxyfile to generate Doxygen documentation" + ) + + # Generate documentation. + add_custom_target(doc + COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile" + DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Generating API documentation with Doxygen" + ) + + install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html" + DESTINATION "${CMAKE_INSTALL_DOCDIR}" + COMPONENT doc + OPTIONAL + ) endif () - # Preprocess the Doxyfile. This is done before 'make doc'. - add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile - PRE_BUILD - COMMAND ${CMAKE_COMMAND} - -D DESTDIR=${CMAKE_BINARY_DIR} - -D MATHJAX="${MATHJAX}" - -D MATHJAX_FOUND="${MATHJAX_FOUND}" - -D MATHJAX_PATH="${MATHJAX_PATH}" - -P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile" - COMMENT "Creating Doxyfile to generate Doxygen documentation" - ) - - # Generate documentation. - add_custom_target(doc - COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile" - DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Generating API documentation with Doxygen" - ) - - install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html" - DESTINATION "${CMAKE_INSTALL_DOCDIR}" - COMPONENT doc - OPTIONAL - ) -endif () +endif() # Create the pkg-config file, if we have pkg-config. find_package(PkgConfig) From 0277addfce9238e0a3e4083299f8c16353768935 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 22 Nov 2020 15:11:30 -0500 Subject: [PATCH 175/550] Update documentation. --- README.md | 2 ++ doc/guide/build.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index ab804757b1..82cbecf9c0 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,8 @@ Options are specified with the -D flag. The allowed options include: STB_IMAGE_INCLUDE_DIR=(/path/to/stb/include): path to include directory for STB image library USE_OPENMP=(ON/OFF): whether or not to use OpenMP if available + BUILD_DOCS=(ON/OFF): build Doxygen documentation, if Doxygen is available + (default ON) Other tools can also be used to configure CMake, but those are not documented here. See [this section of the build guide](https://www.mlpack.org/doc/mlpack-git/doxygen/build.html#build_config) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 08068eaa73..064d5ffd5b 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -179,6 +179,8 @@ The full list of options mlpack allows: - JULIA_EXECUTABLE=(/path/to/julia): Path to specific Julia executable - BUILD_MARKDOWN_BINDINGS=(ON/OFF): Build Markdown bindings for website documentation (default OFF) + - BUILD_DOCS=(ON/OFF): build Doxygen documentation, if Doxygen is available + (default ON) - MATHJAX=(ON/OFF): use MathJax for generated Doxygen documentation (default OFF) - FORCE_CXX11=(ON/OFF): assume that the compiler supports C++11 instead of From 90b8eb69751f2079b079b5dd51cf846e5da87726 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 22 Nov 2020 15:13:12 -0500 Subject: [PATCH 176/550] Update HISTORY. --- HISTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index be8a4d66b0..cfff16dff2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,9 @@ ###### ????-??-?? * Added an implementation to Stratify Data (#2671). + * Add `BUILD_DOCS` CMake option to control whether Doxygen documentation is + built (default ON) (#2730). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. From 47a5c0b4597180f836db9a5d127035a9fc4aa07d Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Sun, 22 Nov 2020 16:47:32 -0500 Subject: [PATCH 177/550] Update src/mlpack/methods/ann/layer/noisylinear_impl.hpp Minor edit to match coding style Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index 8bb7890bf9..b7bc47d1f5 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -65,7 +65,8 @@ template NoisyLinear& NoisyLinear::operator=(NoisyLinear const& layer) { - if(this != &layer) { + if( this != &layer) + { inSize = layer.inSize; outSize = layer.outSize; weights = layer.weights; From ab261aee7e89d872bbb50c74b78558bd94ef9583 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Sun, 22 Nov 2020 16:47:54 -0500 Subject: [PATCH 178/550] Update src/mlpack/methods/ann/layer/noisylinear_impl.hpp Minor edit to match coding style Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index b7bc47d1f5..cf0af4a06f 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -50,7 +50,7 @@ NoisyLinear::NoisyLinear( template NoisyLinear::NoisyLinear( - NoisyLinear&& layer) : + NoisyLinear&& layer) : inSize(std::move(layer.inSize)), outSize(std::move(layer.outSize)), weights(std::move(layer.weights)) From 9095dd47804881f3b4e8dc7b2a3599edff4b3122 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Sun, 22 Nov 2020 16:48:09 -0500 Subject: [PATCH 179/550] Update src/mlpack/methods/ann/layer/noisylinear_impl.hpp Minor edit to match coding style Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index cf0af4a06f..04841a9315 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -79,7 +79,8 @@ template NoisyLinear& NoisyLinear::operator=(NoisyLinear&& layer) { - if(this != &layer) { + if (this != &layer) + { inSize = std::move(layer.inSize); layer.inSize = 0; outSize = std::move(layer.outSize); From 0471e3bc728c8665ba8a0770c2ce279dc61ba1b2 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 22 Nov 2020 20:54:37 -0500 Subject: [PATCH 180/550] Maybe some extra options here might tell us more. --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 4b35b09f08..552999ed6a 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -9,21 +9,24 @@ mlpack-windows Package mlpack-win-installer + false HarvestPath=.\SourceDir;SourceDir=SourceDir + $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets + true bin\$(Configuration)\ obj\$(Configuration)\ - Debug + Debug;$(DefineConstants) bin\$(Configuration)\ obj\$(Configuration)\ - Debug bin\$(Platform)\$(Configuration)\ obj\$(Platform)\$(Configuration)\ + Debug;$(DefineConstants) bin\$(Platform)\$(Configuration)\ From 895543b2588e8ca40ca7c0ca123cae3e571a156d Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 23 Nov 2020 09:54:45 -0500 Subject: [PATCH 181/550] I have no idea if this will make a difference. --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 552999ed6a..3c652f4ce5 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -10,7 +10,7 @@ Package mlpack-win-installer false - HarvestPath=.\SourceDir;SourceDir=SourceDir + SourceDir=SourceDir $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets true From 5552b8caa99374482a2b45d7d426bf0ed61e937c Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 23 Nov 2020 10:04:00 -0500 Subject: [PATCH 182/550] Change default for WARN_AS_ERROR to NO. --- Doxyfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index 465aa90974..b7afc561b9 100644 --- a/Doxyfile +++ b/Doxyfile @@ -75,7 +75,8 @@ FILE_VERSION_FILTER = #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES -WARN_AS_ERROR = YES +# This will be set to YES for the Jenkins doxygen check build. +WARN_AS_ERROR = NO WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES From 0cb0a79b2dcf633e023e755732248df4118cc441 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Mon, 23 Nov 2020 20:23:20 -0500 Subject: [PATCH 183/550] Update src/mlpack/methods/ann/layer/noisylinear.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/layer/noisylinear.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear.hpp b/src/mlpack/methods/ann/layer/noisylinear.hpp index 625f7d6c6c..f3050c9add 100644 --- a/src/mlpack/methods/ann/layer/noisylinear.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear.hpp @@ -52,7 +52,7 @@ class NoisyLinear NoisyLinear(NoisyLinear&&); //! Operator= copy constructor. - NoisyLinear& operator=(NoisyLinear const& layer); + NoisyLinear& operator=(const NoisyLinear& layer); //! Operator= move constructor. NoisyLinear& operator=(NoisyLinear&& layer); From 133dc670145c0b4cd88f69769df17ec837843462 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Mon, 23 Nov 2020 20:23:34 -0500 Subject: [PATCH 184/550] Update src/mlpack/methods/ann/layer/noisylinear_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index 04841a9315..0689d46de9 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -65,7 +65,7 @@ template NoisyLinear& NoisyLinear::operator=(NoisyLinear const& layer) { - if( this != &layer) + if (this != &layer) { inSize = layer.inSize; outSize = layer.outSize; From 30589d9325c05fa50a990b63743567a774945d86 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Mon, 23 Nov 2020 20:23:41 -0500 Subject: [PATCH 185/550] Update src/mlpack/methods/ann/layer/noisylinear_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index 0689d46de9..f1ae97ffd6 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -63,7 +63,7 @@ NoisyLinear::NoisyLinear( template NoisyLinear& -NoisyLinear::operator=(NoisyLinear const& layer) +NoisyLinear::operator=(const NoisyLinear& layer) { if (this != &layer) { From 835b4945dfc631c54ffa18afcd80da4811c7dc9f Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 24 Nov 2020 00:01:44 -0500 Subject: [PATCH 186/550] remove unreasonable set to nullptr and other unnecessaries --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index f1ae97ffd6..62e6a8c84c 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -51,13 +51,10 @@ NoisyLinear::NoisyLinear( template NoisyLinear::NoisyLinear( NoisyLinear&& layer) : - inSize(std::move(layer.inSize)), - outSize(std::move(layer.outSize)), + inSize(layer.inSize), + outSize(layer.outSize), weights(std::move(layer.weights)) { - layer.inSize = 0; - layer.outSize = 0; - layer.weights = nullptr; Reset(); } @@ -81,12 +78,9 @@ NoisyLinear::operator=(NoisyLinear&& layer) { if (this != &layer) { - inSize = std::move(layer.inSize); - layer.inSize = 0; - outSize = std::move(layer.outSize); - layer.outSize = 0; + inSize = layer.inSize; + outSize = layer.outSize; weights = std::move(layer.weights); - layer.weights = nullptr; Reset(); } return *this; From 16b70bdbccd44d76a2fee5c5dbf108bcd3117906 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 24 Nov 2020 00:09:14 -0500 Subject: [PATCH 187/550] change style and correct nullptr wrongly set. --- src/mlpack/methods/ann/layer/concatenate.hpp | 4 ++-- src/mlpack/methods/ann/layer/concatenate_impl.hpp | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/mlpack/methods/ann/layer/concatenate.hpp b/src/mlpack/methods/ann/layer/concatenate.hpp index 6dbcc54d1d..561ecf2595 100644 --- a/src/mlpack/methods/ann/layer/concatenate.hpp +++ b/src/mlpack/methods/ann/layer/concatenate.hpp @@ -47,10 +47,10 @@ class Concatenate //! Move constructor. Concatenate(Concatenate&& layer); - //! Copy operator constructor. + //! Operator= copy constructor. Concatenate& operator=(const Concatenate& layer); - //! move operator constructor. + //! Operator= move constructor. Concatenate& operator=(Concatenate&& layer); /** diff --git a/src/mlpack/methods/ann/layer/concatenate_impl.hpp b/src/mlpack/methods/ann/layer/concatenate_impl.hpp index efa642f2b9..10a6015de1 100644 --- a/src/mlpack/methods/ann/layer/concatenate_impl.hpp +++ b/src/mlpack/methods/ann/layer/concatenate_impl.hpp @@ -37,7 +37,7 @@ Concatenate::Concatenate(const Concatenate& layer template Concatenate::Concatenate(Concatenate&& layer) : - inRows(std::move(layer.inRows)), + inRows(layer.inRows), weights(std::move(layer.weights)), delta(std::move(layer.delta)), concat(std::move(layer.concat)) @@ -67,14 +67,10 @@ operator=(Concatenate&& layer) { if (this != &layer) { - inRows = std::move(layer.inRows); - layer.inRows = 0; + inRows = layer.inRows; weights = std::move(layer.weights); - layer.weights = nullptr; delta = std::move(layer.delta); - layer.delta = nullptr; concat = std::move(layer.concat); - layer.concat = nullptr; } return *this; } From 2ce058db0c05efbc55a4d264bdd6db487d34751d Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 24 Nov 2020 21:23:17 +0530 Subject: [PATCH 188/550] changed comments --- src/mlpack/methods/ann/layer/convolution.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index ab26c7e80e..bcebf756cf 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -207,10 +207,10 @@ class Convolution //! Modify the output height. size_t& OutputHeight() { return outputHeight; } - //! Get the input size. + //! Get the number of input maps. size_t InputSize() const { return inSize; } - //! Get the output size. + //! Get the number of output maps. size_t OutputSize() const { return outSize; } //! Get the kernel width. From 77d84636caa13c3281fdf077c087695aad3ac414 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 24 Nov 2020 18:49:56 -0500 Subject: [PATCH 189/550] What if we use a relative path? --- .../mlpack-win-installer/mlpack-win-installer.wixproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index 3c652f4ce5..e87b37c56f 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -10,7 +10,7 @@ Package mlpack-win-installer false - SourceDir=SourceDir + SourceDir=.\SourceDir $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets true @@ -34,7 +34,7 @@ - + SourceDir SourceDir var.SourceDir From f602dfa8105520a540da1f39c930ef58d53600f2 Mon Sep 17 00:00:00 2001 From: prince Date: Fri, 14 Feb 2020 23:57:26 +0530 Subject: [PATCH 190/550] Added Triplet margin loss function and Resolved Merge Conflicts --- .../methods/ann/loss_functions/CMakeLists.txt | 2 + .../loss_functions/triplet_margin_loss.hpp | 92 +++++++++++++++++++ .../triplet_margin_loss_impl.hpp | 68 ++++++++++++++ src/mlpack/tests/loss_functions_test.cpp | 46 ++++++++++ 4 files changed, 208 insertions(+) create mode 100644 src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp create mode 100644 src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp diff --git a/src/mlpack/methods/ann/loss_functions/CMakeLists.txt b/src/mlpack/methods/ann/loss_functions/CMakeLists.txt index e04e38dc4c..87100de0db 100644 --- a/src/mlpack/methods/ann/loss_functions/CMakeLists.txt +++ b/src/mlpack/methods/ann/loss_functions/CMakeLists.txt @@ -41,6 +41,8 @@ set(SOURCES empty_loss_impl.hpp mean_absolute_percentage_error.hpp mean_absolute_percentage_error_impl.hpp + triplet_margin_loss.hpp + triplet_margin_loss_impl.hpp ) # Add directory name to sources. diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp new file mode 100644 index 0000000000..fa23999d8f --- /dev/null +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp @@ -0,0 +1,92 @@ +/** + * @file triplet_margin_loss.hpp + * @author Prince Gupta + * + * Definition of the Triplet Margin Loss function. + * + * 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_ANN_LOSS_FUNCTION_TRIPLET_MARGIN_LOSS_HPP +#define MLPACK_ANN_LOSS_FUNCTION_TRIPLET_MARGIN_LOSS_HPP + +#include + +namespace mlpack { +namespace ann /** Artificial Neural Network. */ { + +template < + typename InputDataType = arma::mat, + typename OutputDataType = arma::mat +> +class TripletMarginLoss +{ + public: + + /** + * Create the TripletMarginLoss object with Hyperparameter margin. + */ + TripletMarginLoss(const double margin = 1.0); + + /** + * Computes the Triplet Margin Loss function. + * + * @param input The propagated input activation. + * @param target The target vector. + */ +template + double Forward(const AnchorType&& anchor, + const PositiveType&& positive, + const NegativeType&& negative); + + /** + * Ordinary feed backward pass of a neural network. + * + * @param input The propagated input activation. + * @param target The target vector. + * @param output The calculated error. + */ +template < + typename AnchorType, + typename PositiveType, + typename NegativeType, + typename OutputType +> + void Backward(const AnchorType&& anchor, + const PositiveType&& positive, + const NegativeType&& negative, + OutputType&& output); + + //! Get the output parameter. + OutputDataType& OutputParameter() const { return outputParameter; } + //! Modify the output parameter. + OutputDataType& OutputParameter() { return outputParameter; } + + //! Get the output parameter. + double& Margin() const { return margin; } + //! Modify the output parameter. + double& Margin() { return margin; } + + /** + * Serialize the layer. + */ + template + void serialize(Archive& ar, const unsigned int /* version */); + + private: + //! Locally-stored output parameter object. + OutputDataType outputParameter; + + //! The margin value used in calculating Triplet Margin Loss. + double margin; +}; // class TripletLossMargin + +} //namespace ann +} // namespace mlpack + +// include implementation. +#include "triplet_margin_loss_impl.hpp" + +#endif diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp new file mode 100644 index 0000000000..8cbd972f08 --- /dev/null +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -0,0 +1,68 @@ +/** + * @file triplet_margin_loss_impl.hpp + * @author Prince Gupta + * + * Implementation of the Triplet Margin Loss function. + * + * 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_LOSS_FUNCTION_TRIPLET_MARGIN_IMPL_LOSS_HPP +#define MLPACK_METHODS_ANN_LOSS_FUNCTION_TRIPLET_MARGIN_IMPL_LOSS_HPP + +// In case it hasn't been included. +#include "triplet_margin_loss.hpp" + +namespace mlpack { +namespace ann /** Artifical Neural Network. */ { + +template +TripletMarginLoss::TripletMarginLoss( + const double margin) : margin(margin) +{ + // Nothing to do here. +} + +template +template +double TripletMarginLoss::Forward( + const AnchorType&& anchor, + const PositiveType&& positive, + const NegativeType&& negative) +{ + return std::max(0.0, arma::accu(arma::pow(anchor - positive, 2)) - + arma::accu(arma::pow(anchor - negative, 2)) + margin) / anchor.n_cols; +} + +template +template < + typename AnchorType, + typename PositiveType, + typename NegativeType, + typename OutputType +> +void TripletMarginLoss::Backward( + const AnchorType&& anchor, + const PositiveType&& positive, + const NegativeType&& negative, + OutputType&& output + ) +{ + output = 2 * (negative - positive) / anchor.n_cols; +} + +template +template +void TripletMarginLoss::serialize( + Archive& ar, + const unsigned int /* version */) +{ + ar & BOOST_SERIALIZATION_NVP(margin); +} + +} // namespace ann +} // namespace mlpack + +#endif diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 42762bd96d..0c2c1bff4b 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -897,3 +898,48 @@ TEST_CASE("MeanAbsolutePercentageErrorTest", "[LossFunctionsTest]") REQUIRE(output.n_cols == input.n_cols); CheckMatrices(output, expectedOutput, 0.1); } + +/* + * Simple test for the Triplet Margin Loss function. + */ +BOOST_AUTO_TEST_CASE(TripletMarginLossTest) +{ + arma::mat anchor, positive, negative, output; + TripletMarginLoss<> module; + + // Test the Forward function on a user generator input and compare it against + // the manually calculated result. + anchor = arma::mat("2 3 5"); + positive = arma::mat("10 12 13"); + negative = arma::mat("4 5 7"); + double error = module.Forward(std::move(anchor), + std::move(positive), std::move(negative)); + BOOST_REQUIRE_EQUAL(error, 66); + + // Test the Backward function. + module.Backward(std::move(anchor), + std::move(positive), std::move(negative), std::move(output)); + // According to the used backward formula: + // output = 2 * (negative - positive) / anchor.n_cols, + // output * nofColumns / 2 + positive should be equal to negative. + CheckMatrices(negative, output * output.n_cols / 2 + positive); + BOOST_REQUIRE_EQUAL(output.n_rows, anchor.n_rows); + BOOST_REQUIRE_EQUAL(output.n_cols, anchor.n_cols); + + // Test the error function on a single input. + anchor = arma::mat("4"); + positive = arma::mat("7"); + negative = arma::mat("1"); + error = module.Forward(std::move(anchor), + std::move(positive), std::move(negative)); + BOOST_REQUIRE_EQUAL(error, 1.0); + + // Test the Backward function on a single input. + module.Backward(std::move(anchor), + std::move(positive), std::move(negative), std::move(output)); + // Test whether the output is negative. + BOOST_REQUIRE_EQUAL(arma::accu(output), -12); + BOOST_REQUIRE_EQUAL(output.n_elem, 1); +} + +BOOST_AUTO_TEST_SUITE_END(); From bac726ac677cbaae999859a955fbe1edf3849ed7 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 25 Nov 2020 16:54:22 +0530 Subject: [PATCH 191/550] remove unused weightSize variable --- src/mlpack/tests/ann_visitor_test.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index d741b94328..e5d1310368 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -95,8 +95,6 @@ TEST_CASE("WeightSizeVisitorTestForLinearLayer", "[ANNVisitorTest]") LayerTypes<> linearLayer = new Linear<>(randomInSize, randomOutSize); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), linearLayer); - CheckCorrectnessOfWeightSize(linearLayer); } @@ -107,8 +105,6 @@ TEST_CASE("WeightSizeVisitorTestForConcatLayer", "[ANNVisitorTest]") { LayerTypes<> concatLayer = new Concat<>(); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), concatLayer); - CheckCorrectnessOfWeightSize(concatLayer); } @@ -122,8 +118,6 @@ TEST_CASE("WeightSizeVisitorTestForFastLSTMLayer", "[ANNVisitorTest]") LayerTypes<> fastLSTMLayer = new FastLSTM<>(randomInSize, randomOutSize); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), fastLSTMLayer); - CheckCorrectnessOfWeightSize(fastLSTMLayer); } @@ -136,8 +130,6 @@ TEST_CASE("WeightSizeVisitorTestForAddLayer", "[ANNVisitorTest]") LayerTypes<> addLayer = new Add<>(randomOutSize); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), addLayer); - CheckCorrectnessOfWeightSize(addLayer); } @@ -154,9 +146,6 @@ TEST_CASE("WeightSizeVisitorTestForAtrousConvolutionLayer", "[ANNVisitorTest]") LayerTypes<> atrousConvLayer = new AtrousConvolution<>(randomInSize, randomOutSize, randomKernelWidth, randomKernelHeight); - size_t weightSize = boost::apply_visitor(WeightSizeVisitor(), - atrousConvLayer); - CheckCorrectnessOfWeightSize(atrousConvLayer); } From 4cb44be9c97e5c550e43392da6709f9925c97819 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 25 Nov 2020 09:43:30 -0500 Subject: [PATCH 192/550] Is "SourceDir" somehow a word that I'm not supposed to use? --- .ci/windows-steps.yaml | 24 +++++++++---------- .../mlpack-win-installer/Product.wxs | 4 ++-- .../mlpack-win-installer.wixproj | 8 +++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index ff8db4481c..20a402ad30 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -130,20 +130,20 @@ steps: } try { (Add-Type -AssemblyName System.IO.Compression.FileSystem); - [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\mlpack-win-installer\SourceDir\doc') + [System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\mlpack-win-installer\Sources\doc') } catch{Write-Output "Unable to add doc to installer, skipping!"} # Preparing installer staging. - mkdir dist\win-installer\mlpack-win-installer\SourceDir\lib - cp build\Release\*.lib dist\win-installer\mlpack-win-installer\SourceDir\lib\ - cp build\Release\*.exp dist\win-installer\mlpack-win-installer\SourceDir\lib\ - cp build\Release\*.dll dist\win-installer\mlpack-win-installer\SourceDir\ - cp build\Release\*.exe dist\win-installer\mlpack-win-installer\SourceDir\ - cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\SourceDir\ - cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\mlpack-win-installer\SourceDir\ - cp build\include\mlpack dist\win-installer\mlpack-win-installer\SourceDir -recurse - cp doc\examples dist\win-installer\mlpack-win-installer\SourceDir -recurse - cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\SourceDir\examples\sample-ml-app\sample-ml-app\data\ + mkdir dist\win-installer\mlpack-win-installer\Sources\lib + cp build\Release\*.lib dist\win-installer\mlpack-win-installer\Sources\lib\ + cp build\Release\*.exp dist\win-installer\mlpack-win-installer\Sources\lib\ + cp build\Release\*.dll dist\win-installer\mlpack-win-installer\Sources\ + cp build\Release\*.exe dist\win-installer\mlpack-win-installer\Sources\ + cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\Sources\ + cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\mlpack-win-installer\Sources\ + cp build\include\mlpack dist\win-installer\mlpack-win-installer\Sources -recurse + cp doc\examples dist\win-installer\mlpack-win-installer\Sources -recurse + cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\Sources\examples\sample-ml-app\sample-ml-app\data\ # Check current git version or mlpack version. $ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"}); $env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.'; @@ -163,7 +163,7 @@ steps: # Build the MSI installer. cd dist\win-installer\mlpack-win-installer dir - cd SourceDir + cd Sources dir cd .. & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' ` diff --git a/dist/win-installer/mlpack-win-installer/Product.wxs b/dist/win-installer/mlpack-win-installer/Product.wxs index fc2b19f544..4341139f71 100644 --- a/dist/win-installer/mlpack-win-installer/Product.wxs +++ b/dist/win-installer/mlpack-win-installer/Product.wxs @@ -20,13 +20,13 @@ - + - + $(env.MLPACK_VERSION) diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index e87b37c56f..b4166cedd1 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -10,7 +10,7 @@ Package mlpack-win-installer false - SourceDir=.\SourceDir + SourceDir=.\Sources $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets true @@ -34,9 +34,9 @@ - - SourceDir - SourceDir + + Sources + Sources var.SourceDir true From dcd64e669fb43f6c617b778fc283c60e0c4f5366 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Wed, 25 Nov 2020 23:33:05 +0530 Subject: [PATCH 193/550] Added name to copyright --- COPYRIGHT.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 8e4088dceb..4365856baf 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -136,6 +136,7 @@ Copyright: Copyright 2020, Aakash Kaushik Copyright 2020, Anush Kini Copyright 2020, Nippun Sharma + Copyright 2020, Rishabh Garg License: BSD-3-clause All rights reserved. From e4df97a82a4d0cf258eda4095d4977bb2c0a10c5 Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Wed, 25 Nov 2020 21:57:56 +0100 Subject: [PATCH 194/550] Removed template specialization --- src/mlpack/core/cv/metrics/r2_score.hpp | 31 ++------------ src/mlpack/core/cv/metrics/r2_score_impl.hpp | 44 ++++---------------- 2 files changed, 12 insertions(+), 63 deletions(-) diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp index 7fb733eb0c..37e6131fe7 100644 --- a/src/mlpack/core/cv/metrics/r2_score.hpp +++ b/src/mlpack/core/cv/metrics/r2_score.hpp @@ -44,13 +44,12 @@ namespace cv { * the response data around its mean. */ -template class R2Score; - -template<> class R2Score +template +class R2Score { public: /** - * Run prediction and calculate the R squared error. + * Run prediction and calculate the R squared or Adjusted R sauared error. * * @param model A regression model. * @param data Column-major data containing test items. @@ -70,30 +69,6 @@ template<> class R2Score static const bool NeedsMinimization = false; }; -template<> class R2Score -{ - public: - /** - * Run prediction and calculate the Adjusted R squared error. - * - * @param model A regression model. - * @param data Column-major data containing test items. - * @param responses Ground truth (correct) target values for the test items, - * should be either a row vector or a column-major matrix. - * @return calculated Ajusted R2 Score. - */ - template - static double Evaluate(MLAlgorithm& model, - const DataType& data, - const ResponsesType& responses); - - /** - * Information for hyper-parameter tuning code. It indicates that we want - * to maximize the measurement. - */ - static const bool NeedsMinimization = false; -}; - } // namespace cv } // namespace mlpack diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 0d935f867d..1023f731ea 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -15,8 +15,9 @@ namespace mlpack { namespace cv { +template template -double R2Score::Evaluate(MLAlgorithm& model, +double R2Score::Evaluate(MLAlgorithm& model, const DataType& data, const ResponsesType& responses) { @@ -42,41 +43,8 @@ double R2Score::Evaluate(MLAlgorithm& model, // Calculate the denominator i.e.total sum of squares. double totalSumSquared = arma::accu(arma::square(responses - meanResponses)); - // Handling undefined R2 Score when both denominator and numerator is 0.0. - if (residualSumSquared == 0.0) - return totalSumSquared ? 1.0 : DBL_MIN; - - // Returning R-squared - return 1 - residualSumSquared / totalSumSquared; -} - -template - double R2Score::Evaluate(MLAlgorithm& model, - const DataType& data, - const ResponsesType& responses) + if (AdjustedR2) { - if (data.n_cols != responses.n_cols) - { - std::ostringstream oss; - oss << "R2Score::Evaluate(): number of points (" << data.n_cols << ") " - << "does not match number of responses (" << responses.n_cols << ")!" - << std::endl; - throw std::invalid_argument(oss.str()); - } - - ResponsesType predictedResponses; - // Taking Predicted Output from the model. - model.Predict(data, predictedResponses); - // Mean value of response. - double meanResponses = arma::mean(responses); - - // Calculate the numerator i.e. residual sum of squares. - double residualSumSquared = arma::accu(arma::square(responses - - predictedResponses)); - - // Calculate the denominator i.e.total sum of squares. - double totalSumSquared = arma::accu(arma::square(responses - meanResponses)); - // Handling undefined R2 Score when both denominator and numerator is 0.0. if (residualSumSquared == 0.0) return totalSumSquared ? 1.0 : DBL_MIN; @@ -84,6 +52,12 @@ template double rsq = 1 - (residualSumSquared / totalSumSquared); return (1 - ((1 - rsq) * ((data.n_cols - 1) / (data.n_cols - data.n_rows - 1)))); } + else + { + // Returning R-squared + return 1 - residualSumSquared / totalSumSquared; + } +} } // namespace cv } // namespace mlpack From 83466773cdb588999659a3dbd538e82b69fcbc7b Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Wed, 25 Nov 2020 22:00:09 +0100 Subject: [PATCH 195/550] Corrected parameter name --- src/mlpack/core/cv/metrics/r2_score.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp index 37e6131fe7..b3cc2c5fad 100644 --- a/src/mlpack/core/cv/metrics/r2_score.hpp +++ b/src/mlpack/core/cv/metrics/r2_score.hpp @@ -44,7 +44,7 @@ namespace cv { * the response data around its mean. */ -template +template class R2Score { public: From b3444b28d4a448bfe63c4560a4c4e2ae0cbd5d04 Mon Sep 17 00:00:00 2001 From: Omar Shrit Date: Wed, 25 Nov 2020 23:13:03 +0100 Subject: [PATCH 196/550] Remove strange characters situated at the end of each line I can not see what are these chars, but they are detect by kakoune and represented by a strange question mark. So I am removing them. Signed-off-by: Omar Shrit --- src/mlpack/core/data/load_image_impl.hpp | 190 +++++++++++------------ 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/src/mlpack/core/data/load_image_impl.hpp b/src/mlpack/core/data/load_image_impl.hpp index 8cd9b9a2ef..9a757838b9 100644 --- a/src/mlpack/core/data/load_image_impl.hpp +++ b/src/mlpack/core/data/load_image_impl.hpp @@ -1,96 +1,96 @@ -/** +/** * @file core/data/load_image_impl.hpp - * @author Mehul Kumar Nirala - * - * An image loading utility implementation. - * - * 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_CORE_DATA_LOAD_IMAGE_IMPL_HPP -#define MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP - -// In case it hasn't been included yet. -#include "load.hpp" - -namespace mlpack { -namespace data { - -// Image loading API. -template -bool Load(const std::string& filename, - arma::Mat& matrix, - ImageInfo& info, - const bool fatal) -{ - Timer::Start("loading_image"); - - // STB loads into unsigned char matrices, so we may have to convert once - // loaded. - arma::Mat tempMatrix; - const bool result = LoadImage(filename, tempMatrix, info, fatal); - - // If fatal is true, then the program will have already thrown an exception. - if (!result) - { - Timer::Stop("loading_image"); - return false; - } - - matrix = arma::conv_to>::from(tempMatrix); - Timer::Stop("loading_image"); - return true; -} - -// Image loading API for multiple files. -template -bool Load(const std::vector& files, - arma::Mat& matrix, - ImageInfo& info, - const bool fatal) -{ - if (files.size() == 0) - { - std::ostringstream oss; - oss << "Load(): vector of image files is empty." << std::endl; - - if (fatal) - Log::Fatal << oss.str(); - else - Log::Warn << oss.str(); - - return false; - } - - arma::Mat img; - bool status = LoadImage(files[0], img, info, fatal); - - if (!status) - return false; - - // Decide matrix dimension using the image height and width. - arma::Mat tmpMatrix( - info.Width() * info.Height() * info.Channels(), files.size()); - tmpMatrix.col(0) = img; - - for (size_t i = 1; i < files.size() ; ++i) - { - arma::Mat colImg(tmpMatrix.colptr(i), tmpMatrix.n_rows, 1, - false, true); - status = LoadImage(files[i], colImg, info, fatal); - - if (!status) - return false; - } - - matrix = arma::conv_to>::from(tmpMatrix); - return true; -} - -} // namespace data -} // namespace mlpack - -#endif + * @author Mehul Kumar Nirala + * + * An image loading utility implementation. + * + * 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_CORE_DATA_LOAD_IMAGE_IMPL_HPP +#define MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP + +// In case it hasn't been included yet. +#include "load.hpp" + +namespace mlpack { +namespace data { + +// Image loading API. +template +bool Load(const std::string& filename, + arma::Mat& matrix, + ImageInfo& info, + const bool fatal) +{ + Timer::Start("loading_image"); + + // STB loads into unsigned char matrices, so we may have to convert once + // loaded. + arma::Mat tempMatrix; + const bool result = LoadImage(filename, tempMatrix, info, fatal); + + // If fatal is true, then the program will have already thrown an exception. + if (!result) + { + Timer::Stop("loading_image"); + return false; + } + + matrix = arma::conv_to>::from(tempMatrix); + Timer::Stop("loading_image"); + return true; +} + +// Image loading API for multiple files. +template +bool Load(const std::vector& files, + arma::Mat& matrix, + ImageInfo& info, + const bool fatal) +{ + if (files.size() == 0) + { + std::ostringstream oss; + oss << "Load(): vector of image files is empty." << std::endl; + + if (fatal) + Log::Fatal << oss.str(); + else + Log::Warn << oss.str(); + + return false; + } + + arma::Mat img; + bool status = LoadImage(files[0], img, info, fatal); + + if (!status) + return false; + + // Decide matrix dimension using the image height and width. + arma::Mat tmpMatrix( + info.Width() * info.Height() * info.Channels(), files.size()); + tmpMatrix.col(0) = img; + + for (size_t i = 1; i < files.size() ; ++i) + { + arma::Mat colImg(tmpMatrix.colptr(i), tmpMatrix.n_rows, 1, + false, true); + status = LoadImage(files[i], colImg, info, fatal); + + if (!status) + return false; + } + + matrix = arma::conv_to>::from(tmpMatrix); + return true; +} + +} // namespace data +} // namespace mlpack + +#endif From cb4303a37e8a07d63a0faca1ef0cdf2e95693fcd Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 25 Nov 2020 17:40:55 -0500 Subject: [PATCH 197/550] Wait. It worked??? --- .ci/windows-steps.yaml | 2 +- .../mlpack-win-installer/mlpack-win-installer.wixproj | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 20a402ad30..4a4461d1fa 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -191,7 +191,7 @@ steps: displayName: 'Publish artifacts test results' - task: PublishBuildArtifacts@1 inputs: - pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\x64\Release\*.msi' + pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\Release\*.msi' artifactName: mlpack-windows-installer displayName: 'Publish Windows MSI installer' diff --git a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj index b4166cedd1..0e89ee825c 100644 --- a/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj +++ b/dist/win-installer/mlpack-win-installer/mlpack-win-installer.wixproj @@ -12,7 +12,6 @@ false SourceDir=.\Sources $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets - true bin\$(Configuration)\ From 16aeaa1f764e892094ebd3c869c0f740ac5058ca Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 25 Nov 2020 20:57:05 -0500 Subject: [PATCH 198/550] Revert "remove unreasonable set to nullptr and other unnecessaries" This reverts commit 835b4945dfc631c54ffa18afcd80da4811c7dc9f. --- src/mlpack/methods/ann/layer/noisylinear_impl.hpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp index 62e6a8c84c..f1ae97ffd6 100644 --- a/src/mlpack/methods/ann/layer/noisylinear_impl.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear_impl.hpp @@ -51,10 +51,13 @@ NoisyLinear::NoisyLinear( template NoisyLinear::NoisyLinear( NoisyLinear&& layer) : - inSize(layer.inSize), - outSize(layer.outSize), + inSize(std::move(layer.inSize)), + outSize(std::move(layer.outSize)), weights(std::move(layer.weights)) { + layer.inSize = 0; + layer.outSize = 0; + layer.weights = nullptr; Reset(); } @@ -78,9 +81,12 @@ NoisyLinear::operator=(NoisyLinear&& layer) { if (this != &layer) { - inSize = layer.inSize; - outSize = layer.outSize; + inSize = std::move(layer.inSize); + layer.inSize = 0; + outSize = std::move(layer.outSize); + layer.outSize = 0; weights = std::move(layer.weights); + layer.weights = nullptr; Reset(); } return *this; From 26f94f265269eaa9d7a88d96a0b4ddd0e20511ea Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 25 Nov 2020 20:59:03 -0500 Subject: [PATCH 199/550] fix comment --- src/mlpack/tests/feedforward_network_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index c5b1b874d8..57af43ff39 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -186,8 +186,8 @@ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") // Check whether move constructor is working or not. CheckMoveFunction<>(model2, input, output, 1); - * Check whether copying and moving network with dropout is working or not. - */ +} + TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]") { // Load the dataset. From 51b5719f7ab0fa125cebd1cc0e5dcbca88202846 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 25 Nov 2020 21:09:20 -0500 Subject: [PATCH 200/550] more comment fix --- src/mlpack/tests/feedforward_network_test.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 57af43ff39..774bb53f18 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -154,7 +154,7 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") } /** - * Noisy Linear layer constructor test. + * Check whether copying and moving of Noisy Linear layer is working or not. */ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") { @@ -188,6 +188,9 @@ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model2, input, output, 1); } +/** + * Check whether copying and moving of Dropout network is working or not. + */ TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]") { // Load the dataset. From f700776ddbbe3c51e3ec9f0b2c08748059510358 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 25 Nov 2020 23:03:51 -0500 Subject: [PATCH 201/550] Maybe a wildcard doesn't work here. --- .ci/windows-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 4a4461d1fa..1356125809 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -191,7 +191,7 @@ steps: displayName: 'Publish artifacts test results' - task: PublishBuildArtifacts@1 inputs: - pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\Release\*.msi' + pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\Release\mlpack-windows.msi' artifactName: mlpack-windows-installer displayName: 'Publish Windows MSI installer' From 30a1dbcb28c9ea9935e7fa396ec05883b439cf46 Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Thu, 26 Nov 2020 08:10:12 +0100 Subject: [PATCH 202/550] Some styling changes --- src/mlpack/core/cv/metrics/r2_score.hpp | 5 ++++- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 7 ++++--- src/mlpack/tests/cv_test.cpp | 1 - 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mlpack/core/cv/metrics/r2_score.hpp b/src/mlpack/core/cv/metrics/r2_score.hpp index b3cc2c5fad..e677f6e177 100644 --- a/src/mlpack/core/cv/metrics/r2_score.hpp +++ b/src/mlpack/core/cv/metrics/r2_score.hpp @@ -42,6 +42,9 @@ namespace cv { * where @f$ \bar{y} = frac{1}{y}\sum_{i=1}^{n} y_i @f$. * For example, a model having R2Score = 0.85, explains 85 \% variability of * the response data around its mean. + * + * @tparam AdjustedR2 If true, then the Adjusted R2 score will be used. + * Otherwise, the regular R2 score is used. */ template @@ -49,7 +52,7 @@ class R2Score { public: /** - * Run prediction and calculate the R squared or Adjusted R sauared error. + * Run prediction and calculate the R squared or Adjusted R squared error. * * @param model A regression model. * @param data Column-major data containing test items. diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 1023f731ea..65fadc1a95 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -18,8 +18,8 @@ namespace cv { template template double R2Score::Evaluate(MLAlgorithm& model, - const DataType& data, - const ResponsesType& responses) + const DataType& data, + const ResponsesType& responses) { if (data.n_cols != responses.n_cols) { @@ -50,7 +50,8 @@ double R2Score::Evaluate(MLAlgorithm& model, return totalSumSquared ? 1.0 : DBL_MIN; // Returning adjusted R-squared. double rsq = 1 - (residualSumSquared / totalSumSquared); - return (1 - ((1 - rsq) * ((data.n_cols - 1) / (data.n_cols - data.n_rows - 1)))); + return (1 - ((1 - rsq) * ((data.n_cols - 1) / + (data.n_cols - data.n_rows - 1)))); } else { diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index d2bc7d7418..83c11374c5 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -212,7 +212,6 @@ TEST_CASE("AdjR2ScoreTest", "[CVTest]") <= 1e-7); } - /** * Test the mean squared error with matrix responses. */ From 19eb5c9bf57404d52b3c34dc82b3f0a887968fff Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Thu, 26 Nov 2020 08:13:47 +0100 Subject: [PATCH 203/550] Edited HISTORY.md --- HISTORY.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 4d3807e380..52ad2c23b9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,6 @@ -### mlpack ?.?.? -###### ????-??-?? +### mlpack 3.4.2 +###### 2020-11-26 + * Add Adjusted R squared functionality to R2Score::Evalute (#2624) ### mlpack 3.4.1 ###### 2020-09-07 From 60d4c2a3bcf6ec86b7283da92b1b751b7e8cee3a Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Thu, 26 Nov 2020 08:15:40 +0100 Subject: [PATCH 204/550] Corrected Evaluate in HISTORY.md --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 52ad2c23b9..5501a5dcd4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,6 @@ ### mlpack 3.4.2 ###### 2020-11-26 - * Add Adjusted R squared functionality to R2Score::Evalute (#2624) + * Add Adjusted R squared functionality to R2Score::Evaluate (#2624) ### mlpack 3.4.1 ###### 2020-09-07 From d810ca65622748dc536ec96fbac22d3fd6ee2e8b Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Thu, 26 Nov 2020 08:22:31 +0100 Subject: [PATCH 205/550] Corrected HISTORY.md --- HISTORY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 5501a5dcd4..fea0f23f7d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -### mlpack 3.4.2 -###### 2020-11-26 +### mlpack ?.?.? +###### ????-??-?? * Add Adjusted R squared functionality to R2Score::Evaluate (#2624) ### mlpack 3.4.1 From 4028ef8de1596251a02427b46a968b8f23cacdea Mon Sep 17 00:00:00 2001 From: Omar Shrit Date: Thu, 26 Nov 2020 11:19:39 +0100 Subject: [PATCH 206/550] Remove Windows ending from this file too Signed-off-by: Omar Shrit --- src/mlpack/core/data/image_info_impl.hpp | 152 +++++++++++------------ 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/src/mlpack/core/data/image_info_impl.hpp b/src/mlpack/core/data/image_info_impl.hpp index b0257c5d89..3040a38415 100644 --- a/src/mlpack/core/data/image_info_impl.hpp +++ b/src/mlpack/core/data/image_info_impl.hpp @@ -1,77 +1,77 @@ -/** +/** * @file core/data/image_info_impl.hpp - * @author Mehul Kumar Nirala - * - * An image information holder implementation. - * - * 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_CORE_DATA_IMAGE_INFO_IMPL_HPP -#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP - -#ifdef HAS_STB // Compile this only if stb is present. - -// In case it hasn't been included yet. -#include "image_info.hpp" - -namespace mlpack { -namespace data { - -static const std::vector loadFileTypes({"jpg", "png", "tga", - "bmp", "psd", "gif", "hdr", "pic", "pnm", "jpeg"}); - -static const std::vector saveFileTypes({"jpg", "png", "tga", - "bmp", "hdr"}); - -inline bool ImageFormatSupported(const std::string& fileName, const bool save) -{ - if (save) - { - // Iterate over all supported file types that can be saved. - for (auto extension : saveFileTypes) - { - if (extension == Extension(fileName)) - return true; - } - } - else - { - // Iterate over all supported file types that can be loaded. - for (auto extension : loadFileTypes) - { - if (extension == Extension(fileName)) - return true; - } - } - - return false; -} - -} // namespace data -} // namespace mlpack - -#endif // HAS_STB. - -namespace mlpack { -namespace data { - -inline ImageInfo::ImageInfo(const size_t width, - const size_t height, - const size_t channels, - const size_t quality) : - width(width), - height(height), - channels(channels), - quality(quality) -{ - // Do nothing. -} - -} // namespace data -} // namespace mlpack - -#endif + * @author Mehul Kumar Nirala + * + * An image information holder implementation. + * + * 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_CORE_DATA_IMAGE_INFO_IMPL_HPP +#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP + +#ifdef HAS_STB // Compile this only if stb is present. + +// In case it hasn't been included yet. +#include "image_info.hpp" + +namespace mlpack { +namespace data { + +static const std::vector loadFileTypes({"jpg", "png", "tga", + "bmp", "psd", "gif", "hdr", "pic", "pnm", "jpeg"}); + +static const std::vector saveFileTypes({"jpg", "png", "tga", + "bmp", "hdr"}); + +inline bool ImageFormatSupported(const std::string& fileName, const bool save) +{ + if (save) + { + // Iterate over all supported file types that can be saved. + for (auto extension : saveFileTypes) + { + if (extension == Extension(fileName)) + return true; + } + } + else + { + // Iterate over all supported file types that can be loaded. + for (auto extension : loadFileTypes) + { + if (extension == Extension(fileName)) + return true; + } + } + + return false; +} + +} // namespace data +} // namespace mlpack + +#endif // HAS_STB. + +namespace mlpack { +namespace data { + +inline ImageInfo::ImageInfo(const size_t width, + const size_t height, + const size_t channels, + const size_t quality) : + width(width), + height(height), + channels(channels), + quality(quality) +{ + // Do nothing. +} + +} // namespace data +} // namespace mlpack + +#endif From 451c5fde743b5c9861e6180d78dcbe874977cedc Mon Sep 17 00:00:00 2001 From: Omar Shrit Date: Thu, 26 Nov 2020 11:32:00 +0100 Subject: [PATCH 207/550] Fix these dataset too from windows ending Signed-off-by: Omar Shrit --- .../tests/data/nbc_high_dim_test_labels.csv | 100 ++--- .../tests/data/nbc_high_dim_train_labels.csv | 400 +++++++++--------- 2 files changed, 250 insertions(+), 250 deletions(-) diff --git a/src/mlpack/tests/data/nbc_high_dim_test_labels.csv b/src/mlpack/tests/data/nbc_high_dim_test_labels.csv index dd6bde5f4b..59847158f6 100644 --- a/src/mlpack/tests/data/nbc_high_dim_test_labels.csv +++ b/src/mlpack/tests/data/nbc_high_dim_test_labels.csv @@ -1,50 +1,50 @@ -3 -2 -0 -0 -0 -1 -2 -3 -3 -2 -4 -2 -1 -2 -3 -1 -2 -4 -4 -1 -3 -0 -2 -0 -0 -2 -0 -1 -3 -3 -2 -2 -2 -3 -3 -3 -3 -3 -0 -0 -4 -3 -3 -0 -3 -2 -3 -2 -1 -1 +3 +2 +0 +0 +0 +1 +2 +3 +3 +2 +4 +2 +1 +2 +3 +1 +2 +4 +4 +1 +3 +0 +2 +0 +0 +2 +0 +1 +3 +3 +2 +2 +2 +3 +3 +3 +3 +3 +0 +0 +4 +3 +3 +0 +3 +2 +3 +2 +1 +1 diff --git a/src/mlpack/tests/data/nbc_high_dim_train_labels.csv b/src/mlpack/tests/data/nbc_high_dim_train_labels.csv index 064f0e24a2..c25922d7a4 100644 --- a/src/mlpack/tests/data/nbc_high_dim_train_labels.csv +++ b/src/mlpack/tests/data/nbc_high_dim_train_labels.csv @@ -1,200 +1,200 @@ -1 -4 -2 -2 -1 -0 -1 -0 -0 -4 -0 -4 -3 -4 -3 -2 -4 -2 -2 -2 -4 -1 -2 -1 -3 -0 -4 -1 -4 -4 -4 -0 -3 -4 -3 -1 -3 -2 -3 -0 -4 -1 -4 -1 -4 -2 -1 -4 -2 -1 -2 -0 -2 -2 -4 -2 -0 -2 -0 -3 -3 -3 -0 -2 -1 -4 -3 -1 -2 -2 -4 -0 -1 -3 -4 -4 -4 -2 -4 -2 -3 -4 -4 -3 -2 -3 -3 -4 -3 -4 -2 -4 -0 -3 -3 -1 -3 -4 -2 -1 -2 -3 -1 -3 -3 -0 -4 -0 -0 -3 -2 -1 -0 -3 -2 -1 -0 -0 -1 -0 -2 -2 -4 -2 -3 -1 -4 -4 -2 -3 -4 -0 -2 -2 -0 -4 -0 -3 -1 -4 -4 -2 -0 -0 -0 -0 -3 -4 -3 -2 -0 -4 -3 -3 -4 -0 -3 -1 -3 -4 -3 -2 -2 -4 -0 -0 -0 -0 -1 -4 -0 -3 -4 -3 -1 -4 -0 -1 -4 -3 -2 -1 -3 -2 -4 -3 -2 -0 -1 -4 -2 -0 -2 -3 -0 -0 -2 -1 -3 -1 +1 +4 +2 +2 +1 +0 +1 +0 +0 +4 +0 +4 +3 +4 +3 +2 +4 +2 +2 +2 +4 +1 +2 +1 +3 +0 +4 +1 +4 +4 +4 +0 +3 +4 +3 +1 +3 +2 +3 +0 +4 +1 +4 +1 +4 +2 +1 +4 +2 +1 +2 +0 +2 +2 +4 +2 +0 +2 +0 +3 +3 +3 +0 +2 +1 +4 +3 +1 +2 +2 +4 +0 +1 +3 +4 +4 +4 +2 +4 +2 +3 +4 +4 +3 +2 +3 +3 +4 +3 +4 +2 +4 +0 +3 +3 +1 +3 +4 +2 +1 +2 +3 +1 +3 +3 +0 +4 +0 +0 +3 +2 +1 +0 +3 +2 +1 +0 +0 +1 +0 +2 +2 +4 +2 +3 +1 +4 +4 +2 +3 +4 +0 +2 +2 +0 +4 +0 +3 +1 +4 +4 +2 +0 +0 +0 +0 +3 +4 +3 +2 +0 +4 +3 +3 +4 +0 +3 +1 +3 +4 +3 +2 +2 +4 +0 +0 +0 +0 +1 +4 +0 +3 +4 +3 +1 +4 +0 +1 +4 +3 +2 +1 +3 +2 +4 +3 +2 +0 +1 +4 +2 +0 +2 +3 +0 +0 +2 +1 +3 +1 From d0d56d0049afab7a67c9a664272483ad49497e75 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 26 Nov 2020 11:02:03 -0500 Subject: [PATCH 208/550] Fix apparent typo. --- dist/win-installer/mlpack-win-installer/Product.wxs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/win-installer/mlpack-win-installer/Product.wxs b/dist/win-installer/mlpack-win-installer/Product.wxs index 4341139f71..3cd7598a85 100644 --- a/dist/win-installer/mlpack-win-installer/Product.wxs +++ b/dist/win-installer/mlpack-win-installer/Product.wxs @@ -30,7 +30,7 @@ $(env.MLPACK_VERSION) - + From 85422870f4b01f1800512cf5515a3fcfbe3983b7 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 26 Nov 2020 11:02:26 -0500 Subject: [PATCH 209/550] Re-add other CI jobs. --- .ci/ci.yaml | 100 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/.ci/ci.yaml b/.ci/ci.yaml index fad956f7f8..26efee03ae 100644 --- a/.ci/ci.yaml +++ b/.ci/ci.yaml @@ -8,56 +8,56 @@ pr: - '*' jobs: -#- job: Linux -# timeoutInMinutes: 360 -# pool: -# vmImage: ubuntu-16.04 -# strategy: -# matrix: -# Plain: -# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' -# Python: -# binding: 'python' -# python.version: '3.7' -# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' -# Julia: -# julia.version: '1.3.0' -# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia -DBUILD_R_BINDINGS=OFF' -# Go: -# binding: 'go' -# go.version: '1.11.0' -# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' -# Markdown: -# CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' -# -# steps: -# - template: linux-steps.yaml -# -#- job: macOS -# timeoutInMinutes: 360 -# pool: -# vmImage: macOS-latest -# strategy: -# matrix: -# Plain: -# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' -# python.version: '2.7' -# Python: -# binding: 'python' -# python.version: '3.7' -# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' -# Julia: -# python.version: '2.7' -# julia.version: '1.3.0' -# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' -# Go: -# binding: 'go' -# python.version: '2.7' -# go.version: '1.11.0' -# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' -# -# steps: -# - template: macos-steps.yaml +- job: Linux + timeoutInMinutes: 360 + pool: + vmImage: ubuntu-16.04 + strategy: + matrix: + Plain: + CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' + Python: + binding: 'python' + python.version: '3.7' + CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' + Julia: + julia.version: '1.3.0' + CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia -DBUILD_R_BINDINGS=OFF' + Go: + binding: 'go' + go.version: '1.11.0' + CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' + Markdown: + CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' + + steps: + - template: linux-steps.yaml + +- job: macOS + timeoutInMinutes: 360 + pool: + vmImage: macOS-latest + strategy: + matrix: + Plain: + CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' + python.version: '2.7' + Python: + binding: 'python' + python.version: '3.7' + CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' + Julia: + python.version: '2.7' + julia.version: '1.3.0' + CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' + Go: + binding: 'go' + python.version: '2.7' + go.version: '1.11.0' + CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF' + + steps: + - template: macos-steps.yaml - job: WindowsVS16 timeoutInMinutes: 360 From f1956ffd338e7c20d204abea1fb58db2984cb08a Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 26 Nov 2020 23:07:06 +0530 Subject: [PATCH 210/550] first commit --- src/mlpack/methods/ann/ffn.hpp | 9 +++ src/mlpack/methods/ann/ffn_impl.hpp | 38 ++++++++++++- src/mlpack/methods/ann/layer/layer_traits.hpp | 4 ++ src/mlpack/methods/ann/layer/linear.hpp | 6 ++ src/mlpack/methods/ann/visitor/CMakeLists.txt | 2 + .../ann/visitor/input_shape_visitor.hpp | 57 +++++++++++++++++++ .../ann/visitor/input_shape_visitor_impl.hpp | 52 +++++++++++++++++ 7 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/mlpack/methods/ann/visitor/input_shape_visitor.hpp create mode 100644 src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 1c65bbb749..512f51fcf9 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -24,6 +24,7 @@ #include "visitor/weight_size_visitor.hpp" #include "visitor/copy_visitor.hpp" #include "visitor/loss_visitor.hpp" +#include "visitor/input_shape_visitor.hpp" #include "init_rules/network_init.hpp" @@ -324,6 +325,14 @@ class FFN //! Modify the matrix of data points (predictors). arma::mat& Predictors() { return predictors; } + /** + * Check wether the input size is consistent with the layer requirements. + * + * @param inputShape shape of the input + * @param functionName function that checks the input size + */ + void CheckInputShape(size_t inputShape, std::string functionName); + /** * Reset the module infomration (weights/parameters). */ diff --git a/src/mlpack/methods/ann/ffn_impl.hpp b/src/mlpack/methods/ann/ffn_impl.hpp index c16de548f4..9335a7bded 100644 --- a/src/mlpack/methods/ann/ffn_impl.hpp +++ b/src/mlpack/methods/ann/ffn_impl.hpp @@ -14,7 +14,7 @@ // In case it hasn't been included yet. #include "ffn.hpp" - +#include #include "visitor/forward_visitor.hpp" #include "visitor/backward_visitor.hpp" #include "visitor/deterministic_set_visitor.hpp" @@ -22,6 +22,7 @@ #include "visitor/gradient_visitor.hpp" #include "visitor/set_input_height_visitor.hpp" #include "visitor/set_input_width_visitor.hpp" +#include "visitor/input_shape_visitor.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { @@ -50,6 +51,33 @@ FFN::~FFN() boost::apply_visitor(deleteVisitor)); } +template +void FFN::CheckInputShape( + size_t inputShape, std::string functionName) +{ + for (size_t l=0; l void FFN::ResetData( @@ -109,6 +137,8 @@ double FFN::Train( OptimizerType& optimizer, CallbackTypes&&... callbacks) { + CheckInputShape(predictors.n_rows, "Train()"); + ResetData(std::move(predictors), std::move(responses)); WarnMessageMaxIterations(optimizer, this->predictors.n_cols); @@ -131,6 +161,8 @@ double FFN::Train( arma::mat responses, CallbackTypes&&... callbacks) { + CheckInputShape(predictors.n_rows, "Train()"); + ResetData(std::move(predictors), std::move(responses)); OptimizerType optimizer; @@ -217,6 +249,8 @@ template::Predict( arma::mat predictors, arma::mat& results) { + CheckInputShape(predictors.n_rows, "Predict()"); + if (parameter.is_empty()) ResetParameters(); @@ -250,6 +284,8 @@ template double FFN::Evaluate( const PredictorsType& predictors, const ResponsesType& responses) { + CheckInputShape(predictors.n_rows, "Evaluate()"); + if (parameter.is_empty()) ResetParameters(); diff --git a/src/mlpack/methods/ann/layer/layer_traits.hpp b/src/mlpack/methods/ann/layer/layer_traits.hpp index b9e2621d89..a6a447f43d 100644 --- a/src/mlpack/methods/ann/layer/layer_traits.hpp +++ b/src/mlpack/methods/ann/layer/layer_traits.hpp @@ -120,6 +120,10 @@ HAS_MEM_FUNC(Bias, HasBiasCheck); // we can use with SFINAE to catch when a type has a MaxIterations() function. HAS_MEM_FUNC(MaxIterations, HasMaxIterations); +// This gives us a HasInShapeCheck type we can use with SFINAE to catch when +// a type has a function named InputShape. +HAS_ANY_METHOD_FORM(InputShape, HasInputShapeCheck); + } // namespace ann } // namespace mlpack diff --git a/src/mlpack/methods/ann/layer/linear.hpp b/src/mlpack/methods/ann/layer/linear.hpp index f2c8015e04..cc31117c53 100644 --- a/src/mlpack/methods/ann/layer/linear.hpp +++ b/src/mlpack/methods/ann/layer/linear.hpp @@ -152,6 +152,12 @@ class Linear return (inSize * outSize) + outSize; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/visitor/CMakeLists.txt b/src/mlpack/methods/ann/visitor/CMakeLists.txt index 43bcf71225..fa207d6092 100644 --- a/src/mlpack/methods/ann/visitor/CMakeLists.txt +++ b/src/mlpack/methods/ann/visitor/CMakeLists.txt @@ -57,6 +57,8 @@ set(SOURCES weight_set_visitor_impl.hpp weight_size_visitor.hpp weight_size_visitor_impl.hpp + input_shape_visitor.hpp + input_shape_visitor_impl.hpp ) # Add directory name to sources. diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp new file mode 100644 index 0000000000..663057673d --- /dev/null +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp @@ -0,0 +1,57 @@ +/** + * @file input_shape_visitor.hpp + * @author Nippun Sharma + * + * This file provides an abstraction for the InputShape() 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_INPUT_SHAPE_VISITOR_HPP +#define MLPACK_METHODS_ANN_VISITOR_INPUT_SHAPE_VISITOR_HPP + +#include +#include + +#include + +namespace mlpack { +namespace ann { + +/** + * InShapeVisitor returns the input shape a Layer expects. + */ +class InShapeVisitor : public boost::static_visitor +{ + public: + //! Return the input shape of layer. + template + size_t operator()(LayerType* layer) const; + + size_t operator()(MoreTypes layer) const; + + private: + //! If the module doesn't implement the InputShape() function return 0. + template + typename std::enable_if< + !HasInputShapeCheck::value, size_t>::type + LayerInputShape(T* layer) const; + + //! If the module implements the InputShape() function returns the input shape. + template + typename std::enable_if< + HasInputShapeCheck::value, size_t>::type + LayerInputShape(T* layer) const; +}; + +} // namespace ann +} // namespace mlpack + +// Include implementation. +#include "input_shape_visitor_impl.hpp" + +#endif \ No newline at end of file diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp new file mode 100644 index 0000000000..6f8c3b123d --- /dev/null +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp @@ -0,0 +1,52 @@ +/** + * @file input_shape_visitor_impl.hpp + * @author Nippun Sharma + * + * Implementation of the InputShape() 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_INPUT_SHAPE_VISITOR_IMPL_HPP +#define MLPACK_METHODS_ANN_VISITOR_INPUT_SHAPE_VISITOR_IMPL_HPP + +// In case it hasn't been included yet. +#include "input_shape_visitor.hpp" + +namespace mlpack { +namespace ann { + +//! InShapeVisitor visitor class. +template +inline std::size_t InShapeVisitor::operator()(LayerType* layer) const +{ + return LayerInputShape(layer); +} + +inline std::size_t InShapeVisitor::operator()(MoreTypes layer) const +{ + return layer.apply_visitor(*this); +} + +template +inline typename std::enable_if< + !HasInputShapeCheck::value, std::size_t>::type +InShapeVisitor::LayerInputShape(T* /* layer */) const +{ + return 0; +} + +template +inline typename std::enable_if< + HasInputShapeCheck::value, std::size_t>::type +InShapeVisitor::LayerInputShape(T* layer) const +{ + return layer->InputShape(); +} + +} // namespace ann +} // namespace mlpack + +#endif \ No newline at end of file From 9e0b93a068b193a70089a0fa12d674245cc29f57 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 26 Nov 2020 23:11:35 +0530 Subject: [PATCH 211/550] removed some stuff --- src/mlpack/methods/ann/ffn_impl.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/ann/ffn_impl.hpp b/src/mlpack/methods/ann/ffn_impl.hpp index 9335a7bded..4ef10c2912 100644 --- a/src/mlpack/methods/ann/ffn_impl.hpp +++ b/src/mlpack/methods/ann/ffn_impl.hpp @@ -14,7 +14,6 @@ // In case it hasn't been included yet. #include "ffn.hpp" -#include #include "visitor/forward_visitor.hpp" #include "visitor/backward_visitor.hpp" #include "visitor/deterministic_set_visitor.hpp" From 5f067334cb26fd1c8ade45b05ead919f5942efd3 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 26 Nov 2020 23:14:24 +0530 Subject: [PATCH 212/550] added empty lines --- src/mlpack/methods/ann/ffn_impl.hpp | 1 + src/mlpack/methods/ann/visitor/input_shape_visitor.hpp | 2 +- src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/ffn_impl.hpp b/src/mlpack/methods/ann/ffn_impl.hpp index 4ef10c2912..8b5ac908c2 100644 --- a/src/mlpack/methods/ann/ffn_impl.hpp +++ b/src/mlpack/methods/ann/ffn_impl.hpp @@ -14,6 +14,7 @@ // In case it hasn't been included yet. #include "ffn.hpp" + #include "visitor/forward_visitor.hpp" #include "visitor/backward_visitor.hpp" #include "visitor/deterministic_set_visitor.hpp" diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp index 663057673d..bb1b4b392a 100644 --- a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp @@ -54,4 +54,4 @@ class InShapeVisitor : public boost::static_visitor // Include implementation. #include "input_shape_visitor_impl.hpp" -#endif \ No newline at end of file +#endif diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp index 6f8c3b123d..2b87081927 100644 --- a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp @@ -49,4 +49,4 @@ InShapeVisitor::LayerInputShape(T* layer) const } // namespace ann } // namespace mlpack -#endif \ No newline at end of file +#endif From 70749bd0bb8f241810acdc1bcf9738906a5e258d Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 26 Nov 2020 23:49:34 +0530 Subject: [PATCH 213/550] changed comments --- src/mlpack/methods/ann/ffn.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 512f51fcf9..93b3136a0b 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -326,7 +326,7 @@ class FFN arma::mat& Predictors() { return predictors; } /** - * Check wether the input size is consistent with the layer requirements. + * Check wether the input shape is consistent with the layer requirements. * * @param inputShape shape of the input * @param functionName function that checks the input size From b63f5ad0af68105a12915da0717233359a8c0d6a Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 27 Nov 2020 13:03:00 +0530 Subject: [PATCH 214/550] added InputShape() to conv --- src/mlpack/methods/ann/layer/convolution.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index bcebf756cf..6eda5989a5 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -259,6 +259,12 @@ class Convolution return (outSize * inSize * kernelWidth * kernelHeight) + outSize; } + //! Get the shape of the input. + size_t InputShape() const + { + return inputHeight*inputWidth*inSize; + } + /** * Serialize the layer. */ From 73299a6d073ea9526c2ffa66925736181994501c Mon Sep 17 00:00:00 2001 From: shawnbrar <59639827+shawnbrar@users.noreply.github.com> Date: Fri, 27 Nov 2020 08:33:58 +0100 Subject: [PATCH 215/550] Added Copyright statement Pull Request 2624 --- COPYRIGHT.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 8e4088dceb..851f65cc0d 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -136,6 +136,7 @@ Copyright: Copyright 2020, Aakash Kaushik Copyright 2020, Anush Kini Copyright 2020, Nippun Sharma + Copyright 2020, Sudhakar Brar License: BSD-3-clause All rights reserved. From ecc63a81aac1b9e14209a2ac84aa6178ec50275d Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 28 Nov 2020 17:52:25 +0530 Subject: [PATCH 216/550] add InputShape() to lstm and fast lstm --- src/mlpack/methods/ann/layer/fast_lstm.hpp | 5 +++++ src/mlpack/methods/ann/layer/lstm.hpp | 5 +++++ src/mlpack/methods/ann/rnn.hpp | 1 + src/mlpack/methods/ann/rnn_impl.hpp | 1 + 4 files changed, 12 insertions(+) diff --git a/src/mlpack/methods/ann/layer/fast_lstm.hpp b/src/mlpack/methods/ann/layer/fast_lstm.hpp index 121c97e176..67859bd0d4 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm.hpp @@ -170,6 +170,11 @@ class FastLSTM return 4 * outSize * inSize + 4 * outSize + 4 * outSize * outSize; } + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/lstm.hpp b/src/mlpack/methods/ann/layer/lstm.hpp index 1941778ce9..685d7b7994 100644 --- a/src/mlpack/methods/ann/layer/lstm.hpp +++ b/src/mlpack/methods/ann/layer/lstm.hpp @@ -171,6 +171,11 @@ class LSTM //! Get the number of output units. size_t OutSize() const { return outSize; } + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/rnn.hpp b/src/mlpack/methods/ann/rnn.hpp index e9e6815de4..34a613daaf 100644 --- a/src/mlpack/methods/ann/rnn.hpp +++ b/src/mlpack/methods/ann/rnn.hpp @@ -18,6 +18,7 @@ #include "visitor/delta_visitor.hpp" #include "visitor/output_parameter_visitor.hpp" #include "visitor/reset_visitor.hpp" +#include "visitor/input_shape_visitor.hpp" #include "init_rules/network_init.hpp" diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index b81bc397b2..586e4e95dc 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -24,6 +24,7 @@ #include "visitor/gradient_set_visitor.hpp" #include "visitor/gradient_visitor.hpp" #include "visitor/weight_set_visitor.hpp" +#include "visitor/input_shape_visitor.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { From 2467580ef6c3f8efd23a54aaf144e26735da6605 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 28 Nov 2020 18:30:21 +0530 Subject: [PATCH 217/550] added CheckInputShape() to RNN and some comments --- src/mlpack/methods/ann/layer/fast_lstm.hpp | 1 + src/mlpack/methods/ann/layer/lstm.hpp | 1 + src/mlpack/methods/ann/rnn.hpp | 8 ++++++ src/mlpack/methods/ann/rnn_impl.hpp | 33 ++++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/mlpack/methods/ann/layer/fast_lstm.hpp b/src/mlpack/methods/ann/layer/fast_lstm.hpp index 67859bd0d4..bcf1a1c201 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm.hpp @@ -170,6 +170,7 @@ class FastLSTM return 4 * outSize * inSize + 4 * outSize + 4 * outSize * outSize; } + //! Get the shape of the input. size_t InputShape() const { return inSize; diff --git a/src/mlpack/methods/ann/layer/lstm.hpp b/src/mlpack/methods/ann/layer/lstm.hpp index 685d7b7994..50a1d466af 100644 --- a/src/mlpack/methods/ann/layer/lstm.hpp +++ b/src/mlpack/methods/ann/layer/lstm.hpp @@ -171,6 +171,7 @@ class LSTM //! Get the number of output units. size_t OutSize() const { return outSize; } + //! Get the shape of the input. size_t InputShape() const { return inSize; diff --git a/src/mlpack/methods/ann/rnn.hpp b/src/mlpack/methods/ann/rnn.hpp index 34a613daaf..e0f00a0e87 100644 --- a/src/mlpack/methods/ann/rnn.hpp +++ b/src/mlpack/methods/ann/rnn.hpp @@ -302,6 +302,14 @@ class RNN //! Modify the matrix of data points (predictors). arma::cube& Predictors() { return predictors; } + /** + * Check wether the input shape is consistent with the layer requirements. + * + * @param inputShape shape of the input + * @param functionName function that checks the input size + */ + void CheckInputShape(size_t inputShape, std::string functionName); + /** * Reset the state of the network. This ensures that all internally-held * gradients are set to 0, all memory cells are reset, and the parameters diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index 586e4e95dc..d6fd26d501 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -60,6 +60,33 @@ RNN::~RNN() } } +template +void RNN::CheckInputShape( + size_t inputShape, std::string functionName) +{ + for (size_t l=0; l template @@ -104,6 +131,8 @@ double RNN::Train( OptimizerType& optimizer, CallbackTypes&&... callbacks) { + CheckInputShape(predictors.n_rows, "Train()"); + numFunctions = responses.n_cols; this->predictors = std::move(predictors); @@ -148,6 +177,8 @@ double RNN::Train( arma::cube responses, CallbackTypes&&... callbacks) { + CheckInputShape(predictors.n_rows, "Train()"); + numFunctions = responses.n_cols; this->predictors = std::move(predictors); @@ -180,6 +211,8 @@ template::Predict( arma::cube predictors, arma::cube& results, const size_t batchSize) { + CheckInputShape(predictors.n_rows, "Train()"); + ResetCells(); if (parameter.is_empty()) From 1ae1bae7acbc0e50f0bea559b55dd9296c03a440 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 28 Nov 2020 13:44:55 -0500 Subject: [PATCH 218/550] Remove boost unit test framework entirely. --- .ci/windows-steps.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 1356125809..ee5e9ba578 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -10,7 +10,6 @@ steps: - powershell: | nuget install OpenBLAS -o $(Agent.ToolsDirectory) nuget install boost -o $(Agent.ToolsDirectory) -Version 1.60.0 - nuget install boost_unit_test_framework-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 nuget install boost_random-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 nuget install boost_math_c99-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 nuget install OpenBLAS -o $(Agent.ToolsDirectory) @@ -19,7 +18,6 @@ steps: mkdir -p $(Agent.ToolsDirectory)/boost_libs cp $(Agent.ToolsDirectory)/boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs cp $(Agent.ToolsDirectory)/boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs - cp $(Agent.ToolsDirectory)/boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs displayName: 'Fetch build dependencies' # Configure armadillo @@ -140,7 +138,6 @@ steps: cp build\Release\*.dll dist\win-installer\mlpack-win-installer\Sources\ cp build\Release\*.exe dist\win-installer\mlpack-win-installer\Sources\ cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\Sources\ - cp $(Agent.ToolsDirectory)\boost_libs\boost_unit_test_framework-vc*.dll dist\win-installer\mlpack-win-installer\Sources\ cp build\include\mlpack dist\win-installer\mlpack-win-installer\Sources -recurse cp doc\examples dist\win-installer\mlpack-win-installer\Sources -recurse cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\Sources\examples\sample-ml-app\sample-ml-app\data\ From dd0d16f7304bacea463d3c41a2c466f6e97da2a7 Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Sat, 28 Nov 2020 20:39:18 +0100 Subject: [PATCH 219/550] Changes by Zoq --- src/mlpack/tests/cv_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index 51b1e39071..9294790661 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -192,12 +192,12 @@ TEST_CASE("R2ScoreTest", "[CVTest]") } /** - * Test the Adjusted R squared metric + * Test the Adjusted R squared metric. */ TEST_CASE("AdjR2ScoreTest", "[CVTest]") { // Making two variables that define the linear function is - // f(x1, x2) = x1 + x2 + // f(x1, x2) = x1 + x2. arma::mat X; X << 1 << 2 << 3 << 4 << 5 << 6 << arma::endr << 2 << 3 << 4 << 5 << 6 << 7 << arma::endr; @@ -206,7 +206,7 @@ TEST_CASE("AdjR2ScoreTest", "[CVTest]") LinearRegression lr(X, Y); - //Theoretically Adjusted R squared should be equal 1 + // Theoretically Adjusted R squared should be equal 1 double expAdjR2 = 1; REQUIRE(std::abs(R2Score::Evaluate(lr, X, Y) - expAdjR2) <= 1e-7); From c95a1f5469b1110066a1fd9e849bb7a6ca4bdaaf Mon Sep 17 00:00:00 2001 From: Sudhakar Brar Date: Sat, 28 Nov 2020 20:40:37 +0100 Subject: [PATCH 220/550] Changes by Zoq 2 --- src/mlpack/core/cv/metrics/r2_score_impl.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mlpack/core/cv/metrics/r2_score_impl.hpp b/src/mlpack/core/cv/metrics/r2_score_impl.hpp index 65fadc1a95..2859a17f9d 100644 --- a/src/mlpack/core/cv/metrics/r2_score_impl.hpp +++ b/src/mlpack/core/cv/metrics/r2_score_impl.hpp @@ -43,11 +43,12 @@ double R2Score::Evaluate(MLAlgorithm& model, // Calculate the denominator i.e.total sum of squares. double totalSumSquared = arma::accu(arma::square(responses - meanResponses)); + // Handling undefined R2 Score when both denominator and numerator is 0.0. + if (residualSumSquared == 0.0) + return totalSumSquared ? 1.0 : DBL_MIN; + if (AdjustedR2) { - // Handling undefined R2 Score when both denominator and numerator is 0.0. - if (residualSumSquared == 0.0) - return totalSumSquared ? 1.0 : DBL_MIN; // Returning adjusted R-squared. double rsq = 1 - (residualSumSquared / totalSumSquared); return (1 - ((1 - rsq) * ((data.n_cols - 1) / From ef5e56e63cc52b00679f77936a7a0d35a809d545 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 29 Nov 2020 12:32:03 +0530 Subject: [PATCH 221/550] added InputShape() to recurrent class --- src/mlpack/methods/ann/layer/recurrent.hpp | 4 +++ .../methods/ann/layer/recurrent_impl.hpp | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/mlpack/methods/ann/layer/recurrent.hpp b/src/mlpack/methods/ann/layer/recurrent.hpp index 0466b265b0..c6e396ddad 100644 --- a/src/mlpack/methods/ann/layer/recurrent.hpp +++ b/src/mlpack/methods/ann/layer/recurrent.hpp @@ -19,6 +19,7 @@ #include "../visitor/delta_visitor.hpp" #include "../visitor/copy_visitor.hpp" #include "../visitor/output_parameter_visitor.hpp" +#include "../visitor/input_shape_visitor.hpp" #include "layer_types.hpp" #include "add_merge.hpp" @@ -139,6 +140,9 @@ class Recurrent //! Get the number of steps to backpropagate through time. size_t const& Rho() const { return rho; } + //! Get the shape of the input. + size_t InputShape() const; + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 23a1dc4625..0c1ace86c1 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -20,6 +20,7 @@ #include "../visitor/backward_visitor.hpp" #include "../visitor/gradient_visitor.hpp" #include "../visitor/gradient_zero_visitor.hpp" +#include "../visitor/input_shape_visitor.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { @@ -126,6 +127,36 @@ Recurrent::Recurrent( this->network.push_back(recurrentModule); } +template +size_t Recurrent::InputShape() const +{ + size_t inputShapeStartModule = boost::apply_visitor(InShapeVisitor(), startModule); + size_t inputShapeInputModule = boost::apply_visitor(InShapeVisitor(), inputModule); + size_t inputShapeFeedbackModule = boost::apply_visitor(InShapeVisitor(), feedbackModule); + size_t inputShapeTransferModule = boost::apply_visitor(InShapeVisitor(), transferModule); + + if (inputShapeStartModule != 0) + return inputShapeStartModule; + else + { + if (inputShapeInputModule != 0) + return inputShapeInputModule; + else + { + if (inputShapeFeedbackModule != 0) + return inputShapeFeedbackModule; + else + { + if (inputShapeTransferModule != 0) + return inputShapeTransferModule; + else + return 0; + } + } + } +} + template template From 01b1480f22d08e0d5d0523ae4b91a1105b456ca1 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 29 Nov 2020 12:49:22 +0530 Subject: [PATCH 222/550] changed functionName from Train() to Predict() --- src/mlpack/methods/ann/rnn_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index d6fd26d501..ff58a81ff1 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -211,7 +211,7 @@ template::Predict( arma::cube predictors, arma::cube& results, const size_t batchSize) { - CheckInputShape(predictors.n_rows, "Train()"); + CheckInputShape(predictors.n_rows, "Predict()"); ResetCells(); From 0ea76f39348084e7cb7bd1a4814ef7aea5ac74c9 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Sun, 29 Nov 2020 13:22:24 +0530 Subject: [PATCH 223/550] changed from LinearLayer to Recurrent --- src/mlpack/methods/ann/layer/recurrent.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/recurrent.hpp b/src/mlpack/methods/ann/layer/recurrent.hpp index 0466b265b0..88f6d97ab4 100644 --- a/src/mlpack/methods/ann/layer/recurrent.hpp +++ b/src/mlpack/methods/ann/layer/recurrent.hpp @@ -2,8 +2,7 @@ * @file methods/ann/layer/recurrent.hpp * @author Marcus Edel * - * Definition of the LinearLayer class also known as fully-connected layer or - * affine transformation. + * Definition of the Recurrent 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 From 56271d92f4a261dffc6bf39d457ff8f375e8b09b Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Sun, 29 Nov 2020 13:23:30 +0530 Subject: [PATCH 224/550] changed comment from LinearLayer to Recurrent in impl --- src/mlpack/methods/ann/layer/recurrent_impl.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 23a1dc4625..43d807dd1a 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -2,8 +2,7 @@ * @file methods/ann/layer/recurrent_impl.hpp * @author Marcus Edel * - * Implementation of the LinearLayer class also known as fully-connected layer - * or affine transformation. + * Implementation of the Recurrent 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 From 9dc9aa01f209d3b6e44df0a9cecd185f8709dc02 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 29 Nov 2020 14:13:25 +0530 Subject: [PATCH 225/550] added InputShape() to LinearNoBias, NoisyLinear --- src/mlpack/methods/ann/layer/linear_no_bias.hpp | 6 ++++++ src/mlpack/methods/ann/layer/noisylinear.hpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/mlpack/methods/ann/layer/linear_no_bias.hpp b/src/mlpack/methods/ann/layer/linear_no_bias.hpp index a06e97e735..7182e84238 100644 --- a/src/mlpack/methods/ann/layer/linear_no_bias.hpp +++ b/src/mlpack/methods/ann/layer/linear_no_bias.hpp @@ -123,6 +123,12 @@ class LinearNoBias //! Modify the gradient. OutputDataType& Gradient() { return gradient; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/noisylinear.hpp b/src/mlpack/methods/ann/layer/noisylinear.hpp index 34ca70193b..af10496d61 100644 --- a/src/mlpack/methods/ann/layer/noisylinear.hpp +++ b/src/mlpack/methods/ann/layer/noisylinear.hpp @@ -130,6 +130,12 @@ class NoisyLinear //! Modify the gradient. OutputDataType& Gradient() { return gradient; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + //! Modify the bias weights of the layer. arma::mat& Bias() { return bias; } From 36abf95778fe4538a489b6d9ccf940b4c57c1ede Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 29 Nov 2020 12:14:37 -0500 Subject: [PATCH 226/550] Remove debugging output. --- .ci/windows-steps.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index ee5e9ba578..e2a9ed38e0 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -159,10 +159,6 @@ steps: # Build the MSI installer. cd dist\win-installer\mlpack-win-installer - dir - cd Sources - dir - cd .. & 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' ` -t:rebuild ` -p:Configuration=Release ` From 8c49ba0b3a80a15eb38a919944080450d6905b02 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 30 Nov 2020 14:22:43 +0530 Subject: [PATCH 227/550] FastLSTM and RNN Copy and Move constructor added --- src/mlpack/methods/ann/layer/fast_lstm.hpp | 12 ++++ .../methods/ann/layer/fast_lstm_impl.hpp | 54 +++++++++++++++++ src/mlpack/methods/ann/rnn.hpp | 12 ++++ src/mlpack/methods/ann/rnn_impl.hpp | 43 ++++++++++++++ src/mlpack/tests/ann_layer_test.cpp | 59 +++++++++++++++++++ 5 files changed, 180 insertions(+) diff --git a/src/mlpack/methods/ann/layer/fast_lstm.hpp b/src/mlpack/methods/ann/layer/fast_lstm.hpp index 121c97e176..212fc8f503 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm.hpp @@ -73,6 +73,18 @@ class FastLSTM //! Create the Fast LSTM object. FastLSTM(); + //! Copy Constructor + FastLSTM(const FastLSTM& layer); + + //! Move Constructor + FastLSTM(FastLSTM&& layer); + + //! Copy assignment operator + FastLSTM& operator=(const FastLSTM& layer); + + //! Move assignment operator + FastLSTM& operator=(FastLSTM&& layer); + /** * Create the Fast LSTM layer object using the specified parameters. * diff --git a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp index 5f5502cf9a..7ffe95833b 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp @@ -45,6 +45,60 @@ FastLSTM::FastLSTM( weights.set_size(WeightSize(), 1); } +template +FastLSTM::FastLSTM(const FastLSTM& layer) : + inSize(layer.inSize), + outSize(layer.outSize), + rho(layer.rho), + weights(layer.weights) +{ + // Nothing to do here. + std::cout << "Trying to copy fast LSTM layer" << std::endl; +} + +template +FastLSTM::FastLSTM(FastLSTM&& layer) : + inSize(std::move(layer.inSize)), + outSize(std::move(layer.outSize)), + rho(std::move(layer.rho)), + weights(std::move(layer.weights)) +{ + // Nothing to do here. + std::cout << "Trying to move fast LSTM layer" << std::endl; +} + +template +FastLSTM& +FastLSTM::operator=(const FastLSTM& layer) +{ + std::cout << "Trying to copy fast LSTM layer" << std::endl; + if (this != &layer) + { + inSize = layer.inSize; + outSize = layer.outSize; + rho = layer.rho; + weights = layer.weights; + } + std::cout << "Copied layer and returned" << std::endl; + return *this; +} + +template +FastLSTM& +FastLSTM::operator=(FastLSTM&& layer) +{ + std::cout << "Trying to move fast LSTM layer" << std::endl; + if (this != &layer) + { + inSize = std::move(layer.inSize); + outSize = std::move(layer.outSize); + rho = std::move(layer.rho); + weights = std::move(layer.weights); + } + std::cout << "Moved and returned" << std::endl; + return *this; +} + template void FastLSTM::Reset() { diff --git a/src/mlpack/methods/ann/rnn.hpp b/src/mlpack/methods/ann/rnn.hpp index e9e6815de4..0e653ea0f9 100644 --- a/src/mlpack/methods/ann/rnn.hpp +++ b/src/mlpack/methods/ann/rnn.hpp @@ -70,6 +70,15 @@ class RNN OutputLayerType outputLayer = OutputLayerType(), InitializationRuleType initializeRule = InitializationRuleType()); + //! Copy constructor. + RNN(const RNN&); + + //! Move constructor. + RNN(RNN&&); + + //! Copy/move assignment operator. + RNN& operator = (RNN); + //! Destructor to release allocated memory. ~RNN(); @@ -412,6 +421,9 @@ class RNN //! Locally-stored weight size visitor. WeightSizeVisitor weightSizeVisitor; + //! Locally-stored copy visitor + CopyVisitor copyVisitor; + //! Locally-stored reset visitor. ResetVisitor resetVisitor; diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index b81bc397b2..66bef0855b 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -49,6 +49,49 @@ RNN::RNN( /* Nothing to do here */ } +template +RNN::RNN( + const RNN& network) : + rho(network.rho), + initializeRule(network.initializeRule), + inputSize(network.inputSize), + outputLayer(network.outputLayer), + outputSize(network.outputSize), + targetSize(network.targetSize), + reset(network.reset), + single(network.single), + numFunctions(network.numFunctions), + deterministic(network.deterministic), + parameter(network.parameter) +{ + for (size_t i = 0; i < network.network.size(); ++i) + { + this->network.push_back(boost::apply_visitor(copyVisitor, + network.network[i])); + boost::apply_visitor(resetVisitor, this->network[i]); + } +} + +template +RNN::RNN( + RNN&& network) : + rho(std::move(network.rho)), + initializeRule(std::move(network.initializeRule)), + inputSize(std::move(network.inputSize)), + outputLayer(std::move(network.outputLayer)), + outputSize(std::move(network.outputSize)), + targetSize(std::move(network.targetSize)), + reset(std::move(network.reset)), + single(std::move(network.single)), + numFunctions(std::move(network.numFunctions)), + deterministic(std::move(network.deterministic)), + parameter(std::move(network.parameter)) +{ + this->network = std::move(network.network); +} + template RNN::~RNN() diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 63da44b2ee..c3f6efc70a 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -1183,6 +1183,65 @@ TEST_CASE("FastLSTMLayerParametersTest", "[ANNLayerTest]") REQUIRE(layer1.Rho() == layer2.Rho()); } +/** + * Check whether copying and moving network with FastLSTM is working or not. + */ + TEST_CASE("CheckCopyFastLSTMTest", "[ANNLayerTest]") + { + std::cout << "Starting copy test" << std::endl; + arma::cube input = arma::randu(1, 1, 5); + arma::cube target = arma::ones(1, 1, 5); + const size_t rho = 5; + + RNN > *model1 = new RNN >(rho); + model1->Predictors() = input; + model1->Responses() = target; + model1->Add >(1, 10); + model1->Add >(10, 3, rho); + model1->Add >(); + + ens::StandardSGD opt(0.1, 1, 5, -100, false); + std::cout << "Before Training Model" << std::endl; + model1->Train(input, target, opt); + std::cout << "After Training" << std::endl; + + arma::cube predictions1; + model1->Predict(input, predictions1); + + std::cout << "After model1 predict" << std::endl; + + RNN<> model2(rho); + model2 = *model1; + delete model1; + + arma::cube predictions2; + std::cout << "After model1 delete" << std::endl; + model2.Predict(input, predictions2); + std::cout << "After model2 predictions" << std::endl; + CheckMatrices(predictions1, predictions2); + // FastLSTM<> *layer1 = new FastLSTM<>(1,2,3); + // FastLSTM<> layer2(); + // + // // Provide input of all ones. + // arma::mat input = arma::ones(3, 1); + // + // // Declaring two ouput matrices for each layer. + // arma::mat output1; + // arma::mat output2; + // + // // Forward pass through layer1. + // layer1->Forward(input, output1); + // layer2 = *layer1; + // + // // Freeing up layer1 to prevent memory leaks. + // delete layer1; + // + // // Forward pass through layer2. + // layer2.Forward(input, output2); + // + // CheckMatrices(output1, output2); + } + /** * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell * state. Besides output, the overloaded function provides read access to cell From 91508c3e803597bb90c03aefacf7c34bd151eee6 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 30 Nov 2020 19:03:50 +0530 Subject: [PATCH 228/550] Minor fixes --- .../methods/ann/layer/fast_lstm_impl.hpp | 6 - src/mlpack/tests/ann_layer_test.cpp | 146 ++++++++++++------ 2 files changed, 97 insertions(+), 55 deletions(-) diff --git a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp index 7ffe95833b..2f90963674 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp @@ -53,7 +53,6 @@ FastLSTM::FastLSTM(const FastLSTM& layer) : weights(layer.weights) { // Nothing to do here. - std::cout << "Trying to copy fast LSTM layer" << std::endl; } template @@ -64,14 +63,12 @@ FastLSTM::FastLSTM(FastLSTM&& layer) : weights(std::move(layer.weights)) { // Nothing to do here. - std::cout << "Trying to move fast LSTM layer" << std::endl; } template FastLSTM& FastLSTM::operator=(const FastLSTM& layer) { - std::cout << "Trying to copy fast LSTM layer" << std::endl; if (this != &layer) { inSize = layer.inSize; @@ -79,7 +76,6 @@ FastLSTM::operator=(const FastLSTM& layer) rho = layer.rho; weights = layer.weights; } - std::cout << "Copied layer and returned" << std::endl; return *this; } @@ -87,7 +83,6 @@ template FastLSTM& FastLSTM::operator=(FastLSTM&& layer) { - std::cout << "Trying to move fast LSTM layer" << std::endl; if (this != &layer) { inSize = std::move(layer.inSize); @@ -95,7 +90,6 @@ FastLSTM::operator=(FastLSTM&& layer) rho = std::move(layer.rho); weights = std::move(layer.weights); } - std::cout << "Moved and returned" << std::endl; return *this; } diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index c3f6efc70a..4b8d8d08b0 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -31,6 +31,51 @@ using namespace mlpack; using namespace mlpack::ann; +// network1 should be allocated with `new`, and trained on some data. +template +void CheckCopyFunction(ModelType* network1, + MatType& trainData, + MatType& trainLabels, + const size_t maxEpochs) +{ + ens::RMSProp opt(0.01, 32, 0.88, 1e-8, maxEpochs * trainData.n_cols, -1); + network1->Train(trainData, trainLabels, opt); + + arma::mat predictions1; + network1->Predict(trainData, predictions1); + FFN<> network2; + network2 = *network1; + delete network1; + + // Deallocating all of network1's memory, so that + // if network2 is trying to use any of that memory. + arma::mat predictions2; + network2.Predict(trainData, predictions2); + CheckMatrices(predictions1, predictions2); +} + +// network1 should be allocated with `new`, and trained on some data. +template +void CheckMoveFunction(ModelType* network1, + MatType& trainData, + MatType& trainLabels, + const size_t maxEpochs) +{ + ens::RMSProp opt(0.01, 32, 0.88, 1e-8, maxEpochs * trainData.n_cols, -1); + network1->Train(trainData, trainLabels, opt); + + arma::mat predictions1; + network1->Predict(trainData, predictions1); + FFN<> network2(std::move(*network1)); + delete network1; + + // Deallocating all of network1's memory, so that + // if network2 is trying to use any of that memory. + arma::mat predictions2; + network2.Predict(trainData, predictions2); + CheckMatrices(predictions1, predictions2); +} + /** * Simple add module test. */ @@ -1186,61 +1231,64 @@ TEST_CASE("FastLSTMLayerParametersTest", "[ANNLayerTest]") /** * Check whether copying and moving network with FastLSTM is working or not. */ - TEST_CASE("CheckCopyFastLSTMTest", "[ANNLayerTest]") - { - std::cout << "Starting copy test" << std::endl; - arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); - const size_t rho = 5; +TEST_CASE("CheckCopyFastLSTMTest", "[ANNLayerTest]") +{ + arma::cube input = arma::randu(1, 1, 5); + arma::cube target = arma::ones(1, 1, 5); + const size_t rho = 5; - RNN > *model1 = new RNN >(rho); - model1->Predictors() = input; - model1->Responses() = target; - model1->Add >(1, 10); - model1->Add >(10, 3, rho); - model1->Add >(); + RNN > *model1 = + new RNN >(rho); + model1->Predictors() = input; + model1->Responses() = target; + model1->Add >(1, 10); + model1->Add >(10, 3, rho); + model1->Add >(); - ens::StandardSGD opt(0.1, 1, 5, -100, false); - std::cout << "Before Training Model" << std::endl; - model1->Train(input, target, opt); - std::cout << "After Training" << std::endl; + ens::StandardSGD opt(0.1, 1, 5, -100, false); + model1->Train(input, target, opt); - arma::cube predictions1; - model1->Predict(input, predictions1); + arma::cube predictions1; + model1->Predict(input, predictions1); - std::cout << "After model1 predict" << std::endl; + RNN<> model2() = *model1; + delete model1; - RNN<> model2(rho); - model2 = *model1; - delete model1; + arma::cube predictions2; + model2.Predict(input, predictions2); + CheckMatrices(predictions1, predictions2); +} - arma::cube predictions2; - std::cout << "After model1 delete" << std::endl; - model2.Predict(input, predictions2); - std::cout << "After model2 predictions" << std::endl; - CheckMatrices(predictions1, predictions2); - // FastLSTM<> *layer1 = new FastLSTM<>(1,2,3); - // FastLSTM<> layer2(); - // - // // Provide input of all ones. - // arma::mat input = arma::ones(3, 1); - // - // // Declaring two ouput matrices for each layer. - // arma::mat output1; - // arma::mat output2; - // - // // Forward pass through layer1. - // layer1->Forward(input, output1); - // layer2 = *layer1; - // - // // Freeing up layer1 to prevent memory leaks. - // delete layer1; - // - // // Forward pass through layer2. - // layer2.Forward(input, output2); - // - // CheckMatrices(output1, output2); - } + /** + * Check whether copying and moving network with FastLSTM is working or not. + */ +TEST_CASE("CheckMoveFastLSTMTest", "[ANNLayerTest]") +{ + arma::cube input = arma::randu(1, 1, 5); + arma::cube target = arma::ones(1, 1, 5); + const size_t rho = 5; + + RNN > *model1 = + new RNN >(rho); + model1->Predictors() = input; + model1->Responses() = target; + model1->Add >(1, 10); + model1->Add >(10, 3, rho); + model1->Add >(); + + ens::StandardSGD opt(0.1, 1, 5, -100, false); + model1->Train(input, target, opt); + + arma::cube predictions1; + model1->Predict(input, predictions1); + + RNN<> model2(std::move(*model1)); + delete model1; + + arma::cube predictions2; + model2.Predict(input, predictions2); + CheckMatrices(predictions1, predictions2); +} /** * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell From b3f296d91524f050912e352f79e88c8aca0ab022 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 30 Nov 2020 19:06:01 +0530 Subject: [PATCH 229/550] Removed copy and move functions --- src/mlpack/tests/ann_layer_test.cpp | 45 ----------------------------- 1 file changed, 45 deletions(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 4b8d8d08b0..ea5dba8c98 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -31,51 +31,6 @@ using namespace mlpack; using namespace mlpack::ann; -// network1 should be allocated with `new`, and trained on some data. -template -void CheckCopyFunction(ModelType* network1, - MatType& trainData, - MatType& trainLabels, - const size_t maxEpochs) -{ - ens::RMSProp opt(0.01, 32, 0.88, 1e-8, maxEpochs * trainData.n_cols, -1); - network1->Train(trainData, trainLabels, opt); - - arma::mat predictions1; - network1->Predict(trainData, predictions1); - FFN<> network2; - network2 = *network1; - delete network1; - - // Deallocating all of network1's memory, so that - // if network2 is trying to use any of that memory. - arma::mat predictions2; - network2.Predict(trainData, predictions2); - CheckMatrices(predictions1, predictions2); -} - -// network1 should be allocated with `new`, and trained on some data. -template -void CheckMoveFunction(ModelType* network1, - MatType& trainData, - MatType& trainLabels, - const size_t maxEpochs) -{ - ens::RMSProp opt(0.01, 32, 0.88, 1e-8, maxEpochs * trainData.n_cols, -1); - network1->Train(trainData, trainLabels, opt); - - arma::mat predictions1; - network1->Predict(trainData, predictions1); - FFN<> network2(std::move(*network1)); - delete network1; - - // Deallocating all of network1's memory, so that - // if network2 is trying to use any of that memory. - arma::mat predictions2; - network2.Predict(trainData, predictions2); - CheckMatrices(predictions1, predictions2); -} - /** * Simple add module test. */ From 83b37c4070c3292af5b65f7a255d3224d6ab8cf1 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 30 Nov 2020 23:49:52 +0530 Subject: [PATCH 230/550] Review comments fix and code refactoring --- src/mlpack/tests/ann_layer_test.cpp | 104 ++++++++++++++++------------ 1 file changed, 60 insertions(+), 44 deletions(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index ea5dba8c98..9b9f1f39c8 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -31,6 +31,52 @@ using namespace mlpack; using namespace mlpack::ann; +// network1 should be allocated with `new`, and trained on some data. +template +void CheckRNNCopyFunction(ModelType* network1, + MatType& trainData, + MatType& trainLabels, + const size_t maxEpochs) +{ + arma::cube predictions1; + arma::cube predictions2; + ens::StandardSGD opt(0.1, 1, 5, -100, false); + + network1->Train(trainData, trainLabels, opt); + network1->Predict(trainData, predictions1); + + RNN<> network2 = *network1; + delete network1; + + // Deallocating all of network1's memory, so that + // if network2 is trying to use any of that memory. + network2.Predict(trainData, predictions2); + CheckMatrices(predictions1, predictions2); +} + +// network1 should be allocated with `new`, and trained on some data. +template +void CheckRNNMoveFunction(ModelType* network1, + MatType& trainData, + MatType& trainLabels, + const size_t maxEpochs) +{ + arma::cube predictions1; + arma::cube predictions2; + ens::StandardSGD opt(0.1, 1, 5, -100, false); + + network1->Train(trainData, trainLabels, opt); + network1->Predict(trainData, predictions1); + + RNN<> network2(std::move(*network1)); + delete network1; + + // Deallocating all of network1's memory, so that + // if network2 is trying to use any of that memory. + network2.Predict(trainData, predictions2); + CheckMatrices(predictions1, predictions2); +} + /** * Simple add module test. */ @@ -1186,63 +1232,33 @@ TEST_CASE("FastLSTMLayerParametersTest", "[ANNLayerTest]") /** * Check whether copying and moving network with FastLSTM is working or not. */ -TEST_CASE("CheckCopyFastLSTMTest", "[ANNLayerTest]") -{ - arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); - const size_t rho = 5; - - RNN > *model1 = - new RNN >(rho); - model1->Predictors() = input; - model1->Responses() = target; - model1->Add >(1, 10); - model1->Add >(10, 3, rho); - model1->Add >(); - - ens::StandardSGD opt(0.1, 1, 5, -100, false); - model1->Train(input, target, opt); - - arma::cube predictions1; - model1->Predict(input, predictions1); - - RNN<> model2() = *model1; - delete model1; - - arma::cube predictions2; - model2.Predict(input, predictions2); - CheckMatrices(predictions1, predictions2); -} - - /** - * Check whether copying and moving network with FastLSTM is working or not. - */ -TEST_CASE("CheckMoveFastLSTMTest", "[ANNLayerTest]") +TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]") { arma::cube input = arma::randu(1, 1, 5); arma::cube target = arma::ones(1, 1, 5); const size_t rho = 5; RNN > *model1 = - new RNN >(rho); + new RNN >(rho); model1->Predictors() = input; model1->Responses() = target; model1->Add >(1, 10); model1->Add >(10, 3, rho); model1->Add >(); - ens::StandardSGD opt(0.1, 1, 5, -100, false); - model1->Train(input, target, opt); + RNN > *model2 = + new RNN >(rho); + model2->Predictors() = input; + model2->Responses() = target; + model2->Add >(1, 10); + model2->Add >(10, 3, rho); + model2->Add >(); - arma::cube predictions1; - model1->Predict(input, predictions1); - - RNN<> model2(std::move(*model1)); - delete model1; - - arma::cube predictions2; - model2.Predict(input, predictions2); - CheckMatrices(predictions1, predictions2); + // Check whether copy constructor is working or not. + CheckRNNCopyFunction<>(model1, input, target, 1); + + // Check whether move constructor is working or not. + CheckRNNMoveFunction<>(model2, input, target, 1); } /** From a44167f289a51286f8f67a70844c9f583e4d08a8 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 1 Dec 2020 11:19:01 +0530 Subject: [PATCH 231/550] Update src/mlpack/methods/ann/ffn.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/ffn.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 93b3136a0b..7befd23bda 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -326,7 +326,7 @@ class FFN arma::mat& Predictors() { return predictors; } /** - * Check wether the input shape is consistent with the layer requirements. + * Check whether the input shape is consistent with the layer requirements. * * @param inputShape shape of the input * @param functionName function that checks the input size From 45845f804c1153efa8b64753caf39864f85318cc Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 1 Dec 2020 11:19:14 +0530 Subject: [PATCH 232/550] Update src/mlpack/methods/ann/ffn.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/ffn.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 7befd23bda..6cbb81d064 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -328,8 +328,8 @@ class FFN /** * Check whether the input shape is consistent with the layer requirements. * - * @param inputShape shape of the input - * @param functionName function that checks the input size + * @param inputShape Dhape of the input + * @param functionName Function that checks the input size */ void CheckInputShape(size_t inputShape, std::string functionName); From e773dff64e2e00b51ebbda2f1b72d2ccacf40807 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Tue, 1 Dec 2020 11:21:03 +0530 Subject: [PATCH 233/550] Update src/mlpack/methods/ann/ffn.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/ffn.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 6cbb81d064..8a02e1983d 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -331,7 +331,7 @@ class FFN * @param inputShape Dhape of the input * @param functionName Function that checks the input size */ - void CheckInputShape(size_t inputShape, std::string functionName); + void CheckInputShape(const size_t inputShape, const std::string& functionName); /** * Reset the module infomration (weights/parameters). From a6cdc2db1f1c454b315b0ffef468878f38b88c4b Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 1 Dec 2020 12:30:06 +0530 Subject: [PATCH 234/550] updated CheckInputShape in ffn_impl, rnn, rnn_impl --- src/mlpack/methods/ann/ffn_impl.hpp | 2 +- src/mlpack/methods/ann/rnn.hpp | 2 +- src/mlpack/methods/ann/rnn_impl.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/ffn_impl.hpp b/src/mlpack/methods/ann/ffn_impl.hpp index 8b5ac908c2..4261ad5260 100644 --- a/src/mlpack/methods/ann/ffn_impl.hpp +++ b/src/mlpack/methods/ann/ffn_impl.hpp @@ -54,7 +54,7 @@ FFN::~FFN() template void FFN::CheckInputShape( - size_t inputShape, std::string functionName) + const size_t inputShape, const std::string& functionName) { for (size_t l=0; l::~RNN() template void RNN::CheckInputShape( - size_t inputShape, std::string functionName) + const size_t inputShape, const std::string& functionName) { for (size_t l=0; l Date: Tue, 1 Dec 2020 12:49:26 +0530 Subject: [PATCH 235/550] Minor fixes --- src/mlpack/tests/ann_layer_test.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 9b9f1f39c8..515b91078a 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -40,7 +40,7 @@ void CheckRNNCopyFunction(ModelType* network1, { arma::cube predictions1; arma::cube predictions2; - ens::StandardSGD opt(0.1, 1, 5, -100, false); + ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_cols, -100, false); network1->Train(trainData, trainLabels, opt); network1->Predict(trainData, predictions1); @@ -63,7 +63,7 @@ void CheckRNNMoveFunction(ModelType* network1, { arma::cube predictions1; arma::cube predictions2; - ens::StandardSGD opt(0.1, 1, 5, -100, false); + ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_cols, -100, false); network1->Train(trainData, trainLabels, opt); network1->Predict(trainData, predictions1); @@ -1242,21 +1242,23 @@ TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]") new RNN >(rho); model1->Predictors() = input; model1->Responses() = target; + model1->Add >(); model1->Add >(1, 10); model1->Add >(10, 3, rho); model1->Add >(); + // Check whether copy constructor is working or not. + CheckRNNCopyFunction<>(model1, input, target, 1); + RNN > *model2 = new RNN >(rho); model2->Predictors() = input; model2->Responses() = target; + model2->Add >(); model2->Add >(1, 10); model2->Add >(10, 3, rho); model2->Add >(); - // Check whether copy constructor is working or not. - CheckRNNCopyFunction<>(model1, input, target, 1); - // Check whether move constructor is working or not. CheckRNNMoveFunction<>(model2, input, target, 1); } From 147f9e06e32fa0a961fa2c16c567293bcb2e7a40 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 00:06:43 +0530 Subject: [PATCH 236/550] added util folder and moved CheckInputShape --- src/mlpack/methods/ann/CMakeLists.txt | 1 + src/mlpack/methods/ann/ffn.hpp | 9 ---- src/mlpack/methods/ann/ffn_impl.hpp | 46 +++++----------- src/mlpack/methods/ann/rnn.hpp | 9 ---- src/mlpack/methods/ann/rnn_impl.hpp | 42 ++++----------- src/mlpack/methods/ann/util/CMakeLists.txt | 14 +++++ .../methods/ann/util/check_input_shape.hpp | 52 +++++++++++++++++++ 7 files changed, 92 insertions(+), 81 deletions(-) create mode 100644 src/mlpack/methods/ann/util/CMakeLists.txt create mode 100644 src/mlpack/methods/ann/util/check_input_shape.hpp diff --git a/src/mlpack/methods/ann/CMakeLists.txt b/src/mlpack/methods/ann/CMakeLists.txt index 3c8236809c..8888113548 100644 --- a/src/mlpack/methods/ann/CMakeLists.txt +++ b/src/mlpack/methods/ann/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(gan) add_subdirectory(rbm) add_subdirectory(augmented) add_subdirectory(regularizer) +add_subdirectory(util) # Add directory name to sources. set(DIR_SRCS) diff --git a/src/mlpack/methods/ann/ffn.hpp b/src/mlpack/methods/ann/ffn.hpp index 8a02e1983d..1c65bbb749 100644 --- a/src/mlpack/methods/ann/ffn.hpp +++ b/src/mlpack/methods/ann/ffn.hpp @@ -24,7 +24,6 @@ #include "visitor/weight_size_visitor.hpp" #include "visitor/copy_visitor.hpp" #include "visitor/loss_visitor.hpp" -#include "visitor/input_shape_visitor.hpp" #include "init_rules/network_init.hpp" @@ -325,14 +324,6 @@ class FFN //! Modify the matrix of data points (predictors). arma::mat& Predictors() { return predictors; } - /** - * Check whether the input shape is consistent with the layer requirements. - * - * @param inputShape Dhape of the input - * @param functionName Function that checks the input size - */ - void CheckInputShape(const size_t inputShape, const std::string& functionName); - /** * Reset the module infomration (weights/parameters). */ diff --git a/src/mlpack/methods/ann/ffn_impl.hpp b/src/mlpack/methods/ann/ffn_impl.hpp index 4261ad5260..401c094ca6 100644 --- a/src/mlpack/methods/ann/ffn_impl.hpp +++ b/src/mlpack/methods/ann/ffn_impl.hpp @@ -22,7 +22,8 @@ #include "visitor/gradient_visitor.hpp" #include "visitor/set_input_height_visitor.hpp" #include "visitor/set_input_width_visitor.hpp" -#include "visitor/input_shape_visitor.hpp" + +#include "util/check_input_shape.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { @@ -51,33 +52,6 @@ FFN::~FFN() boost::apply_visitor(deleteVisitor)); } -template -void FFN::CheckInputShape( - const size_t inputShape, const std::string& functionName) -{ - for (size_t l=0; l void FFN::ResetData( @@ -137,7 +111,9 @@ double FFN::Train( OptimizerType& optimizer, CallbackTypes&&... callbacks) { - CheckInputShape(predictors.n_rows, "Train()"); + CheckInputShape > >(network, + predictors.n_rows, + "FFN<>::Train()"); ResetData(std::move(predictors), std::move(responses)); @@ -161,7 +137,9 @@ double FFN::Train( arma::mat responses, CallbackTypes&&... callbacks) { - CheckInputShape(predictors.n_rows, "Train()"); + CheckInputShape > >(network, + predictors.n_rows, + "FFN<>::Train()"); ResetData(std::move(predictors), std::move(responses)); @@ -249,7 +227,9 @@ template::Predict( arma::mat predictors, arma::mat& results) { - CheckInputShape(predictors.n_rows, "Predict()"); + CheckInputShape > >(network, + predictors.n_rows, + "FFN<>::Predict()"); if (parameter.is_empty()) ResetParameters(); @@ -284,7 +264,9 @@ template double FFN::Evaluate( const PredictorsType& predictors, const ResponsesType& responses) { - CheckInputShape(predictors.n_rows, "Evaluate()"); + CheckInputShape > >(network, + predictors.n_rows, + "FFN<>::Evaluate()"); if (parameter.is_empty()) ResetParameters(); diff --git a/src/mlpack/methods/ann/rnn.hpp b/src/mlpack/methods/ann/rnn.hpp index 031731533c..e9e6815de4 100644 --- a/src/mlpack/methods/ann/rnn.hpp +++ b/src/mlpack/methods/ann/rnn.hpp @@ -18,7 +18,6 @@ #include "visitor/delta_visitor.hpp" #include "visitor/output_parameter_visitor.hpp" #include "visitor/reset_visitor.hpp" -#include "visitor/input_shape_visitor.hpp" #include "init_rules/network_init.hpp" @@ -302,14 +301,6 @@ class RNN //! Modify the matrix of data points (predictors). arma::cube& Predictors() { return predictors; } - /** - * Check wether the input shape is consistent with the layer requirements. - * - * @param inputShape shape of the input - * @param functionName function that checks the input size - */ - void CheckInputShape(const size_t inputShape, const std::string& functionName); - /** * Reset the state of the network. This ensures that all internally-held * gradients are set to 0, all memory cells are reset, and the parameters diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index 0feb8bea58..365056a739 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -24,7 +24,8 @@ #include "visitor/gradient_set_visitor.hpp" #include "visitor/gradient_visitor.hpp" #include "visitor/weight_set_visitor.hpp" -#include "visitor/input_shape_visitor.hpp" + +#include "util/check_input_shape.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { @@ -60,33 +61,6 @@ RNN::~RNN() } } -template -void RNN::CheckInputShape( - const size_t inputShape, const std::string& functionName) -{ - for (size_t l=0; l template @@ -131,7 +105,9 @@ double RNN::Train( OptimizerType& optimizer, CallbackTypes&&... callbacks) { - CheckInputShape(predictors.n_rows, "Train()"); + CheckInputShape > >(network, + predictors.n_rows, + "RNN<>::Train()"); numFunctions = responses.n_cols; @@ -177,7 +153,9 @@ double RNN::Train( arma::cube responses, CallbackTypes&&... callbacks) { - CheckInputShape(predictors.n_rows, "Train()"); + CheckInputShape > >(network, + predictors.n_rows, + "RNN<>::Train()"); numFunctions = responses.n_cols; @@ -211,7 +189,9 @@ template::Predict( arma::cube predictors, arma::cube& results, const size_t batchSize) { - CheckInputShape(predictors.n_rows, "Predict()"); + CheckInputShape > >(network, + predictors.n_rows, + "RNN<>::Predict()"); ResetCells(); diff --git a/src/mlpack/methods/ann/util/CMakeLists.txt b/src/mlpack/methods/ann/util/CMakeLists.txt new file mode 100644 index 0000000000..dffec0c265 --- /dev/null +++ b/src/mlpack/methods/ann/util/CMakeLists.txt @@ -0,0 +1,14 @@ +# Define the files we need to compile +# Anything not in this list will not be compiled into mlpack. +set(SOURCES + check_input_shape.hpp +) + +# Add directory name to sources. +set(DIR_SRCS) +foreach(file ${SOURCES}) + set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}) +endforeach() +# Append sources (with directory name) to list of all mlpack sources (used at +# the parent scope). +set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE) \ No newline at end of file diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp new file mode 100644 index 0000000000..52fa019e9c --- /dev/null +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -0,0 +1,52 @@ +/** + * @file check_input_shape.hpp + * @author Nippun Sharma + * + * Definition of the CheckInputShape() function that checks + * whether the shape of input is consistent with the first layer + * of the neural network. + * + * 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_UTIL_CHECK_INPUT_SHAPE_HPP +#define MLPACK_METHODS_ANN_UTIL_CHECK_INPUT_SHAPE_HPP + +#include + +namespace mlpack { +namespace ann /** Artificial Neural Network. */{ + +template +void CheckInputShape(T network, const size_t inputShape, + const std::string& functionName) +{ + for (size_t l=0; l Date: Tue, 1 Dec 2020 19:52:58 -0500 Subject: [PATCH 237/550] Update src/mlpack/methods/ann/layer/concatenate_impl.hpp Co-authored-by: kartikdutt18 <39593019+kartikdutt18@users.noreply.github.com> --- src/mlpack/methods/ann/layer/concatenate_impl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mlpack/methods/ann/layer/concatenate_impl.hpp b/src/mlpack/methods/ann/layer/concatenate_impl.hpp index 10a6015de1..ba0060aa5f 100644 --- a/src/mlpack/methods/ann/layer/concatenate_impl.hpp +++ b/src/mlpack/methods/ann/layer/concatenate_impl.hpp @@ -57,6 +57,7 @@ operator=(const Concatenate& layer) delta = layer.delta; concat = layer.concat; } + return *this; } From 4fd725381e46f158fcf78af98dc259cb673760aa Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 2 Dec 2020 15:13:08 +0530 Subject: [PATCH 238/550] Update src/mlpack/methods/ann/layer/convolution.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/layer/convolution.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index 6eda5989a5..1571c3e414 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -262,7 +262,7 @@ class Convolution //! Get the shape of the input. size_t InputShape() const { - return inputHeight*inputWidth*inSize; + return inputHeight * inputWidth * inSize; } /** From dd444d6c55b00fafb55e21ff3756a4e2efd2f16f Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 2 Dec 2020 15:13:58 +0530 Subject: [PATCH 239/550] Update src/mlpack/methods/ann/layer/recurrent_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/layer/recurrent_impl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 0c1ace86c1..a4e962227b 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -136,6 +136,7 @@ size_t Recurrent::InputShape() c size_t inputShapeFeedbackModule = boost::apply_visitor(InShapeVisitor(), feedbackModule); size_t inputShapeTransferModule = boost::apply_visitor(InShapeVisitor(), transferModule); + // Return the size of the first module that we have. if (inputShapeStartModule != 0) return inputShapeStartModule; else From ecf66d7bbbfa7d39f7e8c6fc6dbc0f3cfb007c0d Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 15:52:21 +0530 Subject: [PATCH 240/550] added comments in recurrent --- src/mlpack/methods/ann/layer/recurrent_impl.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index a4e962227b..e37df89b69 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -139,18 +139,25 @@ size_t Recurrent::InputShape() c // Return the size of the first module that we have. if (inputShapeStartModule != 0) return inputShapeStartModule; + // If first module does not have any weights. else { + // Return the size of the second module we have. if (inputShapeInputModule != 0) return inputShapeInputModule; + // If second module does not have any weights. else { + // Return the size of the third module we have. if (inputShapeFeedbackModule != 0) return inputShapeFeedbackModule; + // If the third module does not have any weights. else { + // Return the size of the fourth module we have if (inputShapeTransferModule != 0) return inputShapeTransferModule; + // If the fourth module does not have any weights. else return 0; } From b9e4bcd72932e462450e39e3635232e272942048 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 15:56:21 +0530 Subject: [PATCH 241/550] changed rows to dimensions --- src/mlpack/methods/ann/util/check_input_shape.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp index 52fa019e9c..346b8e929f 100644 --- a/src/mlpack/methods/ann/util/check_input_shape.hpp +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -40,7 +40,7 @@ void CheckInputShape(T network, const size_t inputShape, std::string estr = functionName + ": "; estr += "the first layer of the network expects "; estr += std::to_string(layerInShape) + " elements, "; - estr += "but the input has " + std::to_string(inputShape) + " rows! "; + estr += "but the input has " + std::to_string(inputShape) + " dimensions! "; throw std::logic_error(estr); } } From 6d66dfe846fdd137928d34741b9a3beadb448f09 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 16:03:07 +0530 Subject: [PATCH 242/550] to avoid extra copies --- src/mlpack/methods/ann/util/check_input_shape.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp index 346b8e929f..b2b7b7e67e 100644 --- a/src/mlpack/methods/ann/util/check_input_shape.hpp +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -21,7 +21,7 @@ namespace mlpack { namespace ann /** Artificial Neural Network. */{ template -void CheckInputShape(T network, const size_t inputShape, +void CheckInputShape(const T& network, const size_t inputShape, const std::string& functionName) { for (size_t l=0; l Date: Wed, 2 Dec 2020 16:16:51 +0530 Subject: [PATCH 243/550] added to atrous conv --- src/mlpack/methods/ann/layer/atrous_convolution.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mlpack/methods/ann/layer/atrous_convolution.hpp b/src/mlpack/methods/ann/layer/atrous_convolution.hpp index 478f62abe2..daddab76f2 100644 --- a/src/mlpack/methods/ann/layer/atrous_convolution.hpp +++ b/src/mlpack/methods/ann/layer/atrous_convolution.hpp @@ -263,6 +263,12 @@ class AtrousConvolution return (outSize * inSize * kernelWidth * kernelHeight) + outSize; } + //! Get the shape of the input. + size_t InputShape() const + { + return inputHeight * inputWidth * inSize; + } + /** * Serialize the layer. */ From 3f2863b06d195825f17e42ddcac3bf8182e9bc2e Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 16:18:47 +0530 Subject: [PATCH 244/550] added to transposed conv --- src/mlpack/methods/ann/layer/transposed_convolution.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mlpack/methods/ann/layer/transposed_convolution.hpp b/src/mlpack/methods/ann/layer/transposed_convolution.hpp index a7a89b1dbc..350ca43a26 100644 --- a/src/mlpack/methods/ann/layer/transposed_convolution.hpp +++ b/src/mlpack/methods/ann/layer/transposed_convolution.hpp @@ -274,6 +274,12 @@ class TransposedConvolution //! Modify the right padding width. size_t& PadWRight() { return padWRight; } + //! Get the shape of the input. + size_t InputShape() const + { + return inputHeight * inputWidth * inSize; + } + /** * Serialize the layer. */ From f03464aa2cf46ffc34b18e36253836898456c5b5 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 17:39:10 +0530 Subject: [PATCH 245/550] added to bilinear, glimpse, gru, highway, layer_norm, linear3d --- src/mlpack/methods/ann/layer/bilinear_interpolation.hpp | 6 ++++++ src/mlpack/methods/ann/layer/glimpse.hpp | 6 ++++++ src/mlpack/methods/ann/layer/gru.hpp | 6 ++++++ src/mlpack/methods/ann/layer/highway.hpp | 6 ++++++ src/mlpack/methods/ann/layer/layer_norm.hpp | 6 ++++++ src/mlpack/methods/ann/layer/linear3d.hpp | 6 ++++++ 6 files changed, 36 insertions(+) diff --git a/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp b/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp index 817763e973..2d611feb19 100644 --- a/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp +++ b/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp @@ -118,6 +118,12 @@ class BilinearInterpolation //! Modify the depth of the input. size_t& InDepth() { return depth; } + //! Get the shape of the input. + size_t WeightSize() const + { + return InRowSize; + } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/glimpse.hpp b/src/mlpack/methods/ann/layer/glimpse.hpp index 661fab551d..99a268b6a8 100644 --- a/src/mlpack/methods/ann/layer/glimpse.hpp +++ b/src/mlpack/methods/ann/layer/glimpse.hpp @@ -182,6 +182,12 @@ class Glimpse //! Get the used glimpse size (height = width). size_t GlimpseSize() const { return size;} + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/gru.hpp b/src/mlpack/methods/ann/layer/gru.hpp index b732b41af1..3d98a712d8 100644 --- a/src/mlpack/methods/ann/layer/gru.hpp +++ b/src/mlpack/methods/ann/layer/gru.hpp @@ -155,6 +155,12 @@ class GRU //! Get the number of output units. size_t OutSize() const { return outSize; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/highway.hpp b/src/mlpack/methods/ann/layer/highway.hpp index 7e5893c424..aa539a4972 100644 --- a/src/mlpack/methods/ann/layer/highway.hpp +++ b/src/mlpack/methods/ann/layer/highway.hpp @@ -177,6 +177,12 @@ class Highway //! Get the number of input units. size_t InSize() const { return inSize; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/layer_norm.hpp b/src/mlpack/methods/ann/layer/layer_norm.hpp index ba0d3f4c29..c22408c221 100644 --- a/src/mlpack/methods/ann/layer/layer_norm.hpp +++ b/src/mlpack/methods/ann/layer/layer_norm.hpp @@ -148,6 +148,12 @@ class LayerNorm //! Get the value of epsilon. double Epsilon() const { return eps; } + //! Get the shape of the input. + size_t InputShape() const + { + return size; + } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/linear3d.hpp b/src/mlpack/methods/ann/layer/linear3d.hpp index b4579a6c62..7bd03e8176 100644 --- a/src/mlpack/methods/ann/layer/linear3d.hpp +++ b/src/mlpack/methods/ann/layer/linear3d.hpp @@ -136,6 +136,12 @@ class Linear3D //! Modify the bias weights of the layer. OutputDataType& Bias() { return bias; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer */ From ed274d7a8b62a1ef1ffa0bd8fdaee6250157760a Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 2 Dec 2020 18:02:14 +0530 Subject: [PATCH 246/550] added to minibatch_discrimination, radial_basis_function --- src/mlpack/methods/ann/layer/minibatch_discrimination.hpp | 6 ++++++ src/mlpack/methods/ann/layer/radial_basis_function.hpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/mlpack/methods/ann/layer/minibatch_discrimination.hpp b/src/mlpack/methods/ann/layer/minibatch_discrimination.hpp index 88f8dff1ba..3448f36b5d 100644 --- a/src/mlpack/methods/ann/layer/minibatch_discrimination.hpp +++ b/src/mlpack/methods/ann/layer/minibatch_discrimination.hpp @@ -134,6 +134,12 @@ class MiniBatchDiscrimination //! Modify the gradient. OutputDataType& Gradient() { return gradient; } + //! Get the shape of the input. + size_t InputShape() const + { + return A; + } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/radial_basis_function.hpp b/src/mlpack/methods/ann/layer/radial_basis_function.hpp index b867e9e936..2387d612ab 100644 --- a/src/mlpack/methods/ann/layer/radial_basis_function.hpp +++ b/src/mlpack/methods/ann/layer/radial_basis_function.hpp @@ -110,6 +110,12 @@ class RBF //! Modify the delta. OutputDataType& Delta() { return delta; } + //! Get the shape of the input. + size_t InputShape() const + { + return inSize; + } + /** * Serialize the layer. */ From 96b04c2a94ee8fef5ede1a709f47ae0ed9fe326f Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Thu, 3 Dec 2020 15:45:59 +0530 Subject: [PATCH 247/550] Review fixes --- src/mlpack/methods/ann/rnn.hpp | 7 +++++-- src/mlpack/methods/ann/rnn_impl.hpp | 19 +++++++++++------- src/mlpack/tests/ann_layer_test.cpp | 20 +++++++++---------- src/mlpack/tests/feedforward_network_test.cpp | 10 +++++----- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/mlpack/methods/ann/rnn.hpp b/src/mlpack/methods/ann/rnn.hpp index 0e653ea0f9..949aecee9b 100644 --- a/src/mlpack/methods/ann/rnn.hpp +++ b/src/mlpack/methods/ann/rnn.hpp @@ -76,8 +76,11 @@ class RNN //! Move constructor. RNN(RNN&&); - //! Copy/move assignment operator. - RNN& operator = (RNN); + //! Copy assignment operator. + RNN& operator=(const RNN&); + + //! Move assignment operator + RNN& operator=(RNN&&); //! Destructor to release allocated memory. ~RNN(); diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index 66bef0855b..65ab29ad4f 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -54,22 +54,27 @@ template::RNN( const RNN& network) : rho(network.rho), + outputLayer(network.outputLayer), initializeRule(network.initializeRule), inputSize(network.inputSize), - outputLayer(network.outputLayer), outputSize(network.outputSize), targetSize(network.targetSize), reset(network.reset), single(network.single), + parameter(network.parameter), numFunctions(network.numFunctions), - deterministic(network.deterministic), - parameter(network.parameter) + deterministic(network.deterministic) { for (size_t i = 0; i < network.network.size(); ++i) { this->network.push_back(boost::apply_visitor(copyVisitor, network.network[i])); - boost::apply_visitor(resetVisitor, this->network[i]); + boost::apply_visitor(resetVisitor, this->network.back()); + } + ResetCells(); + if (parameter.is_empty()) + { + ResetParameters(); } } @@ -78,16 +83,16 @@ template::RNN( RNN&& network) : rho(std::move(network.rho)), + outputLayer(std::move(network.outputLayer)), initializeRule(std::move(network.initializeRule)), inputSize(std::move(network.inputSize)), - outputLayer(std::move(network.outputLayer)), outputSize(std::move(network.outputSize)), targetSize(std::move(network.targetSize)), reset(std::move(network.reset)), single(std::move(network.single)), + parameter(std::move(network.parameter)), numFunctions(std::move(network.numFunctions)), - deterministic(std::move(network.deterministic)), - parameter(std::move(network.parameter)) + deterministic(std::move(network.deterministic)) { this->network = std::move(network.network); } diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 515b91078a..3950c1a2fd 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -40,7 +40,7 @@ void CheckRNNCopyFunction(ModelType* network1, { arma::cube predictions1; arma::cube predictions2; - ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_cols, -100, false); + ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_slices, -100, false); network1->Train(trainData, trainLabels, opt); network1->Predict(trainData, predictions1); @@ -48,8 +48,8 @@ void CheckRNNCopyFunction(ModelType* network1, RNN<> network2 = *network1; delete network1; - // Deallocating all of network1's memory, so that - // if network2 is trying to use any of that memory. + // Deallocating all of network1's memory, so that network2 does not use any + // of that memory. network2.Predict(trainData, predictions2); CheckMatrices(predictions1, predictions2); } @@ -63,7 +63,7 @@ void CheckRNNMoveFunction(ModelType* network1, { arma::cube predictions1; arma::cube predictions2; - ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_cols, -100, false); + ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_slices, -100, false); network1->Train(trainData, trainLabels, opt); network1->Predict(trainData, predictions1); @@ -71,8 +71,8 @@ void CheckRNNMoveFunction(ModelType* network1, RNN<> network2(std::move(*network1)); delete network1; - // Deallocating all of network1's memory, so that - // if network2 is trying to use any of that memory. + // Deallocating all of network1's memory, so that network2 does not use any + // of that memory. network2.Predict(trainData, predictions2); CheckMatrices(predictions1, predictions2); } @@ -1239,7 +1239,7 @@ TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]") const size_t rho = 5; RNN > *model1 = - new RNN >(rho); + new RNN >(rho); model1->Predictors() = input; model1->Responses() = target; model1->Add >(); @@ -1247,9 +1247,6 @@ TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]") model1->Add >(10, 3, rho); model1->Add >(); - // Check whether copy constructor is working or not. - CheckRNNCopyFunction<>(model1, input, target, 1); - RNN > *model2 = new RNN >(rho); model2->Predictors() = input; @@ -1259,6 +1256,9 @@ TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]") model2->Add >(10, 3, rho); model2->Add >(); + // Check whether copy constructor is working or not. + CheckRNNCopyFunction<>(model1, input, target, 1); + // Check whether move constructor is working or not. CheckRNNMoveFunction<>(model2, input, target, 1); } diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 774bb53f18..81086a019e 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -71,8 +71,8 @@ void CheckCopyFunction(ModelType* network1, network2 = *network1; delete network1; - // Deallocating all of network1's memory, so that - // if network2 is trying to use any of that memory. + // Deallocating all of network1's memory, so that network2 does not use any + // of that memory. arma::mat predictions2; network2.Predict(trainData, predictions2); CheckMatrices(predictions1, predictions2); @@ -93,8 +93,8 @@ void CheckMoveFunction(ModelType* network1, FFN<> network2(std::move(*network1)); delete network1; - // Deallocating all of network1's memory, so that - // if network2 is trying to use any of that memory. + // Deallocating all of network1's memory, so that network2 does not use any + // of that memory. arma::mat predictions2; network2.Predict(trainData, predictions2); CheckMatrices(predictions1, predictions2); @@ -171,7 +171,7 @@ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") model1->Add>(10, 5); model1->Add >(5, 1); model1->Add>(); - + // Check whether copy constructor is working or not. CheckCopyFunction<>(model1, input, output, 1); From 376a44fe85cfb80ad80bcab7093c731073c41ae4 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Thu, 3 Dec 2020 18:16:46 +0530 Subject: [PATCH 248/550] add assert in spatial_dropout_impl.hpp --- src/mlpack/methods/ann/layer/spatial_dropout_impl.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mlpack/methods/ann/layer/spatial_dropout_impl.hpp b/src/mlpack/methods/ann/layer/spatial_dropout_impl.hpp index 79114d2471..4bd2cb767b 100644 --- a/src/mlpack/methods/ann/layer/spatial_dropout_impl.hpp +++ b/src/mlpack/methods/ann/layer/spatial_dropout_impl.hpp @@ -51,6 +51,9 @@ template void SpatialDropout::Forward( const arma::Mat& input, arma::Mat& output) { + Log::Assert(input.n_rows % size == 0, "Input features must be divisible \ + by feature maps."); + if (!reset) { batchSize = input.n_cols; From 57b93807d0baeb311c4ef0f3ea310e3a50adbe82 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Thu, 3 Dec 2020 18:22:23 +0530 Subject: [PATCH 249/550] add assert to virtual_batch_norm_impl.hpp --- src/mlpack/methods/ann/layer/virtual_batch_norm_impl.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mlpack/methods/ann/layer/virtual_batch_norm_impl.hpp b/src/mlpack/methods/ann/layer/virtual_batch_norm_impl.hpp index 2b93960b82..7bd20415a2 100644 --- a/src/mlpack/methods/ann/layer/virtual_batch_norm_impl.hpp +++ b/src/mlpack/methods/ann/layer/virtual_batch_norm_impl.hpp @@ -67,6 +67,9 @@ template void VirtualBatchNorm::Forward( const arma::Mat& input, arma::Mat& output) { + Log::Assert(input.n_rows % size == 0, "Input features must be divisible \ + by feature maps."); + inputParameter = input; arma::mat inputMean = arma::mean(input, 1); arma::mat inputMeanSquared = arma::mean(arma::square(input), 1); From a79cf8dd2dc66fbfdabf37610c366fab4c4a98df Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Thu, 3 Dec 2020 19:14:17 +0530 Subject: [PATCH 250/550] Fix for failing tests --- .../methods/ann/layer/fast_lstm_impl.hpp | 40 ++++++++++++++++++- src/mlpack/methods/ann/rnn_impl.hpp | 5 --- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp index 2f90963674..752b132ae4 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp @@ -50,7 +50,16 @@ FastLSTM::FastLSTM(const FastLSTM& layer) : inSize(layer.inSize), outSize(layer.outSize), rho(layer.rho), - weights(layer.weights) + forwardStep(layer.forwardStep), + backwardStep(layer.backwardStep), + gradientStep(layer.gradientStep), + weights(layer.weights), + batchSize(layer.batchSize), + batchStep(layer.batchStep), + gradientStepIdx(layer.gradientStepIdx), + grad(layer.grad), + rhoSize(layer.rho), + bpttSteps(layer.bpttSteps) { // Nothing to do here. } @@ -60,7 +69,16 @@ FastLSTM::FastLSTM(FastLSTM&& layer) : inSize(std::move(layer.inSize)), outSize(std::move(layer.outSize)), rho(std::move(layer.rho)), - weights(std::move(layer.weights)) + forwardStep(std::move(layer.forwardStep)), + backwardStep(std::move(layer.backwardStep)), + gradientStep(std::move(layer.gradientStep)), + weights(std::move(layer.weights)), + batchSize(std::move(layer.batchSize)), + batchStep(std::move(layer.batchStep)), + gradientStepIdx(std::move(layer.gradientStepIdx)), + grad(std::move(layer.grad)), + rhoSize(std::move(layer.rho)), + bpttSteps(std::move(layer.bpttSteps)) { // Nothing to do here. } @@ -74,7 +92,16 @@ FastLSTM::operator=(const FastLSTM& layer) inSize = layer.inSize; outSize = layer.outSize; rho = layer.rho; + forwardStep = layer.forwardStep; + backwardStep = layer.backwardStep; + gradientStep = layer.gradientStep; weights = layer.weights; + batchSize = layer.batchSize; + batchStep = layer.batchStep; + gradientStepIdx = layer.gradientStepIdx; + grad = layer.grad; + rhoSize = layer.rho; + bpttSteps = layer.bpttSteps; } return *this; } @@ -88,7 +115,16 @@ FastLSTM::operator=(FastLSTM&& layer) inSize = std::move(layer.inSize); outSize = std::move(layer.outSize); rho = std::move(layer.rho); + forwardStep = std::move(layer.forwardStep); + backwardStep = std::move(layer.backwardStep); + gradientStep = std::move(layer.gradientStep); weights = std::move(layer.weights); + batchSize = std::move(layer.batchSize); + batchStep = std::move(layer.batchStep); + gradientStepIdx = std::move(layer.gradientStepIdx); + grad = std::move(layer.grad); + rhoSize = std::move(layer.rho); + bpttSteps = std::move(layer.bpttSteps); } return *this; } diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index 65ab29ad4f..6c909585c7 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -71,11 +71,6 @@ RNN::RNN( network.network[i])); boost::apply_visitor(resetVisitor, this->network.back()); } - ResetCells(); - if (parameter.is_empty()) - { - ResetParameters(); - } } template Date: Fri, 4 Dec 2020 11:39:50 +0530 Subject: [PATCH 251/550] Review fixes --- src/mlpack/methods/ann/rnn_impl.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index 6c909585c7..75749982f5 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -87,9 +87,10 @@ RNN::RNN( single(std::move(network.single)), parameter(std::move(network.parameter)), numFunctions(std::move(network.numFunctions)), - deterministic(std::move(network.deterministic)) + deterministic(std::move(network.deterministic)), + network(std::move(network.network)) { - this->network = std::move(network.network); + // Nothing to do here. } template Date: Fri, 4 Dec 2020 15:06:32 +0530 Subject: [PATCH 252/550] Added fail messages and comment fix --- src/mlpack/tests/callback_test.cpp | 8 ++++---- src/mlpack/tests/svd_batch_test.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mlpack/tests/callback_test.cpp b/src/mlpack/tests/callback_test.cpp index e66fc1e051..0d532df67c 100644 --- a/src/mlpack/tests/callback_test.cpp +++ b/src/mlpack/tests/callback_test.cpp @@ -42,9 +42,9 @@ TEST_CASE("FFNCallbackTest", "[CallbackTest]") arma::mat data; arma::mat labels; - if (!data::Load("lab1.csv", data, true)) + if (!data::Load("lab1.csv", data)) FAIL("Cannot load test dataset lab1.csv!"); - if (!data::Load("lab3.csv", labels, true)) + if (!data::Load("lab3.csv", labels)) FAIL("Cannot load test dataset lab3.csv!"); FFN, RandomInitialization> model; @@ -68,9 +68,9 @@ TEST_CASE("FFNWithOptimizerCallbackTest", "[CallbackTest]") arma::mat data; arma::mat labels; - if (!data::Load("lab1.csv", data, true)) + if (!data::Load("lab1.csv", data)) FAIL("Cannot load test dataset lab1.csv!"); - if (!data::Load("lab3.csv", labels, true)) + if (!data::Load("lab3.csv", labels)) FAIL("Cannot load test dataset lab3.csv!"); FFN, RandomInitialization> model; diff --git a/src/mlpack/tests/svd_batch_test.cpp b/src/mlpack/tests/svd_batch_test.cpp index bac6df4917..ab9eb99f5a 100644 --- a/src/mlpack/tests/svd_batch_test.cpp +++ b/src/mlpack/tests/svd_batch_test.cpp @@ -70,7 +70,8 @@ class SpecificRandomInitialization TEST_CASE("SVDBatchMomentumTest", "[SVDBatchTest]") { mat dataset; - data::Load("GroupLensSmall.csv", dataset); + if (data::Load("GroupLensSmall.csv", dataset)) + FAIL("Cannot load dataset GroupLensSmall.csv!"); // Generate list of locations for batch insert constructor for sparse // matrices. @@ -117,7 +118,8 @@ TEST_CASE("SVDBatchMomentumTest", "[SVDBatchTest]") TEST_CASE("SVDBatchRegularizationTest", "[SVDBatchTest]") { mat dataset; - data::Load("GroupLensSmall.csv", dataset); + if (data::Load("GroupLensSmall.csv", dataset)) + FAIL("Cannot load dataset GroupLensSmall.csv!"); // Generate list of locations for batch insert constructor for sparse // matrices. From 6cad509c2fe31c4239f111165c4e8f23b06fb697 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Fri, 4 Dec 2020 16:04:58 +0530 Subject: [PATCH 253/550] Minor fix --- src/mlpack/tests/svd_batch_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/svd_batch_test.cpp b/src/mlpack/tests/svd_batch_test.cpp index ab9eb99f5a..41b005a28d 100644 --- a/src/mlpack/tests/svd_batch_test.cpp +++ b/src/mlpack/tests/svd_batch_test.cpp @@ -70,7 +70,7 @@ class SpecificRandomInitialization TEST_CASE("SVDBatchMomentumTest", "[SVDBatchTest]") { mat dataset; - if (data::Load("GroupLensSmall.csv", dataset)) + if (!data::Load("GroupLensSmall.csv", dataset)) FAIL("Cannot load dataset GroupLensSmall.csv!"); // Generate list of locations for batch insert constructor for sparse @@ -118,7 +118,7 @@ TEST_CASE("SVDBatchMomentumTest", "[SVDBatchTest]") TEST_CASE("SVDBatchRegularizationTest", "[SVDBatchTest]") { mat dataset; - if (data::Load("GroupLensSmall.csv", dataset)) + if (!data::Load("GroupLensSmall.csv", dataset)) FAIL("Cannot load dataset GroupLensSmall.csv!"); // Generate list of locations for batch insert constructor for sparse From 117f18cf7dfcffd75bc034690d1e7931bd9cfe2e Mon Sep 17 00:00:00 2001 From: Matheus Gomes Date: Thu, 26 Nov 2020 20:06:13 +0000 Subject: [PATCH 254/550] Added Visual Studio CMake integration build guide to docs. --- doc/guide/build_windows.hpp | 118 +++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/doc/guide/build_windows.hpp b/doc/guide/build_windows.hpp index e150cc3b54..41eb911659 100644 --- a/doc/guide/build_windows.hpp +++ b/doc/guide/build_windows.hpp @@ -9,8 +9,13 @@ @section build_windows_intro Introduction -This tutorial will show you how to build mlpack for Windows from source, so you can -later create your own C++ applications. Before you try building mlpack, you may +This tutorial will show you how to build mlpack for Windows from source, so +you can later create your own C++ applications, using two different ways: + + - Using CMake to generate an intermeditate Visual Studio solution (`.sln`). + - @ref build_visual_studio_cmake_integration "Use Visual Studio's CMake integration to directly build from the `CMakeLists`." + +Before you try building mlpack, you may want to install mlpack using vcpkg for Windows. If you don't want to install using vcpkg, skip this section and continue with the build tutorial. @@ -78,6 +83,23 @@ system environment variables or manually set the PATH before running CMake) - Click on OpenBlas and check the mlpack project, then click Install - Once it has finished installing, close Visual Studio + Building OpenBLAS from Source + +Unfortunately, the support for building `LAPACK` and `BLAS` on Windows is quite poor, due to the need for Fortran +compiler and libraries. The easiest method to get the necessary `BLAS/LAPACK` libraries built on Windows is to +compile OpenBLAS with LLVM's `clang-cl` and `flang` to produce the required static library (`.lib`) files +compatible with the MSVC compiler. A comprehensive guide on the +compilation +of OpenBLAS for Windows can be found here. + +One could always download prebuilt `LAPACK` and `BLAS` libraries for Windows. However, there are few official +sources, and some of those libraries may require further `dll`s at runtime which may not be available in your +system. + +It you choose to build `OpenBLAS` from source, make sure that `LAPACK` functions are also built. Finally, make +sure that the `openblas.lib` library is linked in your `Armadillo` build (see below), as well as the library +path used for the CMake options `BLAS_LIBRARIES` and `LAPACK_LIBRARIES` in the mlpack CMake project. + Boost Dependency You can either get Boost via NuGet or you can download the prebuilt Windows binaries separately. @@ -110,7 +132,7 @@ compiler version, check if the Visual Studio compiler and Windows SDK are instal - Build > Build Solution - Once it has successfully finished, close Visual Studio -@section build_windows_mlpack Building mlpack +@section build_windows_mlpack Building mlpack with CMake-Generated Solution - Create a "build" directory into "C:\mlpack\mlpack\" - You can generate the project using either cmake via command line or GUI. If you prefer to use GUI, refer to the \ref build_windows_appendix "appendix" @@ -129,6 +151,96 @@ cmake -G "Visual Studio 16 2019" -A x64 -DBLAS_LIBRARIES:FILEPATH="C:/mlpack/mlp You are ready to create your first application, take a look at the @ref sample_ml_app "Sample C++ ML App" +@section build_visual_studio_cmake_integration Building mlpack with Visual Studio's CMake Integration + +This project can be directly built from the `CMakeLists.txt` with the latest version of MS Visual Studio, +given you have CMake integration via the +C++ +CMake tools for Windows. To open the CMake project with Visual Studio, select File->Open->CMake +in the top menu, followed by selecting the root `CMakeLists.txt` located in mlpack's root directory. + +In order to allow Visual Studio to configure the CMake project, the CMake configuration json will have +to be edited to provide the relevant options +shown in the `README` needed to find all the dependencies. The options that you +must provide to Visual Studio's CMake are: + + - `ARMADILLO_INCLUDE_DIR` + - `ARMADILLO_LIBRARY` + - `BOOST_ROOT` + - `CEREAL_INCLUDE_DIR` + - `BLAS_LIBRARIES` + - `LAPACK_LIBRARIES` + +The CMake configuration json can be editted in Visual Studio by right clicking the root `CMakeLists.txt` +in the project view, selecting CMake settings for mlpack and finally clicking on edit JSON. +Adding a new CMake option can be done by adding object fields with the following format to the variables +array in the `CMakeSettings.json`: + +@code +{ + "name": "options_name_string", + "value": "options_value_string", + "type" : "{BOOL|FILEPATH|PATH|STRING}" +} +@endcode + +Here is a full example of the `CMakeSettings.json`file: + +@code +{ + "configurations": [ + { + "name": "x64-Debug (default)", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [ + { + "name": "ARMADILLO_INCLUDE_DIR", + "value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/include", + "type": "PATH" + }, + { + "name": "ARMADILLO_LIBBRARY", + "value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/lib/armadillo.lib", + "type": "PATH" + }, + { + "name": "CEREAL_INCLUDE_DIR", + "value": "PATH/TO/CPP/DEPENDENCY/cereal-1.3.0/include", + "type": "PATH" + }, + { + "name": "BUILD_ROOT", + "value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0", + "type": "PATH" + }, + { + "name": "BOOST_INCLUDEDIR", + "value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0", + "type": "PATH" + }, + { + "name": "BLAS_LIBRARIES", + "value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib", + "type": "PATH" + }, + { + "name": "LAPACK_LIBRARIES", + "value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib", + "type": "PATH" + } + ] + } + ] +} +@endcode + @section build_windows_appendix Appendix If you prefer to use cmake GUI, follow these instructions: From 7b56328e5c638ba1bd7fdc799a5a0f3d1302d513 Mon Sep 17 00:00:00 2001 From: prince776 Date: Fri, 13 Mar 2020 15:21:08 +0530 Subject: [PATCH 255/550] Refactored to avoid r value references --- .../ann/loss_functions/triplet_margin_loss.hpp | 16 ++++++++-------- .../loss_functions/triplet_margin_loss_impl.hpp | 15 +++++++-------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp index fa23999d8f..a14a767717 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp @@ -36,10 +36,10 @@ class TripletMarginLoss * @param input The propagated input activation. * @param target The target vector. */ -template - double Forward(const AnchorType&& anchor, - const PositiveType&& positive, - const NegativeType&& negative); + template + double Forward(const AnchorType& anchor, + const PositiveType& positive, + const NegativeType& negative); /** * Ordinary feed backward pass of a neural network. @@ -53,10 +53,10 @@ template < typename PositiveType, typename NegativeType, typename OutputType -> - void Backward(const AnchorType&& anchor, - const PositiveType&& positive, - const NegativeType&& negative, + > + void Backward(const AnchorType& anchor, + const PositiveType& positive, + const NegativeType& negative, OutputType&& output); //! Get the output parameter. diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index 8cbd972f08..58a8b5b8e6 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -28,9 +28,9 @@ TripletMarginLoss::TripletMarginLoss( template template double TripletMarginLoss::Forward( - const AnchorType&& anchor, - const PositiveType&& positive, - const NegativeType&& negative) + const AnchorType& anchor, + const PositiveType& positive, + const NegativeType& negative) { return std::max(0.0, arma::accu(arma::pow(anchor - positive, 2)) - arma::accu(arma::pow(anchor - negative, 2)) + margin) / anchor.n_cols; @@ -44,11 +44,10 @@ template < typename OutputType > void TripletMarginLoss::Backward( - const AnchorType&& anchor, - const PositiveType&& positive, - const NegativeType&& negative, - OutputType&& output - ) + const AnchorType& anchor, + const PositiveType& positive, + const NegativeType& negative, + OutputType&& output) { output = 2 * (negative - positive) / anchor.n_cols; } From b8ae24a12e210e39dfbc97c6bfb5d4a973101400 Mon Sep 17 00:00:00 2001 From: Prince Gupta Date: Fri, 27 Mar 2020 23:33:10 +0530 Subject: [PATCH 256/550] Fixed Forward() and Backward() to match Layer API --- .../loss_functions/triplet_margin_loss.hpp | 30 ++++++++----------- .../triplet_margin_loss_impl.hpp | 26 ++++++++-------- src/mlpack/tests/loss_functions_test.cpp | 26 ++++++++++------ 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp index a14a767717..7c1ab250dc 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp @@ -33,31 +33,25 @@ class TripletMarginLoss /** * Computes the Triplet Margin Loss function. * - * @param input The propagated input activation. - * @param target The target vector. + * @param input The propagated input activation. It should be + * concatenated anchor and positive samples. + * @param target The target vector. It should be negative samples. */ - template - double Forward(const AnchorType& anchor, - const PositiveType& positive, - const NegativeType& negative); + template + double Forward(const InputType& input, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. - * @param target The target vector. + * @param input The propagated input activation. It should be + * concatenated anchor and positive samples. + * @param target The target vector. It should be negative samples. * @param output The calculated error. */ -template < - typename AnchorType, - typename PositiveType, - typename NegativeType, - typename OutputType - > - void Backward(const AnchorType& anchor, - const PositiveType& positive, - const NegativeType& negative, - OutputType&& output); + template + void Backward(const InputType& input, + const TargetType& target, + OutputType& output); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index 58a8b5b8e6..dce0968668 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -26,30 +26,30 @@ TripletMarginLoss::TripletMarginLoss( } template -template +template double TripletMarginLoss::Forward( - const AnchorType& anchor, - const PositiveType& positive, - const NegativeType& negative) + const InputType& input, + const TargetType& target) { + arma::mat anchor = input.submat(0, 0, input.n_rows / 2 - 1, input.n_cols - 1); + arma::mat positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, input.n_cols - 1); return std::max(0.0, arma::accu(arma::pow(anchor - positive, 2)) - - arma::accu(arma::pow(anchor - negative, 2)) + margin) / anchor.n_cols; + arma::accu(arma::pow(anchor - target, 2)) + margin) / anchor.n_cols; } template template < - typename AnchorType, - typename PositiveType, - typename NegativeType, + typename InputType, + typename TargetType, typename OutputType > void TripletMarginLoss::Backward( - const AnchorType& anchor, - const PositiveType& positive, - const NegativeType& negative, - OutputType&& output) + const InputType& input, + const TargetType& target, + OutputType& output) { - output = 2 * (negative - positive) / anchor.n_cols; + arma::mat positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, input.n_cols - 1); + output = 2 * (target - positive) / target.n_cols; } template diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 0c2c1bff4b..f277554bc5 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -904,7 +904,8 @@ TEST_CASE("MeanAbsolutePercentageErrorTest", "[LossFunctionsTest]") */ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) { - arma::mat anchor, positive, negative, output; + arma::mat anchor, positive, negative; + arma::mat input, target, output; TripletMarginLoss<> module; // Test the Forward function on a user generator input and compare it against @@ -912,13 +913,17 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) anchor = arma::mat("2 3 5"); positive = arma::mat("10 12 13"); negative = arma::mat("4 5 7"); - double error = module.Forward(std::move(anchor), - std::move(positive), std::move(negative)); + + input = { + {2, 3, 5}, + {10, 12, 13} + }; + + double error = module.Forward(input, negative); BOOST_REQUIRE_EQUAL(error, 66); // Test the Backward function. - module.Backward(std::move(anchor), - std::move(positive), std::move(negative), std::move(output)); + module.Backward(input, negative, output); // According to the used backward formula: // output = 2 * (negative - positive) / anchor.n_cols, // output * nofColumns / 2 + positive should be equal to negative. @@ -930,13 +935,16 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) anchor = arma::mat("4"); positive = arma::mat("7"); negative = arma::mat("1"); - error = module.Forward(std::move(anchor), - std::move(positive), std::move(negative)); + + input = arma::mat(2, 1); + input[0] = 4; + input[1] = 7; + + error = module.Forward(input, negative); BOOST_REQUIRE_EQUAL(error, 1.0); // Test the Backward function on a single input. - module.Backward(std::move(anchor), - std::move(positive), std::move(negative), std::move(output)); + module.Backward(input, negative, output); // Test whether the output is negative. BOOST_REQUIRE_EQUAL(arma::accu(output), -12); BOOST_REQUIRE_EQUAL(output.n_elem, 1); From 66b9e80793b5e869f99e7016eaf398706ad35193 Mon Sep 17 00:00:00 2001 From: Ayush Date: Sat, 5 Dec 2020 17:18:39 +0530 Subject: [PATCH 257/550] Minor Fixes for comments of PR#2208 --- .../loss_functions/triplet_margin_loss.hpp | 43 +++++++++++++++---- .../triplet_margin_loss_impl.hpp | 13 +++--- src/mlpack/tests/loss_functions_test.cpp | 9 ++-- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp index 7c1ab250dc..bf833b392f 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp @@ -4,6 +4,17 @@ * * Definition of the Triplet Margin Loss function. * + * For more information, refer the following paper. + * + * @code + * @article{Schroff2015, + * author = {Florian Schroff, Dmitry Kalenichenko, James Philbin}, + * title = {FaceNet: A Unified Embedding for Face Recognition and Clustering}, + * year = {2015}, + * url = {https://arxiv.org/abs/1503.03832}, + * } + * @endcode + * * 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 @@ -17,6 +28,16 @@ namespace mlpack { namespace ann /** Artificial Neural Network. */ { +/** + * The TripletMarginLoss function's objective is that the distance from the + * anchor input to the positive input is minimized, and the distance from the + * anchor input to the negative input is maximized. + * + * @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 @@ -24,9 +45,13 @@ template < class TripletMarginLoss { public: - /** * Create the TripletMarginLoss object with Hyperparameter margin. + * Hyperparameter margin defines the minimum value by which the distance + * between Anchor and Negative sample exceeds the distance between + * Anchor and Positive sample. + * The distance between two samples A and B is defined as square of L2 norm + * of A-B. */ TripletMarginLoss(const double margin = 1.0); @@ -34,17 +59,17 @@ class TripletMarginLoss * Computes the Triplet Margin Loss function. * * @param input The propagated input activation. It should be - * concatenated anchor and positive samples. + * concatenated anchor and positive samples. * @param target The target vector. It should be negative samples. */ template - double Forward(const InputType& input, const TargetType& target); - + typename InputType::elem_type Forward(const InputType& input, + const TargetType& target); /** * Ordinary feed backward pass of a neural network. * * @param input The propagated input activation. It should be - * concatenated anchor and positive samples. + * concatenated anchor and positive samples. * @param target The target vector. It should be negative samples. * @param output The calculated error. */ @@ -59,7 +84,7 @@ class TripletMarginLoss OutputDataType& OutputParameter() { return outputParameter; } //! Get the output parameter. - double& Margin() const { return margin; } + double Margin() const { return margin; } //! Modify the output parameter. double& Margin() { return margin; } @@ -75,12 +100,12 @@ class TripletMarginLoss //! The margin value used in calculating Triplet Margin Loss. double margin; -}; // class TripletLossMargin +}; // class TripletLossMargin -} //namespace ann +} // namespace ann } // namespace mlpack // include implementation. #include "triplet_margin_loss_impl.hpp" -#endif +#endif \ No newline at end of file diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index dce0968668..37be8db9b4 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -27,12 +27,14 @@ TripletMarginLoss::TripletMarginLoss( template template -double TripletMarginLoss::Forward( +typename InputType::elem_type +TripletMarginLoss::Forward( const InputType& input, const TargetType& target) { - arma::mat anchor = input.submat(0, 0, input.n_rows / 2 - 1, input.n_cols - 1); - arma::mat positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, input.n_cols - 1); + InputType anchor = input.submat(0, 0, input.n_rows / 2 - 1, input.n_cols - 1); + InputType positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, + input.n_cols - 1); return std::max(0.0, arma::accu(arma::pow(anchor - positive, 2)) - arma::accu(arma::pow(anchor - target, 2)) + margin) / anchor.n_cols; } @@ -48,7 +50,8 @@ void TripletMarginLoss::Backward( const TargetType& target, OutputType& output) { - arma::mat positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, input.n_cols - 1); + InputType positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, + input.n_cols - 1); output = 2 * (target - positive) / target.n_cols; } @@ -64,4 +67,4 @@ void TripletMarginLoss::serialize( } // namespace ann } // namespace mlpack -#endif +#endif \ No newline at end of file diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index f277554bc5..22c59cf798 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -908,16 +908,13 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) arma::mat input, target, output; TripletMarginLoss<> module; - // Test the Forward function on a user generator input and compare it against + // Test the Forward function on a user generated input and compare it against // the manually calculated result. anchor = arma::mat("2 3 5"); positive = arma::mat("10 12 13"); negative = arma::mat("4 5 7"); - input = { - {2, 3, 5}, - {10, 12, 13} - }; + input = { {2, 3, 5}, {10, 12, 13} }; double error = module.Forward(input, negative); BOOST_REQUIRE_EQUAL(error, 66); @@ -950,4 +947,4 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) BOOST_REQUIRE_EQUAL(output.n_elem, 1); } -BOOST_AUTO_TEST_SUITE_END(); +BOOST_AUTO_TEST_SUITE_END(); \ No newline at end of file From eb47d8c4af1963db548d555e914b97856e398b01 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sat, 5 Dec 2020 10:54:08 -0500 Subject: [PATCH 258/550] static code check error fix --- src/mlpack/methods/ann/layer/concatenate_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/concatenate_impl.hpp b/src/mlpack/methods/ann/layer/concatenate_impl.hpp index ba0060aa5f..bfede6c162 100644 --- a/src/mlpack/methods/ann/layer/concatenate_impl.hpp +++ b/src/mlpack/methods/ann/layer/concatenate_impl.hpp @@ -20,7 +20,8 @@ namespace mlpack { namespace ann /** Artificial Neural Network. */ { template -Concatenate::Concatenate() +Concatenate::Concatenate() : + inRows(0) { // Nothing to do here. } From b35ad950e9449e8ab7c2b710fdc50173f41d88ad Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Sat, 5 Dec 2020 14:59:37 -0500 Subject: [PATCH 259/550] Update src/mlpack/tests/feedforward_network_test.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 30bfd1d226..f7c0b99ea9 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -271,7 +271,7 @@ TEST_CASE("CheckCopyMovingConcatenateTest", "[FeedForwardNetworkTest]") // Check whether copy constructor is working or not. CheckCopyFunction<>(model1, input, output, 1); - // check moving constructor. + // Check moving constructor. FFN> *model2 = new FFN>(); model2->Predictors() = input; model2->Responses() = output; From 10f9b49dc0bf91f2a0dddd9b62cee5ac05616c30 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 6 Dec 2020 17:26:58 +0530 Subject: [PATCH 260/550] made some changes --- .../methods/ann/layer/recurrent_impl.hpp | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 975103df12..5b1b2d29b5 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -130,35 +130,44 @@ template size_t Recurrent::InputShape() const { - size_t inputShapeStartModule = boost::apply_visitor(InShapeVisitor(), startModule); - size_t inputShapeInputModule = boost::apply_visitor(InShapeVisitor(), inputModule); - size_t inputShapeFeedbackModule = boost::apply_visitor(InShapeVisitor(), feedbackModule); - size_t inputShapeTransferModule = boost::apply_visitor(InShapeVisitor(), transferModule); - - // Return the size of the first module that we have. + const size_t inputShapeStartModule = boost::apply_visitor(InShapeVisitor(), startModule); + // Return the input shape of the first module that we have. if (inputShapeStartModule != 0) - return inputShapeStartModule; - // If first module does not have any weights. - else { - // Return the size of the second module we have. - if (inputShapeInputModule != 0) - return inputShapeInputModule; - // If second module does not have any weights. + return inputShapeStartModule; + // If input shape of first module is 0 else { - // Return the size of the third module we have. - if (inputShapeFeedbackModule != 0) - return inputShapeFeedbackModule; - // If the third module does not have any weights. - else + // Return input shape of the second module that we have. + const size_t inputShapeInputModule = boost::apply_visitor(InShapeVisitor(), inputModule); + if (inputShapeInputModule != 0) { - // Return the size of the fourth module we have - if (inputShapeTransferModule != 0) - return inputShapeTransferModule; - // If the fourth module does not have any weights. + return inputShapeInputModule; + // If the input shape of second module is 0 else - return 0; + { + // Return input shape of the third module that we have. + const size_t inputShapeFeedbackModule = boost::apply_visitor(InShapeVisitor(), + feedbackModule); + if (inputShapeFeedbackModule != 0) + { + return inputShapeFeedbackModule; + // If the input shape of the third module is 0 + else + { + // Return the shape of the fourth module that we have. + const size_t inputShapeTransferModule = boost::apply_visitor(InShapeVisitor(), + transferModule); + if (inputShapeTransferModule != 0) + { + return inputShapeTransferModule; + } + // If the input shape of the fourth module is 0. + else + return 0; + } + } + } } } } From f654f9221683aaa1ef8935944c0d49593c107356 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 6 Dec 2020 18:53:24 +0530 Subject: [PATCH 261/550] fixing errors --- .../methods/ann/layer/recurrent_impl.hpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 5b1b2d29b5..0276318b0f 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -136,40 +136,40 @@ size_t Recurrent::InputShape() c { return inputShapeStartModule; // If input shape of first module is 0 + else + { + // Return input shape of the second module that we have. + const size_t inputShapeInputModule = boost::apply_visitor(InShapeVisitor(), inputModule); + if (inputShapeInputModule != 0) + { + return inputShapeInputModule; + // If the input shape of second module is 0 else { - // Return input shape of the second module that we have. - const size_t inputShapeInputModule = boost::apply_visitor(InShapeVisitor(), inputModule); - if (inputShapeInputModule != 0) + // Return input shape of the third module that we have. + const size_t inputShapeFeedbackModule = boost::apply_visitor(InShapeVisitor(), + feedbackModule); + if (inputShapeFeedbackModule != 0) { - return inputShapeInputModule; - // If the input shape of second module is 0 - else + return inputShapeFeedbackModule; + // If the input shape of the third module is 0 + else + { + // Return the shape of the fourth module that we have. + const size_t inputShapeTransferModule = boost::apply_visitor(InShapeVisitor(), + transferModule); + if (inputShapeTransferModule != 0) { - // Return input shape of the third module that we have. - const size_t inputShapeFeedbackModule = boost::apply_visitor(InShapeVisitor(), - feedbackModule); - if (inputShapeFeedbackModule != 0) - { - return inputShapeFeedbackModule; - // If the input shape of the third module is 0 - else - { - // Return the shape of the fourth module that we have. - const size_t inputShapeTransferModule = boost::apply_visitor(InShapeVisitor(), - transferModule); - if (inputShapeTransferModule != 0) - { - return inputShapeTransferModule; - } - // If the input shape of the fourth module is 0. - else - return 0; - } - } + return inputShapeTransferModule; } + // If the input shape of the fourth module is 0. + else + return 0; + } } } + } + } } } From f9f4c86aa30b37471d9a2ded3c39eac087d8241a Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 6 Dec 2020 19:24:35 +0530 Subject: [PATCH 262/550] fixing errors again --- src/mlpack/methods/ann/layer/recurrent_impl.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 0276318b0f..fae8c21672 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -135,7 +135,8 @@ size_t Recurrent::InputShape() c if (inputShapeStartModule != 0) { return inputShapeStartModule; - // If input shape of first module is 0 + } + // If input shape of first module is 0 else { // Return input shape of the second module that we have. @@ -143,7 +144,8 @@ size_t Recurrent::InputShape() c if (inputShapeInputModule != 0) { return inputShapeInputModule; - // If the input shape of second module is 0 + // If the input shape of second module is 0 + } else { // Return input shape of the third module that we have. @@ -152,7 +154,8 @@ size_t Recurrent::InputShape() c if (inputShapeFeedbackModule != 0) { return inputShapeFeedbackModule; - // If the input shape of the third module is 0 + // If the input shape of the third module is 0 + } else { // Return the shape of the fourth module that we have. @@ -166,10 +169,7 @@ size_t Recurrent::InputShape() c else return 0; } - } } - } - } } } From 788716c67f91545ef739b64ab02ceaccfd4d27f4 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 6 Dec 2020 10:21:07 -0500 Subject: [PATCH 263/550] update contributor --- COPYRIGHT.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 32ca43b3c6..907caf9d1a 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -138,6 +138,7 @@ Copyright: Copyright 2020, Nippun Sharma Copyright 2020, Rishabh Garg Copyright 2020, Sudhakar Brar + Copyright 2020, Alex Nguyen License: BSD-3-clause All rights reserved. From 19e30df98a67edd4f5c04cd4e66882824ce3ab54 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 6 Dec 2020 15:14:52 -0500 Subject: [PATCH 264/550] Ensure that Armadillo doesn't release memory with Armadillo 10+. --- src/mlpack/bindings/julia/julia_util.cpp | 88 +++++++++++++----------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/src/mlpack/bindings/julia/julia_util.cpp b/src/mlpack/bindings/julia/julia_util.cpp index d888b10296..4bf027fb9c 100644 --- a/src/mlpack/bindings/julia/julia_util.cpp +++ b/src/mlpack/bindings/julia/julia_util.cpp @@ -66,7 +66,7 @@ void IO_SetParamBool(const char* paramName, bool paramValue) * Call IO::SetParam>() to set the length. */ void IO_SetParamVectorStrLen(const char* paramName, - const size_t length) + const size_t length) { IO::GetParam>(paramName).clear(); IO::GetParam>(paramName).resize(length); @@ -77,8 +77,8 @@ void IO_SetParamVectorStrLen(const char* paramName, * Call IO::SetParam>() to set an individual element. */ void IO_SetParamVectorStrStr(const char* paramName, - const char* str, - const size_t element) + const char* str, + const size_t element) { IO::GetParam>(paramName)[element] = std::string(str); @@ -88,8 +88,8 @@ void IO_SetParamVectorStrStr(const char* paramName, * Call IO::SetParam>(). */ void IO_SetParamVectorInt(const char* paramName, - int* ints, - const size_t length) + int* ints, + const size_t length) { // Create a std::vector object; unfortunately this requires copying the // vector elements. @@ -106,10 +106,10 @@ void IO_SetParamVectorInt(const char* paramName, * Call IO::SetParam(). */ void IO_SetParamMat(const char* paramName, - double* memptr, - const size_t rows, - const size_t cols, - const bool pointsAsRows) + double* memptr, + const size_t rows, + const size_t cols, + const bool pointsAsRows) { // Create the matrix as an alias. arma::mat m(memptr, arma::uword(rows), arma::uword(cols), false, true); @@ -121,10 +121,10 @@ void IO_SetParamMat(const char* paramName, * Call IO::SetParam>(). */ void IO_SetParamUMat(const char* paramName, - size_t* memptr, - const size_t rows, - const size_t cols, - const bool pointsAsRows) + size_t* memptr, + const size_t rows, + const size_t cols, + const bool pointsAsRows) { // Create the matrix as an alias. arma::Mat m(memptr, arma::uword(rows), arma::uword(cols), false, @@ -138,8 +138,8 @@ void IO_SetParamUMat(const char* paramName, * Call IO::SetParam(). */ void IO_SetParamRow(const char* paramName, - double* memptr, - const size_t cols) + double* memptr, + const size_t cols) { arma::rowvec m(memptr, arma::uword(cols), false, true); IO::GetParam(paramName) = std::move(m); @@ -150,8 +150,8 @@ void IO_SetParamRow(const char* paramName, * Call IO::SetParam>(). */ void IO_SetParamURow(const char* paramName, - size_t* memptr, - const size_t cols) + size_t* memptr, + const size_t cols) { arma::Row m(memptr, arma::uword(cols), false, true); IO::GetParam>(paramName) = std::move(m); @@ -162,8 +162,8 @@ void IO_SetParamURow(const char* paramName, * Call IO::SetParam(). */ void IO_SetParamCol(const char* paramName, - double* memptr, - const size_t rows) + double* memptr, + const size_t rows) { arma::vec m(memptr, arma::uword(rows), false, true); IO::GetParam(paramName) = std::move(m); @@ -174,8 +174,8 @@ void IO_SetParamCol(const char* paramName, * Call IO::SetParam>(). */ void IO_SetParamUCol(const char* paramName, - size_t* memptr, - const size_t rows) + size_t* memptr, + const size_t rows) { arma::Col m(memptr, arma::uword(rows), false, true); IO::GetParam>(paramName) = std::move(m); @@ -186,11 +186,11 @@ void IO_SetParamUCol(const char* paramName, * Call IO::SetParam>(). */ void IO_SetParamMatWithInfo(const char* paramName, - bool* dimensions, - double* memptr, - const size_t rows, - const size_t cols, - const bool pointsAreRows) + bool* dimensions, + double* memptr, + const size_t rows, + const size_t cols, + const bool pointsAreRows) { data::DatasetInfo d(pointsAreRows ? cols : rows); for (size_t i = 0; i < d.Dimensionality(); ++i) @@ -316,6 +316,9 @@ double* IO_GetParamMat(const char* paramName) else { arma::access::rw(mat.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(mat.n_alloc) = 0; + #endif return mat.memptr(); } } @@ -344,20 +347,19 @@ size_t IO_GetParamUMatCols(const char* paramName) size_t* IO_GetParamUMat(const char* paramName) { arma::Mat& mat = IO::GetParam>(paramName); - - // Are we using preallocated memory? If so we have to handle this more - // carefully. if (mat.n_elem <= arma::arma_config::mat_prealloc) { // Copy the memory to something that we can give back to Julia. size_t* newMem = new size_t[mat.n_elem]; arma::arrayops::copy(newMem, mat.mem, mat.n_elem); - // We believe Julia will free it. Hopefully we are right. - return newMem; + return newMem; // We believe Julia will free it. Hopefully we are right. } else { arma::access::rw(mat.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(mat.n_alloc) = 0; + #endif return mat.memptr(); } } @@ -390,6 +392,9 @@ double* IO_GetParamCol(const char* paramName) else { arma::access::rw(vec.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(vec.n_alloc) = 0; + #endif return vec.memptr(); } } @@ -410,20 +415,19 @@ size_t IO_GetParamUColRows(const char* paramName) size_t* IO_GetParamUCol(const char* paramName) { arma::Col& vec = IO::GetParam>(paramName); - - // Are we using preallocated memory? If so we have to handle this more - // carefully. if (vec.n_elem <= arma::arma_config::mat_prealloc) { // Copy the memory to something we can give back to Julia. size_t* newMem = new size_t[vec.n_elem]; arma::arrayops::copy(newMem, vec.mem, vec.n_elem); - // We believe Julia will free it. Hopefully we are right. - return newMem; + return newMem; // We believe Julia will free it. Hopefully we are right. } else { arma::access::rw(vec.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(vec.n_alloc) = 0; + #endif return vec.memptr(); } } @@ -456,6 +460,9 @@ double* IO_GetParamRow(const char* paramName) else { arma::access::rw(vec.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(vec.n_alloc) = 0; + #endif return vec.memptr(); } } @@ -476,9 +483,6 @@ size_t IO_GetParamURowCols(const char* paramName) size_t* IO_GetParamURow(const char* paramName) { arma::Row& vec = IO::GetParam>(paramName); - - // Are we using preallocated memory? If so we have to handle this more - // carefully. if (vec.n_elem <= arma::arma_config::mat_prealloc) { // Copy the memory to something we can give back to Julia. @@ -489,6 +493,9 @@ size_t* IO_GetParamURow(const char* paramName) else { arma::access::rw(vec.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(vec.n_alloc) = 0; + #endif return vec.memptr(); } } @@ -547,6 +554,9 @@ double* IO_GetParamMatWithInfoPtr(const char* paramName) else { arma::access::rw(m.mem_state) = 1; + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(m.n_alloc) = 0; + #endif return m.memptr(); } } From 9ad6ac8f4c93dfdb40cfc53b2ef8ad5c1adac764 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 6 Dec 2020 15:15:24 -0500 Subject: [PATCH 265/550] Try to avoid accidental Armadillo 10 deallocations on Python. --- src/mlpack/bindings/python/mlpack/arma_util.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mlpack/bindings/python/mlpack/arma_util.hpp b/src/mlpack/bindings/python/mlpack/arma_util.hpp index af3a87d4e3..70f0dd1b3e 100644 --- a/src/mlpack/bindings/python/mlpack/arma_util.hpp +++ b/src/mlpack/bindings/python/mlpack/arma_util.hpp @@ -22,6 +22,12 @@ template void SetMemState(T& t, int state) { const_cast(t.mem_state) = state; + // If we just "released" the memory, so that the matrix does not own it, with + // Armadillo 10 we must also ensure that the matrix does not deallocate the + // memory by specifying `n_alloc = 0`. + #if ARMA_VERSION_MAJOR >= 10 + const_cast(t.n_alloc) = 0; + #endif } /** From be1cd87146df0f38fb0376b4b9e339203d4a2975 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 6 Dec 2020 15:16:32 -0500 Subject: [PATCH 266/550] Try to prevent deallocations with Armadillo 10 for Go bindings. --- src/mlpack/bindings/go/mlpack/capi/arma_util.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mlpack/bindings/go/mlpack/capi/arma_util.hpp b/src/mlpack/bindings/go/mlpack/capi/arma_util.hpp index 74629141f5..0c57590e26 100644 --- a/src/mlpack/bindings/go/mlpack/capi/arma_util.hpp +++ b/src/mlpack/bindings/go/mlpack/capi/arma_util.hpp @@ -37,6 +37,11 @@ inline typename T::elem_type* GetMemory(T& m) else { arma::access::rw(m.mem_state) = 1; + // With Armadillo 10 and newer, we must set `n_alloc` to 0 so that + // Armadillo does not deallocate the memory. + #if ARMA_VERSION_MAJOR >= 10 + arma::access::rw(m.n_alloc) = 0; + #endif return m.memptr(); } } From ff19f754f695a86d18fde3853bb2570578e0a4a7 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 6 Dec 2020 15:18:20 -0500 Subject: [PATCH 267/550] Restore typical Homebrew Julia installation. --- .ci/macos-steps.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index 7b98eb3d05..c437344050 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -21,11 +21,9 @@ steps: pip install cython numpy pandas zipp configparser fi - # Install Julia manually. - wget https://julialang-s3.julialang.org/bin/mac/x64/1.4/julia-1.4.2-mac64.dmg - sudo hdiutil mount julia-1.4.2-mac64.dmg - ls /Volumes/Julia-1.4.2/Julia-1.4.app/ - sudo cp -R /Volumes/Julia-1.4.2/Julia-1.4.app /Applications + if [ "a$(julia.version)" != "a" ]; then + brew cask install julia + fi git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf displayName: 'Install Build Dependencies' From 4b1f21758552e1e3097c1473b2148c0da04c2d0e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 6 Dec 2020 15:28:17 -0500 Subject: [PATCH 268/550] Re-add comments I accidentally removed. --- src/mlpack/bindings/julia/julia_util.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mlpack/bindings/julia/julia_util.cpp b/src/mlpack/bindings/julia/julia_util.cpp index 4bf027fb9c..ac8663eab0 100644 --- a/src/mlpack/bindings/julia/julia_util.cpp +++ b/src/mlpack/bindings/julia/julia_util.cpp @@ -347,6 +347,9 @@ size_t IO_GetParamUMatCols(const char* paramName) size_t* IO_GetParamUMat(const char* paramName) { arma::Mat& mat = IO::GetParam>(paramName); + + // Are we using preallocated memory? If so we have to handle this more + // carefully. if (mat.n_elem <= arma::arma_config::mat_prealloc) { // Copy the memory to something that we can give back to Julia. @@ -415,6 +418,9 @@ size_t IO_GetParamUColRows(const char* paramName) size_t* IO_GetParamUCol(const char* paramName) { arma::Col& vec = IO::GetParam>(paramName); + + // Are we using preallocated memory? If so we have to handle this more + // carefully. if (vec.n_elem <= arma::arma_config::mat_prealloc) { // Copy the memory to something we can give back to Julia. @@ -483,6 +489,9 @@ size_t IO_GetParamURowCols(const char* paramName) size_t* IO_GetParamURow(const char* paramName) { arma::Row& vec = IO::GetParam>(paramName); + + // Are we using preallocated memory? If so we have to handle this more + // carefully. if (vec.n_elem <= arma::arma_config::mat_prealloc) { // Copy the memory to something we can give back to Julia. From dd4f2c3c9763f81b7117788f1e96683c86956727 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:11:51 -0500 Subject: [PATCH 269/550] Update HISTORY.md Co-authored-by: Ryan Curtin --- HISTORY.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index a1a8ae1580..6e2ee62e7c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ ### mlpack ?.?.? ###### ????-??-?? - * HMM: calculate likelihood for data stream with/without pre-calculated emission probability + * HMM: add functions to calculate likelihood for data stream with/without + pre-calculated emission probability (#2142). ### mlpack 3.4.2 ###### 2020-10-26 From 0cad47fb833f858794f2a2f689728e347586677b Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:12:11 -0500 Subject: [PATCH 270/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 726b60ca47..d0f57cb831 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -306,7 +306,7 @@ class HMM * @return Log scale factor of the given sequence of emission at time t. */ double EmissionLogScaleFactor(const arma::vec& emissionLogProb, - arma::vec& forwardLogProb) const; + arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given emission probability up to time t, * storing the result in logLikelihood. From ef29ca6db3782ad93820a1659a9f0cb167600a19 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:12:27 -0500 Subject: [PATCH 271/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index d0f57cb831..56e4cc0c0c 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -318,8 +318,8 @@ class HMM * @param logLikelihood Log-likelihood of the given sequence of emission * probability up to time t-1 * @param forwardLogProb Vector in which forward probabilities will be saved. - * Passing forwardLogProb as an empty vector indicates the start of sequence - * or time t=0 + * Passing forwardLogProb as an empty vector indicates the start of the + * sequence (i.e. time t=0). * @return Log-likelihood of the given sequence of emission up to time t. */ double EmissionLogLikelihood(const arma::vec& emissionLogProb, From 499a94bbc1a67dd385f78c1ce02ee7ef19a88b6f Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:12:43 -0500 Subject: [PATCH 272/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 56e4cc0c0c..f984f9d478 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -301,8 +301,8 @@ class HMM * @param emissionLogProb emission probability at time t. * probability up to time t-1 * @param forwardLogProb Vector in which forward probabilities will be saved. - * Passing forwardLogProb as an empty vector indicates the start of sequence - * or time t=0 + * Passing forwardLogProb as an empty vector indicates the start of the + * sequence (i.e. time t=0). * @return Log scale factor of the given sequence of emission at time t. */ double EmissionLogScaleFactor(const arma::vec& emissionLogProb, From 9b047b2769854f5f0bed8c67fdfa66a08ec8e3c6 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:13:00 -0500 Subject: [PATCH 273/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index f984f9d478..ef7b70be96 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -323,8 +323,8 @@ class HMM * @return Log-likelihood of the given sequence of emission up to time t. */ double EmissionLogLikelihood(const arma::vec& emissionLogProb, - double &logLikelihood, - arma::vec& forwardLogProb) const; + double &logLikelihood, + arma::vec& forwardLogProb) const; /** * Compute the log of the scaling factor of the given data at time t. * To calculate the log-likelihood for the whole sequence, accumulate log From 8b714a84e1f52912621123e78de6cb41c37e5e3d Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:13:26 -0500 Subject: [PATCH 274/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index ef7b70be96..abad722437 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -299,7 +299,6 @@ class HMM * forwardLogProb vector. * * @param emissionLogProb emission probability at time t. - * probability up to time t-1 * @param forwardLogProb Vector in which forward probabilities will be saved. * Passing forwardLogProb as an empty vector indicates the start of the * sequence (i.e. time t=0). From bfffcd3bd73de7a209e124d5186ce3124f6e9872 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:15:18 -0500 Subject: [PATCH 275/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index abad722437..aa4e58b60a 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -315,7 +315,8 @@ class HMM * * @param emissionLogProb emission probability at time t. * @param logLikelihood Log-likelihood of the given sequence of emission - * probability up to time t-1 + * probability up to time t-1. This will be overwritten with the log-likelihood + * of the given emission probability up to time t. * @param forwardLogProb Vector in which forward probabilities will be saved. * Passing forwardLogProb as an empty vector indicates the start of the * sequence (i.e. time t=0). From a384e51c37b7de91bc7bd30d28143fc7da78665b Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:16:07 -0500 Subject: [PATCH 276/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index aa4e58b60a..69d7fecce3 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -327,8 +327,9 @@ class HMM arma::vec& forwardLogProb) const; /** * Compute the log of the scaling factor of the given data at time t. - * To calculate the log-likelihood for the whole sequence, accumulate log - * scale over the entire sequence. + * To calculate the log-likelihood for the whole sequence, accumulate the + * log scale factor (the return value of this function) over the entire + * sequence. * This is meant for incremental or streaming computation of the * log-likelihood of a sequence. For the first data point, provide an empty * forwardLogProb vector. From b1154511d7e782657b62d1d4f9629b4557978304 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:16:24 -0500 Subject: [PATCH 277/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 69d7fecce3..10fe1cc080 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -341,7 +341,7 @@ class HMM * @return Log scale factor of the given sequence of data up at time t. */ double LogScaleFactor(const arma::vec &data, - arma::vec& forwardLogProb) const; + arma::vec& forwardLogProb) const; /** * Compute the log-likelihood of the given data up to time t, storing the * result in logLikelihood. From 8ef0206a92a6104bff99c99396c6d4e0b8816c41 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:16:42 -0500 Subject: [PATCH 278/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 10fe1cc080..50166fc103 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -336,8 +336,8 @@ class HMM * * @param data observation at time t. * @param forwardLogProb Vector in which forward probabilities will be saved. - * Passing forwardLogProb as an empty vector indicates the start of sequence - * or time t=0 + * Passing forwardLogProb as an empty vector indicates the start of the + * sequence (i.e. time t=0). * @return Log scale factor of the given sequence of data up at time t. */ double LogScaleFactor(const arma::vec &data, From df99ef8a4bf2b1411fa0bf672ccee6e573e416c5 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:17:00 -0500 Subject: [PATCH 279/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 50166fc103..a6df706620 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -351,7 +351,7 @@ class HMM * * @param data observation at time t. * @param logLikelihood Log-likelihood of the given sequence of data - * up to time t-1 + * up to time t-1. * @param forwardLogProb Vector in which forward probabilities will be saved. * Passing forwardLogProb as an empty vector indicates the start of sequence * or time t=0 From f7c09a3e6e44b2875414d8c57f8b009a0d977082 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:17:15 -0500 Subject: [PATCH 280/550] Update src/mlpack/methods/hmm/hmm.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index a6df706620..d0f555f1d7 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -353,8 +353,8 @@ class HMM * @param logLikelihood Log-likelihood of the given sequence of data * up to time t-1. * @param forwardLogProb Vector in which forward probabilities will be saved. - * Passing forwardLogProb as an empty vector indicates the start of sequence - * or time t=0 + * Passing forwardLogProb as an empty vector indicates the start of the + * sequence (i.e. time t=0). * @return Log-likelihood of the given sequence of data up to time t. */ double LogLikelihood(const arma::vec &data, From 0118cddbd2a57fad725be7b903997a7c0c88efe0 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:17:35 -0500 Subject: [PATCH 281/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 92b3d3c16b..b446f447ab 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -535,7 +535,7 @@ double HMM::EmissionLogScaleFactor( double curLogScale; if (forwardLogProb.empty()) { - // start of sequence or time t=0 + // We are at the start of the sequence (i.e. time t=0). forwardLogProb = ForwardAtT0(emissionLogProb, curLogScale); } else From 4d2d3b29d0a11695db9e9122b40102cefd013f38 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:17:53 -0500 Subject: [PATCH 282/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index b446f447ab..cf763128bf 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -529,8 +529,8 @@ double HMM::LogLikelihood(const arma::mat& dataSeq) const */ template double HMM::EmissionLogScaleFactor( - const arma::vec& emissionLogProb, - arma::vec& forwardLogProb) const + const arma::vec& emissionLogProb, + arma::vec& forwardLogProb) const { double curLogScale; if (forwardLogProb.empty()) From 62d193ada83b9b0009cfe4fb8f2acad3458e81c5 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:18:07 -0500 Subject: [PATCH 283/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index cf763128bf..6652f11aba 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -552,9 +552,9 @@ double HMM::EmissionLogScaleFactor( */ template double HMM::EmissionLogLikelihood( - const arma::vec& emissionLogProb, - double &logLikelihood, - arma::vec& forwardLogProb) const + const arma::vec& emissionLogProb, + double& logLikelihood, + arma::vec& forwardLogProb) const { bool isStartOfSeq = forwardLogProb.empty(); double curLogScale = EmissionLogScaleFactor(emissionLogProb, From 92ba668ebd8196955b5bfa4e989f727bd6bb0e01 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:18:28 -0500 Subject: [PATCH 284/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 6652f11aba..62bedf658d 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -570,7 +570,7 @@ double HMM::EmissionLogLikelihood( */ template double HMM::LogScaleFactor(const arma::vec &data, - arma::vec& forwardLogProb) const + arma::vec& forwardLogProb) const { arma::vec emissionLogProb(logTransition.n_rows); From 0e1168de6ff66b2fb97203cc6e8dcb2f3bd13551 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:18:47 -0500 Subject: [PATCH 285/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 62bedf658d..12fc62a6b4 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -586,8 +586,8 @@ double HMM::LogScaleFactor(const arma::vec &data, * Compute the log-likelihood of the given data up to time t */ template -double HMM::LogLikelihood(const arma::vec &data, - double &logLikelihood, +double HMM::LogLikelihood(const arma::vec& data, + double& logLikelihood, arma::vec& forwardLogProb) const { bool isStartOfSeq = forwardLogProb.empty(); From a11df25c24c85a4578d5d0aa7c4abe3e7fc8cacc Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:19:05 -0500 Subject: [PATCH 286/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 12fc62a6b4..a28a9370f2 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -649,7 +649,7 @@ void HMM::Smooth(const arma::mat& dataSeq, */ template arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, - double& logScales) const + double& logScales) const { // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. From ab7aa8749239f3adcb4e61b90d28db7a872d7a86 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:19:22 -0500 Subject: [PATCH 287/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index a28a9370f2..a056130179 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -653,8 +653,6 @@ arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, { // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. - - ConvertToLogSpace(); arma::vec forwardLogProb(logTransition.n_rows); From 5ba630aca305f0c28aa3c36b713fdbbf5ffda707 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:19:37 -0500 Subject: [PATCH 288/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index a056130179..800ce3fcbb 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -667,7 +667,7 @@ arma::vec HMM::ForwardAtT0(const arma::vec& emissionLogProb, // Normalize probability. logScales = math::AccuLog(forwardLogProb); if (std::isfinite(logScales)) - forwardLogProb -= logScales; + forwardLogProb -= logScales; return forwardLogProb; } From 493f8dbc38dfeec708cde684d2a046f06aa1c02f Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:19:52 -0500 Subject: [PATCH 289/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 800ce3fcbb..8d1f561d41 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -683,7 +683,6 @@ arma::vec HMM::ForwardAtTn(const arma::vec& emissionLogProb, // Our goal is to calculate the forward probabilities: // P(X_k | o_{1:k}) for all possible states X_k, for each time point k. - arma::vec forwardLogProb(logTransition.n_rows); forwardLogProb.fill(-std::numeric_limits::infinity()); // Now compute the probabilities for each successive observation. From 1bcea5a8918875e206f82db362547a20ca1fe809 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:20:06 -0500 Subject: [PATCH 290/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 8d1f561d41..9015fbfbad 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -696,7 +696,7 @@ arma::vec HMM::ForwardAtTn(const arma::vec& emissionLogProb, // Normalize probability. logScales = math::AccuLog(forwardLogProb); if (std::isfinite(logScales)) - forwardLogProb -= logScales; + forwardLogProb -= logScales; return forwardLogProb; } From b32328c720ab4b2fe3123ba81b4f953d336f19d4 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:20:25 -0500 Subject: [PATCH 291/550] Update src/mlpack/methods/hmm/hmm_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/hmm/hmm_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 9015fbfbad..4a42cd6d38 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -725,8 +725,8 @@ void HMM::Forward(const arma::mat& dataSeq, arma::vec emissionLogProb(logTransition.n_rows); for (size_t state = 0; state < logTransition.n_rows; state++) { - emissionLogProb(state) = - emission[state].LogProbability(dataSeq.unsafe_col(0)); + emissionLogProb(state) = + emission[state].LogProbability(dataSeq.unsafe_col(0)); } forwardLogProb.col(0) = ForwardAtT0(emissionLogProb, logScales(0)); From 34adc0f478c01bfe64cbfc4625a28af545527586 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:20:41 -0500 Subject: [PATCH 292/550] Update src/mlpack/tests/hmm_test.cpp Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 69fe66e756..b22912c3e6 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -800,7 +800,7 @@ TEST_CASE("GaussianHMMPredictTest", "[HMMTest]") emission.Covariance(cov.at(i)); } - //100 2D observations + // 100 2D observations. arma::mat obs = { { -0.0424, -0.0395, -0.0336, -0.0294, -0.0299, -0.032, -0.0289, -0.0148, From 0013b068a03a6f7b77aed94e605a5f1996dab241 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:20:59 -0500 Subject: [PATCH 293/550] Update src/mlpack/tests/hmm_test.cpp Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index b22912c3e6..181293116b 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -835,7 +835,7 @@ TEST_CASE("GaussianHMMPredictTest", "[HMMTest]") }; //100 pre-calculated emission probabilities each for 10 states - std::vector emissionProb={ + std::vector emissionProb = { { -2.7301e+03, 1.7874e+00, -1.9428e+00, -3.6365e+00, -4.0397e-01, -1.5115e-01, -1.0328e+00, -1.1071e+00, 5.2876e-01, -1.0643e-01 }, { -2.3684e+03, 1.8059e+00, -2.2058e+00, -4.0514e+00, -5.0935e-01, From abdfc9ea1d697a25c8ed974d6cbc4b31129b7408 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:21:12 -0500 Subject: [PATCH 294/550] Update src/mlpack/tests/hmm_test.cpp Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 181293116b..64bebcf440 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -1040,7 +1040,7 @@ TEST_CASE("GaussianHMMPredictTest", "[HMMTest]") const double loglikelihoodRef = -2734.43; - //test loglikelihood calculation for the whole data + // Test log-likelihood calculation for the whole data. { const double loglikelihood = hmm.LogLikelihood(obs); REQUIRE(loglikelihood == Approx(loglikelihoodRef).epsilon(1e-3)); From 9d9c592d7edb78775f9fc59af81e049a04dfe6ff Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 7 Dec 2020 10:21:22 -0500 Subject: [PATCH 295/550] Update src/mlpack/tests/hmm_test.cpp Co-authored-by: Ryan Curtin --- src/mlpack/tests/hmm_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/hmm_test.cpp b/src/mlpack/tests/hmm_test.cpp index 64bebcf440..21135acd9a 100644 --- a/src/mlpack/tests/hmm_test.cpp +++ b/src/mlpack/tests/hmm_test.cpp @@ -1062,7 +1062,7 @@ TEST_CASE("GaussianHMMPredictTest", "[HMMTest]") // Test loglikelihood calculation in an incremental way. // It simulates the case where we have a stream of data. // In this case the accumulation of the log scales factor to calculate - // the logkielihood value is done outside of the loop + // the log-likelihood value is done outside of the loop { double loglikelihood = 0; arma::vec forwardLogProb; From 5b10897d762382444efa64b2dd874328e480b7a3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 8 Dec 2020 17:04:11 -0500 Subject: [PATCH 296/550] Clean up description and use Authors@R. --- src/mlpack/bindings/R/mlpack/DESCRIPTION.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mlpack/bindings/R/mlpack/DESCRIPTION.in b/src/mlpack/bindings/R/mlpack/DESCRIPTION.in index 9183f6bb62..dc583f0dd9 100644 --- a/src/mlpack/bindings/R/mlpack/DESCRIPTION.in +++ b/src/mlpack/bindings/R/mlpack/DESCRIPTION.in @@ -2,11 +2,11 @@ Package: mlpack Title: 'Rcpp' Integration for the 'mlpack' Library Version: @PACKAGE_VERSION@ Date: @PACKAGE_DATE@ -Author: mlpack Team -Maintainer: Ryan Curtin -Description: 'mlpack' is a fast, flexible machine learning library, written - in C++, that aims to provide fast, extensible implementations of - cutting-edge machine learning algorithms. +Authors@R: @AUTHORS_R@ +Description: A fast, flexible machine learning library, written in C++, that + aims to provide fast, extensible implementations of cutting-edge + machine learning algorithms. See also Curtin et al. (2018) + . SystemRequirements: A C++11 compiler. Versions 4.8.*, 4.9.* or later of GCC will be fine. License: BSD_3_clause + file LICENSE From 724402337d43086fa3ed2b52abf6e34be218af2d Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 8 Dec 2020 17:04:26 -0500 Subject: [PATCH 297/550] Use CMake to extract Authors@R list. --- src/mlpack/bindings/R/CMakeLists.txt | 84 ++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index a6e8ee16e1..23a4c69139 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -87,6 +87,90 @@ if (BUILD_R_BINDINGS) string(TIMESTAMP PACKAGE_DATE "%Y-%m-%d") + # We need to generate an Authors@R list using every single contributor in + # COPYRIGHT.txt. That takes a little bit of processing. + file(READ "${CMAKE_SOURCE_DIR}/COPYRIGHT.txt" COPYRIGHT_TXT_CONTENTS) + string(REGEX MATCHALL " Copyright [0-9-]*, ([^\n]*)\n" CONTRIBUTORS_LIST + "${COPYRIGHT_TXT_CONTENTS}") + + # These are the authors meant to be listed as 'authors' and not + # 'contributors'. If you contributed specifically to the R bindings, you + # should probably be listed here, so if you're not, open a PR to fix it! :) + set(SPECIAL_AUTHORS "Yashwant Singh Parihar" "Ryan Curtin" "Dirk Eddelbuettel" + "James Balamuta") + + string(CONCAT AUTHORS_R "c(\n" + " person(\"Yashwant\", \"Singh Parihar\", " + "email = \"yashwantsingh.sngh@gmail.com\", " + "role = c(\"aut\", \"ctb\", \"cph\")),\n" + " person(\"Ryan\", \"Curtin\", email = \"ryan@ratml.org\", " + "role = c(\"aut\", \"ctb\", \"cph\", \"cre\")),\n" + " person(\"Dirk\", \"Eddelbuettel\", email = \"edd@debian.org\", " + "role = c(\"aut\", \"ctb\", \"cph\")),\n" + " person(\"James\", \"Balamuta\", " + "email = \"james.balamuta@gmail.com\", " + "role = c(\"aut\", \"ctb\", \"cph\")),") + foreach (CONTRIBUTOR_LINE ${CONTRIBUTORS_LIST}) + # Strip 'Copyright XXXX-YYYY, '. + string(REGEX REPLACE "^ Copyright [0-9-]*, (.*)\n$" "\\1" + CONTRIBUTOR_FILTERED "${CONTRIBUTOR_LINE}") + + # Extract the email if it exists. + string(REGEX MATCH "^[^<]*<(.*)>.*$" HAS_EMAIL "${CONTRIBUTOR_FILTERED}") + + # The first name is just the first space-delimited word. (That may not + # always be right, but we have no way to know what is a first name and last + # name and therefore must assume.) + string(REGEX REPLACE "^([^ ]*) .*$" "\\1" CONTRIBUTOR_FIRST_NAME + "${CONTRIBUTOR_FILTERED}") + + # Extracting the last name is just the rest of the tokens, but the regex is + # different depending on whether we managed to get an email. + if (HAS_EMAIL) + string(REGEX REPLACE "^[^<]*<(.*)>.*$" "\\1" CONTRIBUTOR_EMAIL + "${CONTRIBUTOR_FILTERED}") + string(REGEX MATCH "^[^ ]* (.*) <.*$" CONTRIBUTOR_LAST_NAME + "${CONTRIBUTOR_FILTERED}") + if (NOT CONTRIBUTOR_LAST_NAME) + set (CONTRIBUTOR_LAST_NAME "") + else () + string(REGEX REPLACE "^[^ ]* (.*) <.*$" "\\1" CONTRIBUTOR_LAST_NAME + "${CONTRIBUTOR_FILTERED}") + endif () + + # Skip anyone already listed as an author. + if ("${CONTRIBUTOR_FIRST_NAME} ${CONTRIBUTOR_LAST_NAME}" IN_LIST + SPECIAL_AUTHORS) + continue() + endif () + + string(CONCAT AUTHORS_R "${AUTHORS_R}\n " + "person(\"${CONTRIBUTOR_FIRST_NAME}\", \"${CONTRIBUTOR_LAST_NAME}\", " + "email = \"${CONTRIBUTOR_EMAIL}\", role = c(\"ctb\", \"cph\")),") + + else () + # No email is available. So just get the last name. + string(REGEX MATCH "^[^ ]* (.*)$" CONTRIBUTOR_LAST_NAME + "${CONTRIBUTOR_FILTERED}") + if (NOT CONTRIBUTOR_LAST_NAME) + set (CONTRIBUTOR_LAST_NAME "") + endif () + + # Skip anyone already listed as an author. + if ("${CONTRIBUTOR_FIRST_NAME} ${CONTRIBUTOR_LAST_NAME}" IN_LIST + SPECIAL_AUTHORS) + continue() + endif () + + string(CONCAT AUTHORS_R "${AUTHORS_R}\n " + "person(\"${CONTRIBUTOR_FIRST_NAME}\", \"${CONTRIBUTOR_LAST_NAME}\", " + "role = c(\"ctb\", \"cph\")),") + endif () + endforeach () + # We also have to remove the final comma... + string(REGEX REPLACE ",$" "" AUTHORS_R_OUT "${AUTHORS_R}") + set(AUTHORS_R "${AUTHORS_R_OUT})") + configure_file(${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/mlpack/DESCRIPTION.in ${CMAKE_CURRENT_BINARY_DIR}/mlpack/DESCRIPTION @ONLY) From 91a7ca1d3068456393d8073df783c2e3e386f2f5 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 8 Dec 2020 17:14:54 -0500 Subject: [PATCH 298/550] Oops, set last name correctly for no-email contributors. --- src/mlpack/bindings/R/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index 23a4c69139..d2c5b46dea 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -154,6 +154,9 @@ if (BUILD_R_BINDINGS) "${CONTRIBUTOR_FILTERED}") if (NOT CONTRIBUTOR_LAST_NAME) set (CONTRIBUTOR_LAST_NAME "") + else () + string(REGEX REPLACE "^[^ ]* (.*)$" "\\1" CONTRIBUTOR_LAST_NAME + "${CONTRIBUTOR_FILTERED}") endif () # Skip anyone already listed as an author. From 107cb48d2f646aaff5f3bd535c532dcc80729dac Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 8 Dec 2020 19:55:27 -0500 Subject: [PATCH 299/550] Add finalizers to mlpack objects. --- CMake/julia/AppendType.cmake | 11 ++++++++++- CMake/julia/ConfigureJuliaHCPP.cmake | 9 +++++++++ src/mlpack/bindings/julia/print_param_defn.hpp | 18 ++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CMake/julia/AppendType.cmake b/CMake/julia/AppendType.cmake index 299be1c6a4..a3b5d2aea6 100644 --- a/CMake/julia/AppendType.cmake +++ b/CMake/julia/AppendType.cmake @@ -32,8 +32,17 @@ function(append_type TYPES_FILE PROGRAM_NAME PROGRAM_MAIN_FILE) # function. file(APPEND "${TYPES_FILE}" - "struct ${MODEL_SAFE_TYPE}\n" + "mutable struct ${MODEL_SAFE_TYPE}\n" " ptr::Ptr{Nothing}\n" + "\n" + " # Construct object and set finalizer to free memory.\n" + " function ${MODEL_SAFE_TYPE}(ptr::Ptr{Nothing})::${MODEL_SAFE_TYPE}\n" + " result = new(ptr)\n" + " finalizer(\n" + " x -> _Internal.${PROGRAM_NAME}_internal.Delete${MODEL_SAFE_TYPE}(x.ptr),\n" + " result)\n" + " return result\n" + " end\n" "end\n" "\n") endif () diff --git a/CMake/julia/ConfigureJuliaHCPP.cmake b/CMake/julia/ConfigureJuliaHCPP.cmake index 1fb9a4b4be..38c7be5cbf 100644 --- a/CMake/julia/ConfigureJuliaHCPP.cmake +++ b/CMake/julia/ConfigureJuliaHCPP.cmake @@ -29,6 +29,8 @@ if (${NUM_MODEL_TYPES} GREATER 0) void* IO_GetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName); // Set the pointer to a ${MODEL_TYPE} parameter. void IO_SetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName, void* ptr); +// Delete a ${MODEL_TYPE} pointer. +void Delete${MODEL_SAFE_TYPE}Ptr(void* ptr); // Serialize a ${MODEL_TYPE} pointer. char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length); // Deserialize a ${MODEL_TYPE} pointer. @@ -50,6 +52,13 @@ void IO_SetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName, void* ptr) IO::SetPassed(paramName); } +// Delete a ${MODEL_TYPE} pointer. +void Delete${MODEL_SAFE_TYPE}Ptr(void* ptr) +{ + ${MODEL_TYPE}* modelPtr = (${MODEL_TYPE}*) ptr; + delete modelPtr; +} + // Serialize a ${MODEL_TYPE} pointer. char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length) { diff --git a/src/mlpack/bindings/julia/print_param_defn.hpp b/src/mlpack/bindings/julia/print_param_defn.hpp index 450b614d5b..51a47d39fd 100644 --- a/src/mlpack/bindings/julia/print_param_defn.hpp +++ b/src/mlpack/bindings/julia/print_param_defn.hpp @@ -59,15 +59,20 @@ void PrintParamDefn( // import ... // // function IOGetParam(paramName::String) - // (ccall((:IOGetParamPtr, Library), + // (ccall((:IO_GetParamPtr, Library), // Ptr{Nothing}, (Cstring,), paramName)) // end // // function IOSetParam(paramName::String, model::) - // ccall((:IOSetParamPtr, Library), Nothing, + // ccall((:IO_SetParamPtr, Library), Nothing, // (Cstring, Ptr{Nothing}), paramName, model.ptr) // end // + // function Delete(ptr::Ptr{Nothing}) + // ccall((:DeletePtr, Library), Nothing, + // (Ptr{Nothing},), ptr) + // end + // // function serialize(stream::IO, model::) // buf_len = UInt[0] // buffer = ccall((:SerializePtr, Library), @@ -111,6 +116,15 @@ void PrintParamDefn( std::cout << "end" << std::endl; std::cout << std::endl; + // Next, Delete(). + std::cout << "# Delete an instantiated model pointer." << std::endl; + std::cout << "function Delete" << type << "(ptr::Ptr{Nothing})" + << std::endl; + std::cout << " ccall((:Delete" << type << "Ptr, " << programName + << "Library), Nothing, (Ptr{Nothing},), ptr)" << std::endl; + std::cout << "end" << std::endl; + std::cout << std::endl; + // Now the serialization functionality. std::cout << "# Serialize a model to the given stream." << std::endl; std::cout << "function serialize" << type << "(stream::IO, model::" << type From d8c77a382de9fe08b255b7360eb515fb4f570244 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 8 Dec 2020 20:03:58 -0500 Subject: [PATCH 300/550] Update HISTORY. --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index cfff16dff2..6acb34b51e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,8 @@ * Add `BUILD_DOCS` CMake option to control whether Doxygen documentation is built (default ON) (#2730). + * Add finalizers to Julia binding model types to fix memory handling (#2756). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. From 11410db316d2ba66178f20e2e5fd16409b6b8d0e Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 9 Dec 2020 15:47:58 +0530 Subject: [PATCH 301/550] Update src/mlpack/methods/ann/layer/recurrent_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/recurrent_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index fae8c21672..905ead9764 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -136,7 +136,7 @@ size_t Recurrent::InputShape() c { return inputShapeStartModule; } - // If input shape of first module is 0 + // If input shape of first module is 0. else { // Return input shape of the second module that we have. From cfa26a6b20220d9b616bddf89866384a0c7571a3 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 9 Dec 2020 15:52:39 +0530 Subject: [PATCH 302/550] added stops --- src/mlpack/methods/ann/layer/recurrent_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/recurrent_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_impl.hpp index 905ead9764..e6b933bd20 100644 --- a/src/mlpack/methods/ann/layer/recurrent_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_impl.hpp @@ -144,7 +144,7 @@ size_t Recurrent::InputShape() c if (inputShapeInputModule != 0) { return inputShapeInputModule; - // If the input shape of second module is 0 + // If the input shape of second module is 0. } else { @@ -154,7 +154,7 @@ size_t Recurrent::InputShape() c if (inputShapeFeedbackModule != 0) { return inputShapeFeedbackModule; - // If the input shape of the third module is 0 + // If the input shape of the third module is 0. } else { From 203d57a8cbe50865d89510f240b87dd7c206795c Mon Sep 17 00:00:00 2001 From: gauravghati Date: Thu, 10 Dec 2020 15:14:46 +0530 Subject: [PATCH 303/550] LSTM copy and move construction --- src/mlpack/methods/ann/layer/lstm.hpp | 12 +++ src/mlpack/methods/ann/layer/lstm_impl.hpp | 88 ++++++++++++++++++++++ src/mlpack/tests/ann_layer_test.cpp | 34 +++++++++ 3 files changed, 134 insertions(+) diff --git a/src/mlpack/methods/ann/layer/lstm.hpp b/src/mlpack/methods/ann/layer/lstm.hpp index 1941778ce9..d535f0ee2b 100644 --- a/src/mlpack/methods/ann/layer/lstm.hpp +++ b/src/mlpack/methods/ann/layer/lstm.hpp @@ -76,6 +76,18 @@ class LSTM const size_t outSize, const size_t rho = std::numeric_limits::max()); + //! Copy constructor. + LSTM(const LSTM& layer); + + //! Move constructor. + LSTM(LSTM&&); + + //! Copy assignment operator. + LSTM& operator=(const LSTM& layer); + + //! Move assignment operator. + LSTM& operator=(LSTM&& layer); + /** * Ordinary feed-forward pass of a neural network, evaluating the function * f(x) by propagating the activity forward through f. diff --git a/src/mlpack/methods/ann/layer/lstm_impl.hpp b/src/mlpack/methods/ann/layer/lstm_impl.hpp index 36dd9f1be3..e298011e84 100644 --- a/src/mlpack/methods/ann/layer/lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/lstm_impl.hpp @@ -24,6 +24,94 @@ LSTM::LSTM() // Nothing to do here. } +template +LSTM::LSTM( + const LSTM& layer) : + inSize(layer.inSize), + outSize(layer.outSize), + rho(layer.rho), + forwardStep(layer.forwardStep), + backwardStep(layer.backwardStep), + gradientStep(layer.gradientStep), + weights(layer.weights), + batchSize(layer.batchSize), + batchStep(layer.batchStep), + gradientStepIdx(layer.gradientStepIdx), + rhoSize(layer.rho), + bpttSteps(layer.bpttSteps) +{ + // Nothing to do here. + std::cout << "LSTM Constructor \n"; +} + +template +LSTM::LSTM( + LSTM&& layer) : + inSize(std::move(layer.inSize)), + outSize(std::move(layer.outSize)), + rho(std::move(layer.rho)), + forwardStep(std::move(layer.forwardStep)), + backwardStep(std::move(layer.backwardStep)), + gradientStep(std::move(layer.gradientStep)), + weights(std::move(layer.weights)), + batchSize(std::move(layer.batchSize)), + batchStep(std::move(layer.batchStep)), + gradientStepIdx(std::move(layer.gradientStepIdx)), + rhoSize(std::move(layer.rho)), + bpttSteps(std::move(layer.bpttSteps)) +{ + // Nothing to do here. + std::cout << "LSTM Constructor \n"; +} + +template +LSTM& +LSTM :: operator=(const LSTM& layer) +{ + if(this != &layer) + { + inSize = layer.inSize; + outSize = layer.outSize; + rho = layer.rho; + forwardStep = layer.forwardStep; + backwardStep = layer.backwardStep; + gradientStep = layer.gradientStep; + weights = layer.weights; + batchSize = layer.batchSize; + batchStep = layer.batchStep; + gradientStepIdx = layer.gradientStepIdx; + grad = layer.grad; + rhoSize = layer.rho; + bpttSteps = layer.bpttSteps; + std::cout << "LSTM Constructor \n"; + } + return *this; +} + +template +LSTM& +LSTM :: operator=(LSTM&& layer) +{ + if(this != &layer) + { + inSize = std::move(layer.inSize); + outSize = std::move(layer.outSize); + rho = std::move(layer.rho); + forwardStep = std::move(layer.forwardStep); + backwardStep = std::move(layer.backwardStep); + gradientStep = std::move(layer.gradientStep); + weights = std::move(layer.weights); + batchSize = std::move(layer.batchSize); + batchStep = std::move(layer.batchStep); + gradientStepIdx = std::move(layer.gradientStepIdx); + grad = std::move(layer.grad); + rhoSize = std::move(layer.rho); + bpttSteps = std::move(layer.bpttSteps); + std::cout << "LSTM Constructor \n"; + } + return *this; +} + template LSTM::LSTM( const size_t inSize, const size_t outSize, const size_t rho) : diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 3950c1a2fd..def0c56a6b 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -1263,6 +1263,40 @@ TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]") CheckRNNMoveFunction<>(model2, input, target, 1); } +/** + * Check whether copying and moving network with LSTM is working or not. + */ +TEST_CASE("CheckCopyMoveLSTMTest", "[ANNLayerTest]") +{ + arma::cube input = arma::randu(1, 1, 5); + arma::cube target = arma::ones(1, 1, 5); + const size_t rho = 5; + + RNN > *model1 = + new RNN >(rho); + model1->Predictors() = input; + model1->Responses() = target; + model1->Add >(); + model1->Add >(1, 10); + model1->Add >(10, 3, rho); + model1->Add >(); + + RNN > *model2 = + new RNN >(rho); + model2->Predictors() = input; + model2->Responses() = target; + model2->Add >(); + model2->Add >(1, 10); + model2->Add >(10, 3, rho); + model2->Add >(); + + // Check whether copy constructor is working or not. + CheckRNNCopyFunction<>(model1, input, target, 1); + + // Check whether move constructor is working or not. + CheckRNNMoveFunction<>(model2, input, target, 1); +} + /** * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell * state. Besides output, the overloaded function provides read access to cell From 045f772e79be679fea03cc851950511678cbabe2 Mon Sep 17 00:00:00 2001 From: gauravghati Date: Thu, 10 Dec 2020 18:21:16 +0530 Subject: [PATCH 304/550] removed print state --- src/mlpack/methods/ann/layer/lstm_impl.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lstm_impl.hpp b/src/mlpack/methods/ann/layer/lstm_impl.hpp index e298011e84..8c608198b6 100644 --- a/src/mlpack/methods/ann/layer/lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/lstm_impl.hpp @@ -41,7 +41,6 @@ LSTM::LSTM( bpttSteps(layer.bpttSteps) { // Nothing to do here. - std::cout << "LSTM Constructor \n"; } template @@ -61,7 +60,6 @@ LSTM::LSTM( bpttSteps(std::move(layer.bpttSteps)) { // Nothing to do here. - std::cout << "LSTM Constructor \n"; } template @@ -83,7 +81,6 @@ LSTM :: operator=(const LSTM& layer) grad = layer.grad; rhoSize = layer.rho; bpttSteps = layer.bpttSteps; - std::cout << "LSTM Constructor \n"; } return *this; } @@ -107,7 +104,6 @@ LSTM :: operator=(LSTM&& layer) grad = std::move(layer.grad); rhoSize = std::move(layer.rho); bpttSteps = std::move(layer.bpttSteps); - std::cout << "LSTM Constructor \n"; } return *this; } From e96ed1e52ec8536aa50cdc62bc1c7b1c896b35fc Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 10 Dec 2020 09:33:17 -0500 Subject: [PATCH 305/550] Fix some typos and clarify documentation. --- .../methods/preprocess/preprocess_split_main.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/mlpack/methods/preprocess/preprocess_split_main.cpp b/src/mlpack/methods/preprocess/preprocess_split_main.cpp index 357450f516..8b935e16db 100644 --- a/src/mlpack/methods/preprocess/preprocess_split_main.cpp +++ b/src/mlpack/methods/preprocess/preprocess_split_main.cpp @@ -35,7 +35,7 @@ BINDING_LONG_DESC( PRINT_PARAM_STRING("training") + " and " + PRINT_PARAM_STRING("test") + " output parameters." "\n\n" - "Optionally, labels can be also be split along with the data by specifying " + "Optionally, labels can also be split along with the data by specifying " "the " + PRINT_PARAM_STRING("input_labels") + " parameter. Splitting " "labels works the same way as splitting the data. The output training and " "test labels may be saved with the " + @@ -96,7 +96,7 @@ PARAM_DOUBLE_IN("test_ratio", "Ratio of test set; if not set," "the ratio defaults to 0.2", "r", 0.2); PARAM_INT_IN("seed", "Random seed (0 for std::time(NULL)).", "s", 0); -PARAM_FLAG("no_shuffle", "Avoid shuffling and splitting the data.", "S"); +PARAM_FLAG("no_shuffle", "Avoid shuffling the data before splitting.", "S"); PARAM_FLAG("stratify_data", "Stratify the data according to labels", "z") using namespace mlpack; @@ -141,12 +141,6 @@ static void mlpackMain() [](double x) { return x >= 0.0 && x <= 1.0; }, true, "test ratio must be between 0.0 and 1.0"); - if (!IO::HasParam("test_ratio")) // If test_ratio is not set, warn the user. - { - Log::Warn << "You did not specify " << PRINT_PARAM_STRING("test_ratio") - << ", so it will be automatically set to 0.2." << endl; - } - // Load the data. arma::mat& data = IO::GetParam("input"); From 2ca2ee1fdd09000fc36073a5ee21961a34f80e84 Mon Sep 17 00:00:00 2001 From: gauravghati Date: Fri, 11 Dec 2020 06:29:07 +0530 Subject: [PATCH 306/550] style changes --- src/mlpack/methods/ann/layer/lstm_impl.hpp | 68 +++++++++++----------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/mlpack/methods/ann/layer/lstm_impl.hpp b/src/mlpack/methods/ann/layer/lstm_impl.hpp index 8c608198b6..b1bd784194 100644 --- a/src/mlpack/methods/ann/layer/lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/lstm_impl.hpp @@ -66,46 +66,46 @@ template LSTM& LSTM :: operator=(const LSTM& layer) { - if(this != &layer) - { - inSize = layer.inSize; - outSize = layer.outSize; - rho = layer.rho; - forwardStep = layer.forwardStep; - backwardStep = layer.backwardStep; - gradientStep = layer.gradientStep; - weights = layer.weights; - batchSize = layer.batchSize; - batchStep = layer.batchStep; - gradientStepIdx = layer.gradientStepIdx; - grad = layer.grad; - rhoSize = layer.rho; - bpttSteps = layer.bpttSteps; - } - return *this; + if (this != &layer) + { + inSize = layer.inSize; + outSize = layer.outSize; + rho = layer.rho; + forwardStep = layer.forwardStep; + backwardStep = layer.backwardStep; + gradientStep = layer.gradientStep; + weights = layer.weights; + batchSize = layer.batchSize; + batchStep = layer.batchStep; + gradientStepIdx = layer.gradientStepIdx; + grad = layer.grad; + rhoSize = layer.rho; + bpttSteps = layer.bpttSteps; + } + return *this; } template LSTM& LSTM :: operator=(LSTM&& layer) { - if(this != &layer) - { - inSize = std::move(layer.inSize); - outSize = std::move(layer.outSize); - rho = std::move(layer.rho); - forwardStep = std::move(layer.forwardStep); - backwardStep = std::move(layer.backwardStep); - gradientStep = std::move(layer.gradientStep); - weights = std::move(layer.weights); - batchSize = std::move(layer.batchSize); - batchStep = std::move(layer.batchStep); - gradientStepIdx = std::move(layer.gradientStepIdx); - grad = std::move(layer.grad); - rhoSize = std::move(layer.rho); - bpttSteps = std::move(layer.bpttSteps); - } - return *this; + if (this != &layer) + { + inSize = std::move(layer.inSize); + outSize = std::move(layer.outSize); + rho = std::move(layer.rho); + forwardStep = std::move(layer.forwardStep); + backwardStep = std::move(layer.backwardStep); + gradientStep = std::move(layer.gradientStep); + weights = std::move(layer.weights); + batchSize = std::move(layer.batchSize); + batchStep = std::move(layer.batchStep); + gradientStepIdx = std::move(layer.gradientStepIdx); + grad = std::move(layer.grad); + rhoSize = std::move(layer.rho); + bpttSteps = std::move(layer.bpttSteps); + } + return *this; } template From 86c4105841477db899ef6192501b54eb5aa1eb2f Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 10:47:44 +0530 Subject: [PATCH 307/550] added test for FFN --- src/mlpack/tests/feedforward_network_test.cpp | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index f7c0b99ea9..00a91f0e9c 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -908,3 +908,41 @@ TEST_CASE("OptimizerTest", "[FeedForwardNetworkTest]") ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); model.Train(trainData, trainLabels, opt); } + +/** + * Test to see if an exception is thrown when input with + * wrong shape is provided to a FFN. + */ +TEST_CASE("CheckInputShapeTest", "[FeedForwardNetworkTest]") +{ + // Load the dataset. + arma::mat trainData; + data::Load("thyroid_train.csv", trainData, true); + + arma::mat trainLabels = trainData.row(trainData.n_rows - 1); + trainData.shed_row(trainData.n_rows - 1); + + arma::mat testData; + data::Load("thyroid_test.csv", testData, true); + + arma::mat testLabels = testData.row(testData.n_rows - 1); + testData.shed_row(testData.n_rows - 1); + + FFN, RandomInitialization, CustomLayer<> > model; + // Purposely putting wrong input shape so that error is thrown + model.Add >(trainData.n_rows - 3, 8); + model.Add >(); + model.Add >(8, 3); + model.Add >(); + + std::string expectedMsg = "FFN<>::Train: "; + expectedMsg += "the first layer of the network expects "; + expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; + expectedMsg += "but the input shape has " + std::to_string(trainData.n_rows) + " dimensions! "; + + ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); + + REQUIRE_THROWS_MATCHES(model.Train(trainData, trainLabels, opt), + std::logic_error, + expectedMsg); +} From 818011bcf4d75a760a14254067d68680d3a6108f Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 11:55:46 +0530 Subject: [PATCH 308/550] added tests for RNN --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- src/mlpack/tests/recurrent_network_test.cpp | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 00a91f0e9c..9398c75240 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -944,5 +944,5 @@ TEST_CASE("CheckInputShapeTest", "[FeedForwardNetworkTest]") REQUIRE_THROWS_MATCHES(model.Train(trainData, trainLabels, opt), std::logic_error, - expectedMsg); + Message(expectedMsg)); } diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 987c808ef2..0d69bcf40f 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -868,3 +868,68 @@ TEST_CASE("LargeRhoValueRnnTest", "[RecurrentNetworkTest]") model.Train(inputs[0], targets[0], opt); INFO("Training over"); } + +/** + * Test to make sure that an error is thrown when input with + * wrong input shape is provided to a RNN. + */ +TEST_CASE("CheckInputShapeTest", "[RecurrentNetworkTest]") +{ + const size_t rho = 10; + + // Generate 12 (2 * 6) noisy sines. A single sine contains rho + // points/features. + arma::cube input; + arma::mat labelsTemp; + GenerateNoisySines(input, labelsTemp, rho, 6); + + arma::cube labels = arma::zeros(1, labelsTemp.n_cols, rho); + for (size_t i = 0; i < labelsTemp.n_cols; ++i) + { + const int value = arma::as_scalar(arma::find( + arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; + labels.tube(0, i).fill(value); + } + + /** + * Construct a network with 1 input unit, 4 hidden units and 10 output + * units. The hidden layer is connected to itself. The network structure + * looks like: + * + * Input Hidden Output + * Layer(1) Layer(4) Layer(10) + * +-----+ +-----+ +-----+ + * | | | | | | + * | +------>| +------>| | + * | | ..>| | | | + * +-----+ . +--+--+ +-----+ + * . . + * . . + * ....... + */ + Add<> add(4); + // Purposely providing wrong input shape of 3. + // The correct input shape is 1. + Linear<> lookup(3, 4); + SigmoidLayer<> sigmoidLayer; + Linear<> linear(4, 4); + Recurrent<>* recurrent = new Recurrent<>(add, lookup, linear, + sigmoidLayer, rho); + + RNN<> model(rho); + model.Add >(); + model.Add(recurrent); + model.Add >(4, 10); + model.Add >(); + + std::string expectedMsg = "RNN<>::Train: "; + expectedMsg += "the first layer of the network expects "; + expectedMsg += std::to_string(3) + " elements, "; + expectedMsg += "but the input shape has " + std::to_string(1) + " dimensions! " + + StandardSGD opt(0.1, 1, input.n_cols /* 1 epoch */, -100); + + REQUIRE_THROWS_MATCHES(model.Train(input, labels, opt), + std::logic_error, + Message(expectedMsg)); +} From 0c256c8fbfb6e46d11db0806a0c63da802e279d0 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 12:43:57 +0530 Subject: [PATCH 309/550] fixing errors --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- src/mlpack/tests/recurrent_network_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 9398c75240..abd392c720 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -944,5 +944,5 @@ TEST_CASE("CheckInputShapeTest", "[FeedForwardNetworkTest]") REQUIRE_THROWS_MATCHES(model.Train(trainData, trainLabels, opt), std::logic_error, - Message(expectedMsg)); + Catch::Matchers::Message(expectedMsg)); } diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 0d69bcf40f..6b3c1730a3 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -931,5 +931,5 @@ TEST_CASE("CheckInputShapeTest", "[RecurrentNetworkTest]") REQUIRE_THROWS_MATCHES(model.Train(input, labels, opt), std::logic_error, - Message(expectedMsg)); + Catch::Matchers::Message(expectedMsg)); } From 5c58eb01f012cedc689bb6d66dd2ec9c0a8850a6 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 13:21:50 +0530 Subject: [PATCH 310/550] added ; --- src/mlpack/tests/recurrent_network_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 6b3c1730a3..9318154b89 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -925,7 +925,7 @@ TEST_CASE("CheckInputShapeTest", "[RecurrentNetworkTest]") std::string expectedMsg = "RNN<>::Train: "; expectedMsg += "the first layer of the network expects "; expectedMsg += std::to_string(3) + " elements, "; - expectedMsg += "but the input shape has " + std::to_string(1) + " dimensions! " + expectedMsg += "but the input shape has " + std::to_string(1) + " dimensions! "; StandardSGD opt(0.1, 1, input.n_cols /* 1 epoch */, -100); From d0aa3de850a58f8bc76dde91dfa6e9a28cc2e011 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 14:11:15 +0530 Subject: [PATCH 311/550] changed names of tests --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- src/mlpack/tests/recurrent_network_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index abd392c720..ee501871dc 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -913,7 +913,7 @@ TEST_CASE("OptimizerTest", "[FeedForwardNetworkTest]") * Test to see if an exception is thrown when input with * wrong shape is provided to a FFN. */ -TEST_CASE("CheckInputShapeTest", "[FeedForwardNetworkTest]") +TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") { // Load the dataset. arma::mat trainData; diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 9318154b89..d02f5a18e4 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -873,7 +873,7 @@ TEST_CASE("LargeRhoValueRnnTest", "[RecurrentNetworkTest]") * Test to make sure that an error is thrown when input with * wrong input shape is provided to a RNN. */ -TEST_CASE("CheckInputShapeTest", "[RecurrentNetworkTest]") +TEST_CASE("RNNCheckInputShapeTest", "[RecurrentNetworkTest]") { const size_t rho = 10; From 684dd5e513d8183fdb89e9f7be063b1746b6a5d6 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 15:55:47 +0530 Subject: [PATCH 312/550] fixes --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- src/mlpack/tests/recurrent_network_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index ee501871dc..17cf23eab4 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -938,7 +938,7 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") std::string expectedMsg = "FFN<>::Train: "; expectedMsg += "the first layer of the network expects "; expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; - expectedMsg += "but the input shape has " + std::to_string(trainData.n_rows) + " dimensions! "; + expectedMsg += "but the input has " + std::to_string(trainData.n_rows) + " dimensions! "; ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index d02f5a18e4..07150f9433 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -925,7 +925,7 @@ TEST_CASE("RNNCheckInputShapeTest", "[RecurrentNetworkTest]") std::string expectedMsg = "RNN<>::Train: "; expectedMsg += "the first layer of the network expects "; expectedMsg += std::to_string(3) + " elements, "; - expectedMsg += "but the input shape has " + std::to_string(1) + " dimensions! "; + expectedMsg += "but the input has " + std::to_string(1) + " dimensions! "; StandardSGD opt(0.1, 1, input.n_cols /* 1 epoch */, -100); From db9550507e36b77b3e614c2de5c201510a1c3217 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 11 Dec 2020 17:46:06 +0530 Subject: [PATCH 313/550] fixing again --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- src/mlpack/tests/recurrent_network_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 17cf23eab4..81a87ccc6d 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -935,7 +935,7 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") model.Add >(8, 3); model.Add >(); - std::string expectedMsg = "FFN<>::Train: "; + std::string expectedMsg = "FFN<>::Train(): "; expectedMsg += "the first layer of the network expects "; expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; expectedMsg += "but the input has " + std::to_string(trainData.n_rows) + " dimensions! "; diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 07150f9433..b78523b150 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -922,7 +922,7 @@ TEST_CASE("RNNCheckInputShapeTest", "[RecurrentNetworkTest]") model.Add >(4, 10); model.Add >(); - std::string expectedMsg = "RNN<>::Train: "; + std::string expectedMsg = "RNN<>::Train(): "; expectedMsg += "the first layer of the network expects "; expectedMsg += std::to_string(3) + " elements, "; expectedMsg += "but the input has " + std::to_string(1) + " dimensions! "; From 6391705099710d9ee55a7806f78f683c55891aff Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 12 Dec 2020 00:08:05 +0530 Subject: [PATCH 314/550] deleting the layer --- src/mlpack/tests/ann_visitor_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index e5d1310368..b6502fad3e 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -190,6 +190,8 @@ TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") randomOutSize, randomKernelWidth, randomKernelHeight); CheckCorrectnessOfWeightSize(transposedConvLayer); + + delete transposedConvLayer; } /** @@ -204,4 +206,6 @@ TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") randomOutSize); CheckCorrectnessOfWeightSize(noisyLinearLayer); + + delete noisyLinearLayer; } From 1168acb0e413cde2317efeb2766c37eb169fc462 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Sat, 12 Dec 2020 00:11:56 +0530 Subject: [PATCH 315/550] Update src/mlpack/tests/feedforward_network_test.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 81a87ccc6d..bef5dbe7af 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -929,7 +929,7 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") testData.shed_row(testData.n_rows - 1); FFN, RandomInitialization, CustomLayer<> > model; - // Purposely putting wrong input shape so that error is thrown + // Purposely putting wrong input shape so that error is thrown. model.Add >(trainData.n_rows - 3, 8); model.Add >(); model.Add >(8, 3); From 588a9be14bee12834a828a03b6f97f1a1d1455a1 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 12 Dec 2020 00:18:46 +0530 Subject: [PATCH 316/550] style fixes --- src/mlpack/tests/feedforward_network_test.cpp | 9 ++++----- src/mlpack/tests/recurrent_network_test.cpp | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 81a87ccc6d..cab3f03891 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -936,13 +936,12 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") model.Add >(); std::string expectedMsg = "FFN<>::Train(): "; - expectedMsg += "the first layer of the network expects "; - expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; - expectedMsg += "but the input has " + std::to_string(trainData.n_rows) + " dimensions! "; + expectedMsg += "the first layer of the network expects "; + expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; + expectedMsg += "but the input has " + std::to_string(trainData.n_rows) + " dimensions! "; ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); REQUIRE_THROWS_MATCHES(model.Train(trainData, trainLabels, opt), - std::logic_error, - Catch::Matchers::Message(expectedMsg)); + std::logic_error, Catch::Matchers::Message(expectedMsg)); } diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index b78523b150..d0912802d0 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -930,6 +930,5 @@ TEST_CASE("RNNCheckInputShapeTest", "[RecurrentNetworkTest]") StandardSGD opt(0.1, 1, input.n_cols /* 1 epoch */, -100); REQUIRE_THROWS_MATCHES(model.Train(input, labels, opt), - std::logic_error, - Catch::Matchers::Message(expectedMsg)); + std::logic_error, Catch::Matchers::Message(expectedMsg)); } From da78659ff3c414cea867c03fc3b8e4a3cc37a2aa Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Sat, 12 Dec 2020 00:22:38 +0530 Subject: [PATCH 317/550] style fixes 2 --- src/mlpack/tests/feedforward_network_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index e512fe3f7c..45530ea466 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -936,9 +936,9 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") model.Add >(); std::string expectedMsg = "FFN<>::Train(): "; - expectedMsg += "the first layer of the network expects "; - expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; - expectedMsg += "but the input has " + std::to_string(trainData.n_rows) + " dimensions! "; + expectedMsg += "the first layer of the network expects "; + expectedMsg += std::to_string(trainData.n_rows - 3) + " elements, "; + expectedMsg += "but the input has " + std::to_string(trainData.n_rows) + " dimensions! "; ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); From 040721affc4b83adbe9cc39c1bf00e17c08ce03f Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 11 Dec 2020 17:35:51 -0500 Subject: [PATCH 318/550] floor()ing an int isn't necessary. --- src/mlpack/core/util/prefixedoutstream_impl.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mlpack/core/util/prefixedoutstream_impl.hpp b/src/mlpack/core/util/prefixedoutstream_impl.hpp index 601c81c4fc..3cb9eea353 100644 --- a/src/mlpack/core/util/prefixedoutstream_impl.hpp +++ b/src/mlpack/core/util/prefixedoutstream_impl.hpp @@ -178,8 +178,7 @@ PrefixedOutStream::BaseLogic(const T& val) if (maxVal == 0.0) maxVal = 1; - int maxLog = log10(maxVal); - maxLog = (maxLog > 0) ? floor(maxLog) + 1 : 1; + const int maxLog = int(log10(maxVal)) + 1; const int padding = 4; convert.width(convert.precision() + maxLog + padding); printVal.raw_print(convert); From d64a0ae52bdaa1dda917f89651fea76360d39166 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 11 Dec 2020 17:36:57 -0500 Subject: [PATCH 319/550] Fix types to match available log() overloads. --- src/mlpack/methods/gmm/em_fit_impl.hpp | 2 +- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/gmm/em_fit_impl.hpp b/src/mlpack/methods/gmm/em_fit_impl.hpp index 6b4168bf2d..7f1a4eafd7 100644 --- a/src/mlpack/methods/gmm/em_fit_impl.hpp +++ b/src/mlpack/methods/gmm/em_fit_impl.hpp @@ -156,7 +156,7 @@ Estimate(const arma::mat& observations, // Calculate the new values for omega using the updated conditional // probabilities. - weights = arma::exp(probRowSums - log(observations.n_cols)); + weights = arma::exp(probRowSums - log(1.0 * observations.n_cols)); // Update values of l; calculate new log-likelihood. lOld = l; diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 8e4d8a2b2f..ac75389a9e 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -193,7 +193,7 @@ double HMM::Train(const std::vector& dataSeq) // Normalize the new initial probabilities. if (dataSeq.size() > 1) - logInitial = newLogInitial - log(dataSeq.size()); + logInitial = newLogInitial - log(1.0 * dataSeq.size()); else logInitial = newLogInitial; From 2c0e1745808ddbbbfe685881ca8538b86647b29b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 11 Dec 2020 17:37:39 -0500 Subject: [PATCH 320/550] Cleaner patch: use std::log() instead. --- src/mlpack/methods/gmm/em_fit_impl.hpp | 2 +- src/mlpack/methods/hmm/hmm_impl.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/gmm/em_fit_impl.hpp b/src/mlpack/methods/gmm/em_fit_impl.hpp index 7f1a4eafd7..c8d8b6ca9e 100644 --- a/src/mlpack/methods/gmm/em_fit_impl.hpp +++ b/src/mlpack/methods/gmm/em_fit_impl.hpp @@ -156,7 +156,7 @@ Estimate(const arma::mat& observations, // Calculate the new values for omega using the updated conditional // probabilities. - weights = arma::exp(probRowSums - log(1.0 * observations.n_cols)); + weights = arma::exp(probRowSums - std::log(observations.n_cols)); // Update values of l; calculate new log-likelihood. lOld = l; diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index ac75389a9e..74688a1273 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -193,7 +193,7 @@ double HMM::Train(const std::vector& dataSeq) // Normalize the new initial probabilities. if (dataSeq.size() > 1) - logInitial = newLogInitial - log(1.0 * dataSeq.size()); + logInitial = newLogInitial - std::log(dataSeq.size()); else logInitial = newLogInitial; From 817ed61bb040c82a286355dceeaa3866e7ae0d27 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 11 Dec 2020 18:01:08 -0500 Subject: [PATCH 321/550] Fix duplicate names that happen to live in the same namespace. --- src/mlpack/methods/rann/ra_model.hpp | 44 +++++++++--------- src/mlpack/methods/rann/ra_model_impl.hpp | 54 +++++++++++------------ src/mlpack/methods/rann/ra_search.hpp | 2 +- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/mlpack/methods/rann/ra_model.hpp b/src/mlpack/methods/rann/ra_model.hpp index ed32d4a352..cadc6ad46d 100644 --- a/src/mlpack/methods/rann/ra_model.hpp +++ b/src/mlpack/methods/rann/ra_model.hpp @@ -37,10 +37,10 @@ using RAType = RASearch; /** - * MonoSearchVisitor executes a monochromatic neighbor search on the given + * RAMonoSearchVisitor executes a monochromatic neighbor search on the given * RAType. We don't make any difference for different instantiation of RAType. */ -class MonoSearchVisitor : public boost::static_visitor +class RAMonoSearchVisitor : public boost::static_visitor { private: //! Number of neighbors to search for. @@ -55,10 +55,10 @@ class MonoSearchVisitor : public boost::static_visitor template void operator()(RAType* ra) const; - //! Construct the MonoSearchVisitor object with the given parameters. - MonoSearchVisitor(const size_t k, - arma::Mat& neighbors, - arma::mat& distances) : + //! Construct the RAMonoSearchVisitor object with the given parameters. + RAMonoSearchVisitor(const size_t k, + arma::Mat& neighbors, + arma::mat& distances) : k(k), neighbors(neighbors), distances(distances) @@ -66,13 +66,13 @@ class MonoSearchVisitor : public boost::static_visitor }; /** - * BiSearchVisitor executes a bichromatic neighbor search on the given RAType. + * RABiSearchVisitor executes a bichromatic neighbor search on the given RAType. * We use template specialization to differentiate those tree types types that * accept leafSize as a parameter. In these cases, before doing neighbor search * a query tree with proper leafSize is built from the querySet. */ template -class BiSearchVisitor : public boost::static_visitor +class RABiSearchVisitor : public boost::static_visitor { private: //! The query set for the bichromatic search. @@ -109,22 +109,22 @@ class BiSearchVisitor : public boost::static_visitor //! Bichromatic search on the given RAType specialized for octrees. void operator()(RATypeT* ra) const; - //! Construct the BiSearchVisitor. - BiSearchVisitor(const arma::mat& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, - const size_t leafSize); + //! Construct the RABiSearchVisitor. + RABiSearchVisitor(const arma::mat& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize); }; /** - * TrainVisitor sets the reference set to a new reference set on the given + * RATrainVisitor sets the reference set to a new reference set on the given * RAType. We use template specialization to differentiate those trees that * accept leafSize as a parameter. In these cases, a reference tree with proper * leafSize is built from the referenceSet. */ template -class TrainVisitor : public boost::static_visitor +class RATrainVisitor : public boost::static_visitor { private: //! The reference set to use for training. @@ -155,10 +155,10 @@ class TrainVisitor : public boost::static_visitor //! Train on the given RAType specialized for Octrees. void operator()(RATypeT* ra) const; - //! Construct the TrainVisitor object with the given reference set, leafSize + //! Construct the RATrainVisitor object with the given reference set, leafSize //! for BinarySpaceTrees. - TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize); + RATrainVisitor(arma::mat&& referenceSet, + const size_t leafSize); }; /** @@ -228,7 +228,7 @@ class SingleModeVisitor : public boost::static_visitor /** * Exposes the referenceSet of the given RAType. */ -class ReferenceSetVisitor : public boost::static_visitor +class RAReferenceSetVisitor : public boost::static_visitor { public: //! Return the reference set. @@ -237,9 +237,9 @@ class ReferenceSetVisitor : public boost::static_visitor }; /** - * DeleteVisitor deletes the give RAType Instance. + * RADeleteVisitor deletes the give RAType Instance. */ -class DeleteVisitor : public boost::static_visitor +class RADeleteVisitor : public boost::static_visitor { public: //! Delete the RAType Object. diff --git a/src/mlpack/methods/rann/ra_model_impl.hpp b/src/mlpack/methods/rann/ra_model_impl.hpp index 3b27bfa2d6..e66b3b268a 100644 --- a/src/mlpack/methods/rann/ra_model_impl.hpp +++ b/src/mlpack/methods/rann/ra_model_impl.hpp @@ -21,7 +21,7 @@ namespace neighbor { //! Monochromatic search for the given RAType instance. template -void MonoSearchVisitor::operator()(RAType* ra) const +void RAMonoSearchVisitor::operator()(RAType* ra) const { if (ra) return ra->Search(k, neighbors, distances); @@ -30,11 +30,11 @@ void MonoSearchVisitor::operator()(RAType* ra) const //! Save the parameters for the rank-approximate search. template -BiSearchVisitor::BiSearchVisitor(const arma::mat& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, - const size_t leafSize) : +RABiSearchVisitor::RABiSearchVisitor(const arma::mat& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize) : querySet(querySet), k(k), neighbors(neighbors), @@ -47,7 +47,7 @@ template template class TreeType> -void BiSearchVisitor::operator()(RATypeT* ra) const +void RABiSearchVisitor::operator()(RATypeT* ra) const { if (ra) return ra->Search(querySet, k, neighbors, distances); @@ -56,7 +56,7 @@ void BiSearchVisitor::operator()(RATypeT* ra) const //! Bichromatic search on the given RAType specialized for KDTrees. template -void BiSearchVisitor::operator()(RATypeT* ra) const +void RABiSearchVisitor::operator()(RATypeT* ra) const { if (ra) return SearchLeaf(ra); @@ -65,7 +65,7 @@ void BiSearchVisitor::operator()(RATypeT* ra) const //! Bichromatic search on the given RAType specialized for Octrees. template -void BiSearchVisitor::operator()(RATypeT* ra) const +void RABiSearchVisitor::operator()(RATypeT* ra) const { if (ra) return SearchLeaf(ra); @@ -75,7 +75,7 @@ void BiSearchVisitor::operator()(RATypeT* ra) const //! Bichromatic search on the given RAType considering the leafSize. template template -void BiSearchVisitor::SearchLeaf(RAType* ra) const +void RABiSearchVisitor::SearchLeaf(RAType* ra) const { if (!ra->Naive() && !ra->SingleMode()) { @@ -110,8 +110,8 @@ void BiSearchVisitor::SearchLeaf(RAType* ra) const //! Save parameters for the Train. template -TrainVisitor::TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize) : +RATrainVisitor::RATrainVisitor(arma::mat&& referenceSet, + const size_t leafSize) : referenceSet(std::move(referenceSet)), leafSize(leafSize) {}; @@ -121,7 +121,7 @@ template template class TreeType> -void TrainVisitor::operator()(RATypeT* ra) const +void RATrainVisitor::operator()(RATypeT* ra) const { if (ra) return ra->Train(std::move(referenceSet)); @@ -130,7 +130,7 @@ void TrainVisitor::operator()(RATypeT* ra) const //! Train on the given RAType specialized for KDTrees. template -void TrainVisitor::operator()(RATypeT* ra) const +void RATrainVisitor::operator()(RATypeT* ra) const { if (ra) return TrainLeaf(ra); @@ -139,7 +139,7 @@ void TrainVisitor::operator()(RATypeT* ra) const //! Train on the given RAType specialized for Octrees. template -void TrainVisitor::operator()(RATypeT* ra) const +void RATrainVisitor::operator()(RATypeT* ra) const { if (ra) return TrainLeaf(ra); @@ -149,7 +149,7 @@ void TrainVisitor::operator()(RATypeT* ra) const //! Train on the given RAType considering the leafSize. template template -void TrainVisitor::TrainLeaf(RAType* ra) const +void RATrainVisitor::TrainLeaf(RAType* ra) const { // Build tree, if necessary if (ra->Naive()) @@ -226,7 +226,7 @@ bool& SingleModeVisitor::operator()(RAType* ra) const //! Exposes the referenceSet of the given RAType. template -const arma::mat& ReferenceSetVisitor::operator()(RAType* ra) const +const arma::mat& RAReferenceSetVisitor::operator()(RAType* ra) const { if (ra) return ra->ReferenceSet(); @@ -244,7 +244,7 @@ bool& NaiveVisitor::operator()(RAType* ra) const //! For cleaning memory template -void DeleteVisitor::operator()(RSType* rs) const +void RADeleteVisitor::operator()(RSType* rs) const { if (rs) delete rs; @@ -292,7 +292,7 @@ template RAModel& RAModel::operator=(const RAModel& other) { // Clear current model. - boost::apply_visitor(DeleteVisitor(), raSearch); + boost::apply_visitor(RADeleteVisitor(), raSearch); treeType = other.treeType; leafSize = other.leafSize; @@ -306,7 +306,7 @@ RAModel& RAModel::operator=(const RAModel& other) template RAModel& RAModel::operator=(RAModel&& other) { - boost::apply_visitor(DeleteVisitor(), raSearch); + boost::apply_visitor(RADeleteVisitor(), raSearch); treeType = other.treeType; leafSize = other.leafSize; @@ -327,7 +327,7 @@ RAModel& RAModel::operator=(RAModel&& other) template RAModel::~RAModel() { - boost::apply_visitor(DeleteVisitor(), raSearch); + boost::apply_visitor(RADeleteVisitor(), raSearch); } template @@ -342,7 +342,7 @@ void RAModel::serialize(Archive& ar, // This should never happen, but just in case, be clean with memory. if (cereal::is_loading()) { - boost::apply_visitor(DeleteVisitor(), raSearch); + boost::apply_visitor(RADeleteVisitor(), raSearch); } // We only need to serialize one of the kRANN objects. @@ -352,7 +352,7 @@ void RAModel::serialize(Archive& ar, template const arma::mat& RAModel::Dataset() const { - return boost::apply_visitor(ReferenceSetVisitor(), raSearch); + return boost::apply_visitor(RAReferenceSetVisitor(), raSearch); } template @@ -489,7 +489,7 @@ void RAModel::BuildModel(arma::mat&& referenceSet, } // Clean memory, if necessary. - boost::apply_visitor(DeleteVisitor(), raSearch); + boost::apply_visitor(RADeleteVisitor(), raSearch); this->leafSize = leafSize; @@ -538,7 +538,7 @@ void RAModel::BuildModel(arma::mat&& referenceSet, break; } - TrainVisitor tn(std::move(referenceSet), leafSize); + RATrainVisitor tn(std::move(referenceSet), leafSize); boost::apply_visitor(tn, raSearch); if (!naive) @@ -567,7 +567,7 @@ void RAModel::Search(arma::mat&& querySet, Log::Info << "brute-force (naive) rank-approximate search..."; Log::Info << std::endl; - BiSearchVisitor search(querySet, k, neighbors, distances, + RABiSearchVisitor search(querySet, k, neighbors, distances, leafSize); boost::apply_visitor(search, raSearch); } @@ -586,7 +586,7 @@ void RAModel::Search(const size_t k, Log::Info << "brute-force (naive) rank-approximate search..."; Log::Info << std::endl; - MonoSearchVisitor search(k, neighbors, distances); + RAMonoSearchVisitor search(k, neighbors, distances); boost::apply_visitor(search, raSearch); } diff --git a/src/mlpack/methods/rann/ra_search.hpp b/src/mlpack/methods/rann/ra_search.hpp index da3f61c48d..2dd91baf68 100644 --- a/src/mlpack/methods/rann/ra_search.hpp +++ b/src/mlpack/methods/rann/ra_search.hpp @@ -395,7 +395,7 @@ class RASearch //! For access to mappings when building models. template - friend class TrainVisitor; + friend class RATrainVisitor; }; // class RASearch } // namespace neighbor From e6a57cd9f1f5a9c8a4ff41e5b908f6edea9c8784 Mon Sep 17 00:00:00 2001 From: ayushsingh11 <30299945+ayushsingh11@users.noreply.github.com> Date: Sat, 12 Dec 2020 11:45:11 +0530 Subject: [PATCH 322/550] Update HISTORY.md Added Triplet margin loss function --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index be8a4d66b0..9f4276b20b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,8 @@ ###### ????-??-?? * Added an implementation to Stratify Data (#2671). + * Add Triplet Margin Loss function (#2762). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. From df39e59f475fa316b7e09d5c42a38bd9a8f75b6b Mon Sep 17 00:00:00 2001 From: ayushsingh11 <30299945+ayushsingh11@users.noreply.github.com> Date: Sat, 12 Dec 2020 13:42:56 +0530 Subject: [PATCH 323/550] Update triplet_margin_loss_impl.hpp Replace BOOST_SERIALIZATION_NVP with CEREAL_NVP. --- .../methods/ann/loss_functions/triplet_margin_loss_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index 37be8db9b4..6c6224f95a 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -61,10 +61,10 @@ void TripletMarginLoss::serialize( Archive& ar, const unsigned int /* version */) { - ar & BOOST_SERIALIZATION_NVP(margin); + ar(CEREAL_NVP(reduction)); } } // namespace ann } // namespace mlpack -#endif \ No newline at end of file +#endif From 8e162504414b9c7bbfd75230f006c3d79ed9cbe0 Mon Sep 17 00:00:00 2001 From: ayushsingh11 <30299945+ayushsingh11@users.noreply.github.com> Date: Sat, 12 Dec 2020 13:44:30 +0530 Subject: [PATCH 324/550] Update triplet_margin_loss_impl.hpp Minor Fix --- .../methods/ann/loss_functions/triplet_margin_loss_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index 6c6224f95a..2f7e11ceae 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -61,7 +61,7 @@ void TripletMarginLoss::serialize( Archive& ar, const unsigned int /* version */) { - ar(CEREAL_NVP(reduction)); + ar(CEREAL_NVP(margin)); } } // namespace ann From 4c9e97a6f50a6e9a904b04f1fadfed5bff188256 Mon Sep 17 00:00:00 2001 From: iamarchit Date: Sat, 21 Nov 2020 12:57:07 +0530 Subject: [PATCH 325/550] Improve Documentation to correctly state what repositories to get for various Linux distros --- README.md | 7 +++++-- doc/guide/build.hpp | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 82cbecf9c0..64486d78e7 100644 --- a/README.md +++ b/README.md @@ -146,9 +146,12 @@ This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, FreeBSD etc). However, mlpack is in the repositories of many Linux distributions and so it may be easier to use the package manager for your system. For example, -on Ubuntu, you can install mlpack with the following command: +on Ubuntu, you can install mlpack library and command line executbles(eg. mlpack_pca, mlpack_kmeans etc.) with the following command: - $ sudo apt-get install libmlpack-dev + $ sudo apt-get install libmlpack-dev mlpack-bin + +On Fedora or Red Hat (EPEL): + $ sudo dnf install mlpack-devel mlpack-bin Note: Older Ubuntu versions may not have the most recent version of mlpack available---for instance, at the time of this writing, Ubuntu 16.04 only has diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 91695d6ab6..4753a7fc7a 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -6,7 +6,19 @@ This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, FreeBSD etc). However, mlpack is in the repositories of many Linux distributions and so it may be easier to use the package manager for your system. For example, -on Ubuntu, you can install mlpack with the following command: +on Ubuntu, you can install mlpack library and command line executables(eg. mlpack_pca, mlpack_kmeans etc.) with the following command: + +@code +$ sudo apt-get install libmlpack-dev mlpack-bin +@endcode + +On Fedora or Red Hat(EPEL): + +@code +$ sudo dnf install mlpack-devel mlpack-bin +@endcode + +For installing only header files and lib for development purposes one could use: @code $ sudo apt-get install libmlpack-dev From e75d7fdce75a11aec774d0114405927a5c95d08b Mon Sep 17 00:00:00 2001 From: iamarchit123 <73429785+iamarchit123@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:31:35 +0530 Subject: [PATCH 326/550] Update doc/guide/build.hpp Co-authored-by: Omar Shrit --- doc/guide/build.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 4753a7fc7a..75afe86336 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -6,7 +6,7 @@ This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, FreeBSD etc). However, mlpack is in the repositories of many Linux distributions and so it may be easier to use the package manager for your system. For example, -on Ubuntu, you can install mlpack library and command line executables(eg. mlpack_pca, mlpack_kmeans etc.) with the following command: +on Ubuntu, you can install mlpack library and command-line executables (eg. mlpack_pca, mlpack_kmeans, etc.) with the following command: @code $ sudo apt-get install libmlpack-dev mlpack-bin From 5c57d1d93c5899f4530a6f31f1b0dbeb3517a026 Mon Sep 17 00:00:00 2001 From: iamarchit123 <73429785+iamarchit123@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:33:54 +0530 Subject: [PATCH 327/550] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64486d78e7..5d33abd958 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, FreeBSD etc). However, mlpack is in the repositories of many Linux distributions and so it may be easier to use the package manager for your system. For example, -on Ubuntu, you can install mlpack library and command line executbles(eg. mlpack_pca, mlpack_kmeans etc.) with the following command: +on Ubuntu, you can install mlpack library and command-line executbles(eg. mlpack_pca, mlpack_kmeans etc.) with the following command: $ sudo apt-get install libmlpack-dev mlpack-bin From ab19efc182491236ecca1190fa5d19cbe6c64e40 Mon Sep 17 00:00:00 2001 From: iamarchit123 <73429785+iamarchit123@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:47:35 +0530 Subject: [PATCH 328/550] Update doc/guide/build.hpp and README.md Add additional information explaining the purpose of libmlpack-dev and wrap to next line after after 80 characters. Co-authored-by: Ryan Curtin --- README.md | 3 ++- doc/guide/build.hpp | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5d33abd958..610e4f6d33 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,8 @@ This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, FreeBSD etc). However, mlpack is in the repositories of many Linux distributions and so it may be easier to use the package manager for your system. For example, -on Ubuntu, you can install mlpack library and command-line executbles(eg. mlpack_pca, mlpack_kmeans etc.) with the following command: +on Ubuntu, you can install the mlpack library and command-line executables (e.g. +mlpack_pca, mlpack_kmeans etc.) with the following command: $ sudo apt-get install libmlpack-dev mlpack-bin diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 75afe86336..20b98e4688 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -6,7 +6,8 @@ This document discusses how to build mlpack from source. These build directions will work for any Linux-like shell environment (for example Ubuntu, macOS, FreeBSD etc). However, mlpack is in the repositories of many Linux distributions and so it may be easier to use the package manager for your system. For example, -on Ubuntu, you can install mlpack library and command-line executables (eg. mlpack_pca, mlpack_kmeans, etc.) with the following command: +on Ubuntu, you can install the mlpack library and command-line executables (e.g. +mlpack_pca, mlpack_kmeans, etc.) with the following command: @code $ sudo apt-get install libmlpack-dev mlpack-bin @@ -18,7 +19,8 @@ On Fedora or Red Hat(EPEL): $ sudo dnf install mlpack-devel mlpack-bin @endcode -For installing only header files and lib for development purposes one could use: +For installing only the header files and library for building C++ applications +on top of mlpack, one could use: @code $ sudo apt-get install libmlpack-dev From cb8353f986160b8b245c80997e7023a4d2e809c1 Mon Sep 17 00:00:00 2001 From: ayushsingh11 <30299945+ayushsingh11@users.noreply.github.com> Date: Sat, 12 Dec 2020 20:22:20 +0530 Subject: [PATCH 329/550] Corrections in using Boost for Triplet Margin Loss --- src/mlpack/tests/loss_functions_test.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 22c59cf798..adcaee3249 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -902,7 +902,7 @@ TEST_CASE("MeanAbsolutePercentageErrorTest", "[LossFunctionsTest]") /* * Simple test for the Triplet Margin Loss function. */ -BOOST_AUTO_TEST_CASE(TripletMarginLossTest) +TEST_CASE("TripletMarginLossTest") { arma::mat anchor, positive, negative; arma::mat input, target, output; @@ -917,7 +917,7 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) input = { {2, 3, 5}, {10, 12, 13} }; double error = module.Forward(input, negative); - BOOST_REQUIRE_EQUAL(error, 66); + REQUIRE(error == 66); // Test the Backward function. module.Backward(input, negative, output); @@ -925,8 +925,8 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) // output = 2 * (negative - positive) / anchor.n_cols, // output * nofColumns / 2 + positive should be equal to negative. CheckMatrices(negative, output * output.n_cols / 2 + positive); - BOOST_REQUIRE_EQUAL(output.n_rows, anchor.n_rows); - BOOST_REQUIRE_EQUAL(output.n_cols, anchor.n_cols); + REQUIRE(output.n_rows == anchor.n_rows); + REQUIRE(output.n_cols == anchor.n_cols); // Test the error function on a single input. anchor = arma::mat("4"); @@ -938,13 +938,11 @@ BOOST_AUTO_TEST_CASE(TripletMarginLossTest) input[1] = 7; error = module.Forward(input, negative); - BOOST_REQUIRE_EQUAL(error, 1.0); + REQUIRE(error == 1.0); // Test the Backward function on a single input. module.Backward(input, negative, output); // Test whether the output is negative. - BOOST_REQUIRE_EQUAL(arma::accu(output), -12); - BOOST_REQUIRE_EQUAL(output.n_elem, 1); + REQUIRE(arma::accu(output) == -12); + REQUIRE(output.n_elem == 1); } - -BOOST_AUTO_TEST_SUITE_END(); \ No newline at end of file From 4eea3e74646a0635a835dbb0126341d7137fa2e8 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 12 Dec 2020 16:44:46 -0500 Subject: [PATCH 330/550] Remove unnecessary _catch suffix from files. --- src/mlpack/tests/CMakeLists.txt | 6 +- src/mlpack/tests/adaboost_test.cpp | 2 +- src/mlpack/tests/ann_layer_test-mod.cpp | 2937 +++++++++++++++++ src/mlpack/tests/ann_layer_test.cpp | 2 +- src/mlpack/tests/ann_regularizer_test.cpp | 2 +- src/mlpack/tests/cf_test.cpp | 2 +- src/mlpack/tests/convolution_test.cpp | 2 +- .../tests/convolutional_network_test.cpp | 2 +- src/mlpack/tests/dcgan_test.cpp | 2 +- src/mlpack/tests/decision_tree_test.cpp | 2 +- src/mlpack/tests/distribution_test.cpp | 2 +- src/mlpack/tests/drusilla_select_test.cpp | 2 +- src/mlpack/tests/fastmks_test.cpp | 2 +- .../tests/feedforward_network_2_test.cpp | 2 +- src/mlpack/tests/feedforward_network_test.cpp | 2 +- src/mlpack/tests/gan_test.cpp | 2 +- src/mlpack/tests/hoeffding_tree_test.cpp | 2 +- src/mlpack/tests/image_load_test.cpp | 2 +- src/mlpack/tests/kde_test.cpp | 2 +- src/mlpack/tests/kernel_test.cpp | 2 +- src/mlpack/tests/linear_regression_test.cpp | 2 +- .../tests/local_coordinate_coding_test.cpp | 2 +- src/mlpack/tests/octree_test.cpp | 2 +- src/mlpack/tests/qdafn_test.cpp | 2 +- src/mlpack/tests/random_forest_test.cpp | 2 +- src/mlpack/tests/recurrent_network_test.cpp | 2 +- src/mlpack/tests/rnn_reber_test.cpp | 2 +- ...ialization_catch.cpp => serialization.cpp} | 4 +- ...ialization_catch.hpp => serialization.hpp} | 2 +- src/mlpack/tests/serialization_test.cpp | 2 +- src/mlpack/tests/sparse_coding_test.cpp | 2 +- src/mlpack/tests/string_encoding_test.cpp | 2 +- src/mlpack/tests/wgan_test.cpp | 2 +- 33 files changed, 2972 insertions(+), 35 deletions(-) create mode 100755 src/mlpack/tests/ann_layer_test-mod.cpp rename src/mlpack/tests/{serialization_catch.cpp => serialization.cpp} (97%) rename src/mlpack/tests/{serialization_catch.hpp => serialization.hpp} (99%) diff --git a/src/mlpack/tests/CMakeLists.txt b/src/mlpack/tests/CMakeLists.txt index 3b7ebb4b05..5657a5d6ee 100644 --- a/src/mlpack/tests/CMakeLists.txt +++ b/src/mlpack/tests/CMakeLists.txt @@ -99,8 +99,8 @@ add_executable(mlpack_test reward_clipping_test.cpp rl_components_test.cpp scaling_test.cpp - serialization_catch.cpp - serialization_catch.hpp + serialization.cpp + serialization.hpp serialization_test.cpp sfinae_test.cpp softmax_regression_test.cpp @@ -202,4 +202,4 @@ add_custom_command(TARGET mlpack_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) -add_test(NAME "catch_test" COMMAND mlpack_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) \ No newline at end of file +add_test(NAME "catch_test" COMMAND mlpack_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/src/mlpack/tests/adaboost_test.cpp b/src/mlpack/tests/adaboost_test.cpp index 89e6699c76..cccf6f42d8 100644 --- a/src/mlpack/tests/adaboost_test.cpp +++ b/src/mlpack/tests/adaboost_test.cpp @@ -12,7 +12,7 @@ #include #include -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "test_catch_tools.hpp" #include "catch.hpp" diff --git a/src/mlpack/tests/ann_layer_test-mod.cpp b/src/mlpack/tests/ann_layer_test-mod.cpp new file mode 100755 index 0000000000..77658fa0ea --- /dev/null +++ b/src/mlpack/tests/ann_layer_test-mod.cpp @@ -0,0 +1,2937 @@ +/** + * @file mlpack/tests/ann_layer_test-mod.cpp + * @author Marcus Edel + * @author Praveen Ch + * + * Tests the ann layer modules. + * + * 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. + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "test_tools.hpp" +#include "ann_test_tools.hpp" +#include "serialization.hpp" + +using namespace mlpack; +using namespace mlpack::ann; + +BOOST_AUTO_TEST_SUITE(ANNLayerTest); + +/** + * Simple add module test. + */ +BOOST_AUTO_TEST_CASE(SimpleAddLayerTest) +{ + arma::mat output, input, delta; + Add<> module(10); + module.Parameters().randu(); + + // Test the Forward function. + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(module.Parameters()), arma::accu(output)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(delta)); + + // Test the forward function. + input = arma::ones(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_CLOSE(10 + arma::accu(module.Parameters()), + arma::accu(output), 1e-3); + + // Test the backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_CLOSE(arma::accu(output), arma::accu(delta), 1e-3); +} + +/** + * Jacobian add module test. + */ +BOOST_AUTO_TEST_CASE(JacobianAddLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t elements = math::RandInt(2, 1000); + arma::mat input; + input.set_size(elements, 1); + + Add<> module(elements); + module.Parameters().randu(); + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Add layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientAddLayerTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + model->Add >(10); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Simple constant module test. + */ +BOOST_AUTO_TEST_CASE(SimpleConstantLayerTest) +{ + arma::mat output, input, delta; + Constant<> module(10, 3.0); + + // Test the Forward function. + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(output), 30.0); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); + + // Test the forward function. + input = arma::ones(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(output), 30.0); + + // Test the backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +/** + * Jacobian constant module test. + */ +BOOST_AUTO_TEST_CASE(JacobianConstantLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t elements = math::RandInt(2, 1000); + arma::mat input; + input.set_size(elements, 1); + + Constant<> module(elements, 1.0); + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Simple dropout module test. + */ +BOOST_AUTO_TEST_CASE(SimpleDropoutLayerTest) +{ + // Initialize the probability of setting a value to zero. + const double p = 0.2; + + // Initialize the input parameter. + arma::mat input(1000, 1); + input.fill(1 - p); + + Dropout<> module(p); + module.Deterministic() = false; + + // Test the Forward function. + arma::mat output; + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_LE( + arma::as_scalar(arma::abs(arma::mean(output) - (1 - p))), 0.05); + + // Test the Backward function. + arma::mat delta; + module.Backward(std::move(input), std::move(input), std::move(delta)); + BOOST_REQUIRE_LE( + arma::as_scalar(arma::abs(arma::mean(delta) - (1 - p))), 0.05); + + // Test the Forward function. + module.Deterministic() = true; + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(output)); +} + +/** + * Perform dropout x times using ones as input, sum the number of ones and + * validate that the layer is producing approximately the correct number of + * ones. + */ +BOOST_AUTO_TEST_CASE(DropoutProbabilityTest) +{ + arma::mat input = arma::ones(1500, 1); + const size_t iterations = 10; + + double probability[5] = { 0.1, 0.3, 0.4, 0.7, 0.8 }; + for (size_t trial = 0; trial < 5; ++trial) + { + double nonzeroCount = 0; + for (size_t i = 0; i < iterations; ++i) + { + Dropout<> module(probability[trial]); + module.Deterministic() = false; + + arma::mat output; + module.Forward(std::move(input), std::move(output)); + + // Return a column vector containing the indices of elements of X that + // are non-zero, we just need the number of non-zero values. + arma::uvec nonzero = arma::find(output); + nonzeroCount += nonzero.n_elem; + } + const double expected = input.n_elem * (1 - probability[trial]) * + iterations; + const double error = fabs(nonzeroCount - expected) / expected; + + BOOST_REQUIRE_LE(error, 0.15); + } +} + +/* + * Perform dropout with probability 1 - p where p = 0, means no dropout. + */ +BOOST_AUTO_TEST_CASE(NoDropoutTest) +{ + arma::mat input = arma::ones(1500, 1); + Dropout<> module(0); + module.Deterministic() = false; + + arma::mat output; + module.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(input)); +} + +/* + * Perform test to check whether mean and variance remain nearly same + * after AlphaDropout. + */ +BOOST_AUTO_TEST_CASE(SimpleAlphaDropoutLayerTest) +{ + // Initialize the probability of setting a value to alphaDash. + const double p = 0.2; + + // Initialize the input parameter having a mean nearabout 0 + // and variance nearabout 1. + arma::mat input = arma::randn(1000, 1); + + AlphaDropout<> module(p); + module.Deterministic() = false; + + // Test the Forward function when training phase. + arma::mat output; + module.Forward(std::move(input), std::move(output)); + // Check whether mean remains nearly same. + BOOST_REQUIRE_LE( + arma::as_scalar(arma::abs(arma::mean(input) - arma::mean(output))), 0.1); + + // Check whether variance remains nearly same. + BOOST_REQUIRE_LE( + arma::as_scalar(arma::abs(arma::var(input) - arma::var(output))), 0.1); + + // Test the Backward function when training phase. + arma::mat delta; + module.Backward(std::move(input), std::move(input), std::move(delta)); + BOOST_REQUIRE_LE( + arma::as_scalar(arma::abs(arma::mean(delta) - 0)), 0.05); + + // Test the Forward function when testing phase. + module.Deterministic() = true; + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(output)); +} + +/** + * Perform AlphaDropout x times using ones as input, sum the number of ones + * and validate that the layer is producing approximately the correct number + * of ones. + */ +BOOST_AUTO_TEST_CASE(AlphaDropoutProbabilityTest) +{ + arma::mat input = arma::ones(1500, 1); + const size_t iterations = 10; + + double probability[5] = { 0.1, 0.3, 0.4, 0.7, 0.8 }; + for (size_t trial = 0; trial < 5; ++trial) + { + double nonzeroCount = 0; + for (size_t i = 0; i < iterations; ++i) + { + AlphaDropout<> module(probability[trial]); + module.Deterministic() = false; + + arma::mat output; + module.Forward(std::move(input), std::move(output)); + + // Return a column vector containing the indices of elements of X + // that are not alphaDash, we just need the number of + // nonAlphaDash values. + arma::uvec nonAlphaDash = arma::find(module.Mask()); + nonzeroCount += nonAlphaDash.n_elem; + } + + const double expected = input.n_elem * (1-probability[trial]) * iterations; + + const double error = fabs(nonzeroCount - expected) / expected; + + BOOST_REQUIRE_LE(error, 0.15); + } +} + +/** + * Perform AlphaDropout with probability 1 - p where p = 0, + * means no AlphaDropout. + */ +BOOST_AUTO_TEST_CASE(NoAlphaDropoutTest) +{ + arma::mat input = arma::ones(1500, 1); + AlphaDropout<> module(0); + module.Deterministic() = false; + + arma::mat output; + module.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(input)); +} + +/** + * Simple linear module test. + */ +BOOST_AUTO_TEST_CASE(SimpleLinearLayerTest) +{ + arma::mat output, input, delta; + Linear<> module(10, 10); + module.Parameters().randu(); + module.Reset(); + + // Test the Forward function. + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_CLOSE(arma::accu( + module.Parameters().submat(100, 0, module.Parameters().n_elem - 1, 0)), + arma::accu(output), 1e-3); + + // Test the Backward function. + module.Backward(std::move(input), std::move(input), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +/** + * Jacobian linear module test. + */ +BOOST_AUTO_TEST_CASE(JacobianLinearLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElements = math::RandInt(2, 1000); + const size_t outputElements = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElements, 1); + + Linear<> module(inputElements, outputElements); + module.Parameters().randu(); + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Linear layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientLinearLayerTest) +{ + // Linear function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + model->Add >(10, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Simple linear no bias module test. + */ +BOOST_AUTO_TEST_CASE(SimpleLinearNoBiasLayerTest) +{ + arma::mat output, input, delta; + LinearNoBias<> module(10, 10); + module.Parameters().randu(); + module.Reset(); + + // Test the Forward function. + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(0, arma::accu(output)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(input), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +/** + * Simple padding layer test. + */ +BOOST_AUTO_TEST_CASE(SimplePaddingLayerTest) +{ + arma::mat output, input, delta; + Padding<> module(1, 2, 3, 4); + + // Test the Forward function. + input = arma::randu(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(output)); + BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows + 3); + BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols + 7); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + CheckMatrices(delta, input); +} + +/** + * Jacobian linear no bias module test. + */ +BOOST_AUTO_TEST_CASE(JacobianLinearNoBiasLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElements = math::RandInt(2, 1000); + const size_t outputElements = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElements, 1); + + LinearNoBias<> module(inputElements, outputElements); + module.Parameters().randu(); + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * LinearNoBias layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientLinearNoBiasLayerTest) +{ + // LinearNoBias function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + model->Add >(10, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Jacobian negative log likelihood module test. + */ +BOOST_AUTO_TEST_CASE(JacobianNegativeLogLikelihoodLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + NegativeLogLikelihood<> module; + const size_t inputElements = math::RandInt(5, 100); + arma::mat input; + RandomInitialization init(0, 1); + init.Initialize(input, inputElements, 1); + + arma::mat target(1, 1); + target(0) = math::RandInt(1, inputElements - 1); + + double error = JacobianPerformanceTest(module, input, target); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Jacobian LeakyReLU module test. + */ +BOOST_AUTO_TEST_CASE(JacobianLeakyReLULayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElements = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElements, 1); + + LeakyReLU<> module; + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Jacobian FlexibleReLU module test. + */ +BOOST_AUTO_TEST_CASE(JacobianFlexibleReLULayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElements = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElements, 1); + + FlexibleReLU<> module; + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Flexible ReLU layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientFlexibleReLULayerTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(2, 1); + target = arma::mat("1"); + + model = new FFN, RandomInitialization>( + NegativeLogLikelihood<>(), RandomInitialization(0.1, 0.5)); + + model->Predictors() = input; + model->Responses() = target; + model->Add >(2, 2); + model->Add >(2, 5); + model->Add >(0.05); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, RandomInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Jacobian MultiplyConstant module test. + */ +BOOST_AUTO_TEST_CASE(JacobianMultiplyConstantLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElements = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElements, 1); + + MultiplyConstant<> module(3.0); + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Jacobian HardTanH module test. + */ +BOOST_AUTO_TEST_CASE(JacobianHardTanHLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElements = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElements, 1); + + HardTanH<> module; + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Simple select module test. + */ +BOOST_AUTO_TEST_CASE(SimpleSelectLayerTest) +{ + arma::mat outputA, outputB, input, delta; + + input = arma::ones(10, 5); + for (size_t i = 0; i < input.n_cols; ++i) + { + input.col(i) *= i; + } + + // Test the Forward function. + Select<> moduleA(3); + moduleA.Forward(std::move(input), std::move(outputA)); + BOOST_REQUIRE_EQUAL(30, arma::accu(outputA)); + + // Test the Forward function. + Select<> moduleB(3, 5); + moduleB.Forward(std::move(input), std::move(outputB)); + BOOST_REQUIRE_EQUAL(15, arma::accu(outputB)); + + // Test the Backward function. + moduleA.Backward(std::move(input), std::move(outputA), std::move(delta)); + BOOST_REQUIRE_EQUAL(30, arma::accu(delta)); + + // Test the Backward function. + moduleB.Backward(std::move(input), std::move(outputA), std::move(delta)); + BOOST_REQUIRE_EQUAL(15, arma::accu(delta)); +} + +/** + * Simple join module test. + */ +BOOST_AUTO_TEST_CASE(SimpleJoinLayerTest) +{ + arma::mat output, input, delta; + input = arma::ones(10, 5); + + // Test the Forward function. + Join<> module; + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(50, arma::accu(output)); + + bool b = output.n_rows == 1 || output.n_cols == 1; + BOOST_REQUIRE_EQUAL(b, true); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(50, arma::accu(delta)); + + b = delta.n_rows == input.n_rows && input.n_cols; + BOOST_REQUIRE_EQUAL(b, true); +} + +/** + * Simple add merge module test. + */ +BOOST_AUTO_TEST_CASE(SimpleAddMergeLayerTest) +{ + arma::mat output, input, delta; + input = arma::ones(10, 1); + + for (size_t i = 0; i < 5; ++i) + { + AddMerge<> module(false, false); + const size_t numMergeModules = math::RandInt(2, 10); + for (size_t m = 0; m < numMergeModules; ++m) + { + IdentityLayer<> identityLayer; + identityLayer.Forward(std::move(input), + std::move(identityLayer.OutputParameter())); + + module.Add >(identityLayer); + } + + // Test the Forward function. + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(10 * numMergeModules, arma::accu(output)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(delta)); + } +} + +/** + * Test the LSTM layer with a user defined rho parameter and without. + */ +BOOST_AUTO_TEST_CASE(LSTMRrhoTest) +{ + const size_t rho = 5; + arma::cube input = arma::randu(1, 1, 5); + arma::cube target = arma::ones(1, 1, 5); + RandomInitialization init(0.5, 0.5); + + // Create model with user defined rho parameter. + RNN, RandomInitialization> modelA( + rho, false, NegativeLogLikelihood<>(), init); + modelA.Add >(); + modelA.Add >(1, 10); + + // Use LSTM layer with rho. + modelA.Add >(10, 3, rho); + modelA.Add >(); + + // Create model without user defined rho parameter. + RNN > modelB( + rho, false, NegativeLogLikelihood<>(), init); + modelB.Add >(); + modelB.Add >(1, 10); + + // Use LSTM layer with rho = MAXSIZE. + modelB.Add >(10, 3); + modelB.Add >(); + + ens::StandardSGD opt(0.1, 1, 5, -100, false); + modelA.Train(input, target, opt); + modelB.Train(input, target, opt); + + CheckMatrices(modelB.Parameters(), modelA.Parameters()); +} + +/** + * LSTM layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientLSTMLayerTest) +{ + // LSTM function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(1, 1, 5); + target.ones(1, 1, 5); + const size_t rho = 5; + + model = new RNN >(rho); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(1, 10); + model->Add >(10, 3, rho); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + RNN >* model; + arma::cube input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Test the FastLSTM layer with a user defined rho parameter and without. + */ +BOOST_AUTO_TEST_CASE(FastLSTMRrhoTest) +{ + const size_t rho = 5; + arma::cube input = arma::randu(1, 1, 5); + arma::cube target = arma::ones(1, 1, 5); + RandomInitialization init(0.5, 0.5); + + // Create model with user defined rho parameter. + RNN, RandomInitialization> modelA( + rho, false, NegativeLogLikelihood<>(), init); + modelA.Add >(); + modelA.Add >(1, 10); + + // Use FastLSTM layer with rho. + modelA.Add >(10, 3, rho); + modelA.Add >(); + + // Create model without user defined rho parameter. + RNN > modelB( + rho, false, NegativeLogLikelihood<>(), init); + modelB.Add >(); + modelB.Add >(1, 10); + + // Use FastLSTM layer with rho = MAXSIZE. + modelB.Add >(10, 3); + modelB.Add >(); + + ens::StandardSGD opt(0.1, 1, 5, -100, false); + modelA.Train(input, target, opt); + modelB.Train(input, target, opt); + + CheckMatrices(modelB.Parameters(), modelA.Parameters()); +} + +/** + * FastLSTM layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientFastLSTMLayerTest) +{ + // Fast LSTM function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(1, 1, 5); + target = arma::ones(1, 1, 5); + const size_t rho = 5; + + model = new RNN >(rho); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(1, 10); + model->Add >(10, 3, rho); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + RNN >* model; + arma::cube input, target; + } function; + + // The threshold should be << 0.1 but since the Fast LSTM layer uses an + // approximation of the sigmoid function the estimated gradient is not + // correct. + BOOST_REQUIRE_LE(CheckGradient(function), 0.2); +} + +/** + * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell + * state. Besides output, the overloaded function provides read access to cell + * state of the LSTM layer. + */ +BOOST_AUTO_TEST_CASE(ReadCellStateParamLSTMLayerTest) +{ + const size_t rho = 5, inputSize = 3, outputSize = 2; + + // Provide input of all ones. + arma::cube input = arma::ones(inputSize, outputSize, rho); + + arma::mat inputGate, forgetGate, outputGate, hidden; + arma::mat outLstm, cellLstm; + + // LSTM layer. + LSTM<> lstm(inputSize, outputSize, rho); + lstm.Reset(); + lstm.ResetCell(rho); + + // Initialize the weights to all ones. + lstm.Parameters().ones(); + + arma::mat inputWeight = arma::ones(outputSize, inputSize); + arma::mat outputWeight = arma::ones(outputSize, outputSize); + arma::mat bias = arma::ones(outputSize, input.n_cols); + arma::mat cellCalc = arma::zeros(outputSize, input.n_cols); + arma::mat outCalc = arma::zeros(outputSize, input.n_cols); + + for (size_t seqNum = 0; seqNum < rho; ++seqNum) + { + // Wrap a matrix around our data to avoid a copy. + arma::mat stepData(input.slice(seqNum).memptr(), + input.n_rows, input.n_cols, false, true); + + // Apply Forward() on LSTM layer. + lstm.Forward(std::move(stepData), // Input. + std::move(outLstm), // Output. + std::move(cellLstm), // Cell state. + false); // Don't write into the cell state. + + // Compute the value of cell state and output. + // i = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). + inputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + + outputWeight * outCalc + outputWeight % cellCalc + bias))); + + // f = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). + forgetGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + + outputWeight * outCalc + outputWeight % cellCalc + bias))); + + // z = tanh(W.dot(x) + W.dot(h) + b). + hidden = arma::tanh(inputWeight * stepData + + outputWeight * outCalc + bias); + + // c = f * c + i * z. + cellCalc = forgetGate % cellCalc + inputGate % hidden; + + // o = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). + outputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + + outputWeight * outCalc + outputWeight % cellCalc + bias))); + + // h = o * tanh(c). + outCalc = outputGate % arma::tanh(cellCalc); + + CheckMatrices(outLstm, outCalc, 1e-12); + CheckMatrices(cellLstm, cellCalc, 1e-12); + } +} + +/** + * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell + * state. Besides output, the overloaded function provides write access to cell + * state of the LSTM layer. + */ +BOOST_AUTO_TEST_CASE(WriteCellStateParamLSTMLayerTest) +{ + const size_t rho = 5, inputSize = 3, outputSize = 2; + + // Provide input of all ones. + arma::cube input = arma::ones(inputSize, outputSize, rho); + + arma::mat inputGate, forgetGate, outputGate, hidden; + arma::mat outLstm, cellLstm; + arma::mat cellCalc; + + // LSTM layer. + LSTM<> lstm(inputSize, outputSize, rho); + lstm.Reset(); + lstm.ResetCell(rho); + + // Initialize the weights to all ones. + lstm.Parameters().ones(); + + arma::mat inputWeight = arma::ones(outputSize, inputSize); + arma::mat outputWeight = arma::ones(outputSize, outputSize); + arma::mat bias = arma::ones(outputSize, input.n_cols); + arma::mat outCalc = arma::zeros(outputSize, input.n_cols); + + for (size_t seqNum = 0; seqNum < rho; ++seqNum) + { + // Wrap a matrix around our data to avoid a copy. + arma::mat stepData(input.slice(seqNum).memptr(), + input.n_rows, input.n_cols, false, true); + + if (cellLstm.is_empty()) + { + // Set the cell state to zeros. + cellLstm = arma::zeros(outputSize, input.n_cols); + cellCalc = arma::zeros(outputSize, input.n_cols); + } + else + { + // Set the cell state to zeros. + cellLstm = arma::zeros(cellLstm.n_rows, cellLstm.n_cols); + cellCalc = arma::zeros(cellCalc.n_rows, cellCalc.n_cols); + } + + // Apply Forward() on the LSTM layer. + lstm.Forward(std::move(stepData), // Input. + std::move(outLstm), // Output. + std::move(cellLstm), // Cell state. + true); // Write into cell state. + + // Compute the value of cell state and output. + // i = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). + inputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + + outputWeight * outCalc + outputWeight % cellCalc + bias))); + + // f = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). + forgetGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + + outputWeight * outCalc + outputWeight % cellCalc + bias))); + + // z = tanh(W.dot(x) + W.dot(h) + b). + hidden = arma::tanh(inputWeight * stepData + + outputWeight * outCalc + bias); + + // c = f * c + i * z. + cellCalc = forgetGate % cellCalc + inputGate % hidden; + + // o = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). + outputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + + outputWeight * outCalc + outputWeight % cellCalc + bias))); + + // h = o * tanh(c). + outCalc = outputGate % arma::tanh(cellCalc); + + CheckMatrices(outLstm, outCalc, 1e-12); + CheckMatrices(cellLstm, cellCalc, 1e-12); + } + + // Attempting to write empty matrix into cell state. + lstm.Reset(); + lstm.ResetCell(rho); + arma::mat stepData(input.slice(0).memptr(), + input.n_rows, input.n_cols, false, true); + + lstm.Forward(std::move(stepData), // Input. + std::move(outLstm), // Output. + std::move(cellLstm), // Cell state. + true); // Write into cell state. + + for (size_t seqNum = 1; seqNum < rho; ++seqNum) + { + arma::mat empty; + // Should throw error. + BOOST_REQUIRE_THROW(lstm.Forward(std::move(stepData), // Input. + std::move(outLstm), // Output. + std::move(empty), // Cell state. + true), // Write into cell state. + std::runtime_error); + } +} + +/** + * Check if the gradients computed by GRU cell are close enough to the + * approximation of the gradients. + */ +BOOST_AUTO_TEST_CASE(GradientGRULayerTest) +{ + // GRU function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(1, 1, 5); + target = arma::ones(1, 1, 5); + const size_t rho = 5; + + model = new RNN >(rho); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(1, 10); + model->Add >(10, 3, rho); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + arma::mat output; + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + RNN >* model; + arma::cube input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * GRU layer manual forward test. + */ +BOOST_AUTO_TEST_CASE(ForwardGRULayerTest) +{ + GRU<> gru(3, 3, 5); + + // Initialize the weights to all ones. + NetworkInitialization + networkInit(ConstInitialization(1)); + networkInit.Initialize(gru.Model(), gru.Parameters()); + + // Provide input of all ones. + arma::mat input = arma::ones(3, 1); + arma::mat output; + + gru.Forward(std::move(input), std::move(output)); + + // Compute the z_t gate output. + arma::mat expectedOutput = arma::ones(3, 1); + expectedOutput *= -4; + expectedOutput = arma::exp(expectedOutput); + expectedOutput = arma::ones(3, 1) / (arma::ones(3, 1) + expectedOutput); + expectedOutput = (arma::ones(3, 1) - expectedOutput) % expectedOutput; + + // For the first input the output should be equal to the output of + // gate z_t as the previous output fed to the cell is all zeros. + BOOST_REQUIRE_LE(arma::as_scalar(arma::trans(output) * expectedOutput), 1e-2); + + expectedOutput = output; + + gru.Forward(std::move(input), std::move(output)); + + double s = arma::as_scalar(arma::sum(expectedOutput)); + + // Compute the value of z_t gate for the second input. + arma::mat z_t = arma::ones(3, 1); + z_t *= -(s + 4); + z_t = arma::exp(z_t); + z_t = arma::ones(3, 1) / (arma::ones(3, 1) + z_t); + + // Compute the value of o_t gate for the second input. + arma::mat o_t = arma::ones(3, 1); + o_t *= -(arma::as_scalar(arma::sum(expectedOutput % z_t)) + 4); + o_t = arma::exp(o_t); + o_t = arma::ones(3, 1) / (arma::ones(3, 1) + o_t); + + // Expected output for the second input. + expectedOutput = z_t % expectedOutput + (arma::ones(3, 1) - z_t) % o_t; + + BOOST_REQUIRE_LE(arma::as_scalar(arma::trans(output) * expectedOutput), 1e-2); +} + +/** + * Simple concat module test. + */ +BOOST_AUTO_TEST_CASE(SimpleConcatLayerTest) +{ + arma::mat output, input, delta, error; + + Linear<> moduleA(10, 10); + moduleA.Parameters().randu(); + moduleA.Reset(); + + Linear<> moduleB(10, 10); + moduleB.Parameters().randu(); + moduleB.Reset(); + + Concat<> module; + module.Add(moduleA); + module.Add(moduleB); + + // Test the Forward function. + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_CLOSE(arma::accu( + moduleA.Parameters().submat(100, 0, moduleA.Parameters().n_elem - 1, 0)) + + arma::accu(moduleB.Parameters().submat(100, 0, + moduleB.Parameters().n_elem - 1, 0)), + arma::accu(output.col(0)), 1e-3); + + // Test the Backward function. + error = arma::zeros(20, 1); + module.Backward(std::move(input), std::move(error), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +/** + * Test to check Concat layer along different axes. + */ +BOOST_AUTO_TEST_CASE(ConcatAlongAxisTest) +{ + arma::mat output, input, input2, input3, error, outputA, outputB; + size_t inputWidth = 4, inputHeight = 4, inputChannel = 2; + size_t outputWidth, outputHeight, outputChannel = 2; + size_t kW = 3, kH = 3; + size_t batch = 1; + + // Using Convolution<> layer as inout to Concat<> layer. + // Compute the output shape of convolution layer. + outputWidth = (inputWidth - kW) + 1; + outputHeight = (inputHeight - kH) + 1; + + input = arma::ones(inputWidth * inputHeight * inputChannel, batch); + input2 = input; + input3 = input; + + Convolution<> moduleA(inputChannel, outputChannel, kW, kH, 1, 1, 0, 0, + inputWidth, inputHeight); + Convolution<> moduleB(inputChannel, outputChannel, kW, kH, 1, 1, 0, 0, + inputWidth, inputHeight); + + moduleA.Reset(); + moduleA.Parameters().randu(); + moduleB.Reset(); + moduleB.Parameters().randu(); + + // Compute output of each layer. + moduleA.Forward(std::move(input), std::move(outputA)); + moduleB.Forward(std::move(input2), std::move(outputB)); + + arma::cube A(outputA.memptr(), outputWidth, outputHeight, outputChannel); + arma::cube B(outputB.memptr(), outputWidth, outputHeight, outputChannel); + + error = arma::ones(outputWidth * outputHeight * outputChannel * 2, 1); + + for (size_t axis = 0; axis < 3; ++axis) + { + size_t x = 1, y = 1, z = 1; + arma::cube calculatedOut; + if (axis == 0) + { + calculatedOut.set_size(2 * outputWidth, outputHeight, outputChannel); + for (size_t i = 0; i < A.n_slices; ++i) + { + arma::mat aMat = A.slice(i); + arma::mat bMat = B.slice(i); + calculatedOut.slice(i) = arma::join_cols(aMat, bMat); + } + x = 2; + } + if (axis == 1) + { + calculatedOut.set_size(outputWidth, 2 * outputHeight, outputChannel); + for (size_t i = 0; i < A.n_slices; ++i) + { + arma::mat aMat = A.slice(i); + arma::mat bMat = B.slice(i); + calculatedOut.slice(i) = arma::join_rows(aMat, bMat); + } + y = 2; + } + if (axis == 2) + { + calculatedOut = arma::join_slices(A, B); + z = 2; + } + + // Compute output of Concat<> layer. + arma::Row inputSize{outputWidth, outputHeight, outputChannel}; + Concat<> module(inputSize, axis); + module.Add(moduleA); + module.Add(moduleB); + arma::mat tmpInput(input3); + module.Forward(std::move(tmpInput), std::move(output)); + arma::cube concatOut(output.memptr(), x * outputWidth, + y * outputHeight, z * outputChannel); + + // Verify if the output reshaped to cubes are similar. + CheckMatrices(concatOut, calculatedOut, 1e-12); + } +} + +/** + * Concat layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientConcatLayerTest) +{ + // Concat function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + + concat = new Concat<>(true); + concat->Add >(10, 2); + model->Add(concat); + + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + Concat<>* concat; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Simple concatenate module test. + */ +BOOST_AUTO_TEST_CASE(SimpleConcatenateLayerTest) +{ + arma::mat input = arma::ones(5, 1); + arma::mat output, delta; + + Concatenate<> module; + module.Concat() = arma::ones(5, 1) * 0.5; + + // Test the Forward function. + module.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), 7.5); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 5); +} + +/** + * Concatenate layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientConcatenateLayerTest) +{ + // Concatenate function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 5); + + arma::mat concat = arma::ones(5, 1); + concatenate = new Concatenate<>(); + concatenate->Concat() = concat; + model->Add(concatenate); + + model->Add >(10, 5); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + Concatenate<>* concatenate; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Simple lookup module test. + */ +BOOST_AUTO_TEST_CASE(SimpleLookupLayerTest) +{ + arma::mat output, input, delta, gradient; + Lookup<> module(10, 5); + module.Parameters().randu(); + + // Test the Forward function. + input = arma::zeros(2, 1); + input(0) = 1; + input(1) = 3; + + module.Forward(std::move(input), std::move(output)); + + // The Lookup module uses index - 1 for the cols. + const double outputSum = arma::accu(module.Parameters().col(0)) + + arma::accu(module.Parameters().col(2)); + + BOOST_REQUIRE_CLOSE(outputSum, arma::accu(output), 1e-3); + + // Test the Backward function. + module.Backward(std::move(input), std::move(input), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(input)); + + // Test the Gradient function. + arma::mat error = arma::ones(2, 5); + error = error.t(); + error.col(1) *= 0.5; + + module.Gradient(std::move(input), std::move(error), std::move(gradient)); + + // The Lookup module uses index - 1 for the cols. + const double gradientSum = arma::accu(gradient.col(0)) + + arma::accu(gradient.col(2)); + + BOOST_REQUIRE_CLOSE(gradientSum, arma::accu(error), 1e-3); + BOOST_REQUIRE_CLOSE(arma::accu(gradient), arma::accu(error), 1e-3); +} + +/** + * Simple LogSoftMax module test. + */ +BOOST_AUTO_TEST_CASE(SimpleLogSoftmaxLayerTest) +{ + arma::mat output, input, error, delta; + LogSoftMax<> module; + + // Test the Forward function. + input = arma::mat("0.5; 0.5"); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_SMALL(arma::accu(arma::abs( + arma::mat("-0.6931; -0.6931") - output)), 1e-3); + + // Test the Backward function. + error = arma::zeros(input.n_rows, input.n_cols); + // Assume LogSoftmax layer is always associated with NLL output layer. + error(1, 0) = -1; + module.Backward(std::move(input), std::move(error), std::move(delta)); + BOOST_REQUIRE_SMALL(arma::accu(arma::abs( + arma::mat("1.6487; 0.6487") - delta)), 1e-3); +} + +/* + * Simple test for the BilinearInterpolation layer + */ +BOOST_AUTO_TEST_CASE(SimpleBilinearInterpolationLayerTest) +{ + // Tested output against tensorflow.image.resize_bilinear() + arma::mat input, output, unzoomedOutput, expectedOutput; + size_t inRowSize = 2; + size_t inColSize = 2; + size_t outRowSize = 5; + size_t outColSize = 5; + size_t depth = 1; + input.zeros(inRowSize * inColSize * depth, 1); + input[0] = 1.0; + input[1] = input[2] = 2.0; + input[3] = 3.0; + BilinearInterpolation<> layer(inRowSize, inColSize, outRowSize, outColSize, + depth); + expectedOutput = arma::mat("1.0000 1.4000 1.8000 2.0000 2.0000 \ + 1.4000 1.8000 2.2000 2.4000 2.4000 \ + 1.8000 2.2000 2.6000 2.8000 2.8000 \ + 2.0000 2.4000 2.8000 3.0000 3.0000 \ + 2.0000 2.4000 2.8000 3.0000 3.0000"); + expectedOutput.reshape(25, 1); + layer.Forward(std::move(input), std::move(output)); + CheckMatrices(output - expectedOutput, arma::zeros(output.n_rows), 1e-12); + + expectedOutput = arma::mat("1.0000 1.9000 1.9000 2.8000"); + expectedOutput.reshape(4, 1); + layer.Backward(std::move(output), std::move(output), + std::move(unzoomedOutput)); + CheckMatrices(unzoomedOutput - expectedOutput, + arma::zeros(input.n_rows), 1e-12); +} + +/** + * Tests the BatchNorm Layer, compares the layers parameters with + * the values from another implementation. + * Link to the implementation - http://cthorey.github.io./backpropagation/ + */ +BOOST_AUTO_TEST_CASE(BatchNormTest) +{ + arma::mat input, output; + input << 5.1 << 3.5 << 1.4 << arma::endr + << 4.9 << 3.0 << 1.4 << arma::endr + << 4.7 << 3.2 << 1.3 << arma::endr; + + BatchNorm<> model(input.n_rows); + model.Reset(); + + // Non-Deteministic Forward Pass Test. + model.Deterministic() = false; + model.Forward(std::move(input), std::move(output)); + arma::mat result; + result << 1.1658 << 0.1100 << -1.2758 << arma::endr + << 1.2579 << -0.0699 << -1.1880 << arma::endr + << 1.1737 << 0.0958 << -1.2695 << arma::endr; + + CheckMatrices(output, result, 1e-1); + result.clear(); + + // Deterministic Forward Pass test. + output = model.TrainingMean(); + result << 3.33333333 << arma::endr + << 3.1 << arma::endr + << 3.06666666 << arma::endr; + + CheckMatrices(output, result, 1e-1); + result.clear(); + + output = model.TrainingVariance(); + result << 2.2956 << arma::endr + << 2.0467 << arma::endr + << 1.9356 << arma::endr; + + CheckMatrices(output, result, 1e-1); + result.clear(); + + model.Deterministic() = true; + model.Forward(std::move(input), std::move(output)); + + result << 1.1658 << 0.1100 << -1.2757 << arma::endr + << 1.2579 << -0.0699 << -1.1880 << arma::endr + << 1.1737 << 0.0958 << -1.2695 << arma::endr; + + CheckMatrices(output, result, 1e-1); +} + +/** + * BatchNorm layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientBatchNormTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randn(10, 256); + arma::mat target; + target.ones(1, 256); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + model->Add >(10); + model->Add >(10, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 256, false); + model->Gradient(model->Parameters(), 0, gradient, 256); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * VirtualBatchNorm layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientVirtualBatchNormTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randn(5, 256); + arma::mat referenceBatch = arma::mat(input.memptr(), input.n_rows, 16); + arma::mat target; + target.ones(1, 256); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(5, 5); + model->Add >(referenceBatch, 5); + model->Add >(5, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 256, false); + model->Gradient(model->Parameters(), 0, gradient, 256); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * MiniBatchDiscrimination layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(MiniBatchDiscriminationTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randn(5, 4); + arma::mat target; + target.ones(1, 4); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(5, 5); + model->Add >(5, 10, 16); + model->Add >(10, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + return model->EvaluateWithGradient(model->Parameters(), 0, gradient, 4); + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Simple Transposed Convolution layer test. + */ +BOOST_AUTO_TEST_CASE(SimpleTransposedConvolutionLayerTest) +{ + arma::mat output, input, delta; + + TransposedConvolution<> module1(1, 1, 3, 3, 1, 1, 0, 0, 4, 4, 6, 6); + // Test the forward function. + input = arma::linspace(0, 15, 16); + module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module1.Parameters()(0) = 1.0; + module1.Parameters()(8) = 2.0; + module1.Reset(); + module1.Forward(std::move(input), std::move(output)); + // Value calculated using tensorflow.nn.conv2d_transpose() + BOOST_REQUIRE_EQUAL(arma::accu(output), 360.0); + + // Test the backward function. + module1.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using tensorflow.nn.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 720.0); + + TransposedConvolution<> module2(1, 1, 4, 4, 1, 1, 1, 1, 5, 5, 6, 6); + // Test the forward function. + input = arma::linspace(0, 24, 25); + module2.Parameters() = arma::mat(16 + 1, 1, arma::fill::zeros); + module2.Parameters()(0) = 1.0; + module2.Parameters()(3) = 1.0; + module2.Parameters()(6) = 1.0; + module2.Parameters()(9) = 1.0; + module2.Parameters()(12) = 1.0; + module2.Parameters()(15) = 2.0; + module2.Reset(); + module2.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 1512.0); + + // Test the backward function. + module2.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using torch.nn.functional.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 6504.0); + + TransposedConvolution<> module3(1, 1, 3, 3, 1, 1, 1, 1, 5, 5, 5, 5); + // Test the forward function. + input = arma::linspace(0, 24, 25); + module3.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module3.Parameters()(1) = 2.0; + module3.Parameters()(2) = 4.0; + module3.Parameters()(3) = 3.0; + module3.Parameters()(8) = 1.0; + module3.Reset(); + module3.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 2370.0); + + // Test the backward function. + module3.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using torch.nn.functional.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 19154.0); + + TransposedConvolution<> module4(1, 1, 3, 3, 1, 1, 0, 0, 5, 5, 7, 7); + // Test the forward function. + input = arma::linspace(0, 24, 25); + module4.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module4.Parameters()(2) = 2.0; + module4.Parameters()(4) = 4.0; + module4.Parameters()(6) = 6.0; + module4.Parameters()(8) = 8.0; + module4.Reset(); + module4.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 6000.0); + + // Test the backward function. + module4.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using torch.nn.functional.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 86208.0); + + TransposedConvolution<> module5(1, 1, 3, 3, 2, 2, 0, 0, 2, 2, 5, 5); + // Test the forward function. + input = arma::linspace(0, 3, 4); + module5.Parameters() = arma::mat(25 + 1, 1, arma::fill::zeros); + module5.Parameters()(2) = 8.0; + module5.Parameters()(4) = 6.0; + module5.Parameters()(6) = 4.0; + module5.Parameters()(8) = 2.0; + module5.Reset(); + module5.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 120.0); + + // Test the backward function. + module5.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using torch.nn.functional.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 960.0); + + TransposedConvolution<> module6(1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 5, 5); + // Test the forward function. + input = arma::linspace(0, 8, 9); + module6.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module6.Parameters()(0) = 8.0; + module6.Parameters()(3) = 6.0; + module6.Parameters()(6) = 2.0; + module6.Parameters()(8) = 4.0; + module6.Reset(); + module6.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 410.0); + + // Test the backward function. + module6.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using torch.nn.functional.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 4444.0); + + TransposedConvolution<> module7(1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 6, 6); + // Test the forward function. + input = arma::linspace(0, 8, 9); + module7.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module7.Parameters()(0) = 8.0; + module7.Parameters()(2) = 6.0; + module7.Parameters()(4) = 2.0; + module7.Parameters()(8) = 4.0; + module7.Reset(); + module7.Forward(std::move(input), std::move(output)); + // Value calculated using torch.nn.functional.conv_transpose2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 606.0); + + module7.Backward(std::move(input), std::move(output), std::move(delta)); + // Value calculated using torch.nn.functional.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(delta), 7732.0); +} + +/** + * Transposed Convolution layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientTransposedConvolutionLayerTest) +{ + // Add function gradient instantiation. + // To make this test robust, check it five times. + bool pass = false; + for (size_t trial = 0; trial < 5; trial++) + { + struct GradientFunction + { + GradientFunction() + { + input = arma::linspace(0, 35, 36); + target = arma::mat("1"); + + model = new FFN, RandomInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add > + (1, 1, 3, 3, 2, 2, 1, 1, 6, 6, 12, 12); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, RandomInitialization>* model; + arma::mat input, target; + } function; + + if (CheckGradient(function) < 1e-3) + { + pass = true; + break; + } + } + BOOST_REQUIRE_EQUAL(pass, true); +} + +/** + * Simple MultiplyMerge module test. + */ +BOOST_AUTO_TEST_CASE(SimpleMultiplyMergeLayerTest) +{ + arma::mat output, input, delta; + input = arma::ones(10, 1); + + for (size_t i = 0; i < 5; ++i) + { + MultiplyMerge<> module(false, false); + const size_t numMergeModules = math::RandInt(2, 10); + for (size_t m = 0; m < numMergeModules; ++m) + { + IdentityLayer<> identityLayer; + identityLayer.Forward(std::move(input), + std::move(identityLayer.OutputParameter())); + + module.Add >(identityLayer); + } + + // Test the Forward function. + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(10, arma::accu(output)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(delta)); + } +} + +/** + * Simple Atrous Convolution layer test. + */ +BOOST_AUTO_TEST_CASE(SimpleAtrousConvolutionLayerTest) +{ + arma::mat output, input, delta; + + AtrousConvolution<> module1(1, 1, 3, 3, 1, 1, 0, 0, 7, 7, 2, 2); + // Test the Forward function. + input = arma::linspace(0, 48, 49); + module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module1.Parameters()(0) = 1.0; + module1.Parameters()(8) = 2.0; + module1.Reset(); + module1.Forward(std::move(input), std::move(output)); + // Value calculated using tensorflow.nn.atrous_conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 792.0); + + // Test the Backward function. + module1.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 2376); + + AtrousConvolution<> module2(1, 1, 3, 3, 2, 2, 0, 0, 7, 7, 2, 2); + // Test the forward function. + input = arma::linspace(0, 48, 49); + module2.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module2.Parameters()(0) = 1.0; + module2.Parameters()(3) = 1.0; + module2.Parameters()(6) = 1.0; + module2.Reset(); + module2.Forward(std::move(input), std::move(output)); + // Value calculated using tensorflow.nn.conv2d() + BOOST_REQUIRE_EQUAL(arma::accu(output), 264.0); + + // Test the backward function. + module2.Backward(std::move(input), std::move(output), std::move(delta)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 792.0); +} + +/** + * Atrous Convolution layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientAtrousConvolutionLayerTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::linspace(0, 35, 36); + target = arma::mat("1"); + + model = new FFN, RandomInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(1, 1, 3, 3, 1, 1, 0, 0, 6, 6, 2, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, RandomInitialization>* model; + arma::mat input, target; + } function; + + // TODO: this tolerance seems far higher than necessary. The implementation + // should be checked. + BOOST_REQUIRE_LE(CheckGradient(function), 0.2); +} + +/** + * Test the functions to access and modify the parameters of the + * AtrousConvolution layer. + */ +BOOST_AUTO_TEST_CASE(AtrousConvolutionLayerParametersTest) +{ + // Parameter order for the constructor: inSize, outSize, kW, kH, dW, dH, padW, + // padH, inputWidth, inputHeight, dilationW, dilationH, paddingType ("none"). + AtrousConvolution<> layer1(1, 2, 3, 4, 5, 6, std::make_tuple(7, 8), + std::make_tuple(9, 10), 11, 12, 13, 14); + AtrousConvolution<> layer2(2, 3, 4, 5, 6, 7, std::make_tuple(8, 9), + std::make_tuple(10, 11), 12, 13, 14, 15); + + // Make sure we can get the parameters successfully. + BOOST_REQUIRE_EQUAL(layer1.InputWidth(), 11); + BOOST_REQUIRE_EQUAL(layer1.InputHeight(), 12); + BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), 3); + BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), 4); + BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), 5); + BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), 6); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadHTop(), 9); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadHBottom(), 10); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadWLeft(), 7); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadWRight(), 8); + BOOST_REQUIRE_EQUAL(layer1.DilationWidth(), 13); + BOOST_REQUIRE_EQUAL(layer1.DilationHeight(), 14); + + // Now modify the parameters to match the second layer. + layer1.InputWidth() = 12; + layer1.InputHeight() = 13; + layer1.KernelWidth() = 4; + layer1.KernelHeight() = 5; + layer1.StrideWidth() = 6; + layer1.StrideHeight() = 7; + layer1.Padding().PadHTop() = 10; + layer1.Padding().PadHBottom() = 11; + layer1.Padding().PadWLeft() = 8; + layer1.Padding().PadWRight() = 9; + layer1.DilationWidth() = 14; + layer1.DilationHeight() = 15; + + // Now ensure all results are the same. + BOOST_REQUIRE_EQUAL(layer1.InputWidth(), layer2.InputWidth()); + BOOST_REQUIRE_EQUAL(layer1.InputHeight(), layer2.InputHeight()); + BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), layer2.KernelWidth()); + BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), layer2.KernelHeight()); + BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), layer2.StrideWidth()); + BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), layer2.StrideHeight()); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadHTop(), layer2.Padding().PadHTop()); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadHBottom(), + layer2.Padding().PadHBottom()); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadWLeft(), + layer2.Padding().PadWLeft()); + BOOST_REQUIRE_EQUAL(layer1.Padding().PadWRight(), + layer2.Padding().PadWRight()); + BOOST_REQUIRE_EQUAL(layer1.DilationWidth(), layer2.DilationWidth()); + BOOST_REQUIRE_EQUAL(layer1.DilationHeight(), layer2.DilationHeight()); +} + +/** + * Test that the padding options are working correctly in Atrous Convolution + * layer. + */ +BOOST_AUTO_TEST_CASE(AtrousConvolutionLayerPaddingTest) +{ + arma::mat output, input, delta; + + // Check valid padding option. + AtrousConvolution<> module1(1, 1, 3, 3, 1, 1, + std::tuple(1, 1), std::tuple(1, 1), 7, 7, + 2, 2, "valid"); + + // Test the Forward function. + input = arma::linspace(0, 48, 49); + module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module1.Reset(); + module1.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, 9); + BOOST_REQUIRE_EQUAL(output.n_cols, 1); + + // Test the Backward function. + module1.Backward(std::move(input), std::move(output), std::move(delta)); + + // Check same padding option. + AtrousConvolution<> module2(1, 1, 3, 3, 1, 1, + std::tuple(0, 0), std::tuple(0, 0), 7, 7, + 2, 2, "same"); + + // Test the forward function. + input = arma::linspace(0, 48, 49); + module2.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module2.Reset(); + module2.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, 49); + BOOST_REQUIRE_EQUAL(output.n_cols, 1); + + // Test the backward function. + module2.Backward(std::move(input), std::move(output), std::move(delta)); +} + +/** + * Tests the LayerNorm layer. + */ +BOOST_AUTO_TEST_CASE(LayerNormTest) +{ + arma::mat input, output; + input << 5.1 << 3.5 << arma::endr + << 4.9 << 3.0 << arma::endr + << 4.7 << 3.2 << arma::endr; + + LayerNorm<> model(input.n_rows); + model.Reset(); + + model.Forward(std::move(input), std::move(output)); + arma::mat result; + result << 1.2247 << 1.2978 << arma::endr + << 0 << -1.1355 << arma::endr + << -1.2247 << -0.1622 << arma::endr; + + CheckMatrices(output, result, 1e-1); + result.clear(); + + output = model.Mean(); + result << 4.9000 << 3.2333 << arma::endr; + + CheckMatrices(output, result, 1e-1); + result.clear(); + + output = model.Variance(); + result << 0.0267 << 0.0422 << arma::endr; + + CheckMatrices(output, result, 1e-1); +} + +/** + * LayerNorm layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientLayerNormTest) +{ + // Add function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randn(10, 256); + arma::mat target; + target.ones(1, 256); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + model->Add >(10); + model->Add >(10, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 256, false); + model->Gradient(model->Parameters(), 0, gradient, 256); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Test if the AddMerge layer is able to forward the + * Forward/Backward/Gradient calls. + */ +BOOST_AUTO_TEST_CASE(AddMergeRunTest) +{ + arma::mat output, input, delta, error; + + AddMerge<> module(true, true); + + Linear<>* linear = new Linear<>(10, 10); + module.Add(linear); + + linear->Parameters().randu(); + linear->Reset(); + + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + + double parameterSum = arma::accu(linear->Parameters().submat( + 100, 0, linear->Parameters().n_elem - 1, 0)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(input), std::move(delta)); + + // Clean up before we break, + delete linear; + + BOOST_REQUIRE_CLOSE(parameterSum, arma::accu(output), 1e-3); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +/** + * Test if the MultiplyMerge layer is able to forward the + * Forward/Backward/Gradient calls. + */ +BOOST_AUTO_TEST_CASE(MultiplyMergeRunTest) +{ + arma::mat output, input, delta, error; + + MultiplyMerge<> module(true, true); + + Linear<>* linear = new Linear<>(10, 10); + module.Add(linear); + + linear->Parameters().randu(); + linear->Reset(); + + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + + double parameterSum = arma::accu(linear->Parameters().submat( + 100, 0, linear->Parameters().n_elem - 1, 0)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(input), std::move(delta)); + + // Clean up before we break, + delete linear; + + BOOST_REQUIRE_CLOSE(parameterSum, arma::accu(output), 1e-3); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +/** + * Simple subview module test. + */ +BOOST_AUTO_TEST_CASE(SimpleSubviewLayerTest) +{ + arma::mat output, input, delta, outputMat; + Subview<> moduleRow(1, 10, 19); + + // Test the Forward function for a vector. + input = arma::ones(20, 1); + moduleRow.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_EQUAL(output.n_rows, 10); + + Subview<> moduleMat(4, 3, 6, 0, 2); + + // Test the Forward function for a matrix. + input = arma::ones(20, 8); + moduleMat.Forward(std::move(input), std::move(outputMat)); + BOOST_REQUIRE_EQUAL(outputMat.n_rows, 12); + BOOST_REQUIRE_EQUAL(outputMat.n_cols, 2); + + // Test the Backward function. + moduleMat.Backward(std::move(input), std::move(input), std::move(delta)); + BOOST_REQUIRE_EQUAL(accu(delta), 160); + BOOST_REQUIRE_EQUAL(delta.n_rows, 20); +} + +/** + * Subview index test. + */ +BOOST_AUTO_TEST_CASE(SubviewIndexTest) +{ + arma::mat outputEnd, outputMid, outputStart, input, delta; + input = arma::linspace(1, 20, 20); + + // Slicing from the initial indices. + Subview<> moduleStart(1, 0, 9); + arma::mat subStart = arma::linspace(1, 10, 10); + + moduleStart.Forward(std::move(input), std::move(outputStart)); + CheckMatrices(outputStart, subStart); + + // Slicing from the mid indices. + Subview<> moduleMid(1, 6, 15); + arma::mat subMid = arma::linspace(7, 16, 10); + + moduleMid.Forward(std::move(input), std::move(outputMid)); + CheckMatrices(outputMid, subMid); + + // Slicing from the end indices. + Subview<> moduleEnd(1, 10, 19); + arma::mat subEnd = arma::linspace(11, 20, 10); + + moduleEnd.Forward(std::move(input), std::move(outputEnd)); + CheckMatrices(outputEnd, subEnd); +} + +/** + * Subview batch test. + */ +BOOST_AUTO_TEST_CASE(SubviewBatchTest) +{ + arma::mat output, input, outputCol, outputMat, outputDef; + + // All rows selected. + Subview<> moduleCol(1, 0, 19); + + // Test with inSize 1. + input = arma::ones(20, 8); + moduleCol.Forward(std::move(input), std::move(outputCol)); + CheckMatrices(outputCol, input); + + // Few rows and columns selected. + Subview<> moduleMat(4, 3, 6, 0, 2); + + // Test with inSize greater than 1. + moduleMat.Forward(std::move(input), std::move(outputMat)); + output = arma::ones(12, 2); + CheckMatrices(outputMat, output); + + // endCol changed to 3 by default. + Subview<> moduleDef(4, 1, 6, 0, 4); + + // Test with inSize greater than 1 and endCol >= inSize. + moduleDef.Forward(std::move(input), std::move(outputDef)); + output = arma::ones(24, 2); + CheckMatrices(outputDef, output); +} + +/* + * Simple Reparametrization module test. + */ +BOOST_AUTO_TEST_CASE(SimpleReparametrizationLayerTest) +{ + arma::mat input, output, delta; + Reparametrization<> module(5); + + // Test the Forward function. As the mean is zero and the standard + // deviation is small, after multiplying the gaussian sample, the + // output should be small enough. + input = join_cols(arma::ones(5, 1) * -15, + arma::zeros(5, 1)); + module.Forward(std::move(input), std::move(output)); + BOOST_REQUIRE_LE(arma::accu(output), 1e-5); + + // Test the Backward function. + arma::mat gy = arma::zeros(5, 1); + module.Backward(std::move(input), std::move(gy), std::move(delta)); + BOOST_REQUIRE(arma::accu(delta) != 0); // klBackward will be added. +} + +/** + * Reparametrization module stochastic boolean test. + */ +BOOST_AUTO_TEST_CASE(ReparametrizationLayerStochasticTest) +{ + arma::mat input, outputA, outputB; + Reparametrization<> module(5, false); + + input = join_cols(arma::ones(5, 1), + arma::zeros(5, 1)); + + // Test if two forward passes generate same output. + module.Forward(std::move(input), std::move(outputA)); + module.Forward(std::move(input), std::move(outputB)); + + CheckMatrices(outputA, outputB); +} + +/** + * Reparametrization module includeKl boolean test. + */ +BOOST_AUTO_TEST_CASE(ReparametrizationLayerIncludeKlTest) +{ + arma::mat input, output, gy, delta; + Reparametrization<> module(5, true, false); + + input = join_cols(arma::ones(5, 1), + arma::zeros(5, 1)); + module.Forward(std::move(input), std::move(output)); + + // As KL divergence is not included, with the above inputs, the delta + // matrix should be all zeros. + gy = arma::zeros(output.n_rows, output.n_cols); + module.Backward(std::move(output), std::move(gy), std::move(delta)); + + BOOST_REQUIRE_EQUAL(arma::accu(std::move(delta)), 0); +} + +/** + * Jacobian Reparametrization module test. + */ +BOOST_AUTO_TEST_CASE(JacobianReparametrizationLayerTest) +{ + for (size_t i = 0; i < 5; i++) + { + const size_t inputElementsHalf = math::RandInt(2, 1000); + + arma::mat input; + input.set_size(inputElementsHalf * 2, 1); + + Reparametrization<> module(inputElementsHalf, false, false); + + double error = JacobianTest(module, input); + BOOST_REQUIRE_LE(error, 1e-5); + } +} + +/** + * Reparametrization layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientReparametrizationLayerTest) +{ + // Linear function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 6); + model->Add >(3, false, true, 1); + model->Add >(3, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Reparametrization layer beta numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientReparametrizationLayerBetaTest) +{ + // Linear function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 2); + target = arma::mat("1 1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 6); + // Use a value of beta not equal to 1. + model->Add >(3, false, true, 2); + model->Add >(3, 2); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Simple residual module test. + */ +BOOST_AUTO_TEST_CASE(SimpleResidualLayerTest) +{ + arma::mat outputA, outputB, input, deltaA, deltaB; + + Sequential<>* sequential = new Sequential<>(true); + Residual<>* residual = new Residual<>(true); + + Linear<>* linearA = new Linear<>(10, 10); + linearA->Parameters().randu(); + linearA->Reset(); + Linear<>* linearB = new Linear<>(10, 10); + linearB->Parameters().randu(); + linearB->Reset(); + + // Add the same layers (with the same parameters) to both Sequential and + // Residual object. + sequential->Add(linearA); + sequential->Add(linearB); + + residual->Add(linearA); + residual->Add(linearB); + + // Test the Forward function (pass the same input to both). + input = arma::randu(10, 1); + sequential->Forward(std::move(input), std::move(outputA)); + residual->Forward(std::move(input), std::move(outputB)); + + CheckMatrices(outputA, outputB - input); + + // Test the Backward function (pass the same error to both). + sequential->Backward(std::move(input), std::move(input), std::move(deltaA)); + residual->Backward(std::move(input), std::move(input), std::move(deltaB)); + + CheckMatrices(deltaA, deltaB - input); + + delete sequential; + delete residual; + delete linearA; + delete linearB; +} + +/** + * Simple Highway module test. + */ +BOOST_AUTO_TEST_CASE(SimpleHighwayLayerTest) +{ + arma::mat outputA, outputB, input, deltaA, deltaB; + Sequential<>* sequential = new Sequential<>(true); + Highway<>* highway = new Highway<>(10, true); + highway->Parameters().zeros(); + highway->Reset(); + + Linear<>* linearA = new Linear<>(10, 10); + linearA->Parameters().randu(); + linearA->Reset(); + Linear<>* linearB = new Linear<>(10, 10); + linearB->Parameters().randu(); + linearB->Reset(); + + // Add the same layers (with the same parameters) to both Sequential and + // Highway object. + highway->Add(linearA); + highway->Add(linearB); + sequential->Add(linearA); + sequential->Add(linearB); + + // Test the Forward function (pass the same input to both). + input = arma::randu(10, 1); + sequential->Forward(std::move(input), std::move(outputA)); + highway->Forward(std::move(input), std::move(outputB)); + + CheckMatrices(outputB, input * 0.5 + outputA * 0.5); + + delete sequential; + delete highway; + delete linearA; + delete linearB; +} + +/** + * Sequential layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientHighwayLayerTest) +{ + // Linear function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(5, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(5, 10); + + highway = new Highway<>(10); + highway->Add >(10, 10); + highway->Add >(); + highway->Add >(10, 10); + highway->Add >(); + + model->Add(highway); + model->Add >(10, 2); + model->Add >(); + } + + ~GradientFunction() + { + highway->DeleteModules(); + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + Highway<>* highway; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Sequential layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientSequentialLayerTest) +{ + // Linear function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(); + model->Add >(10, 10); + sequential = new Sequential<>(); + sequential->Add >(10, 10); + sequential->Add >(); + sequential->Add >(10, 5); + sequential->Add >(); + + model->Add(sequential); + model->Add >(5, 2); + model->Add >(); + } + + ~GradientFunction() + { + sequential->DeleteModules(); + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + Sequential<>* sequential; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * WeightNorm layer numerical gradient test. + */ +BOOST_AUTO_TEST_CASE(GradientWeightNormLayerTest) +{ + // Linear function gradient instantiation. + struct GradientFunction + { + GradientFunction() + { + input = arma::randu(10, 1); + target = arma::mat("1"); + + model = new FFN, NguyenWidrowInitialization>(); + model->Predictors() = input; + model->Responses() = target; + model->Add >(10, 10); + + Linear<>* linear = new Linear<>(10, 2); + weightNorm = new WeightNorm<>(linear); + + model->Add(weightNorm); + model->Add >(); + } + + ~GradientFunction() + { + delete model; + } + + double Gradient(arma::mat& gradient) const + { + double error = model->Evaluate(model->Parameters(), 0, 1); + model->Gradient(model->Parameters(), 0, gradient, 1); + return error; + } + + arma::mat& Parameters() { return model->Parameters(); } + + FFN, NguyenWidrowInitialization>* model; + WeightNorm<>* weightNorm; + arma::mat input, target; + } function; + + BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); +} + +/** + * Test if the WeightNorm layer is able to forward the + * Forward/Backward/Gradient calls. + */ +BOOST_AUTO_TEST_CASE(WeightNormRunTest) +{ + arma::mat output, input, delta, error; + + Linear<>* linear = new Linear<>(10, 10); + + WeightNorm<> module(linear); + + module.Parameters().randu(); + module.Reset(); + + linear->Bias().zeros(); + + input = arma::zeros(10, 1); + module.Forward(std::move(input), std::move(output)); + + // Test the Backward function. + module.Backward(std::move(input), std::move(input), std::move(delta)); + + BOOST_REQUIRE_EQUAL(0, arma::accu(output)); + BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); +} + +// General ANN serialization test. +template +void ANNLayerSerializationTest(LayerType& layer) +{ + arma::mat input(5, 100, arma::fill::randu); + arma::mat output(5, 100, arma::fill::randu); + + FFN, ann::RandomInitialization> model; + model.Add>(input.n_rows, 10); + model.Add(layer); + model.Add>(); + model.Add>(10, output.n_rows); + model.Add>(); + + ens::StandardSGD opt(0.1, 1, 5, -100, false); + model.Train(input, output, opt); + + arma::mat originalOutput; + model.Predict(input, originalOutput); + + // Now serialize the model. + FFN, ann::RandomInitialization> xmlModel, textModel, + binaryModel; + SerializeObjectAll(model, xmlModel, textModel, binaryModel); + + // Ensure that predictions are the same. + arma::mat modelOutput, xmlOutput, textOutput, binaryOutput; + model.Predict(input, modelOutput); + xmlModel.Predict(input, xmlOutput); + textModel.Predict(input, textOutput); + binaryModel.Predict(input, binaryOutput); + + CheckMatrices(originalOutput, modelOutput, 1e-5); + CheckMatrices(originalOutput, xmlOutput, 1e-5); + CheckMatrices(originalOutput, textOutput, 1e-5); + CheckMatrices(originalOutput, binaryOutput, 1e-5); +} + +/** + * Simple serialization test for batch normalization layer. + */ +BOOST_AUTO_TEST_CASE(BatchNormSerializationTest) +{ + BatchNorm<> layer(10); + ANNLayerSerializationTest(layer); +} + +/** + * Simple serialization test for layer normalization layer. + */ +BOOST_AUTO_TEST_CASE(LayerNormSerializationTest) +{ + LayerNorm<> layer(10); + ANNLayerSerializationTest(layer); +} + +/** + * Test that the functions that can modify and access the parameters of the + * Convolution layer work. + */ +BOOST_AUTO_TEST_CASE(ConvolutionLayerParametersTest) +{ + // Parameter order: inSize, outSize, kW, kH, dW, dH, padW, padH, inputWidth, + // inputHeight, paddingType. + Convolution<> layer1(1, 2, 3, 4, 5, 6, std::tuple(7, 8), + std::tuple(9, 10), 11, 12, "none"); + Convolution<> layer2(2, 3, 4, 5, 6, 7, std::tuple(8, 9), + std::tuple(10, 11), 12, 13, "none"); + + // Make sure we can get the parameters successfully. + BOOST_REQUIRE_EQUAL(layer1.InputWidth(), 11); + BOOST_REQUIRE_EQUAL(layer1.InputHeight(), 12); + BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), 3); + BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), 4); + BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), 5); + BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), 6); + BOOST_REQUIRE_EQUAL(layer1.PadWLeft(), 7); + BOOST_REQUIRE_EQUAL(layer1.PadWRight(), 8); + BOOST_REQUIRE_EQUAL(layer1.PadHTop(), 9); + BOOST_REQUIRE_EQUAL(layer1.PadHBottom(), 10); + + // Now modify the parameters to match the second layer. + layer1.InputWidth() = 12; + layer1.InputHeight() = 13; + layer1.KernelWidth() = 4; + layer1.KernelHeight() = 5; + layer1.StrideWidth() = 6; + layer1.StrideHeight() = 7; + layer1.PadWLeft() = 8; + layer1.PadWRight() = 9; + layer1.PadHTop() = 10; + layer1.PadHBottom() = 11; + + // Now ensure all results are the same. + BOOST_REQUIRE_EQUAL(layer1.InputWidth(), layer2.InputWidth()); + BOOST_REQUIRE_EQUAL(layer1.InputHeight(), layer2.InputHeight()); + BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), layer2.KernelWidth()); + BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), layer2.KernelHeight()); + BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), layer2.StrideWidth()); + BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), layer2.StrideHeight()); + BOOST_REQUIRE_EQUAL(layer1.PadWLeft(), layer2.PadWLeft()); + BOOST_REQUIRE_EQUAL(layer1.PadWRight(), layer2.PadWRight()); + BOOST_REQUIRE_EQUAL(layer1.PadHTop(), layer2.PadHTop()); + BOOST_REQUIRE_EQUAL(layer1.PadHBottom(), layer2.PadHBottom()); +} + +/** + * Test that the padding options are working correctly in Convolution layer. + */ +BOOST_AUTO_TEST_CASE(ConvolutionLayerPaddingTest) +{ + arma::mat output, input, delta; + + // Check valid padding option. + Convolution<> module1(1, 1, 3, 3, 1, 1, std::tuple(1, 1), + std::tuple(1, 1), 7, 7, "valid"); + + // Test the Forward function. + input = arma::linspace(0, 48, 49); + module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module1.Reset(); + module1.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, 25); + BOOST_REQUIRE_EQUAL(output.n_cols, 1); + + // Test the Backward function. + module1.Backward(std::move(input), std::move(output), std::move(delta)); + + // Check same padding option. + Convolution<> module2(1, 1, 3, 3, 1, 1, std::tuple(0, 0), + std::tuple(0, 0), 7, 7, "same"); + + // Test the forward function. + input = arma::linspace(0, 48, 49); + module2.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); + module2.Reset(); + module2.Forward(std::move(input), std::move(output)); + + BOOST_REQUIRE_EQUAL(arma::accu(output), 0); + BOOST_REQUIRE_EQUAL(output.n_rows, 49); + BOOST_REQUIRE_EQUAL(output.n_cols, 1); + + // Test the backward function. + module2.Backward(std::move(input), std::move(output), std::move(delta)); +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 3950c1a2fd..0e30e7099b 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -26,7 +26,7 @@ #include "test_catch_tools.hpp" #include "catch.hpp" #include "ann_test_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::ann; diff --git a/src/mlpack/tests/ann_regularizer_test.cpp b/src/mlpack/tests/ann_regularizer_test.cpp index 2252852ee8..e300e6a9b1 100644 --- a/src/mlpack/tests/ann_regularizer_test.cpp +++ b/src/mlpack/tests/ann_regularizer_test.cpp @@ -18,7 +18,7 @@ #include "catch.hpp" #include "ann_test_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::ann; diff --git a/src/mlpack/tests/cf_test.cpp b/src/mlpack/tests/cf_test.cpp index 735fe65c20..22b513b531 100644 --- a/src/mlpack/tests/cf_test.cpp +++ b/src/mlpack/tests/cf_test.cpp @@ -37,7 +37,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::cf; diff --git a/src/mlpack/tests/convolution_test.cpp b/src/mlpack/tests/convolution_test.cpp index 02d3cd800d..c2798090ce 100644 --- a/src/mlpack/tests/convolution_test.cpp +++ b/src/mlpack/tests/convolution_test.cpp @@ -17,7 +17,7 @@ #include #include -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "catch.hpp" #include "test_catch_tools.hpp" diff --git a/src/mlpack/tests/convolutional_network_test.cpp b/src/mlpack/tests/convolutional_network_test.cpp index c04b3af701..ac5a3e4983 100644 --- a/src/mlpack/tests/convolutional_network_test.cpp +++ b/src/mlpack/tests/convolutional_network_test.cpp @@ -18,7 +18,7 @@ #include -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "catch.hpp" #include "test_catch_tools.hpp" diff --git a/src/mlpack/tests/dcgan_test.cpp b/src/mlpack/tests/dcgan_test.cpp index 2496cb1418..0fdfdbd496 100644 --- a/src/mlpack/tests/dcgan_test.cpp +++ b/src/mlpack/tests/dcgan_test.cpp @@ -22,7 +22,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::ann; diff --git a/src/mlpack/tests/decision_tree_test.cpp b/src/mlpack/tests/decision_tree_test.cpp index 67257c34fc..4b34df8de7 100644 --- a/src/mlpack/tests/decision_tree_test.cpp +++ b/src/mlpack/tests/decision_tree_test.cpp @@ -17,7 +17,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "mock_categorical_data.hpp" using namespace mlpack; diff --git a/src/mlpack/tests/distribution_test.cpp b/src/mlpack/tests/distribution_test.cpp index caf3540df1..99282e07ce 100644 --- a/src/mlpack/tests/distribution_test.cpp +++ b/src/mlpack/tests/distribution_test.cpp @@ -20,7 +20,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "test_catch_tools.hpp" using namespace mlpack; diff --git a/src/mlpack/tests/drusilla_select_test.cpp b/src/mlpack/tests/drusilla_select_test.cpp index e33ba16841..2c8e4c23bb 100644 --- a/src/mlpack/tests/drusilla_select_test.cpp +++ b/src/mlpack/tests/drusilla_select_test.cpp @@ -13,7 +13,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::neighbor; diff --git a/src/mlpack/tests/fastmks_test.cpp b/src/mlpack/tests/fastmks_test.cpp index 8f99e4f19f..3f50d8c9b4 100644 --- a/src/mlpack/tests/fastmks_test.cpp +++ b/src/mlpack/tests/fastmks_test.cpp @@ -14,7 +14,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::tree; diff --git a/src/mlpack/tests/feedforward_network_2_test.cpp b/src/mlpack/tests/feedforward_network_2_test.cpp index 456367912c..f0cfcd0672 100644 --- a/src/mlpack/tests/feedforward_network_2_test.cpp +++ b/src/mlpack/tests/feedforward_network_2_test.cpp @@ -21,7 +21,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "custom_layer.hpp" using namespace mlpack; diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index f7c0b99ea9..bd240a794f 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -19,7 +19,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "custom_layer.hpp" using namespace mlpack; diff --git a/src/mlpack/tests/gan_test.cpp b/src/mlpack/tests/gan_test.cpp index db4a397eac..a7350cb1f1 100644 --- a/src/mlpack/tests/gan_test.cpp +++ b/src/mlpack/tests/gan_test.cpp @@ -22,7 +22,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::ann; diff --git a/src/mlpack/tests/hoeffding_tree_test.cpp b/src/mlpack/tests/hoeffding_tree_test.cpp index 49c60b0cea..de7db90443 100644 --- a/src/mlpack/tests/hoeffding_tree_test.cpp +++ b/src/mlpack/tests/hoeffding_tree_test.cpp @@ -19,7 +19,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include diff --git a/src/mlpack/tests/image_load_test.cpp b/src/mlpack/tests/image_load_test.cpp index df9ac6f979..656a9dbfb6 100644 --- a/src/mlpack/tests/image_load_test.cpp +++ b/src/mlpack/tests/image_load_test.cpp @@ -11,7 +11,7 @@ */ #include -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "test_catch_tools.hpp" #include "catch.hpp" diff --git a/src/mlpack/tests/kde_test.cpp b/src/mlpack/tests/kde_test.cpp index da5417f2a2..bb0b3d4eca 100644 --- a/src/mlpack/tests/kde_test.cpp +++ b/src/mlpack/tests/kde_test.cpp @@ -16,7 +16,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::kde; diff --git a/src/mlpack/tests/kernel_test.cpp b/src/mlpack/tests/kernel_test.cpp index e32180a3f9..2eda7cc7ae 100644 --- a/src/mlpack/tests/kernel_test.cpp +++ b/src/mlpack/tests/kernel_test.cpp @@ -25,7 +25,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::kernel; diff --git a/src/mlpack/tests/linear_regression_test.cpp b/src/mlpack/tests/linear_regression_test.cpp index d57adb5681..e8b3371265 100644 --- a/src/mlpack/tests/linear_regression_test.cpp +++ b/src/mlpack/tests/linear_regression_test.cpp @@ -11,7 +11,7 @@ #include #include -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "test_catch_tools.hpp" #include "catch.hpp" diff --git a/src/mlpack/tests/local_coordinate_coding_test.cpp b/src/mlpack/tests/local_coordinate_coding_test.cpp index 55644de877..8ef6b3a555 100644 --- a/src/mlpack/tests/local_coordinate_coding_test.cpp +++ b/src/mlpack/tests/local_coordinate_coding_test.cpp @@ -16,7 +16,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace arma; using namespace mlpack; diff --git a/src/mlpack/tests/octree_test.cpp b/src/mlpack/tests/octree_test.cpp index 610bbd2fbc..bdf7110930 100644 --- a/src/mlpack/tests/octree_test.cpp +++ b/src/mlpack/tests/octree_test.cpp @@ -14,7 +14,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::math; diff --git a/src/mlpack/tests/qdafn_test.cpp b/src/mlpack/tests/qdafn_test.cpp index bf71af6057..b7ee07bba6 100644 --- a/src/mlpack/tests/qdafn_test.cpp +++ b/src/mlpack/tests/qdafn_test.cpp @@ -14,7 +14,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace std; using namespace arma; diff --git a/src/mlpack/tests/random_forest_test.cpp b/src/mlpack/tests/random_forest_test.cpp index b916ac446f..3b9999914e 100644 --- a/src/mlpack/tests/random_forest_test.cpp +++ b/src/mlpack/tests/random_forest_test.cpp @@ -13,7 +13,7 @@ #include #include -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "test_catch_tools.hpp" #include "catch.hpp" #include "mock_categorical_data.hpp" diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index 987c808ef2..bf75410902 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -20,7 +20,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "custom_layer.hpp" using namespace mlpack; diff --git a/src/mlpack/tests/rnn_reber_test.cpp b/src/mlpack/tests/rnn_reber_test.cpp index a7e0ff3ef8..6471e3809f 100644 --- a/src/mlpack/tests/rnn_reber_test.cpp +++ b/src/mlpack/tests/rnn_reber_test.cpp @@ -20,7 +20,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "custom_layer.hpp" using namespace mlpack; diff --git a/src/mlpack/tests/serialization_catch.cpp b/src/mlpack/tests/serialization.cpp similarity index 97% rename from src/mlpack/tests/serialization_catch.cpp rename to src/mlpack/tests/serialization.cpp index a07c4d84f6..0631be7b73 100644 --- a/src/mlpack/tests/serialization_catch.cpp +++ b/src/mlpack/tests/serialization.cpp @@ -1,5 +1,5 @@ /** - * @file tests/serialization_catch.cpp + * @file tests/serialization.cpp * @author Ryan Curtin * * Miscellaneous utility functions for serialization tests. @@ -9,7 +9,7 @@ * 3-clause BSD license along with mlpack. If not, see * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ -#include "serialization_catch.hpp" +#include "serialization.hpp" #include "catch.hpp" namespace mlpack { diff --git a/src/mlpack/tests/serialization_catch.hpp b/src/mlpack/tests/serialization.hpp similarity index 99% rename from src/mlpack/tests/serialization_catch.hpp rename to src/mlpack/tests/serialization.hpp index f5caff467c..b88ff5e957 100644 --- a/src/mlpack/tests/serialization_catch.hpp +++ b/src/mlpack/tests/serialization.hpp @@ -1,5 +1,5 @@ /** - * @file tests/serialization_catch.hpp + * @file tests/serialization.hpp * @author Ryan Curtin * * Miscellaneous utility functions for serialization tests. diff --git a/src/mlpack/tests/serialization_test.cpp b/src/mlpack/tests/serialization_test.cpp index 364a9b1ff2..c564f0a482 100644 --- a/src/mlpack/tests/serialization_test.cpp +++ b/src/mlpack/tests/serialization_test.cpp @@ -17,7 +17,7 @@ #include #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" #include #include diff --git a/src/mlpack/tests/sparse_coding_test.cpp b/src/mlpack/tests/sparse_coding_test.cpp index c2981c776e..a4a83ac791 100644 --- a/src/mlpack/tests/sparse_coding_test.cpp +++ b/src/mlpack/tests/sparse_coding_test.cpp @@ -17,7 +17,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace arma; using namespace mlpack; diff --git a/src/mlpack/tests/string_encoding_test.cpp b/src/mlpack/tests/string_encoding_test.cpp index 8793981fce..b3af269d02 100644 --- a/src/mlpack/tests/string_encoding_test.cpp +++ b/src/mlpack/tests/string_encoding_test.cpp @@ -21,7 +21,7 @@ #include #include "test_catch_tools.hpp" #include "catch.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::data; diff --git a/src/mlpack/tests/wgan_test.cpp b/src/mlpack/tests/wgan_test.cpp index 9bd73449ad..99998723c4 100644 --- a/src/mlpack/tests/wgan_test.cpp +++ b/src/mlpack/tests/wgan_test.cpp @@ -22,7 +22,7 @@ #include "catch.hpp" #include "test_catch_tools.hpp" -#include "serialization_catch.hpp" +#include "serialization.hpp" using namespace mlpack; using namespace mlpack::ann; From 2a7e3fd0cd28bb1b120bd39c3b690f31985d4d26 Mon Sep 17 00:00:00 2001 From: Gaurav Ghati Date: Sun, 13 Dec 2020 10:49:39 +0530 Subject: [PATCH 331/550] Update COPYRIGHT.txt --- COPYRIGHT.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 907caf9d1a..a69bd89e67 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -139,6 +139,7 @@ Copyright: Copyright 2020, Rishabh Garg Copyright 2020, Sudhakar Brar Copyright 2020, Alex Nguyen + Copyright 2020, Gaurav Ghati License: BSD-3-clause All rights reserved. From 00d12a249f7770dc02f3a70374a68457b2c2acb9 Mon Sep 17 00:00:00 2001 From: Ayush Date: Sun, 13 Dec 2020 12:33:56 +0530 Subject: [PATCH 332/550] Improved variable names in triplet margin loss function --- .../loss_functions/triplet_margin_loss.hpp | 16 ++++++------ .../triplet_margin_loss_impl.hpp | 26 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp index bf833b392f..882fcd978e 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp @@ -58,25 +58,25 @@ class TripletMarginLoss /** * Computes the Triplet Margin Loss function. * - * @param input The propagated input activation. It should be + * @param prediction The propagated input activation. It should be * concatenated anchor and positive samples. * @param target The target vector. It should be negative samples. */ - template - typename InputType::elem_type Forward(const InputType& input, + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, const TargetType& target); /** * Ordinary feed backward pass of a neural network. * - * @param input The propagated input activation. It should be + * @param prediction The propagated input activation. It should be * concatenated anchor and positive samples. * @param target The target vector. It should be negative samples. - * @param output The calculated error. + * @param loss The calculated error. */ - template - void Backward(const InputType& input, + template + void Backward(const PredictionType& prediction, const TargetType& target, - OutputType& output); + LossType& loss); //! Get the output parameter. OutputDataType& OutputParameter() const { return outputParameter; } diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index 2f7e11ceae..e68dd5220f 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -26,33 +26,33 @@ TripletMarginLoss::TripletMarginLoss( } template -template -typename InputType::elem_type +template +typename PredictionType::elem_type TripletMarginLoss::Forward( - const InputType& input, + const PredictionType& prediction, const TargetType& target) { - InputType anchor = input.submat(0, 0, input.n_rows / 2 - 1, input.n_cols - 1); - InputType positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, - input.n_cols - 1); + PredictionType anchor = prediction.submat(0, 0, prediction.n_rows / 2 - 1, prediction.n_cols - 1); + PredictionType positive = prediction.submat(prediction.n_rows / 2, 0, prediction.n_rows - 1, + prediction.n_cols - 1); return std::max(0.0, arma::accu(arma::pow(anchor - positive, 2)) - arma::accu(arma::pow(anchor - target, 2)) + margin) / anchor.n_cols; } template template < - typename InputType, + typename PredictionType, typename TargetType, - typename OutputType + typename LossType > void TripletMarginLoss::Backward( - const InputType& input, + const PredictionType& prediction, const TargetType& target, - OutputType& output) + LossType& loss) { - InputType positive = input.submat(input.n_rows / 2, 0, input.n_rows - 1, - input.n_cols - 1); - output = 2 * (target - positive) / target.n_cols; + PredictionType positive = prediction.submat(prediction.n_rows / 2, 0, prediction.n_rows - 1, + prediction.n_cols - 1); + loss = 2 * (target - positive) / target.n_cols; } template From 41e52f58b20cfebc569190bc6184892f114d9f7d Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 13 Dec 2020 13:53:59 +0530 Subject: [PATCH 333/550] added co-author's name for PR #2122 --- src/mlpack/methods/ann/util/check_input_shape.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp index b2b7b7e67e..87ec25bb67 100644 --- a/src/mlpack/methods/ann/util/check_input_shape.hpp +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -1,5 +1,6 @@ /** * @file check_input_shape.hpp + * @author Khizir Siddiqui * @author Nippun Sharma * * Definition of the CheckInputShape() function that checks From a66dcc7c8aca95bc99997c4bcff769dae44c47ac Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 13 Dec 2020 13:55:23 +0530 Subject: [PATCH 334/550] added co-author's name for PR #2122 --- src/mlpack/methods/ann/visitor/input_shape_visitor.hpp | 1 + src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp index bb1b4b392a..92d2c5d553 100644 --- a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp @@ -1,5 +1,6 @@ /** * @file input_shape_visitor.hpp + * @author Khizir Siddiqui * @author Nippun Sharma * * This file provides an abstraction for the InputShape() function for diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp index 2b87081927..5ceef063d0 100644 --- a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp @@ -1,5 +1,6 @@ /** * @file input_shape_visitor_impl.hpp + * @author Khizir Siddiqui * @author Nippun Sharma * * Implementation of the InputShape() function layer abstraction. From a5f005166acb7a41584361e48d54f38a835d4596 Mon Sep 17 00:00:00 2001 From: Ayush Date: Sun, 13 Dec 2020 17:29:21 +0530 Subject: [PATCH 335/550] Added author name and improved comments --- .../loss_functions/triplet_margin_loss.hpp | 58 +++++++++---------- .../triplet_margin_loss_impl.hpp | 3 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp index 882fcd978e..fba54973f0 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss.hpp @@ -1,20 +1,10 @@ /** - * @file triplet_margin_loss.hpp + * @file methods/ann/loss_functions/triplet_margin_loss.hpp * @author Prince Gupta + * @author Ayush Singh * * Definition of the Triplet Margin Loss function. * - * For more information, refer the following paper. - * - * @code - * @article{Schroff2015, - * author = {Florian Schroff, Dmitry Kalenichenko, James Philbin}, - * title = {FaceNet: A Unified Embedding for Face Recognition and Clustering}, - * year = {2015}, - * url = {https://arxiv.org/abs/1503.03832}, - * } - * @endcode - * * 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 @@ -29,9 +19,22 @@ namespace mlpack { namespace ann /** Artificial Neural Network. */ { /** - * The TripletMarginLoss function's objective is that the distance from the - * anchor input to the positive input is minimized, and the distance from the - * anchor input to the negative input is maximized. + * The Triplet Margin Loss performance function measures the network's + * performance according to the relative distance from the anchor input + * of the positive (truthy) and negative (falsy) inputs. + * The distance between two samples A and B is defined as square of L2 norm + * of A-B. + * + * For more information, refer the following paper. + * + * @code + * @article{Schroff2015, + * author = {Florian Schroff, Dmitry Kalenichenko, James Philbin}, + * title = {FaceNet: A Unified Embedding for Face Recognition and Clustering}, + * year = {2015}, + * url = {https://arxiv.org/abs/1503.03832}, + * } + * @endcode * * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, * arma::sp_mat or arma::cube). @@ -46,21 +49,19 @@ class TripletMarginLoss { public: /** - * Create the TripletMarginLoss object with Hyperparameter margin. - * Hyperparameter margin defines the minimum value by which the distance - * between Anchor and Negative sample exceeds the distance between - * Anchor and Positive sample. - * The distance between two samples A and B is defined as square of L2 norm - * of A-B. + * Create the TripletMarginLoss object. + * + * @param margin The minimum value by which the distance between + * Anchor and Negative sample exceeds the distance + * between Anchor and Positive sample. */ TripletMarginLoss(const double margin = 1.0); /** * Computes the Triplet Margin Loss function. * - * @param prediction The propagated input activation. It should be - * concatenated anchor and positive samples. - * @param target The target vector. It should be negative samples. + * @param prediction Concatenated anchor and positive sample. + * @param target The negative sample. */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, @@ -68,9 +69,8 @@ class TripletMarginLoss /** * Ordinary feed backward pass of a neural network. * - * @param prediction The propagated input activation. It should be - * concatenated anchor and positive samples. - * @param target The target vector. It should be negative samples. + * @param prediction Concatenated anchor and positive sample. + * @param target The negative sample. * @param loss The calculated error. */ template @@ -83,9 +83,9 @@ class TripletMarginLoss //! Modify the output parameter. OutputDataType& OutputParameter() { return outputParameter; } - //! Get the output parameter. + //! Get the value of margin. double Margin() const { return margin; } - //! Modify the output parameter. + //! Modify the value of margin. double& Margin() { return margin; } /** diff --git a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp index e68dd5220f..a007490be0 100644 --- a/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/triplet_margin_loss_impl.hpp @@ -1,6 +1,7 @@ /** - * @file triplet_margin_loss_impl.hpp + * @file methods/ann/loss_functions/triplet_margin_loss_impl.hpp * @author Prince Gupta + * @author Ayush Singh * * Implementation of the Triplet Margin Loss function. * From 5bdd46daef5e00dfae6cefefe1a4db368759b466 Mon Sep 17 00:00:00 2001 From: Ayush Date: Sun, 13 Dec 2020 20:29:00 +0530 Subject: [PATCH 336/550] Improved variable names in triplet margin loss function --- src/mlpack/tests/loss_functions_test.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index adcaee3249..b1aac77432 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -916,8 +916,8 @@ TEST_CASE("TripletMarginLossTest") input = { {2, 3, 5}, {10, 12, 13} }; - double error = module.Forward(input, negative); - REQUIRE(error == 66); + double loss = module.Forward(input, negative); + REQUIRE(loss == 66); // Test the Backward function. module.Backward(input, negative, output); @@ -928,7 +928,7 @@ TEST_CASE("TripletMarginLossTest") REQUIRE(output.n_rows == anchor.n_rows); REQUIRE(output.n_cols == anchor.n_cols); - // Test the error function on a single input. + // Test the loss function on a single input. anchor = arma::mat("4"); positive = arma::mat("7"); negative = arma::mat("1"); @@ -937,8 +937,8 @@ TEST_CASE("TripletMarginLossTest") input[0] = 4; input[1] = 7; - error = module.Forward(input, negative); - REQUIRE(error == 1.0); + loss = module.Forward(input, negative); + REQUIRE(loss == 1.0); // Test the Backward function on a single input. module.Backward(input, negative, output); From 700e5ee72b7f3b44d9149a571fb06766f3947ab1 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 13 Dec 2020 10:47:59 -0500 Subject: [PATCH 337/550] Oops, remove accidentally added file. --- src/mlpack/tests/ann_layer_test-mod.cpp | 2937 ----------------------- 1 file changed, 2937 deletions(-) delete mode 100755 src/mlpack/tests/ann_layer_test-mod.cpp diff --git a/src/mlpack/tests/ann_layer_test-mod.cpp b/src/mlpack/tests/ann_layer_test-mod.cpp deleted file mode 100755 index 77658fa0ea..0000000000 --- a/src/mlpack/tests/ann_layer_test-mod.cpp +++ /dev/null @@ -1,2937 +0,0 @@ -/** - * @file mlpack/tests/ann_layer_test-mod.cpp - * @author Marcus Edel - * @author Praveen Ch - * - * Tests the ann layer modules. - * - * 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. - */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include "test_tools.hpp" -#include "ann_test_tools.hpp" -#include "serialization.hpp" - -using namespace mlpack; -using namespace mlpack::ann; - -BOOST_AUTO_TEST_SUITE(ANNLayerTest); - -/** - * Simple add module test. - */ -BOOST_AUTO_TEST_CASE(SimpleAddLayerTest) -{ - arma::mat output, input, delta; - Add<> module(10); - module.Parameters().randu(); - - // Test the Forward function. - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(arma::accu(module.Parameters()), arma::accu(output)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(delta)); - - // Test the forward function. - input = arma::ones(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_CLOSE(10 + arma::accu(module.Parameters()), - arma::accu(output), 1e-3); - - // Test the backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_CLOSE(arma::accu(output), arma::accu(delta), 1e-3); -} - -/** - * Jacobian add module test. - */ -BOOST_AUTO_TEST_CASE(JacobianAddLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t elements = math::RandInt(2, 1000); - arma::mat input; - input.set_size(elements, 1); - - Add<> module(elements); - module.Parameters().randu(); - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Add layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientAddLayerTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - model->Add >(10); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Simple constant module test. - */ -BOOST_AUTO_TEST_CASE(SimpleConstantLayerTest) -{ - arma::mat output, input, delta; - Constant<> module(10, 3.0); - - // Test the Forward function. - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(arma::accu(output), 30.0); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); - - // Test the forward function. - input = arma::ones(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(arma::accu(output), 30.0); - - // Test the backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -/** - * Jacobian constant module test. - */ -BOOST_AUTO_TEST_CASE(JacobianConstantLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t elements = math::RandInt(2, 1000); - arma::mat input; - input.set_size(elements, 1); - - Constant<> module(elements, 1.0); - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Simple dropout module test. - */ -BOOST_AUTO_TEST_CASE(SimpleDropoutLayerTest) -{ - // Initialize the probability of setting a value to zero. - const double p = 0.2; - - // Initialize the input parameter. - arma::mat input(1000, 1); - input.fill(1 - p); - - Dropout<> module(p); - module.Deterministic() = false; - - // Test the Forward function. - arma::mat output; - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_LE( - arma::as_scalar(arma::abs(arma::mean(output) - (1 - p))), 0.05); - - // Test the Backward function. - arma::mat delta; - module.Backward(std::move(input), std::move(input), std::move(delta)); - BOOST_REQUIRE_LE( - arma::as_scalar(arma::abs(arma::mean(delta) - (1 - p))), 0.05); - - // Test the Forward function. - module.Deterministic() = true; - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(output)); -} - -/** - * Perform dropout x times using ones as input, sum the number of ones and - * validate that the layer is producing approximately the correct number of - * ones. - */ -BOOST_AUTO_TEST_CASE(DropoutProbabilityTest) -{ - arma::mat input = arma::ones(1500, 1); - const size_t iterations = 10; - - double probability[5] = { 0.1, 0.3, 0.4, 0.7, 0.8 }; - for (size_t trial = 0; trial < 5; ++trial) - { - double nonzeroCount = 0; - for (size_t i = 0; i < iterations; ++i) - { - Dropout<> module(probability[trial]); - module.Deterministic() = false; - - arma::mat output; - module.Forward(std::move(input), std::move(output)); - - // Return a column vector containing the indices of elements of X that - // are non-zero, we just need the number of non-zero values. - arma::uvec nonzero = arma::find(output); - nonzeroCount += nonzero.n_elem; - } - const double expected = input.n_elem * (1 - probability[trial]) * - iterations; - const double error = fabs(nonzeroCount - expected) / expected; - - BOOST_REQUIRE_LE(error, 0.15); - } -} - -/* - * Perform dropout with probability 1 - p where p = 0, means no dropout. - */ -BOOST_AUTO_TEST_CASE(NoDropoutTest) -{ - arma::mat input = arma::ones(1500, 1); - Dropout<> module(0); - module.Deterministic() = false; - - arma::mat output; - module.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(input)); -} - -/* - * Perform test to check whether mean and variance remain nearly same - * after AlphaDropout. - */ -BOOST_AUTO_TEST_CASE(SimpleAlphaDropoutLayerTest) -{ - // Initialize the probability of setting a value to alphaDash. - const double p = 0.2; - - // Initialize the input parameter having a mean nearabout 0 - // and variance nearabout 1. - arma::mat input = arma::randn(1000, 1); - - AlphaDropout<> module(p); - module.Deterministic() = false; - - // Test the Forward function when training phase. - arma::mat output; - module.Forward(std::move(input), std::move(output)); - // Check whether mean remains nearly same. - BOOST_REQUIRE_LE( - arma::as_scalar(arma::abs(arma::mean(input) - arma::mean(output))), 0.1); - - // Check whether variance remains nearly same. - BOOST_REQUIRE_LE( - arma::as_scalar(arma::abs(arma::var(input) - arma::var(output))), 0.1); - - // Test the Backward function when training phase. - arma::mat delta; - module.Backward(std::move(input), std::move(input), std::move(delta)); - BOOST_REQUIRE_LE( - arma::as_scalar(arma::abs(arma::mean(delta) - 0)), 0.05); - - // Test the Forward function when testing phase. - module.Deterministic() = true; - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(output)); -} - -/** - * Perform AlphaDropout x times using ones as input, sum the number of ones - * and validate that the layer is producing approximately the correct number - * of ones. - */ -BOOST_AUTO_TEST_CASE(AlphaDropoutProbabilityTest) -{ - arma::mat input = arma::ones(1500, 1); - const size_t iterations = 10; - - double probability[5] = { 0.1, 0.3, 0.4, 0.7, 0.8 }; - for (size_t trial = 0; trial < 5; ++trial) - { - double nonzeroCount = 0; - for (size_t i = 0; i < iterations; ++i) - { - AlphaDropout<> module(probability[trial]); - module.Deterministic() = false; - - arma::mat output; - module.Forward(std::move(input), std::move(output)); - - // Return a column vector containing the indices of elements of X - // that are not alphaDash, we just need the number of - // nonAlphaDash values. - arma::uvec nonAlphaDash = arma::find(module.Mask()); - nonzeroCount += nonAlphaDash.n_elem; - } - - const double expected = input.n_elem * (1-probability[trial]) * iterations; - - const double error = fabs(nonzeroCount - expected) / expected; - - BOOST_REQUIRE_LE(error, 0.15); - } -} - -/** - * Perform AlphaDropout with probability 1 - p where p = 0, - * means no AlphaDropout. - */ -BOOST_AUTO_TEST_CASE(NoAlphaDropoutTest) -{ - arma::mat input = arma::ones(1500, 1); - AlphaDropout<> module(0); - module.Deterministic() = false; - - arma::mat output; - module.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(input)); -} - -/** - * Simple linear module test. - */ -BOOST_AUTO_TEST_CASE(SimpleLinearLayerTest) -{ - arma::mat output, input, delta; - Linear<> module(10, 10); - module.Parameters().randu(); - module.Reset(); - - // Test the Forward function. - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_CLOSE(arma::accu( - module.Parameters().submat(100, 0, module.Parameters().n_elem - 1, 0)), - arma::accu(output), 1e-3); - - // Test the Backward function. - module.Backward(std::move(input), std::move(input), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -/** - * Jacobian linear module test. - */ -BOOST_AUTO_TEST_CASE(JacobianLinearLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElements = math::RandInt(2, 1000); - const size_t outputElements = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElements, 1); - - Linear<> module(inputElements, outputElements); - module.Parameters().randu(); - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Linear layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientLinearLayerTest) -{ - // Linear function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - model->Add >(10, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Simple linear no bias module test. - */ -BOOST_AUTO_TEST_CASE(SimpleLinearNoBiasLayerTest) -{ - arma::mat output, input, delta; - LinearNoBias<> module(10, 10); - module.Parameters().randu(); - module.Reset(); - - // Test the Forward function. - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(0, arma::accu(output)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(input), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -/** - * Simple padding layer test. - */ -BOOST_AUTO_TEST_CASE(SimplePaddingLayerTest) -{ - arma::mat output, input, delta; - Padding<> module(1, 2, 3, 4); - - // Test the Forward function. - input = arma::randu(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(output)); - BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows + 3); - BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols + 7); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - CheckMatrices(delta, input); -} - -/** - * Jacobian linear no bias module test. - */ -BOOST_AUTO_TEST_CASE(JacobianLinearNoBiasLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElements = math::RandInt(2, 1000); - const size_t outputElements = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElements, 1); - - LinearNoBias<> module(inputElements, outputElements); - module.Parameters().randu(); - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * LinearNoBias layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientLinearNoBiasLayerTest) -{ - // LinearNoBias function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - model->Add >(10, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Jacobian negative log likelihood module test. - */ -BOOST_AUTO_TEST_CASE(JacobianNegativeLogLikelihoodLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - NegativeLogLikelihood<> module; - const size_t inputElements = math::RandInt(5, 100); - arma::mat input; - RandomInitialization init(0, 1); - init.Initialize(input, inputElements, 1); - - arma::mat target(1, 1); - target(0) = math::RandInt(1, inputElements - 1); - - double error = JacobianPerformanceTest(module, input, target); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Jacobian LeakyReLU module test. - */ -BOOST_AUTO_TEST_CASE(JacobianLeakyReLULayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElements = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElements, 1); - - LeakyReLU<> module; - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Jacobian FlexibleReLU module test. - */ -BOOST_AUTO_TEST_CASE(JacobianFlexibleReLULayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElements = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElements, 1); - - FlexibleReLU<> module; - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Flexible ReLU layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientFlexibleReLULayerTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(2, 1); - target = arma::mat("1"); - - model = new FFN, RandomInitialization>( - NegativeLogLikelihood<>(), RandomInitialization(0.1, 0.5)); - - model->Predictors() = input; - model->Responses() = target; - model->Add >(2, 2); - model->Add >(2, 5); - model->Add >(0.05); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, RandomInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Jacobian MultiplyConstant module test. - */ -BOOST_AUTO_TEST_CASE(JacobianMultiplyConstantLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElements = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElements, 1); - - MultiplyConstant<> module(3.0); - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Jacobian HardTanH module test. - */ -BOOST_AUTO_TEST_CASE(JacobianHardTanHLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElements = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElements, 1); - - HardTanH<> module; - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Simple select module test. - */ -BOOST_AUTO_TEST_CASE(SimpleSelectLayerTest) -{ - arma::mat outputA, outputB, input, delta; - - input = arma::ones(10, 5); - for (size_t i = 0; i < input.n_cols; ++i) - { - input.col(i) *= i; - } - - // Test the Forward function. - Select<> moduleA(3); - moduleA.Forward(std::move(input), std::move(outputA)); - BOOST_REQUIRE_EQUAL(30, arma::accu(outputA)); - - // Test the Forward function. - Select<> moduleB(3, 5); - moduleB.Forward(std::move(input), std::move(outputB)); - BOOST_REQUIRE_EQUAL(15, arma::accu(outputB)); - - // Test the Backward function. - moduleA.Backward(std::move(input), std::move(outputA), std::move(delta)); - BOOST_REQUIRE_EQUAL(30, arma::accu(delta)); - - // Test the Backward function. - moduleB.Backward(std::move(input), std::move(outputA), std::move(delta)); - BOOST_REQUIRE_EQUAL(15, arma::accu(delta)); -} - -/** - * Simple join module test. - */ -BOOST_AUTO_TEST_CASE(SimpleJoinLayerTest) -{ - arma::mat output, input, delta; - input = arma::ones(10, 5); - - // Test the Forward function. - Join<> module; - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(50, arma::accu(output)); - - bool b = output.n_rows == 1 || output.n_cols == 1; - BOOST_REQUIRE_EQUAL(b, true); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(50, arma::accu(delta)); - - b = delta.n_rows == input.n_rows && input.n_cols; - BOOST_REQUIRE_EQUAL(b, true); -} - -/** - * Simple add merge module test. - */ -BOOST_AUTO_TEST_CASE(SimpleAddMergeLayerTest) -{ - arma::mat output, input, delta; - input = arma::ones(10, 1); - - for (size_t i = 0; i < 5; ++i) - { - AddMerge<> module(false, false); - const size_t numMergeModules = math::RandInt(2, 10); - for (size_t m = 0; m < numMergeModules; ++m) - { - IdentityLayer<> identityLayer; - identityLayer.Forward(std::move(input), - std::move(identityLayer.OutputParameter())); - - module.Add >(identityLayer); - } - - // Test the Forward function. - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(10 * numMergeModules, arma::accu(output)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(delta)); - } -} - -/** - * Test the LSTM layer with a user defined rho parameter and without. - */ -BOOST_AUTO_TEST_CASE(LSTMRrhoTest) -{ - const size_t rho = 5; - arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); - RandomInitialization init(0.5, 0.5); - - // Create model with user defined rho parameter. - RNN, RandomInitialization> modelA( - rho, false, NegativeLogLikelihood<>(), init); - modelA.Add >(); - modelA.Add >(1, 10); - - // Use LSTM layer with rho. - modelA.Add >(10, 3, rho); - modelA.Add >(); - - // Create model without user defined rho parameter. - RNN > modelB( - rho, false, NegativeLogLikelihood<>(), init); - modelB.Add >(); - modelB.Add >(1, 10); - - // Use LSTM layer with rho = MAXSIZE. - modelB.Add >(10, 3); - modelB.Add >(); - - ens::StandardSGD opt(0.1, 1, 5, -100, false); - modelA.Train(input, target, opt); - modelB.Train(input, target, opt); - - CheckMatrices(modelB.Parameters(), modelA.Parameters()); -} - -/** - * LSTM layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientLSTMLayerTest) -{ - // LSTM function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(1, 1, 5); - target.ones(1, 1, 5); - const size_t rho = 5; - - model = new RNN >(rho); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(1, 10); - model->Add >(10, 3, rho); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - RNN >* model; - arma::cube input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Test the FastLSTM layer with a user defined rho parameter and without. - */ -BOOST_AUTO_TEST_CASE(FastLSTMRrhoTest) -{ - const size_t rho = 5; - arma::cube input = arma::randu(1, 1, 5); - arma::cube target = arma::ones(1, 1, 5); - RandomInitialization init(0.5, 0.5); - - // Create model with user defined rho parameter. - RNN, RandomInitialization> modelA( - rho, false, NegativeLogLikelihood<>(), init); - modelA.Add >(); - modelA.Add >(1, 10); - - // Use FastLSTM layer with rho. - modelA.Add >(10, 3, rho); - modelA.Add >(); - - // Create model without user defined rho parameter. - RNN > modelB( - rho, false, NegativeLogLikelihood<>(), init); - modelB.Add >(); - modelB.Add >(1, 10); - - // Use FastLSTM layer with rho = MAXSIZE. - modelB.Add >(10, 3); - modelB.Add >(); - - ens::StandardSGD opt(0.1, 1, 5, -100, false); - modelA.Train(input, target, opt); - modelB.Train(input, target, opt); - - CheckMatrices(modelB.Parameters(), modelA.Parameters()); -} - -/** - * FastLSTM layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientFastLSTMLayerTest) -{ - // Fast LSTM function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(1, 1, 5); - target = arma::ones(1, 1, 5); - const size_t rho = 5; - - model = new RNN >(rho); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(1, 10); - model->Add >(10, 3, rho); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - RNN >* model; - arma::cube input, target; - } function; - - // The threshold should be << 0.1 but since the Fast LSTM layer uses an - // approximation of the sigmoid function the estimated gradient is not - // correct. - BOOST_REQUIRE_LE(CheckGradient(function), 0.2); -} - -/** - * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell - * state. Besides output, the overloaded function provides read access to cell - * state of the LSTM layer. - */ -BOOST_AUTO_TEST_CASE(ReadCellStateParamLSTMLayerTest) -{ - const size_t rho = 5, inputSize = 3, outputSize = 2; - - // Provide input of all ones. - arma::cube input = arma::ones(inputSize, outputSize, rho); - - arma::mat inputGate, forgetGate, outputGate, hidden; - arma::mat outLstm, cellLstm; - - // LSTM layer. - LSTM<> lstm(inputSize, outputSize, rho); - lstm.Reset(); - lstm.ResetCell(rho); - - // Initialize the weights to all ones. - lstm.Parameters().ones(); - - arma::mat inputWeight = arma::ones(outputSize, inputSize); - arma::mat outputWeight = arma::ones(outputSize, outputSize); - arma::mat bias = arma::ones(outputSize, input.n_cols); - arma::mat cellCalc = arma::zeros(outputSize, input.n_cols); - arma::mat outCalc = arma::zeros(outputSize, input.n_cols); - - for (size_t seqNum = 0; seqNum < rho; ++seqNum) - { - // Wrap a matrix around our data to avoid a copy. - arma::mat stepData(input.slice(seqNum).memptr(), - input.n_rows, input.n_cols, false, true); - - // Apply Forward() on LSTM layer. - lstm.Forward(std::move(stepData), // Input. - std::move(outLstm), // Output. - std::move(cellLstm), // Cell state. - false); // Don't write into the cell state. - - // Compute the value of cell state and output. - // i = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). - inputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + - outputWeight * outCalc + outputWeight % cellCalc + bias))); - - // f = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). - forgetGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + - outputWeight * outCalc + outputWeight % cellCalc + bias))); - - // z = tanh(W.dot(x) + W.dot(h) + b). - hidden = arma::tanh(inputWeight * stepData + - outputWeight * outCalc + bias); - - // c = f * c + i * z. - cellCalc = forgetGate % cellCalc + inputGate % hidden; - - // o = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). - outputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + - outputWeight * outCalc + outputWeight % cellCalc + bias))); - - // h = o * tanh(c). - outCalc = outputGate % arma::tanh(cellCalc); - - CheckMatrices(outLstm, outCalc, 1e-12); - CheckMatrices(cellLstm, cellCalc, 1e-12); - } -} - -/** - * Testing the overloaded Forward() of the LSTM layer, for retrieving the cell - * state. Besides output, the overloaded function provides write access to cell - * state of the LSTM layer. - */ -BOOST_AUTO_TEST_CASE(WriteCellStateParamLSTMLayerTest) -{ - const size_t rho = 5, inputSize = 3, outputSize = 2; - - // Provide input of all ones. - arma::cube input = arma::ones(inputSize, outputSize, rho); - - arma::mat inputGate, forgetGate, outputGate, hidden; - arma::mat outLstm, cellLstm; - arma::mat cellCalc; - - // LSTM layer. - LSTM<> lstm(inputSize, outputSize, rho); - lstm.Reset(); - lstm.ResetCell(rho); - - // Initialize the weights to all ones. - lstm.Parameters().ones(); - - arma::mat inputWeight = arma::ones(outputSize, inputSize); - arma::mat outputWeight = arma::ones(outputSize, outputSize); - arma::mat bias = arma::ones(outputSize, input.n_cols); - arma::mat outCalc = arma::zeros(outputSize, input.n_cols); - - for (size_t seqNum = 0; seqNum < rho; ++seqNum) - { - // Wrap a matrix around our data to avoid a copy. - arma::mat stepData(input.slice(seqNum).memptr(), - input.n_rows, input.n_cols, false, true); - - if (cellLstm.is_empty()) - { - // Set the cell state to zeros. - cellLstm = arma::zeros(outputSize, input.n_cols); - cellCalc = arma::zeros(outputSize, input.n_cols); - } - else - { - // Set the cell state to zeros. - cellLstm = arma::zeros(cellLstm.n_rows, cellLstm.n_cols); - cellCalc = arma::zeros(cellCalc.n_rows, cellCalc.n_cols); - } - - // Apply Forward() on the LSTM layer. - lstm.Forward(std::move(stepData), // Input. - std::move(outLstm), // Output. - std::move(cellLstm), // Cell state. - true); // Write into cell state. - - // Compute the value of cell state and output. - // i = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). - inputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + - outputWeight * outCalc + outputWeight % cellCalc + bias))); - - // f = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). - forgetGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + - outputWeight * outCalc + outputWeight % cellCalc + bias))); - - // z = tanh(W.dot(x) + W.dot(h) + b). - hidden = arma::tanh(inputWeight * stepData + - outputWeight * outCalc + bias); - - // c = f * c + i * z. - cellCalc = forgetGate % cellCalc + inputGate % hidden; - - // o = sigmoid(W.dot(x) + W.dot(h) + W.dot(c) + b). - outputGate = 1.0 /(1 + arma::exp(-(inputWeight * stepData + - outputWeight * outCalc + outputWeight % cellCalc + bias))); - - // h = o * tanh(c). - outCalc = outputGate % arma::tanh(cellCalc); - - CheckMatrices(outLstm, outCalc, 1e-12); - CheckMatrices(cellLstm, cellCalc, 1e-12); - } - - // Attempting to write empty matrix into cell state. - lstm.Reset(); - lstm.ResetCell(rho); - arma::mat stepData(input.slice(0).memptr(), - input.n_rows, input.n_cols, false, true); - - lstm.Forward(std::move(stepData), // Input. - std::move(outLstm), // Output. - std::move(cellLstm), // Cell state. - true); // Write into cell state. - - for (size_t seqNum = 1; seqNum < rho; ++seqNum) - { - arma::mat empty; - // Should throw error. - BOOST_REQUIRE_THROW(lstm.Forward(std::move(stepData), // Input. - std::move(outLstm), // Output. - std::move(empty), // Cell state. - true), // Write into cell state. - std::runtime_error); - } -} - -/** - * Check if the gradients computed by GRU cell are close enough to the - * approximation of the gradients. - */ -BOOST_AUTO_TEST_CASE(GradientGRULayerTest) -{ - // GRU function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(1, 1, 5); - target = arma::ones(1, 1, 5); - const size_t rho = 5; - - model = new RNN >(rho); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(1, 10); - model->Add >(10, 3, rho); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - arma::mat output; - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - RNN >* model; - arma::cube input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * GRU layer manual forward test. - */ -BOOST_AUTO_TEST_CASE(ForwardGRULayerTest) -{ - GRU<> gru(3, 3, 5); - - // Initialize the weights to all ones. - NetworkInitialization - networkInit(ConstInitialization(1)); - networkInit.Initialize(gru.Model(), gru.Parameters()); - - // Provide input of all ones. - arma::mat input = arma::ones(3, 1); - arma::mat output; - - gru.Forward(std::move(input), std::move(output)); - - // Compute the z_t gate output. - arma::mat expectedOutput = arma::ones(3, 1); - expectedOutput *= -4; - expectedOutput = arma::exp(expectedOutput); - expectedOutput = arma::ones(3, 1) / (arma::ones(3, 1) + expectedOutput); - expectedOutput = (arma::ones(3, 1) - expectedOutput) % expectedOutput; - - // For the first input the output should be equal to the output of - // gate z_t as the previous output fed to the cell is all zeros. - BOOST_REQUIRE_LE(arma::as_scalar(arma::trans(output) * expectedOutput), 1e-2); - - expectedOutput = output; - - gru.Forward(std::move(input), std::move(output)); - - double s = arma::as_scalar(arma::sum(expectedOutput)); - - // Compute the value of z_t gate for the second input. - arma::mat z_t = arma::ones(3, 1); - z_t *= -(s + 4); - z_t = arma::exp(z_t); - z_t = arma::ones(3, 1) / (arma::ones(3, 1) + z_t); - - // Compute the value of o_t gate for the second input. - arma::mat o_t = arma::ones(3, 1); - o_t *= -(arma::as_scalar(arma::sum(expectedOutput % z_t)) + 4); - o_t = arma::exp(o_t); - o_t = arma::ones(3, 1) / (arma::ones(3, 1) + o_t); - - // Expected output for the second input. - expectedOutput = z_t % expectedOutput + (arma::ones(3, 1) - z_t) % o_t; - - BOOST_REQUIRE_LE(arma::as_scalar(arma::trans(output) * expectedOutput), 1e-2); -} - -/** - * Simple concat module test. - */ -BOOST_AUTO_TEST_CASE(SimpleConcatLayerTest) -{ - arma::mat output, input, delta, error; - - Linear<> moduleA(10, 10); - moduleA.Parameters().randu(); - moduleA.Reset(); - - Linear<> moduleB(10, 10); - moduleB.Parameters().randu(); - moduleB.Reset(); - - Concat<> module; - module.Add(moduleA); - module.Add(moduleB); - - // Test the Forward function. - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_CLOSE(arma::accu( - moduleA.Parameters().submat(100, 0, moduleA.Parameters().n_elem - 1, 0)) + - arma::accu(moduleB.Parameters().submat(100, 0, - moduleB.Parameters().n_elem - 1, 0)), - arma::accu(output.col(0)), 1e-3); - - // Test the Backward function. - error = arma::zeros(20, 1); - module.Backward(std::move(input), std::move(error), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -/** - * Test to check Concat layer along different axes. - */ -BOOST_AUTO_TEST_CASE(ConcatAlongAxisTest) -{ - arma::mat output, input, input2, input3, error, outputA, outputB; - size_t inputWidth = 4, inputHeight = 4, inputChannel = 2; - size_t outputWidth, outputHeight, outputChannel = 2; - size_t kW = 3, kH = 3; - size_t batch = 1; - - // Using Convolution<> layer as inout to Concat<> layer. - // Compute the output shape of convolution layer. - outputWidth = (inputWidth - kW) + 1; - outputHeight = (inputHeight - kH) + 1; - - input = arma::ones(inputWidth * inputHeight * inputChannel, batch); - input2 = input; - input3 = input; - - Convolution<> moduleA(inputChannel, outputChannel, kW, kH, 1, 1, 0, 0, - inputWidth, inputHeight); - Convolution<> moduleB(inputChannel, outputChannel, kW, kH, 1, 1, 0, 0, - inputWidth, inputHeight); - - moduleA.Reset(); - moduleA.Parameters().randu(); - moduleB.Reset(); - moduleB.Parameters().randu(); - - // Compute output of each layer. - moduleA.Forward(std::move(input), std::move(outputA)); - moduleB.Forward(std::move(input2), std::move(outputB)); - - arma::cube A(outputA.memptr(), outputWidth, outputHeight, outputChannel); - arma::cube B(outputB.memptr(), outputWidth, outputHeight, outputChannel); - - error = arma::ones(outputWidth * outputHeight * outputChannel * 2, 1); - - for (size_t axis = 0; axis < 3; ++axis) - { - size_t x = 1, y = 1, z = 1; - arma::cube calculatedOut; - if (axis == 0) - { - calculatedOut.set_size(2 * outputWidth, outputHeight, outputChannel); - for (size_t i = 0; i < A.n_slices; ++i) - { - arma::mat aMat = A.slice(i); - arma::mat bMat = B.slice(i); - calculatedOut.slice(i) = arma::join_cols(aMat, bMat); - } - x = 2; - } - if (axis == 1) - { - calculatedOut.set_size(outputWidth, 2 * outputHeight, outputChannel); - for (size_t i = 0; i < A.n_slices; ++i) - { - arma::mat aMat = A.slice(i); - arma::mat bMat = B.slice(i); - calculatedOut.slice(i) = arma::join_rows(aMat, bMat); - } - y = 2; - } - if (axis == 2) - { - calculatedOut = arma::join_slices(A, B); - z = 2; - } - - // Compute output of Concat<> layer. - arma::Row inputSize{outputWidth, outputHeight, outputChannel}; - Concat<> module(inputSize, axis); - module.Add(moduleA); - module.Add(moduleB); - arma::mat tmpInput(input3); - module.Forward(std::move(tmpInput), std::move(output)); - arma::cube concatOut(output.memptr(), x * outputWidth, - y * outputHeight, z * outputChannel); - - // Verify if the output reshaped to cubes are similar. - CheckMatrices(concatOut, calculatedOut, 1e-12); - } -} - -/** - * Concat layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientConcatLayerTest) -{ - // Concat function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - - concat = new Concat<>(true); - concat->Add >(10, 2); - model->Add(concat); - - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - Concat<>* concat; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Simple concatenate module test. - */ -BOOST_AUTO_TEST_CASE(SimpleConcatenateLayerTest) -{ - arma::mat input = arma::ones(5, 1); - arma::mat output, delta; - - Concatenate<> module; - module.Concat() = arma::ones(5, 1) * 0.5; - - // Test the Forward function. - module.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), 7.5); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 5); -} - -/** - * Concatenate layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientConcatenateLayerTest) -{ - // Concatenate function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 5); - - arma::mat concat = arma::ones(5, 1); - concatenate = new Concatenate<>(); - concatenate->Concat() = concat; - model->Add(concatenate); - - model->Add >(10, 5); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - Concatenate<>* concatenate; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Simple lookup module test. - */ -BOOST_AUTO_TEST_CASE(SimpleLookupLayerTest) -{ - arma::mat output, input, delta, gradient; - Lookup<> module(10, 5); - module.Parameters().randu(); - - // Test the Forward function. - input = arma::zeros(2, 1); - input(0) = 1; - input(1) = 3; - - module.Forward(std::move(input), std::move(output)); - - // The Lookup module uses index - 1 for the cols. - const double outputSum = arma::accu(module.Parameters().col(0)) + - arma::accu(module.Parameters().col(2)); - - BOOST_REQUIRE_CLOSE(outputSum, arma::accu(output), 1e-3); - - // Test the Backward function. - module.Backward(std::move(input), std::move(input), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(input), arma::accu(input)); - - // Test the Gradient function. - arma::mat error = arma::ones(2, 5); - error = error.t(); - error.col(1) *= 0.5; - - module.Gradient(std::move(input), std::move(error), std::move(gradient)); - - // The Lookup module uses index - 1 for the cols. - const double gradientSum = arma::accu(gradient.col(0)) + - arma::accu(gradient.col(2)); - - BOOST_REQUIRE_CLOSE(gradientSum, arma::accu(error), 1e-3); - BOOST_REQUIRE_CLOSE(arma::accu(gradient), arma::accu(error), 1e-3); -} - -/** - * Simple LogSoftMax module test. - */ -BOOST_AUTO_TEST_CASE(SimpleLogSoftmaxLayerTest) -{ - arma::mat output, input, error, delta; - LogSoftMax<> module; - - // Test the Forward function. - input = arma::mat("0.5; 0.5"); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_SMALL(arma::accu(arma::abs( - arma::mat("-0.6931; -0.6931") - output)), 1e-3); - - // Test the Backward function. - error = arma::zeros(input.n_rows, input.n_cols); - // Assume LogSoftmax layer is always associated with NLL output layer. - error(1, 0) = -1; - module.Backward(std::move(input), std::move(error), std::move(delta)); - BOOST_REQUIRE_SMALL(arma::accu(arma::abs( - arma::mat("1.6487; 0.6487") - delta)), 1e-3); -} - -/* - * Simple test for the BilinearInterpolation layer - */ -BOOST_AUTO_TEST_CASE(SimpleBilinearInterpolationLayerTest) -{ - // Tested output against tensorflow.image.resize_bilinear() - arma::mat input, output, unzoomedOutput, expectedOutput; - size_t inRowSize = 2; - size_t inColSize = 2; - size_t outRowSize = 5; - size_t outColSize = 5; - size_t depth = 1; - input.zeros(inRowSize * inColSize * depth, 1); - input[0] = 1.0; - input[1] = input[2] = 2.0; - input[3] = 3.0; - BilinearInterpolation<> layer(inRowSize, inColSize, outRowSize, outColSize, - depth); - expectedOutput = arma::mat("1.0000 1.4000 1.8000 2.0000 2.0000 \ - 1.4000 1.8000 2.2000 2.4000 2.4000 \ - 1.8000 2.2000 2.6000 2.8000 2.8000 \ - 2.0000 2.4000 2.8000 3.0000 3.0000 \ - 2.0000 2.4000 2.8000 3.0000 3.0000"); - expectedOutput.reshape(25, 1); - layer.Forward(std::move(input), std::move(output)); - CheckMatrices(output - expectedOutput, arma::zeros(output.n_rows), 1e-12); - - expectedOutput = arma::mat("1.0000 1.9000 1.9000 2.8000"); - expectedOutput.reshape(4, 1); - layer.Backward(std::move(output), std::move(output), - std::move(unzoomedOutput)); - CheckMatrices(unzoomedOutput - expectedOutput, - arma::zeros(input.n_rows), 1e-12); -} - -/** - * Tests the BatchNorm Layer, compares the layers parameters with - * the values from another implementation. - * Link to the implementation - http://cthorey.github.io./backpropagation/ - */ -BOOST_AUTO_TEST_CASE(BatchNormTest) -{ - arma::mat input, output; - input << 5.1 << 3.5 << 1.4 << arma::endr - << 4.9 << 3.0 << 1.4 << arma::endr - << 4.7 << 3.2 << 1.3 << arma::endr; - - BatchNorm<> model(input.n_rows); - model.Reset(); - - // Non-Deteministic Forward Pass Test. - model.Deterministic() = false; - model.Forward(std::move(input), std::move(output)); - arma::mat result; - result << 1.1658 << 0.1100 << -1.2758 << arma::endr - << 1.2579 << -0.0699 << -1.1880 << arma::endr - << 1.1737 << 0.0958 << -1.2695 << arma::endr; - - CheckMatrices(output, result, 1e-1); - result.clear(); - - // Deterministic Forward Pass test. - output = model.TrainingMean(); - result << 3.33333333 << arma::endr - << 3.1 << arma::endr - << 3.06666666 << arma::endr; - - CheckMatrices(output, result, 1e-1); - result.clear(); - - output = model.TrainingVariance(); - result << 2.2956 << arma::endr - << 2.0467 << arma::endr - << 1.9356 << arma::endr; - - CheckMatrices(output, result, 1e-1); - result.clear(); - - model.Deterministic() = true; - model.Forward(std::move(input), std::move(output)); - - result << 1.1658 << 0.1100 << -1.2757 << arma::endr - << 1.2579 << -0.0699 << -1.1880 << arma::endr - << 1.1737 << 0.0958 << -1.2695 << arma::endr; - - CheckMatrices(output, result, 1e-1); -} - -/** - * BatchNorm layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientBatchNormTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randn(10, 256); - arma::mat target; - target.ones(1, 256); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - model->Add >(10); - model->Add >(10, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 256, false); - model->Gradient(model->Parameters(), 0, gradient, 256); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * VirtualBatchNorm layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientVirtualBatchNormTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randn(5, 256); - arma::mat referenceBatch = arma::mat(input.memptr(), input.n_rows, 16); - arma::mat target; - target.ones(1, 256); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(5, 5); - model->Add >(referenceBatch, 5); - model->Add >(5, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 256, false); - model->Gradient(model->Parameters(), 0, gradient, 256); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * MiniBatchDiscrimination layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(MiniBatchDiscriminationTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randn(5, 4); - arma::mat target; - target.ones(1, 4); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(5, 5); - model->Add >(5, 10, 16); - model->Add >(10, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - return model->EvaluateWithGradient(model->Parameters(), 0, gradient, 4); - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Simple Transposed Convolution layer test. - */ -BOOST_AUTO_TEST_CASE(SimpleTransposedConvolutionLayerTest) -{ - arma::mat output, input, delta; - - TransposedConvolution<> module1(1, 1, 3, 3, 1, 1, 0, 0, 4, 4, 6, 6); - // Test the forward function. - input = arma::linspace(0, 15, 16); - module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module1.Parameters()(0) = 1.0; - module1.Parameters()(8) = 2.0; - module1.Reset(); - module1.Forward(std::move(input), std::move(output)); - // Value calculated using tensorflow.nn.conv2d_transpose() - BOOST_REQUIRE_EQUAL(arma::accu(output), 360.0); - - // Test the backward function. - module1.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using tensorflow.nn.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 720.0); - - TransposedConvolution<> module2(1, 1, 4, 4, 1, 1, 1, 1, 5, 5, 6, 6); - // Test the forward function. - input = arma::linspace(0, 24, 25); - module2.Parameters() = arma::mat(16 + 1, 1, arma::fill::zeros); - module2.Parameters()(0) = 1.0; - module2.Parameters()(3) = 1.0; - module2.Parameters()(6) = 1.0; - module2.Parameters()(9) = 1.0; - module2.Parameters()(12) = 1.0; - module2.Parameters()(15) = 2.0; - module2.Reset(); - module2.Forward(std::move(input), std::move(output)); - // Value calculated using torch.nn.functional.conv_transpose2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 1512.0); - - // Test the backward function. - module2.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using torch.nn.functional.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 6504.0); - - TransposedConvolution<> module3(1, 1, 3, 3, 1, 1, 1, 1, 5, 5, 5, 5); - // Test the forward function. - input = arma::linspace(0, 24, 25); - module3.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module3.Parameters()(1) = 2.0; - module3.Parameters()(2) = 4.0; - module3.Parameters()(3) = 3.0; - module3.Parameters()(8) = 1.0; - module3.Reset(); - module3.Forward(std::move(input), std::move(output)); - // Value calculated using torch.nn.functional.conv_transpose2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 2370.0); - - // Test the backward function. - module3.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using torch.nn.functional.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 19154.0); - - TransposedConvolution<> module4(1, 1, 3, 3, 1, 1, 0, 0, 5, 5, 7, 7); - // Test the forward function. - input = arma::linspace(0, 24, 25); - module4.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module4.Parameters()(2) = 2.0; - module4.Parameters()(4) = 4.0; - module4.Parameters()(6) = 6.0; - module4.Parameters()(8) = 8.0; - module4.Reset(); - module4.Forward(std::move(input), std::move(output)); - // Value calculated using torch.nn.functional.conv_transpose2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 6000.0); - - // Test the backward function. - module4.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using torch.nn.functional.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 86208.0); - - TransposedConvolution<> module5(1, 1, 3, 3, 2, 2, 0, 0, 2, 2, 5, 5); - // Test the forward function. - input = arma::linspace(0, 3, 4); - module5.Parameters() = arma::mat(25 + 1, 1, arma::fill::zeros); - module5.Parameters()(2) = 8.0; - module5.Parameters()(4) = 6.0; - module5.Parameters()(6) = 4.0; - module5.Parameters()(8) = 2.0; - module5.Reset(); - module5.Forward(std::move(input), std::move(output)); - // Value calculated using torch.nn.functional.conv_transpose2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 120.0); - - // Test the backward function. - module5.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using torch.nn.functional.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 960.0); - - TransposedConvolution<> module6(1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 5, 5); - // Test the forward function. - input = arma::linspace(0, 8, 9); - module6.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module6.Parameters()(0) = 8.0; - module6.Parameters()(3) = 6.0; - module6.Parameters()(6) = 2.0; - module6.Parameters()(8) = 4.0; - module6.Reset(); - module6.Forward(std::move(input), std::move(output)); - // Value calculated using torch.nn.functional.conv_transpose2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 410.0); - - // Test the backward function. - module6.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using torch.nn.functional.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 4444.0); - - TransposedConvolution<> module7(1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 6, 6); - // Test the forward function. - input = arma::linspace(0, 8, 9); - module7.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module7.Parameters()(0) = 8.0; - module7.Parameters()(2) = 6.0; - module7.Parameters()(4) = 2.0; - module7.Parameters()(8) = 4.0; - module7.Reset(); - module7.Forward(std::move(input), std::move(output)); - // Value calculated using torch.nn.functional.conv_transpose2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 606.0); - - module7.Backward(std::move(input), std::move(output), std::move(delta)); - // Value calculated using torch.nn.functional.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(delta), 7732.0); -} - -/** - * Transposed Convolution layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientTransposedConvolutionLayerTest) -{ - // Add function gradient instantiation. - // To make this test robust, check it five times. - bool pass = false; - for (size_t trial = 0; trial < 5; trial++) - { - struct GradientFunction - { - GradientFunction() - { - input = arma::linspace(0, 35, 36); - target = arma::mat("1"); - - model = new FFN, RandomInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add > - (1, 1, 3, 3, 2, 2, 1, 1, 6, 6, 12, 12); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, RandomInitialization>* model; - arma::mat input, target; - } function; - - if (CheckGradient(function) < 1e-3) - { - pass = true; - break; - } - } - BOOST_REQUIRE_EQUAL(pass, true); -} - -/** - * Simple MultiplyMerge module test. - */ -BOOST_AUTO_TEST_CASE(SimpleMultiplyMergeLayerTest) -{ - arma::mat output, input, delta; - input = arma::ones(10, 1); - - for (size_t i = 0; i < 5; ++i) - { - MultiplyMerge<> module(false, false); - const size_t numMergeModules = math::RandInt(2, 10); - for (size_t m = 0; m < numMergeModules; ++m) - { - IdentityLayer<> identityLayer; - identityLayer.Forward(std::move(input), - std::move(identityLayer.OutputParameter())); - - module.Add >(identityLayer); - } - - // Test the Forward function. - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(10, arma::accu(output)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(output), arma::accu(delta)); - } -} - -/** - * Simple Atrous Convolution layer test. - */ -BOOST_AUTO_TEST_CASE(SimpleAtrousConvolutionLayerTest) -{ - arma::mat output, input, delta; - - AtrousConvolution<> module1(1, 1, 3, 3, 1, 1, 0, 0, 7, 7, 2, 2); - // Test the Forward function. - input = arma::linspace(0, 48, 49); - module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module1.Parameters()(0) = 1.0; - module1.Parameters()(8) = 2.0; - module1.Reset(); - module1.Forward(std::move(input), std::move(output)); - // Value calculated using tensorflow.nn.atrous_conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 792.0); - - // Test the Backward function. - module1.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 2376); - - AtrousConvolution<> module2(1, 1, 3, 3, 2, 2, 0, 0, 7, 7, 2, 2); - // Test the forward function. - input = arma::linspace(0, 48, 49); - module2.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module2.Parameters()(0) = 1.0; - module2.Parameters()(3) = 1.0; - module2.Parameters()(6) = 1.0; - module2.Reset(); - module2.Forward(std::move(input), std::move(output)); - // Value calculated using tensorflow.nn.conv2d() - BOOST_REQUIRE_EQUAL(arma::accu(output), 264.0); - - // Test the backward function. - module2.Backward(std::move(input), std::move(output), std::move(delta)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 792.0); -} - -/** - * Atrous Convolution layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientAtrousConvolutionLayerTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::linspace(0, 35, 36); - target = arma::mat("1"); - - model = new FFN, RandomInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(1, 1, 3, 3, 1, 1, 0, 0, 6, 6, 2, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, RandomInitialization>* model; - arma::mat input, target; - } function; - - // TODO: this tolerance seems far higher than necessary. The implementation - // should be checked. - BOOST_REQUIRE_LE(CheckGradient(function), 0.2); -} - -/** - * Test the functions to access and modify the parameters of the - * AtrousConvolution layer. - */ -BOOST_AUTO_TEST_CASE(AtrousConvolutionLayerParametersTest) -{ - // Parameter order for the constructor: inSize, outSize, kW, kH, dW, dH, padW, - // padH, inputWidth, inputHeight, dilationW, dilationH, paddingType ("none"). - AtrousConvolution<> layer1(1, 2, 3, 4, 5, 6, std::make_tuple(7, 8), - std::make_tuple(9, 10), 11, 12, 13, 14); - AtrousConvolution<> layer2(2, 3, 4, 5, 6, 7, std::make_tuple(8, 9), - std::make_tuple(10, 11), 12, 13, 14, 15); - - // Make sure we can get the parameters successfully. - BOOST_REQUIRE_EQUAL(layer1.InputWidth(), 11); - BOOST_REQUIRE_EQUAL(layer1.InputHeight(), 12); - BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), 3); - BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), 4); - BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), 5); - BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), 6); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadHTop(), 9); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadHBottom(), 10); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadWLeft(), 7); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadWRight(), 8); - BOOST_REQUIRE_EQUAL(layer1.DilationWidth(), 13); - BOOST_REQUIRE_EQUAL(layer1.DilationHeight(), 14); - - // Now modify the parameters to match the second layer. - layer1.InputWidth() = 12; - layer1.InputHeight() = 13; - layer1.KernelWidth() = 4; - layer1.KernelHeight() = 5; - layer1.StrideWidth() = 6; - layer1.StrideHeight() = 7; - layer1.Padding().PadHTop() = 10; - layer1.Padding().PadHBottom() = 11; - layer1.Padding().PadWLeft() = 8; - layer1.Padding().PadWRight() = 9; - layer1.DilationWidth() = 14; - layer1.DilationHeight() = 15; - - // Now ensure all results are the same. - BOOST_REQUIRE_EQUAL(layer1.InputWidth(), layer2.InputWidth()); - BOOST_REQUIRE_EQUAL(layer1.InputHeight(), layer2.InputHeight()); - BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), layer2.KernelWidth()); - BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), layer2.KernelHeight()); - BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), layer2.StrideWidth()); - BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), layer2.StrideHeight()); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadHTop(), layer2.Padding().PadHTop()); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadHBottom(), - layer2.Padding().PadHBottom()); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadWLeft(), - layer2.Padding().PadWLeft()); - BOOST_REQUIRE_EQUAL(layer1.Padding().PadWRight(), - layer2.Padding().PadWRight()); - BOOST_REQUIRE_EQUAL(layer1.DilationWidth(), layer2.DilationWidth()); - BOOST_REQUIRE_EQUAL(layer1.DilationHeight(), layer2.DilationHeight()); -} - -/** - * Test that the padding options are working correctly in Atrous Convolution - * layer. - */ -BOOST_AUTO_TEST_CASE(AtrousConvolutionLayerPaddingTest) -{ - arma::mat output, input, delta; - - // Check valid padding option. - AtrousConvolution<> module1(1, 1, 3, 3, 1, 1, - std::tuple(1, 1), std::tuple(1, 1), 7, 7, - 2, 2, "valid"); - - // Test the Forward function. - input = arma::linspace(0, 48, 49); - module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module1.Reset(); - module1.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), 0); - BOOST_REQUIRE_EQUAL(output.n_rows, 9); - BOOST_REQUIRE_EQUAL(output.n_cols, 1); - - // Test the Backward function. - module1.Backward(std::move(input), std::move(output), std::move(delta)); - - // Check same padding option. - AtrousConvolution<> module2(1, 1, 3, 3, 1, 1, - std::tuple(0, 0), std::tuple(0, 0), 7, 7, - 2, 2, "same"); - - // Test the forward function. - input = arma::linspace(0, 48, 49); - module2.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module2.Reset(); - module2.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), 0); - BOOST_REQUIRE_EQUAL(output.n_rows, 49); - BOOST_REQUIRE_EQUAL(output.n_cols, 1); - - // Test the backward function. - module2.Backward(std::move(input), std::move(output), std::move(delta)); -} - -/** - * Tests the LayerNorm layer. - */ -BOOST_AUTO_TEST_CASE(LayerNormTest) -{ - arma::mat input, output; - input << 5.1 << 3.5 << arma::endr - << 4.9 << 3.0 << arma::endr - << 4.7 << 3.2 << arma::endr; - - LayerNorm<> model(input.n_rows); - model.Reset(); - - model.Forward(std::move(input), std::move(output)); - arma::mat result; - result << 1.2247 << 1.2978 << arma::endr - << 0 << -1.1355 << arma::endr - << -1.2247 << -0.1622 << arma::endr; - - CheckMatrices(output, result, 1e-1); - result.clear(); - - output = model.Mean(); - result << 4.9000 << 3.2333 << arma::endr; - - CheckMatrices(output, result, 1e-1); - result.clear(); - - output = model.Variance(); - result << 0.0267 << 0.0422 << arma::endr; - - CheckMatrices(output, result, 1e-1); -} - -/** - * LayerNorm layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientLayerNormTest) -{ - // Add function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randn(10, 256); - arma::mat target; - target.ones(1, 256); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - model->Add >(10); - model->Add >(10, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 256, false); - model->Gradient(model->Parameters(), 0, gradient, 256); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Test if the AddMerge layer is able to forward the - * Forward/Backward/Gradient calls. - */ -BOOST_AUTO_TEST_CASE(AddMergeRunTest) -{ - arma::mat output, input, delta, error; - - AddMerge<> module(true, true); - - Linear<>* linear = new Linear<>(10, 10); - module.Add(linear); - - linear->Parameters().randu(); - linear->Reset(); - - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - - double parameterSum = arma::accu(linear->Parameters().submat( - 100, 0, linear->Parameters().n_elem - 1, 0)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(input), std::move(delta)); - - // Clean up before we break, - delete linear; - - BOOST_REQUIRE_CLOSE(parameterSum, arma::accu(output), 1e-3); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -/** - * Test if the MultiplyMerge layer is able to forward the - * Forward/Backward/Gradient calls. - */ -BOOST_AUTO_TEST_CASE(MultiplyMergeRunTest) -{ - arma::mat output, input, delta, error; - - MultiplyMerge<> module(true, true); - - Linear<>* linear = new Linear<>(10, 10); - module.Add(linear); - - linear->Parameters().randu(); - linear->Reset(); - - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - - double parameterSum = arma::accu(linear->Parameters().submat( - 100, 0, linear->Parameters().n_elem - 1, 0)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(input), std::move(delta)); - - // Clean up before we break, - delete linear; - - BOOST_REQUIRE_CLOSE(parameterSum, arma::accu(output), 1e-3); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -/** - * Simple subview module test. - */ -BOOST_AUTO_TEST_CASE(SimpleSubviewLayerTest) -{ - arma::mat output, input, delta, outputMat; - Subview<> moduleRow(1, 10, 19); - - // Test the Forward function for a vector. - input = arma::ones(20, 1); - moduleRow.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_EQUAL(output.n_rows, 10); - - Subview<> moduleMat(4, 3, 6, 0, 2); - - // Test the Forward function for a matrix. - input = arma::ones(20, 8); - moduleMat.Forward(std::move(input), std::move(outputMat)); - BOOST_REQUIRE_EQUAL(outputMat.n_rows, 12); - BOOST_REQUIRE_EQUAL(outputMat.n_cols, 2); - - // Test the Backward function. - moduleMat.Backward(std::move(input), std::move(input), std::move(delta)); - BOOST_REQUIRE_EQUAL(accu(delta), 160); - BOOST_REQUIRE_EQUAL(delta.n_rows, 20); -} - -/** - * Subview index test. - */ -BOOST_AUTO_TEST_CASE(SubviewIndexTest) -{ - arma::mat outputEnd, outputMid, outputStart, input, delta; - input = arma::linspace(1, 20, 20); - - // Slicing from the initial indices. - Subview<> moduleStart(1, 0, 9); - arma::mat subStart = arma::linspace(1, 10, 10); - - moduleStart.Forward(std::move(input), std::move(outputStart)); - CheckMatrices(outputStart, subStart); - - // Slicing from the mid indices. - Subview<> moduleMid(1, 6, 15); - arma::mat subMid = arma::linspace(7, 16, 10); - - moduleMid.Forward(std::move(input), std::move(outputMid)); - CheckMatrices(outputMid, subMid); - - // Slicing from the end indices. - Subview<> moduleEnd(1, 10, 19); - arma::mat subEnd = arma::linspace(11, 20, 10); - - moduleEnd.Forward(std::move(input), std::move(outputEnd)); - CheckMatrices(outputEnd, subEnd); -} - -/** - * Subview batch test. - */ -BOOST_AUTO_TEST_CASE(SubviewBatchTest) -{ - arma::mat output, input, outputCol, outputMat, outputDef; - - // All rows selected. - Subview<> moduleCol(1, 0, 19); - - // Test with inSize 1. - input = arma::ones(20, 8); - moduleCol.Forward(std::move(input), std::move(outputCol)); - CheckMatrices(outputCol, input); - - // Few rows and columns selected. - Subview<> moduleMat(4, 3, 6, 0, 2); - - // Test with inSize greater than 1. - moduleMat.Forward(std::move(input), std::move(outputMat)); - output = arma::ones(12, 2); - CheckMatrices(outputMat, output); - - // endCol changed to 3 by default. - Subview<> moduleDef(4, 1, 6, 0, 4); - - // Test with inSize greater than 1 and endCol >= inSize. - moduleDef.Forward(std::move(input), std::move(outputDef)); - output = arma::ones(24, 2); - CheckMatrices(outputDef, output); -} - -/* - * Simple Reparametrization module test. - */ -BOOST_AUTO_TEST_CASE(SimpleReparametrizationLayerTest) -{ - arma::mat input, output, delta; - Reparametrization<> module(5); - - // Test the Forward function. As the mean is zero and the standard - // deviation is small, after multiplying the gaussian sample, the - // output should be small enough. - input = join_cols(arma::ones(5, 1) * -15, - arma::zeros(5, 1)); - module.Forward(std::move(input), std::move(output)); - BOOST_REQUIRE_LE(arma::accu(output), 1e-5); - - // Test the Backward function. - arma::mat gy = arma::zeros(5, 1); - module.Backward(std::move(input), std::move(gy), std::move(delta)); - BOOST_REQUIRE(arma::accu(delta) != 0); // klBackward will be added. -} - -/** - * Reparametrization module stochastic boolean test. - */ -BOOST_AUTO_TEST_CASE(ReparametrizationLayerStochasticTest) -{ - arma::mat input, outputA, outputB; - Reparametrization<> module(5, false); - - input = join_cols(arma::ones(5, 1), - arma::zeros(5, 1)); - - // Test if two forward passes generate same output. - module.Forward(std::move(input), std::move(outputA)); - module.Forward(std::move(input), std::move(outputB)); - - CheckMatrices(outputA, outputB); -} - -/** - * Reparametrization module includeKl boolean test. - */ -BOOST_AUTO_TEST_CASE(ReparametrizationLayerIncludeKlTest) -{ - arma::mat input, output, gy, delta; - Reparametrization<> module(5, true, false); - - input = join_cols(arma::ones(5, 1), - arma::zeros(5, 1)); - module.Forward(std::move(input), std::move(output)); - - // As KL divergence is not included, with the above inputs, the delta - // matrix should be all zeros. - gy = arma::zeros(output.n_rows, output.n_cols); - module.Backward(std::move(output), std::move(gy), std::move(delta)); - - BOOST_REQUIRE_EQUAL(arma::accu(std::move(delta)), 0); -} - -/** - * Jacobian Reparametrization module test. - */ -BOOST_AUTO_TEST_CASE(JacobianReparametrizationLayerTest) -{ - for (size_t i = 0; i < 5; i++) - { - const size_t inputElementsHalf = math::RandInt(2, 1000); - - arma::mat input; - input.set_size(inputElementsHalf * 2, 1); - - Reparametrization<> module(inputElementsHalf, false, false); - - double error = JacobianTest(module, input); - BOOST_REQUIRE_LE(error, 1e-5); - } -} - -/** - * Reparametrization layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientReparametrizationLayerTest) -{ - // Linear function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 6); - model->Add >(3, false, true, 1); - model->Add >(3, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Reparametrization layer beta numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientReparametrizationLayerBetaTest) -{ - // Linear function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 2); - target = arma::mat("1 1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 6); - // Use a value of beta not equal to 1. - model->Add >(3, false, true, 2); - model->Add >(3, 2); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Simple residual module test. - */ -BOOST_AUTO_TEST_CASE(SimpleResidualLayerTest) -{ - arma::mat outputA, outputB, input, deltaA, deltaB; - - Sequential<>* sequential = new Sequential<>(true); - Residual<>* residual = new Residual<>(true); - - Linear<>* linearA = new Linear<>(10, 10); - linearA->Parameters().randu(); - linearA->Reset(); - Linear<>* linearB = new Linear<>(10, 10); - linearB->Parameters().randu(); - linearB->Reset(); - - // Add the same layers (with the same parameters) to both Sequential and - // Residual object. - sequential->Add(linearA); - sequential->Add(linearB); - - residual->Add(linearA); - residual->Add(linearB); - - // Test the Forward function (pass the same input to both). - input = arma::randu(10, 1); - sequential->Forward(std::move(input), std::move(outputA)); - residual->Forward(std::move(input), std::move(outputB)); - - CheckMatrices(outputA, outputB - input); - - // Test the Backward function (pass the same error to both). - sequential->Backward(std::move(input), std::move(input), std::move(deltaA)); - residual->Backward(std::move(input), std::move(input), std::move(deltaB)); - - CheckMatrices(deltaA, deltaB - input); - - delete sequential; - delete residual; - delete linearA; - delete linearB; -} - -/** - * Simple Highway module test. - */ -BOOST_AUTO_TEST_CASE(SimpleHighwayLayerTest) -{ - arma::mat outputA, outputB, input, deltaA, deltaB; - Sequential<>* sequential = new Sequential<>(true); - Highway<>* highway = new Highway<>(10, true); - highway->Parameters().zeros(); - highway->Reset(); - - Linear<>* linearA = new Linear<>(10, 10); - linearA->Parameters().randu(); - linearA->Reset(); - Linear<>* linearB = new Linear<>(10, 10); - linearB->Parameters().randu(); - linearB->Reset(); - - // Add the same layers (with the same parameters) to both Sequential and - // Highway object. - highway->Add(linearA); - highway->Add(linearB); - sequential->Add(linearA); - sequential->Add(linearB); - - // Test the Forward function (pass the same input to both). - input = arma::randu(10, 1); - sequential->Forward(std::move(input), std::move(outputA)); - highway->Forward(std::move(input), std::move(outputB)); - - CheckMatrices(outputB, input * 0.5 + outputA * 0.5); - - delete sequential; - delete highway; - delete linearA; - delete linearB; -} - -/** - * Sequential layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientHighwayLayerTest) -{ - // Linear function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(5, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(5, 10); - - highway = new Highway<>(10); - highway->Add >(10, 10); - highway->Add >(); - highway->Add >(10, 10); - highway->Add >(); - - model->Add(highway); - model->Add >(10, 2); - model->Add >(); - } - - ~GradientFunction() - { - highway->DeleteModules(); - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - Highway<>* highway; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Sequential layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientSequentialLayerTest) -{ - // Linear function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(); - model->Add >(10, 10); - sequential = new Sequential<>(); - sequential->Add >(10, 10); - sequential->Add >(); - sequential->Add >(10, 5); - sequential->Add >(); - - model->Add(sequential); - model->Add >(5, 2); - model->Add >(); - } - - ~GradientFunction() - { - sequential->DeleteModules(); - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - Sequential<>* sequential; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * WeightNorm layer numerical gradient test. - */ -BOOST_AUTO_TEST_CASE(GradientWeightNormLayerTest) -{ - // Linear function gradient instantiation. - struct GradientFunction - { - GradientFunction() - { - input = arma::randu(10, 1); - target = arma::mat("1"); - - model = new FFN, NguyenWidrowInitialization>(); - model->Predictors() = input; - model->Responses() = target; - model->Add >(10, 10); - - Linear<>* linear = new Linear<>(10, 2); - weightNorm = new WeightNorm<>(linear); - - model->Add(weightNorm); - model->Add >(); - } - - ~GradientFunction() - { - delete model; - } - - double Gradient(arma::mat& gradient) const - { - double error = model->Evaluate(model->Parameters(), 0, 1); - model->Gradient(model->Parameters(), 0, gradient, 1); - return error; - } - - arma::mat& Parameters() { return model->Parameters(); } - - FFN, NguyenWidrowInitialization>* model; - WeightNorm<>* weightNorm; - arma::mat input, target; - } function; - - BOOST_REQUIRE_LE(CheckGradient(function), 1e-4); -} - -/** - * Test if the WeightNorm layer is able to forward the - * Forward/Backward/Gradient calls. - */ -BOOST_AUTO_TEST_CASE(WeightNormRunTest) -{ - arma::mat output, input, delta, error; - - Linear<>* linear = new Linear<>(10, 10); - - WeightNorm<> module(linear); - - module.Parameters().randu(); - module.Reset(); - - linear->Bias().zeros(); - - input = arma::zeros(10, 1); - module.Forward(std::move(input), std::move(output)); - - // Test the Backward function. - module.Backward(std::move(input), std::move(input), std::move(delta)); - - BOOST_REQUIRE_EQUAL(0, arma::accu(output)); - BOOST_REQUIRE_EQUAL(arma::accu(delta), 0); -} - -// General ANN serialization test. -template -void ANNLayerSerializationTest(LayerType& layer) -{ - arma::mat input(5, 100, arma::fill::randu); - arma::mat output(5, 100, arma::fill::randu); - - FFN, ann::RandomInitialization> model; - model.Add>(input.n_rows, 10); - model.Add(layer); - model.Add>(); - model.Add>(10, output.n_rows); - model.Add>(); - - ens::StandardSGD opt(0.1, 1, 5, -100, false); - model.Train(input, output, opt); - - arma::mat originalOutput; - model.Predict(input, originalOutput); - - // Now serialize the model. - FFN, ann::RandomInitialization> xmlModel, textModel, - binaryModel; - SerializeObjectAll(model, xmlModel, textModel, binaryModel); - - // Ensure that predictions are the same. - arma::mat modelOutput, xmlOutput, textOutput, binaryOutput; - model.Predict(input, modelOutput); - xmlModel.Predict(input, xmlOutput); - textModel.Predict(input, textOutput); - binaryModel.Predict(input, binaryOutput); - - CheckMatrices(originalOutput, modelOutput, 1e-5); - CheckMatrices(originalOutput, xmlOutput, 1e-5); - CheckMatrices(originalOutput, textOutput, 1e-5); - CheckMatrices(originalOutput, binaryOutput, 1e-5); -} - -/** - * Simple serialization test for batch normalization layer. - */ -BOOST_AUTO_TEST_CASE(BatchNormSerializationTest) -{ - BatchNorm<> layer(10); - ANNLayerSerializationTest(layer); -} - -/** - * Simple serialization test for layer normalization layer. - */ -BOOST_AUTO_TEST_CASE(LayerNormSerializationTest) -{ - LayerNorm<> layer(10); - ANNLayerSerializationTest(layer); -} - -/** - * Test that the functions that can modify and access the parameters of the - * Convolution layer work. - */ -BOOST_AUTO_TEST_CASE(ConvolutionLayerParametersTest) -{ - // Parameter order: inSize, outSize, kW, kH, dW, dH, padW, padH, inputWidth, - // inputHeight, paddingType. - Convolution<> layer1(1, 2, 3, 4, 5, 6, std::tuple(7, 8), - std::tuple(9, 10), 11, 12, "none"); - Convolution<> layer2(2, 3, 4, 5, 6, 7, std::tuple(8, 9), - std::tuple(10, 11), 12, 13, "none"); - - // Make sure we can get the parameters successfully. - BOOST_REQUIRE_EQUAL(layer1.InputWidth(), 11); - BOOST_REQUIRE_EQUAL(layer1.InputHeight(), 12); - BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), 3); - BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), 4); - BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), 5); - BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), 6); - BOOST_REQUIRE_EQUAL(layer1.PadWLeft(), 7); - BOOST_REQUIRE_EQUAL(layer1.PadWRight(), 8); - BOOST_REQUIRE_EQUAL(layer1.PadHTop(), 9); - BOOST_REQUIRE_EQUAL(layer1.PadHBottom(), 10); - - // Now modify the parameters to match the second layer. - layer1.InputWidth() = 12; - layer1.InputHeight() = 13; - layer1.KernelWidth() = 4; - layer1.KernelHeight() = 5; - layer1.StrideWidth() = 6; - layer1.StrideHeight() = 7; - layer1.PadWLeft() = 8; - layer1.PadWRight() = 9; - layer1.PadHTop() = 10; - layer1.PadHBottom() = 11; - - // Now ensure all results are the same. - BOOST_REQUIRE_EQUAL(layer1.InputWidth(), layer2.InputWidth()); - BOOST_REQUIRE_EQUAL(layer1.InputHeight(), layer2.InputHeight()); - BOOST_REQUIRE_EQUAL(layer1.KernelWidth(), layer2.KernelWidth()); - BOOST_REQUIRE_EQUAL(layer1.KernelHeight(), layer2.KernelHeight()); - BOOST_REQUIRE_EQUAL(layer1.StrideWidth(), layer2.StrideWidth()); - BOOST_REQUIRE_EQUAL(layer1.StrideHeight(), layer2.StrideHeight()); - BOOST_REQUIRE_EQUAL(layer1.PadWLeft(), layer2.PadWLeft()); - BOOST_REQUIRE_EQUAL(layer1.PadWRight(), layer2.PadWRight()); - BOOST_REQUIRE_EQUAL(layer1.PadHTop(), layer2.PadHTop()); - BOOST_REQUIRE_EQUAL(layer1.PadHBottom(), layer2.PadHBottom()); -} - -/** - * Test that the padding options are working correctly in Convolution layer. - */ -BOOST_AUTO_TEST_CASE(ConvolutionLayerPaddingTest) -{ - arma::mat output, input, delta; - - // Check valid padding option. - Convolution<> module1(1, 1, 3, 3, 1, 1, std::tuple(1, 1), - std::tuple(1, 1), 7, 7, "valid"); - - // Test the Forward function. - input = arma::linspace(0, 48, 49); - module1.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module1.Reset(); - module1.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), 0); - BOOST_REQUIRE_EQUAL(output.n_rows, 25); - BOOST_REQUIRE_EQUAL(output.n_cols, 1); - - // Test the Backward function. - module1.Backward(std::move(input), std::move(output), std::move(delta)); - - // Check same padding option. - Convolution<> module2(1, 1, 3, 3, 1, 1, std::tuple(0, 0), - std::tuple(0, 0), 7, 7, "same"); - - // Test the forward function. - input = arma::linspace(0, 48, 49); - module2.Parameters() = arma::mat(9 + 1, 1, arma::fill::zeros); - module2.Reset(); - module2.Forward(std::move(input), std::move(output)); - - BOOST_REQUIRE_EQUAL(arma::accu(output), 0); - BOOST_REQUIRE_EQUAL(output.n_rows, 49); - BOOST_REQUIRE_EQUAL(output.n_cols, 1); - - // Test the backward function. - module2.Backward(std::move(input), std::move(output), std::move(delta)); -} - -BOOST_AUTO_TEST_SUITE_END(); From 6748dc2aed08474e142f059359299240f99eb5e3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 13 Dec 2020 10:52:43 -0500 Subject: [PATCH 338/550] Try to fix static code analysis issues. --- src/mlpack/tests/cf_test.cpp | 2 +- src/mlpack/tests/rnn_reber_test.cpp | 2 -- src/mlpack/tests/serialization_test.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mlpack/tests/cf_test.cpp b/src/mlpack/tests/cf_test.cpp index 22b513b531..af5623f708 100644 --- a/src/mlpack/tests/cf_test.cpp +++ b/src/mlpack/tests/cf_test.cpp @@ -346,7 +346,7 @@ void TrainWithCoordinateList(DecompositionPolicy& decomposition) { arma::mat randomData(3, 100); randomData.row(0) = arma::linspace(0, 99, 100); - randomData.row(1) = arma::linspace(0, 99, 100); + randomData.row(1) = randomData.row(0); randomData.row(2).fill(3); CFType c(randomData, decomposition, 5, 5, 30); diff --git a/src/mlpack/tests/rnn_reber_test.cpp b/src/mlpack/tests/rnn_reber_test.cpp index 6471e3809f..da5d245592 100644 --- a/src/mlpack/tests/rnn_reber_test.cpp +++ b/src/mlpack/tests/rnn_reber_test.cpp @@ -179,7 +179,6 @@ void GenerateNextRecursiveReber(const arma::Mat& transitions, else if (c == 'P' && state == 1) { numPs++; - state = 1; } else if (c == 'T' && state == 1) { @@ -206,7 +205,6 @@ void GenerateNextRecursiveReber(const arma::Mat& transitions, else if (c == 'P' && state == 5) { numPs--; - state = 5; } } diff --git a/src/mlpack/tests/serialization_test.cpp b/src/mlpack/tests/serialization_test.cpp index c564f0a482..8ca83af9f8 100644 --- a/src/mlpack/tests/serialization_test.cpp +++ b/src/mlpack/tests/serialization_test.cpp @@ -1682,7 +1682,7 @@ TEST_CASE("CerealEmptyArrayWrapperTest", "[SerializationTest]") jsonT.mem = new int[5]; jsonT.len = 5; - SerializeObjectAll(t, xmlT, binaryT, jsonT); + SerializeObjectAll(t, xmlT, jsonT, binaryT); // Ensure that all the results are correct. REQUIRE(xmlT.mem == (int*) NULL); From ca0c2118604c5857280b14d0fb7807d903bff2f1 Mon Sep 17 00:00:00 2001 From: Marcus Edel Date: Sun, 13 Dec 2020 19:48:12 +0100 Subject: [PATCH 339/550] Update COPYRIGHT (year). --- COPYRIGHT.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 907caf9d1a..0653df4a21 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -7,7 +7,7 @@ Source: Files: * Copyright: - Copyright 2008-2018, Ryan Curtin + Copyright 2008-2020, Ryan Curtin Copyright 2008-2013, Bill March Copyright 2008-2012, Dongryeol Lee Copyright 2008-2013, Nishant Mehta @@ -22,11 +22,11 @@ Copyright: Copyright 2012, Rajendran Mohan Copyright 2012, Trironk Kiatkungwanglai Copyright 2012, Patrick Mason - Copyright 2013-2018, Marcus Edel + Copyright 2013-2020, Marcus Edel Copyright 2013, Mudit Raj Gupta Copyright 2013-2018, Sumedh Ghaisas Copyright 2014, Michael Fox - Copyright 2014, Ryan Birmingham + Copyright 2014,2020 Ryan Birmingham Copyright 2014, Siddharth Agrawal Copyright 2014, Saheb Motiani Copyright 2014, Yash Vadalia @@ -37,7 +37,7 @@ Copyright: Copyright 2014, Udit Saxena Copyright 2014-2015, Stephen Tu Copyright 2014-2015, Jaskaran Singh - Copyright 2015&2017, Shangtong Zhang + Copyright 2015,2017, Shangtong Zhang Copyright 2015, Hritik Jain Copyright 2015, Vladimir Glazachev Copyright 2015, QiaoAn Chen @@ -55,7 +55,7 @@ Copyright: Copyright 2016, Palash Ahuja Copyright 2016, Yannis Mentekidis Copyright 2016, Ranjan Mondal - Copyright 2016-2018, Mikhail Lozhnikov + Copyright 2016-2020, Mikhail Lozhnikov Copyright 2016, Marcos Pividori Copyright 2016, Keon Kim Copyright 2016, Nilay Jain @@ -84,14 +84,14 @@ Copyright: Copyright 2017, N Rajiv Vaidyanathan Copyright 2017, Kartik Nighania Copyright 2017-2018, Eugene Freyman - Copyright 2017-2018, Manish Kumar + Copyright 2017-2019, Manish Kumar Copyright 2017-2018, Haritha Sreedharan Nair Copyright 2017-2018, Sourabh Varshney Copyright 2018, Projyal Dev Copyright 2018, Nikhil Goel - Copyright 2018, Shikhar Jaiswal + Copyright 2018-2020 Shikhar Jaiswal Copyright 2018, B Kartheek Reddy - Copyright 2018, Atharva Khandait + Copyright 2018-2019 Atharva Khandait Copyright 2018, Wenhao Huang Copyright 2018-2019, Roberto Hueso Copyright 2018, Prabhat Sharma @@ -114,9 +114,9 @@ Copyright: Copyright 2019, Miguel Canteras Copyright 2019, Bishwa Karki Copyright 2019, Mehul Kumar Nirala - Copyright 2019, Yashwant Singh Parihar + Copyright 2019-2020 Yashwant Singh Parihar Copyright 2019, Heet Sankesara - Copyright 2019, Jeffin Sam + Copyright 2019-2020 Jeffin Sam Copyright 2019, Vikas S Shetty Copyright 2019, Khizir Siddiqui Copyright 2019, Tejasvi Tomar @@ -124,7 +124,7 @@ Copyright: Copyright 2019, Ziyang Jiang Copyright 2019, Rohit Kartik Copyright 2019, Aditya Viki - Copyright 2019, Kartik Dutt + Copyright 2019-2020 Kartik Dutt Copyright 2020, Sriram S K Copyright 2020, Manoranjan Kumar Bharti ( Nakul Bharti ) Copyright 2020, Saraansh Tandon From d6d97018dd5ec0e2e9152c700e7e536f2f6942eb Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 13 Dec 2020 17:31:01 -0500 Subject: [PATCH 340/550] Fix edge case for similarly-correlated dimensions. --- src/mlpack/methods/lars/lars.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mlpack/methods/lars/lars.cpp b/src/mlpack/methods/lars/lars.cpp index b86c361a3f..03612406fc 100644 --- a/src/mlpack/methods/lars/lars.cpp +++ b/src/mlpack/methods/lars/lars.cpp @@ -366,13 +366,16 @@ double LARS::Train(const arma::mat& matX, if (isActive[ind] || isIgnored[ind]) continue; - double dirCorr = dot(dataRef.col(ind), yHatDirection); - double val1 = (maxCorr - corr(ind)) / (normalization - dirCorr); - double val2 = (maxCorr + corr(ind)) / (normalization + dirCorr); - if ((val1 > 0) && (val1 < gamma)) - gamma = val1; - if ((val2 > 0) && (val2 < gamma)) - gamma = val2; + const double dirCorr = dot(dataRef.col(ind), yHatDirection); + const double val1 = (maxCorr - corr(ind)) / (normalization - dirCorr); + const double val2 = (maxCorr + corr(ind)) / (normalization + dirCorr); + if ((val1 > 0.0) && (val1 < gamma)) + gamma = val1; + if ((val2 > 0.0) && (val2 < gamma)) + gamma = val2; + // Handle edge case where the largest actually is equal to 0. + if (std::max(val1, val2) == 0.0) + gamma = 0.0; } } From eb46d8610e3337086bb42016d5df44cd835a6588 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 13 Dec 2020 18:01:06 -0500 Subject: [PATCH 341/550] Hardcode LICENSE file. --- src/mlpack/bindings/R/CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index d2c5b46dea..830833b614 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -224,7 +224,7 @@ if (BUILD_R_BINDINGS) ) set(LICENSE_SOURCES - "${CMAKE_SOURCE_DIR}/LICENSE.txt" + "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/LICENSE" ) add_custom_target(r_copy ALL) @@ -276,10 +276,6 @@ if (BUILD_R_BINDINGS) COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${LICENSE_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/mlpack) - add_custom_command(TARGET r_copy PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E rename - "${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE.txt" - "${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE") # This file will take care of multiple definition of functions in .cpp files. add_custom_command(TARGET r_copy PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E touch From ad4057179c7e953c0a065f8a3fb6ebd6ac683d44 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 16 Dec 2020 00:01:27 +0530 Subject: [PATCH 342/550] Update src/mlpack/methods/ann/util/check_input_shape.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/util/check_input_shape.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp index 87ec25bb67..44c6d39b11 100644 --- a/src/mlpack/methods/ann/util/check_input_shape.hpp +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -1,5 +1,5 @@ /** - * @file check_input_shape.hpp + * @file methods/ann/util/check_input_shape.hpp * @author Khizir Siddiqui * @author Nippun Sharma * @@ -50,4 +50,4 @@ void CheckInputShape(const T& network, const size_t inputShape, } // namespace ann } // namespace mlpack -#endif \ No newline at end of file +#endif From f6f3b626250a16b54d470f75392483a9369f82f8 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 16 Dec 2020 00:01:41 +0530 Subject: [PATCH 343/550] Update src/mlpack/methods/ann/visitor/input_shape_visitor.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/visitor/input_shape_visitor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp index 92d2c5d553..c27135aae3 100644 --- a/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor.hpp @@ -1,5 +1,5 @@ /** - * @file input_shape_visitor.hpp + * @file methods/ann/visitor/input_shape_visitor.hpp * @author Khizir Siddiqui * @author Nippun Sharma * From 8c56b4f1edd7fd9a413307afa9e3b123aa881e2d Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Wed, 16 Dec 2020 00:01:54 +0530 Subject: [PATCH 344/550] Update src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp index 5ceef063d0..bda5f7b604 100644 --- a/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp +++ b/src/mlpack/methods/ann/visitor/input_shape_visitor_impl.hpp @@ -1,5 +1,5 @@ /** - * @file input_shape_visitor_impl.hpp + * @file methods/ann/visitor/input_shape_visitor_impl.hpp * @author Khizir Siddiqui * @author Nippun Sharma * From 3d53a4994efdadf8e59b135e12dde2203d36b88b Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 16 Dec 2020 00:05:23 +0530 Subject: [PATCH 345/550] undo delete --- src/mlpack/tests/ann_visitor_test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index b6502fad3e..e5d1310368 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -190,8 +190,6 @@ TEST_CASE("WeightSizeVisitorTestForTransposedConvLayer", "[ANNVisitorTest]") randomOutSize, randomKernelWidth, randomKernelHeight); CheckCorrectnessOfWeightSize(transposedConvLayer); - - delete transposedConvLayer; } /** @@ -206,6 +204,4 @@ TEST_CASE("WeightSizeVisitorTestForNoisyLinearLayer", "[ANNVisitorTest]") randomOutSize); CheckCorrectnessOfWeightSize(noisyLinearLayer); - - delete noisyLinearLayer; } From 8a38ffd33137056df395159d771cd602c7931e63 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 15 Dec 2020 18:58:27 -0500 Subject: [PATCH 346/550] Add forward declaration. --- src/mlpack/methods/rann/ra_search.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/rann/ra_search.hpp b/src/mlpack/methods/rann/ra_search.hpp index 2dd91baf68..3e7147f54f 100644 --- a/src/mlpack/methods/rann/ra_search.hpp +++ b/src/mlpack/methods/rann/ra_search.hpp @@ -40,7 +40,7 @@ namespace neighbor { // Forward declaration. template -class TrainVisitor; +class RATrainVisitor; /** * The RASearch class: This class provides a generic manner to perform From 176dc8b44ba7affe0455051f020193f772107d4b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 15 Dec 2020 20:18:03 -0500 Subject: [PATCH 347/550] Add a test to ensure that we don't finalize a model multiple times. --- src/mlpack/bindings/julia/tests/runtests.jl | 17 +++++++++++++++++ .../julia/tests/test_julia_binding_main.cpp | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/src/mlpack/bindings/julia/tests/runtests.jl b/src/mlpack/bindings/julia/tests/runtests.jl index fe1bf189f6..bb98c54435 100644 --- a/src/mlpack/bindings/julia/tests/runtests.jl +++ b/src/mlpack/bindings/julia/tests/runtests.jl @@ -377,3 +377,20 @@ end Filesystem.rm("model.bin") end + +# Ensure that we don't accidentally free a model multiple times. +@testset "TestMultipleModelDealloc" begin + _, _, _, _, _, _, model, _, _, _, _, _, _, _ = + test_julia_binding(4.0, 12, "hello", build_model=true) + + begin + for i = 1:100 + out = test_julia_binding(4.0, 12, "hello", model_in=model, + duplicate_model=true) + end + end + + # This should free the other models. It's likely to crash if a model might be + # freed multiple times. + GC.gc() +end diff --git a/src/mlpack/bindings/julia/tests/test_julia_binding_main.cpp b/src/mlpack/bindings/julia/tests/test_julia_binding_main.cpp index 5ba385cf2b..28885ca13b 100644 --- a/src/mlpack/bindings/julia/tests/test_julia_binding_main.cpp +++ b/src/mlpack/bindings/julia/tests/test_julia_binding_main.cpp @@ -47,6 +47,8 @@ PARAM_VECTOR_IN(int, "vector_in", "Input vector of numbers.", ""); PARAM_VECTOR_IN(string, "str_vector_in", "Input vector of strings.", ""); PARAM_MODEL_IN(GaussianKernel, "model_in", "Input model.", ""); PARAM_FLAG("build_model", "If true, a model will be returned.", ""); +PARAM_FLAG("duplicate_model", "If true, return the input model as the output " + "model.", ""); PARAM_STRING_OUT("string_out", "Output string, will be 'hello2'.", "S"); PARAM_INT_OUT("int_out", "Output int, will be 13."); @@ -194,4 +196,11 @@ static void mlpackMain() IO::GetParam("model_bw_out") = IO::GetParam("model_in")->Bandwidth() * 2.0; } + + // If requested, duplicate the input model as the output model. + if (IO::HasParam("duplicate_model")) + { + IO::GetParam("model_out") = + IO::GetParam("model_in"); + } } From 10bc8afa3dadb754943c1b7be343ead789d8dcfb Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 15 Dec 2020 20:18:15 -0500 Subject: [PATCH 348/550] Cache all the input pointers, to make sure we don't re-finalize them. --- CMake/julia/AppendType.cmake | 12 +++++++----- .../julia/print_input_processing_impl.hpp | 10 ++++++++++ src/mlpack/bindings/julia/print_jl.cpp | 6 ++++++ .../julia/print_output_processing_impl.hpp | 2 +- src/mlpack/bindings/julia/print_param_defn.hpp | 17 ++++++++++------- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CMake/julia/AppendType.cmake b/CMake/julia/AppendType.cmake index a3b5d2aea6..d8c15d87d2 100644 --- a/CMake/julia/AppendType.cmake +++ b/CMake/julia/AppendType.cmake @@ -35,12 +35,14 @@ function(append_type TYPES_FILE PROGRAM_NAME PROGRAM_MAIN_FILE) "mutable struct ${MODEL_SAFE_TYPE}\n" " ptr::Ptr{Nothing}\n" "\n" - " # Construct object and set finalizer to free memory.\n" - " function ${MODEL_SAFE_TYPE}(ptr::Ptr{Nothing})::${MODEL_SAFE_TYPE}\n" + " # Construct object and set finalizer to free memory if `finalize` is true.\n" + " function ${MODEL_SAFE_TYPE}(ptr::Ptr{Nothing}; finalize::Bool = false)::${MODEL_SAFE_TYPE}\n" " result = new(ptr)\n" - " finalizer(\n" - " x -> _Internal.${PROGRAM_NAME}_internal.Delete${MODEL_SAFE_TYPE}(x.ptr),\n" - " result)\n" + " if finalize\n" + " finalizer(\n" + " x -> _Internal.${PROGRAM_NAME}_internal.Delete${MODEL_SAFE_TYPE}(x.ptr),\n" + " result)\n" + " end\n" " return result\n" " end\n" "end\n" diff --git a/src/mlpack/bindings/julia/print_input_processing_impl.hpp b/src/mlpack/bindings/julia/print_input_processing_impl.hpp index e30827f95d..bfb5608929 100644 --- a/src/mlpack/bindings/julia/print_input_processing_impl.hpp +++ b/src/mlpack/bindings/julia/print_input_processing_impl.hpp @@ -127,6 +127,13 @@ void PrintInputProcessing( // "type" is a reserved keyword or function. const std::string juliaName = (d.name == "type") ? "type_" : d.name; + // For a non-required argument, this gives code like the following: + // + // if !ismissing() + // push!(model_ptrs, convert(, ).ptr) + // IOSetParam("", convert(, )) + // end + // If the argument is not required, then we have to encase the code in an if. size_t extraIndent = 0; if (!d.required) @@ -137,6 +144,9 @@ void PrintInputProcessing( std::string indent(extraIndent + 2, ' '); std::string type = util::StripType(d.cppType); + std::cout << indent << "push!(modelPtrs, convert(" + << GetJuliaType::type>(d) << ", " + << juliaName << ").ptr)" << std::endl; std::cout << indent << functionName << "_internal.IOSetParam" << type << "(\"" << d.name << "\", convert(" << GetJuliaType::type>(d) << ", " diff --git a/src/mlpack/bindings/julia/print_jl.cpp b/src/mlpack/bindings/julia/print_jl.cpp index ac1f7d8b60..6b4c4f5ac0 100644 --- a/src/mlpack/bindings/julia/print_jl.cpp +++ b/src/mlpack/bindings/julia/print_jl.cpp @@ -251,6 +251,12 @@ void PrintJL(const util::BindingDetails& doc, << endl; cout << endl; + // Create the set of model pointers. + cout << " # Create the set of model pointers to avoid setting multiple " + << "finalizers." << endl; + cout << " modelPtrs = Set{Ptr{Nothing}}()" << endl; + cout << endl; + // Restore IO settings. cout << " IORestoreSettings(\"" << programName << "\")" << endl; cout << endl; diff --git a/src/mlpack/bindings/julia/print_output_processing_impl.hpp b/src/mlpack/bindings/julia/print_output_processing_impl.hpp index 1d066f7bca..5515fbf2df 100644 --- a/src/mlpack/bindings/julia/print_output_processing_impl.hpp +++ b/src/mlpack/bindings/julia/print_output_processing_impl.hpp @@ -107,7 +107,7 @@ void PrintOutputProcessing( { std::string type = util::StripType(d.cppType); std::cout << functionName << "_internal.IOGetParam" - << type << "(\"" << d.name << "\")"; + << type << "(\"" << d.name << "\", modelPtrs)"; } /** diff --git a/src/mlpack/bindings/julia/print_param_defn.hpp b/src/mlpack/bindings/julia/print_param_defn.hpp index 51a47d39fd..1ee6d7d164 100644 --- a/src/mlpack/bindings/julia/print_param_defn.hpp +++ b/src/mlpack/bindings/julia/print_param_defn.hpp @@ -58,9 +58,10 @@ void PrintParamDefn( // // import ... // - // function IOGetParam(paramName::String) - // (ccall((:IO_GetParamPtr, Library), - // Ptr{Nothing}, (Cstring,), paramName)) + // function IOGetParam(paramName::String, modelPtrs::Set{Ptr{Nothing}}) + // ptr = ccall((:IO_GetParamPtr, Library), + // Ptr{Nothing}, (Cstring,), paramName) + // return (ptr; finalize=!(ptr in modelPtrs)) // end // // function IOSetParam(paramName::String, model::) @@ -97,11 +98,13 @@ void PrintParamDefn( // Now, IOGetParam(). std::cout << "# Get the value of a model pointer parameter of type " << type << "." << std::endl; - std::cout << "function IOGetParam" << type << "(paramName::String)::" - << type << std::endl; - std::cout << " " << type << "(ccall((:IO_GetParam" << type + std::cout << "function IOGetParam" << type << "(paramName::String, " + << "modelPtrs::Set{Ptr{Nothing}})::" << type << std::endl; + std::cout << " ptr = ccall((:IO_GetParam" << type << "Ptr, " << programName << "Library), Ptr{Nothing}, (Cstring,), " - << "paramName))" << std::endl; + << "paramName)" << std::endl; + std::cout << " return " << type << "(ptr; finalize=!(ptr in modelPtrs))" + << std::endl; std::cout << "end" << std::endl; std::cout << std::endl; From 55c5d3f23b59d0cbbf68f6ebd85bcd289b93bd1e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 15 Dec 2020 20:25:56 -0500 Subject: [PATCH 349/550] Fix static code analysis issue. --- src/mlpack/tests/serialization_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/serialization_test.cpp b/src/mlpack/tests/serialization_test.cpp index f0b19d6950..ebbfdc4f76 100644 --- a/src/mlpack/tests/serialization_test.cpp +++ b/src/mlpack/tests/serialization_test.cpp @@ -1644,7 +1644,7 @@ TEST_CASE("CerealEmptyArrayWrapperTest", "[SerializationTest]") jsonT.mem = new int[5]; jsonT.len = 5; - SerializeObjectAll(t, xmlT, binaryT, jsonT); + SerializeObjectAll(t, xmlT, jsonT, binaryT); // Ensure that all the results are correct. REQUIRE(xmlT.mem == (int*) NULL); From 2774b792cbd11e99ab792f910444a79fa6aceae3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 15 Dec 2020 20:26:39 -0500 Subject: [PATCH 350/550] Fix line wrap. --- src/mlpack/methods/adaboost/adaboost.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mlpack/methods/adaboost/adaboost.hpp b/src/mlpack/methods/adaboost/adaboost.hpp index 8ff6cf6c2b..493f3f8d4e 100644 --- a/src/mlpack/methods/adaboost/adaboost.hpp +++ b/src/mlpack/methods/adaboost/adaboost.hpp @@ -71,8 +71,7 @@ namespace adaboost { * @endcode * * For more information on and examples of weak learners, see - * perceptron::Perceptron<> and - tree::ID3DecisionStump. + * perceptron::Perceptron<> and tree::ID3DecisionStump. * * @tparam MatType Data matrix type (i.e. arma::mat or arma::sp_mat). * @tparam WeakLearnerType Type of weak learner to use. From fa1b299afc1dc74e7c1c47b572b5658ec0449b02 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 15 Dec 2020 22:23:15 -0500 Subject: [PATCH 351/550] Fix incorrect merge. --- .../ann/loss_functions/negative_log_likelihood_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp index f4e85dcd2b..1eace1d772 100644 --- a/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/negative_log_likelihood_impl.hpp @@ -38,7 +38,7 @@ NegativeLogLikelihood::Forward( Log::Assert(target(i) >= 0 && target(i) < prediction.n_rows, "Target class out of range."); - output -= input(target(i), i); + output -= prediction(target(i), i); } return output; @@ -57,7 +57,7 @@ void NegativeLogLikelihood::Backward( Log::Assert(target(i) >= 0 && target(i) < prediction.n_rows, "Target class out of range."); - output(target(i), i) = -1; + loss(target(i), i) = -1; } } From 85c3bbc1dd5482a9e2b6f6434eef02dd465c1eb5 Mon Sep 17 00:00:00 2001 From: Anmol2001 <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 16 Dec 2020 13:37:33 +0530 Subject: [PATCH 352/550] Update pca_impl.hpp --- src/mlpack/methods/pca/pca_impl.hpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/pca/pca_impl.hpp b/src/mlpack/methods/pca/pca_impl.hpp index 360586360a..2373128320 100644 --- a/src/mlpack/methods/pca/pca_impl.hpp +++ b/src/mlpack/methods/pca/pca_impl.hpp @@ -61,7 +61,8 @@ void PCA::Apply(const arma::mat& data, /** * Apply Principal Component Analysis to the provided data set. - * + * It creates matrix to store eigenvectors and + that matrix need not to be passed in paramteres * @param data - Data matrix * @param transformedData - Data with PCA applied * @param eigVal - contains eigen values in a column vector @@ -74,6 +75,20 @@ void PCA::Apply(const arma::mat& data, arma::mat eigvec; Apply(data, transformedData, eigVal, eigvec); } + /*This is another Overload of apply with only 2 parameteres(data & transformed data) + and it will create eigval and eigvec and store the corresponding values in them + as the source of information are first 2 parameters only. + * @param data - Data matrix + * @param transformedData - Data with PCA applied + */ +template +void PCA::Apply(const arma::mat& data, + arma::mat& transformedData) +{ + arma::mat eigvec; + arma::vec eigVal; + Apply(data, transformedData, eigVal, eigvec); +} /** * Use PCA for dimensionality reduction on the given dataset. This will save From de930500247c682dd9a45d8476f8420e09a1b63b Mon Sep 17 00:00:00 2001 From: Anmol2001 <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 16 Dec 2020 13:40:14 +0530 Subject: [PATCH 353/550] Update pca.hpp --- src/mlpack/methods/pca/pca.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mlpack/methods/pca/pca.hpp b/src/mlpack/methods/pca/pca.hpp index 594cb47344..ae973f27cb 100644 --- a/src/mlpack/methods/pca/pca.hpp +++ b/src/mlpack/methods/pca/pca.hpp @@ -68,6 +68,14 @@ class PCA void Apply(const arma::mat& data, arma::mat& transformedData, arma::vec& eigVal); +/** + * Apply Principal Component Analysis to the provided data set. It is safe + * to pass the same matrix reference for both data and transformedData. + * @param data Data matrix. + * @param transformedData Matrix to store results of PCA in. + */ + void Apply(const arma::mat& data, + arma::mat& transformedData); /** * Use PCA for dimensionality reduction on the given dataset. This will save From 3437c01cf2b35a305b50942b91233ca89465b161 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 17 Dec 2020 00:58:23 +0530 Subject: [PATCH 354/550] Update build.hpp I have documented the updates with the test commands and also added a memory warning with the make -j N command. --- doc/guide/build.hpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 20b98e4688..dc9f385c92 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -233,7 +233,8 @@ src/mlpack/CMakeFiles/mlpack.dir/core/optimizers/aug_lagrangian/aug_lagrangian_t @endcode It's often useful to specify \c -jN to the \c make command, which will build on -\c N processor cores. That can accelerate the build significantly. +\c N processor cores. That can accelerate the build significantly. Sometimes +using many cores may exhaust the memory so choose accordingly. You can specify individual components which you want to build, if you do not want to build everything in the library: @@ -249,11 +250,37 @@ suite. You can build this component with $ make mlpack_test @endcode -and then run all of the tests, or an individual test suite: +We use Catch2 to write our tests +To run all tests, you can simply run: @code -$ bin/mlpack_test -$ bin/mlpack_test -t KNNTest +$ ./bin/mlpack_test +@endcode + +To run all tests in a particular file you can run: + +@code +$ ./bin/mlpack_test "[testname]" +@endcode + +where testname is the name of the test suite. +For example to run all collaborative filtering tests implemented in cv_test.cpp you can run: + +@code +./bin/mlpack_test "[CVTest]" +@endcode + +Now similarly you can run all the binding related tests using: + +@code +./bin/mlpack_test "[BindingTests]" +@endcode + +To run a single test, you can explicitly provide the name of the test, for example, +to run BinaryClassificationMetricsTest implemented in cv_test.cpp you can run the following: + +@code +./bin/mlpack_test BinaryClassificationMetricsTest @endcode If the build fails and you cannot figure out why, register an account on Github From eb8fe0a83e94bd78202e03e0cac8491cca39579b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 16 Dec 2020 16:39:31 -0500 Subject: [PATCH 355/550] Remove no-longer-needed files. --- .../methods/decision_stump/CMakeLists.txt | 21 - .../methods/decision_stump/decision_stump.hpp | 239 -------- .../decision_stump/decision_stump_impl.hpp | 518 ------------------ .../decision_stump/decision_stump_main.cpp | 209 ------- src/mlpack/tests/decision_stump_test.cpp | 412 -------------- 5 files changed, 1399 deletions(-) delete mode 100644 src/mlpack/methods/decision_stump/CMakeLists.txt delete mode 100644 src/mlpack/methods/decision_stump/decision_stump.hpp delete mode 100644 src/mlpack/methods/decision_stump/decision_stump_impl.hpp delete mode 100644 src/mlpack/methods/decision_stump/decision_stump_main.cpp delete mode 100644 src/mlpack/tests/decision_stump_test.cpp diff --git a/src/mlpack/methods/decision_stump/CMakeLists.txt b/src/mlpack/methods/decision_stump/CMakeLists.txt deleted file mode 100644 index 5a0405b675..0000000000 --- a/src/mlpack/methods/decision_stump/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Define the files we need to compile. -# Anything not in this list will not be compiled into mlpack. -set(SOURCES - decision_stump.hpp - decision_stump_impl.hpp -) - -# Add directory name to sources. -set(DIR_SRCS) -foreach(file ${SOURCES}) - set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}) -endforeach() -# Append sources (with directory name) to list of all mlpack sources (used at -# the parent scope). -set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE) - -add_cli_executable(decision_stump) -add_python_binding(decision_stump) -add_julia_binding(decision_stump) -add_go_binding(decision_stump) -add_markdown_docs(decision_stump "cli;python;julia;go" "classification") diff --git a/src/mlpack/methods/decision_stump/decision_stump.hpp b/src/mlpack/methods/decision_stump/decision_stump.hpp deleted file mode 100644 index 649fb79b40..0000000000 --- a/src/mlpack/methods/decision_stump/decision_stump.hpp +++ /dev/null @@ -1,239 +0,0 @@ -/** - * @file methods/decision_stump/decision_stump.hpp - * @author Udit Saxena - * - * Definition of decision stumps. - * - * 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_DECISION_STUMP_DECISION_STUMP_HPP -#define MLPACK_METHODS_DECISION_STUMP_DECISION_STUMP_HPP - -#include - -namespace mlpack { -namespace decision_stump { - -/** - * This class implements a decision stump. It constructs a single level - * decision tree, i.e., a decision stump. It uses entropy to decide splitting - * ranges. - * - * The stump is parameterized by a splitting dimension (the dimension on which - * points are split), a vector of bin split values, and a vector of labels for - * each bin. Bin i is specified by the range [split[i], split[i + 1]). The - * last bin has range up to @f$ \infty @f$ (split[i + 1] does not exist in that - * case). - * Points that are below the first bin will take the label of the first bin. - * - * @note - * This class has been deprecated and should be removed in mlpack 4.0.0. Use - * `ID3DecisionStump`, found in src/mlpack/methods/decision_tree/, instead. - * - * @tparam MatType Type of matrix that is being used (sparse or dense). - */ -template -class DecisionStump -{ - public: - /** - * Constructor. Train on the provided data. Generate a decision stump from - * data. - * - * @param data Input, training data. - * @param labels Labels of training data. - * @param numClasses Number of distinct classes in labels. - * @param bucketSize Minimum size of bucket when splitting. - */ - mlpack_deprecated DecisionStump(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize = 10); - - /** - * Alternate constructor which copies the parameters bucketSize and classes - * from an already initiated decision stump, other. It appropriately sets the - * weight vector. - * - * @param other The other initiated Decision Stump object from - * which we copy the values. - * @param data The data on which to train this object on. - * @param labels The labels of data. - * @param numClasses The number of classes. - * @param weights Weight vector to use while training. For boosting purposes. - */ - mlpack_deprecated DecisionStump(const DecisionStump<>& other, - const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const arma::rowvec& weights); - - /** - * Create a decision stump without training. This stump will not be useful - * and will always return a class of 0 for anything that is to be classified, - * so it would be a prudent idea to call Train() after using this constructor. - */ - DecisionStump(); - - /** - * Train the decision stump on the given data. This completely overwrites any - * previous training data, so after training the stump may be completely - * different. - * - * @param data Dataset to train on. - * @param labels Labels for each point in the dataset. - * @param numClasses Number of classes in the dataset. - * @param bucketSize Minimum size of bucket when splitting. - * @return The final entropy after splitting. - */ - mlpack_deprecated double Train(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize); - - /** - * Train the decision stump on the given data, with the given weights. This - * completely overwrites any previous training data, so after training the - * stump may be completely different. - * - * @param data Dataset to train on. - * @param labels Labels for each point in the dataset. - * @param weights Weights for each point in the dataset. - * @param numClasses Number of classes in the dataset. - * @param bucketSize Minimum size of bucket when splitting. - * @return The final entropy after splitting. - */ - mlpack_deprecated double Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights, - const size_t numClasses, - const size_t bucketSize); - - /** - * Classification function. After training, classify test, and put the - * predicted classes in predictedLabels. - * - * @param test Testing data or data to classify. - * @param predictedLabels Vector to store the predicted classes after - * classifying test data. - */ - mlpack_deprecated void Classify(const MatType& test, - arma::Row& predictedLabels); - - //! Access the splitting dimension. - size_t SplitDimension() const { return splitDimension; } - //! Modify the splitting dimension (be careful!). - size_t& SplitDimension() { return splitDimension; } - - //! Access the splitting values. - const arma::vec& Split() const { return split; } - //! Modify the splitting values (be careful!). - arma::vec& Split() { return split; } - - //! Access the labels for each split bin. - const arma::Col BinLabels() const { return binLabels; } - //! Modify the labels for each split bin (be careful!). - arma::Col& BinLabels() { return binLabels; } - - //! Serialize the decision stump. - template - void serialize(Archive& ar, const uint32_t /* version */); - - private: - //! The number of classes (we must store this for boosting). - size_t numClasses; - //! The minimum number of points in a bucket. - size_t bucketSize; - - //! Stores the value of the dimension on which to split. - size_t splitDimension; - //! Stores the splitting values after training. - arma::vec split; - //! Stores the labels for each splitting bin. - arma::Col binLabels; - - /** - * Sets up dimension as if it were splitting on it and finds entropy when - * splitting on dimension. - * - * @param dimension A row from the training data, which might be a - * candidate for the splitting dimension. - * @tparam UseWeights Whether we need to run a weighted Decision Stump. - */ - template - double SetupSplitDimension(const VecType& dimension, - const arma::Row& labels, - const arma::rowvec& weightD); - - /** - * After having decided the dimension on which to split, train on that - * dimension. - * - * @tparam dimension dimension is the dimension decided by the constructor - * on which we now train the decision stump. - */ - template - void TrainOnDim(const VecType& dimension, - const arma::Row& labels); - - /** - * After the "split" matrix has been set up, merge ranges with identical class - * labels. - */ - void MergeRanges(); - - /** - * Count the most frequently occurring element in subCols. - * - * @param subCols The vector in which to find the most frequently occurring - * element. - */ - template - double CountMostFreq(const VecType& subCols); - - /** - * Returns 1 if all the values of featureRow are not same. - * - * @param featureRow The dimension which is checked for identical values. - */ - template - int IsDistinct(const VecType& featureRow); - - /** - * Calculate the entropy of the given dimension. - * - * @param labels Corresponding labels of the dimension. - * @param classes Number of classes. - * @param weights Weights for this set of labels. - * @tparam UseWeights If true, the weights in the weight vector will be used - * (otherwise they are ignored). - */ - template - double CalculateEntropy(const VecType& labels, - const WeightVecType& weights); - - /** - * Train the decision stump on the given data and labels. - * - * @param data Dataset to train on. - * @param labels Labels for dataset. - * @param weights Weights for this set of labels. - * @tparam UseWeights If true, the weights in the weight vector will be used - * (otherwise they are ignored). - * @return The final entropy after splitting. - */ - template - double Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights); -}; - -} // namespace decision_stump -} // namespace mlpack - -#include "decision_stump_impl.hpp" - -#endif diff --git a/src/mlpack/methods/decision_stump/decision_stump_impl.hpp b/src/mlpack/methods/decision_stump/decision_stump_impl.hpp deleted file mode 100644 index 7722eecb38..0000000000 --- a/src/mlpack/methods/decision_stump/decision_stump_impl.hpp +++ /dev/null @@ -1,518 +0,0 @@ -/** - * @file methods/decision_stump/decision_stump_impl.hpp - * @author Udit Saxena - * - * Implementation of DecisionStump 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_DECISION_STUMP_DECISION_STUMP_IMPL_HPP -#define MLPACK_METHODS_DECISION_STUMP_DECISION_STUMP_IMPL_HPP - -// In case it hasn't been included yet. -#include "decision_stump.hpp" - -namespace mlpack { -namespace decision_stump { - -/** - * Constructor. Train on the provided data. Generate a decision stump from data. - * - * @param data Input, training data. - * @param labels Labels of data. - * @param numClasses Number of distinct classes in labels. - * @param bucketSize Minimum size of bucket when splitting. - */ -template -DecisionStump::DecisionStump(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize) : - numClasses(numClasses), - bucketSize(bucketSize) -{ - arma::rowvec weights; - Train(data, labels, weights); -} - -/** - * Empty constructor. - */ -template -DecisionStump::DecisionStump() : - numClasses(1), - bucketSize(0), - splitDimension(0), - split(1), - binLabels(1) -{ - split[0] = DBL_MAX; - binLabels[0] = 0; -} - -/** - * Train on the given data and labels. - */ -template -double DecisionStump::Train(const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const size_t bucketSize) -{ - this->numClasses = numClasses; - this->bucketSize = bucketSize; - - // Pass to unweighted training function. - arma::rowvec weights; - return Train(data, labels, weights); -} - -/** - * Train the decision stump on the given data, with the given weights. This - * completely overwrites any previous training data, so after training the - * stump may be completely different. - */ -template -double DecisionStump::Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights, - const size_t numClasses, - const size_t bucketSize) -{ - this->numClasses = numClasses; - this->bucketSize = bucketSize; - - // Pass to weighted training function. - return Train(data, labels, weights); -} - -/** - * Train the decision stump on the given data and labels. - * - * @param data Dataset to train on. - * @param labels Labels for dataset. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -template -double DecisionStump::Train(const MatType& data, - const arma::Row& labels, - const arma::rowvec& weights) -{ - // If classLabels are not all identical, proceed with training. - size_t bestDim = 0; - double entropy; - const double rootEntropy = CalculateEntropy(labels, weights); - - double gain, bestGain = 0.0; - for (size_t i = 0; i < data.n_rows; ++i) - { - // Go through each dimension of the data. - if (IsDistinct(data.row(i))) - { - // For each dimension with non-identical values, treat it as a potential - // splitting dimension and calculate entropy if split on it. - entropy = SetupSplitDimension(data.row(i), labels, weights); - - gain = rootEntropy - entropy; - // Find the dimension with the best entropy so that the gain is - // maximized. - - // We are maximizing gain, which is what is returned from - // SetupSplitDimension(). - if (gain < bestGain) - { - bestDim = i; - bestGain = gain; - } - } - } - splitDimension = bestDim; - - // Once the splitting column/dimension has been decided, train on it. - TrainOnDim(data.row(splitDimension), labels); - return -bestGain; -} - -/** - * Classification function. After training, classify test, and put the predicted - * classes in predictedLabels. - * - * @param test Testing data or data to classify. - * @param predictedLabels Vector to store the predicted classes after - * classifying test - */ -template -void DecisionStump::Classify(const MatType& test, - arma::Row& predictedLabels) -{ - predictedLabels.set_size(test.n_cols); - for (size_t i = 0; i < test.n_cols; ++i) - { - // Determine which bin the test point falls into. - // Assume first that it falls into the first bin, then proceed through the - // bins until it is known which bin it falls into. - size_t bin = 0; - const double val = test(splitDimension, i); - - while (bin < split.n_elem - 1) - { - if (val < split(bin + 1)) - break; - - ++bin; - } - - predictedLabels(i) = binLabels(bin); - } -} - -/** - * Alternate constructor which copies parameters bucketSize and numClasses - * from an already initiated decision stump, other. It appropriately - * sets the Weight vector. - * - * @param other The other initiated Decision Stump object from - * which we copy the values from. - * @param data The data on which to train this object on. - * @param D Weight vector to use while training. For boosting purposes. - * @param labels The labels of data. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -DecisionStump::DecisionStump(const DecisionStump<>& other, - const MatType& data, - const arma::Row& labels, - const size_t numClasses, - const arma::rowvec& weights) : - numClasses(numClasses), - bucketSize(other.bucketSize) -{ - Train(data, labels, weights); -} - -/** - * Serialize the decision stump. - */ -template -template -void DecisionStump::serialize(Archive& ar, - const uint32_t /* version */) -{ - // This is straightforward; just serialize all of the members of the class. - // None need special handling. - ar(CEREAL_NVP(numClasses)); - ar(CEREAL_NVP(bucketSize)); - ar(CEREAL_NVP(splitDimension)); - ar(CEREAL_NVP(split)); - ar(CEREAL_NVP(binLabels)); -} - -/** - * Sets up dimension as if it were splitting on it and finds entropy when - * splitting on dimension. - * - * @param dimension A row from the training data, which might be a candidate for - * the splitting dimension. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -template -double DecisionStump::SetupSplitDimension( - const VecType& dimension, - const arma::Row& labels, - const arma::rowvec& weights) -{ - size_t i, count, begin, end; - double entropy = 0.0; - - // Store the indices of the sorted dimension to build a vector of sorted - // labels. This sort is stable. - arma::uvec sortedIndexDim = arma::stable_sort_index(dimension.t()); - - arma::Row sortedLabels(dimension.n_elem); - arma::rowvec sortedWeights(dimension.n_elem); - - for (i = 0; i < dimension.n_elem; ++i) - { - sortedLabels(i) = labels(sortedIndexDim(i)); - - // Apply weights if necessary. - if (UseWeights) - sortedWeights(i) = weights(sortedIndexDim(i)); - } - - i = 0; - count = 0; - - // This splits the sorted data into buckets of size greater than or equal to - // bucketSize. - while (i < sortedLabels.n_elem) - { - count++; - if (i == sortedLabels.n_elem - 1) - { - // If we're at the end, then don't worry about the bucket size; just take - // this as the last bin. - begin = i - count + 1; - end = i; - - // Use ratioEl to calculate the ratio of elements in this split. - const double ratioEl = ((double) (end - begin + 1) / sortedLabels.n_elem); - - entropy += ratioEl * CalculateEntropy( - sortedLabels.subvec(begin, end), sortedWeights.subvec(begin, end)); - ++i; - } - else if (sortedLabels(i) != sortedLabels(i + 1)) - { - // If we're not at the last element of sortedLabels, then check whether - // count is less than the current bucket size. - if (count < bucketSize) - { - // If it is, then take the minimum bucket size anyways. - // This is where the inpBucketSize comes into use. - // This makes sure there isn't a bucket for every change in labels. - begin = i - count + 1; - end = begin + bucketSize - 1; - - if (end > sortedLabels.n_elem - 1) - end = sortedLabels.n_elem - 1; - } - else - { - // If it is not, then take the bucket size as the value of count. - begin = i - count + 1; - end = i; - } - const double ratioEl = ((double) (end - begin + 1) / sortedLabels.n_elem); - - entropy += ratioEl * CalculateEntropy( - sortedLabels.subvec(begin, end), sortedWeights.subvec(begin, end)); - - i = end + 1; - count = 0; - } - else - ++i; - } - return entropy; -} - -/** - * After having decided the dimension on which to split, train on that - * dimension. - * - * @param dimension Dimension is the dimension decided by the constructor on - * which we now train the decision stump. - */ -template -template -void DecisionStump::TrainOnDim(const VecType& dimension, - const arma::Row& labels) -{ - size_t i, count, begin, end; - - typename MatType::row_type sortedSplitDim = arma::sort(dimension); - arma::uvec sortedSplitIndexDim = arma::stable_sort_index(dimension.t()); - arma::Row sortedLabels(dimension.n_elem); - sortedLabels.fill(0); - - for (i = 0; i < dimension.n_elem; ++i) - sortedLabels(i) = labels(sortedSplitIndexDim(i)); - - arma::rowvec subCols; - double mostFreq; - i = 0; - count = 0; - while (i < sortedLabels.n_elem) - { - count++; - if (i == sortedLabels.n_elem - 1) - { - begin = i - count + 1; - end = i; - - mostFreq = CountMostFreq(sortedLabels.cols(begin, end)); - - split.resize(split.n_elem + 1); - split(split.n_elem - 1) = sortedSplitDim(begin); - binLabels.resize(binLabels.n_elem + 1); - binLabels(binLabels.n_elem - 1) = mostFreq; - - ++i; - } - else if (sortedLabels(i) != sortedLabels(i + 1)) - { - if (count < bucketSize) - { - // Test for different values of bucketSize, especially extreme cases. - begin = i - count + 1; - end = begin + bucketSize - 1; - - if (end > sortedLabels.n_elem - 1) - end = sortedLabels.n_elem - 1; - } - else - { - begin = i - count + 1; - end = i; - } - - // Find the most frequent element in subCols so as to assign a label to - // the bucket of subCols. - mostFreq = CountMostFreq(sortedLabels.cols(begin, end)); - - split.resize(split.n_elem + 1); - split(split.n_elem - 1) = sortedSplitDim(begin); - binLabels.resize(binLabels.n_elem + 1); - binLabels(binLabels.n_elem - 1) = mostFreq; - - i = end + 1; - count = 0; - } - else - ++i; - } - - // Now trim the split matrix so that buckets one after the after which point - // to the same classLabel are merged as one big bucket. - MergeRanges(); -} - -/** - * After the "split" matrix has been set up, merge ranges with identical class - * labels. - */ -template -void DecisionStump::MergeRanges() -{ - for (size_t i = 1; i < split.n_rows; ++i) - { - if (binLabels(i) == binLabels(i - 1)) - { - // Remove this row, as it has the same label as the previous bucket. - binLabels.shed_row(i); - split.shed_row(i); - // Go back to previous row. - i--; - } - } -} - -template -template -double DecisionStump::CountMostFreq(const VecType& subCols) -{ - // We'll create a map of elements and the number of times that each element is - // seen. - std::map countMap; - - for (size_t i = 0; i < subCols.n_elem; ++i) - { - if (countMap.count(subCols[i]) == 0) - countMap[subCols[i]] = 1; - else - ++countMap[subCols[i]]; - } - - // Now find the maximum value. - typename std::map::iterator it = countMap.begin(); - double mostFreq = it->first; - size_t mostFreqCount = it->second; - while (it != countMap.end()) - { - if (it->second >= mostFreqCount) - { - mostFreq = it->first; - mostFreqCount = it->second; - } - - ++it; - } - - return mostFreq; -} - -/** - * Returns 1 if all the values of featureRow are not the same. - * - * @param featureRow The dimension which is checked for identical values. - */ -template -template -int DecisionStump::IsDistinct(const VecType& featureRow) -{ - typename VecType::elem_type val = featureRow(0); - for (size_t i = 1; i < featureRow.n_elem; ++i) - if (val != featureRow(i)) - return 1; - return 0; -} - -/** - * Calculate entropy of dimension. - * - * @param labels Corresponding labels of the dimension. - * @param UseWeights Whether we need to run a weighted Decision Stump. - */ -template -template -double DecisionStump::CalculateEntropy( - const VecType& labels, - const WeightVecType& weights) -{ - double entropy = 0.0; - size_t j; - - arma::rowvec numElem(numClasses); - numElem.fill(0); - - // Variable to accumulate the weight in this subview_row. - double accWeight = 0.0; - // Populate numElem; they are used as helpers to calculate entropy. - - if (UseWeights) - { - for (j = 0; j < labels.n_elem; ++j) - { - numElem(labels(j)) += weights(j); - accWeight += weights(j); - } - - for (j = 0; j < numClasses; ++j) - { - const double p1 = ((double) numElem(j) / accWeight); - - // Instead of using log2(), which is C99 and may not exist on some - // compilers, use std::log(), then use the change-of-base formula to make - // the result correct. - entropy += (p1 == 0) ? 0 : p1 * std::log(p1); - } - } - else - { - for (j = 0; j < labels.n_elem; ++j) - numElem(labels(j))++; - - for (j = 0; j < numClasses; ++j) - { - const double p1 = ((double) numElem(j) / labels.n_elem); - - // Instead of using log2(), which is C99 and may not exist on some - // compilers, use std::log(), then use the change-of-base formula to make - // the result correct. - entropy += (p1 == 0) ? 0 : p1 * std::log(p1); - } - } - - return entropy / std::log(2.0); -} - -} // namespace decision_stump -} // namespace mlpack - -#endif diff --git a/src/mlpack/methods/decision_stump/decision_stump_main.cpp b/src/mlpack/methods/decision_stump/decision_stump_main.cpp deleted file mode 100644 index 463c680dfd..0000000000 --- a/src/mlpack/methods/decision_stump/decision_stump_main.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file methods/decision_stump/decision_stump_main.cpp - * @author Udit Saxena - * - * Main executable for the decision stump. - * - * 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. - */ -#include -#include -#include -#include -#include "decision_stump.hpp" - -using namespace mlpack; -using namespace mlpack::decision_stump; -using namespace mlpack::util; -using namespace std; -using namespace arma; - -// Program Name. -BINDING_NAME("Decision Stump"); - -// Short description. -BINDING_SHORT_DESC( - "An implementation of a decision stump, which is a single-level decision " - "tree. Given labeled data, a new decision stump can be trained; or, an " - "existing decision stump can be used to classify points."); - -// Long description. -BINDING_LONG_DESC( - "This program implements a decision stump, which is a single-level decision" - " tree. The decision stump will split on one dimension of the input data, " - "and will split into multiple buckets. The dimension and bins are selected" - " by maximizing the information gain of the split. Optionally, the minimum" - " number of training points in each bin can be specified with the " + - PRINT_PARAM_STRING("bucket_size") + " parameter." - "\n\n" - "The decision stump is parameterized by a splitting dimension and a vector " - "of values that denote the splitting values of each bin." - "\n\n" - "This program enables several applications: a decision tree may be trained " - "or loaded, and then that decision tree may be used to classify a given set" - " of test points. The decision tree may also be saved to a file for later " - "usage." - "\n\n" - "To train a decision stump, training data should be passed with the " + - PRINT_PARAM_STRING("training") + " parameter, and their corresponding " - "labels should be passed with the " + PRINT_PARAM_STRING("labels") + " " - "option. Optionally, if " + PRINT_PARAM_STRING("labels") + " is not " - "specified, the labels are assumed to be the last dimension of the " - "training dataset. The " + PRINT_PARAM_STRING("bucket_size") + " " - "parameter controls the minimum number of training points in each decision " - "stump bucket." - "\n\n" - "For classifying a test set, a decision stump may be loaded with the " + - PRINT_PARAM_STRING("input_model") + " parameter (useful for the situation " - "where a stump has already been trained), and a test set may be specified " - "with the " + PRINT_PARAM_STRING("test") + " parameter. The predicted " - "labels can be saved with the " + PRINT_PARAM_STRING("predictions") + " " - "output parameter." - "\n\n" - "Because decision stumps are trained in batch, retraining does not make " - "sense and thus it is not possible to pass both " + - PRINT_PARAM_STRING("training") + " and " + - PRINT_PARAM_STRING("input_model") + "; instead, simply build a new " - "decision stump with the training data." - "\n\n" - "After training, a decision stump can be saved with the " + - PRINT_PARAM_STRING("output_model") + " output parameter. That stump may " - "later be re-used in subsequent calls to this program (or others)."); - -// See also... -BINDING_SEE_ALSO("Decision tree", "#decision_tree"); -BINDING_SEE_ALSO("Decision stumps on Wikipedia", - "https://en.wikipedia.org/wiki/Decision_stump"); -BINDING_SEE_ALSO("mlpack::decision_stump::DecisionStump class documentation", - "@doxygen/classmlpack_1_1decision__stump_1_1DecisionStump.html"); - -// Datasets we might load. -PARAM_MATRIX_IN("training", "The dataset to train on.", "t"); -PARAM_UROW_IN("labels", "Labels for the training set. If not specified, the " - "labels are assumed to be the last row of the training data.", "l"); -PARAM_MATRIX_IN("test", "A dataset to calculate predictions for.", "T"); - -// Output. -PARAM_UROW_OUT("predictions", "The output matrix that will hold the " - "predicted labels for the test set.", "p"); - -/** - * This is the structure that actually saves to disk. We have to save the - * label mappings, too, otherwise everything we load at test time in a future - * run will end up being borked. - */ -struct DSModel -{ - //! The mappings. - arma::Col mappings; - //! The stump. - DecisionStump<> stump; - - //! Serialize the model. - template - void serialize(Archive& ar, const uint32_t /* version */) - { - ar(CEREAL_NVP(mappings)); - ar(CEREAL_NVP(stump)); - } -}; - -// We may load or save a model. -PARAM_MODEL_IN(DSModel, "input_model", "Decision stump model to " - "load.", "m"); -PARAM_MODEL_OUT(DSModel, "output_model", "Output decision stump model to save.", - "M"); - -PARAM_INT_IN("bucket_size", "The minimum number of training points in each " - "decision stump bucket.", "b", 6); - -static void mlpackMain() -{ - // Check that the parameters are reasonable. - RequireOnlyOnePassed({ "training", "input_model" }, true); - RequireAtLeastOnePassed({ "output_model", "predictions" }, false, "no results" - " will be saved"); - - RequireParamValue("bucket_size", [](int x) { return x > 0; }, true, - "bucket size must be positive"); - - ReportIgnoredParam({{ "test", false }}, "predictions"); - - Log::Warn << "DecisionStump is deprecated and will be removed in mlpack " - << "4.0.0. Please use DecisionTree instead with the maximum tree " - << "depth option set to 1 (that will produce a stump)." - << std::endl; - - // We must either load a model, or train a new stump. - DSModel* model; - if (IO::HasParam("training")) - { - model = new DSModel(); - mat trainingData = std::move(IO::GetParam("training")); - - // Load labels, if necessary. - Row labelsIn; - if (IO::HasParam("labels")) - { - labelsIn = std::move(IO::GetParam>("labels")); - } - else - { - // Extract the labels as the last - Log::Info << "Using the last dimension of training set as labels." - << endl; - - labelsIn = arma::conv_to>::from( - trainingData.row(trainingData.n_rows - 1)); - trainingData.shed_row(trainingData.n_rows - 1); - } - - // Normalize the labels. - Row labels; - data::NormalizeLabels(labelsIn, labels, model->mappings); - - const size_t bucketSize = IO::GetParam("bucket_size"); - const size_t classes = labels.max() + 1; - - Timer::Start("training"); - model->stump.Train(trainingData, labels, classes, bucketSize); - Timer::Stop("training"); - } - else - { - model = IO::GetParam("input_model"); - } - - // Now, do we need to do any testing? - if (IO::HasParam("test")) - { - // Load the test file. - mat testingData = std::move(IO::GetParam("test")); - - if (testingData.n_rows <= model->stump.SplitDimension()) - Log::Fatal << "Test data dimensionality (" << testingData.n_rows << ") " - << "is too low; the trained stump requires at least " - << model->stump.SplitDimension() << " dimensions!" << endl; - - Row predictedLabels(testingData.n_cols); - Timer::Start("testing"); - model->stump.Classify(testingData, predictedLabels); - Timer::Stop("testing"); - - // Denormalize predicted labels, if we want to save them. - if (IO::HasParam("predictions")) - { - Row actualLabels; - data::RevertLabels(predictedLabels, model->mappings, actualLabels); - - // Save the predicted labels as output. - IO::GetParam>("predictions") = std::move(actualLabels); - } - } - - // Save the model, if desired. - IO::GetParam("output_model") = model; -} diff --git a/src/mlpack/tests/decision_stump_test.cpp b/src/mlpack/tests/decision_stump_test.cpp deleted file mode 100644 index d9d633fe3e..0000000000 --- a/src/mlpack/tests/decision_stump_test.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/** - * @file tests/decision_stump_test.cpp - * @author Udit Saxena - * - * Tests for DecisionStump 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. - */ -#include -#include - -#include "catch.hpp" - -using namespace mlpack; -using namespace mlpack::decision_stump; -using namespace arma; -using namespace mlpack::distribution; - -/** - * This tests handles the case wherein only one class exists in the input - * labels. It checks whether the only class supplied was the only class - * predicted. - */ -TEST_CASE("OneClass", "[DecisionStumpTest]") -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 6; - - mat trainingData; - trainingData = { { 2.4, 3.8, 3.8 }, - { 1, 1, 2 }, - { 1.3, 1.9, 1.3 } }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 1, 1, 1 }; - - mat testingData; - testingData = { 2.4, 2.5, 2.6 }; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - for (size_t i = 0; i < predictedLabels.size(); ++i) - REQUIRE(predictedLabels(i) == 1); -} - -/** - * This tests whether the entropy is being correctly calculated by checking the - * correct value of the splitting column value. This test is for an - * inpBucketSize of 4 and the correct value of the splitting dimension is 0. - */ -TEST_CASE("CorrectDimensionChosen", "[DecisionStumpTest]") -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 4; - - // This dataset comes from Chapter 6 of the book "Data Mining: Concepts, - // Models, Methods, and Algorithms" (2nd Edition) by Mehmed Kantardzic. It is - // found on page 176 (and a description of the correct splitting dimension is - // given below that). - mat trainingData; - trainingData = { { 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2 }, - { 70, 90, 85, 95, 70, 90, 78, 65, 75, 80, 70, 80, 80, 96 }, - { 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0 } }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - // Only need to check the value of the splitting column, no need of - // classification. - REQUIRE(ds.SplitDimension() == 0); -} - -/** - * This tests for the classification: - * if testinput < 0 - class 0 - * if testinput > 0 - class 1 - * An almost perfect split on zero. - */ -TEST_CASE("PerfectSplitOnZero", "[DecisionStumpTest]") -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 2; - - mat trainingData; - trainingData = { -1, 1, -2, 2, -3, 3 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 1, 0, 1, 0, 1 }; - - mat testingData; - testingData = { -4, 7, -7, -5, 6 }; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - REQUIRE(predictedLabels(0, 0) == 0); - REQUIRE(predictedLabels(0, 1) == 1); - REQUIRE(predictedLabels(0, 2) == 0); - REQUIRE(predictedLabels(0, 3) == 0); - REQUIRE(predictedLabels(0, 4) == 1); -} - -/** - * This tests the binning function for the case when a dataset with cardinality - * of input < inpBucketSize is provided. - */ -TEST_CASE("BinningTesting", "[DecisionStumpTest]") -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 10; - - mat trainingData; - trainingData = { -1, 1, -2, 2, -3, 3, -4 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 1, 0, 1, 0, 1, 0 }; - - mat testingData; - testingData = {5}; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - REQUIRE(predictedLabels(0, 0) == 0); -} - -/** - * This is a test for the case when non-overlapping, multiple classes are - * provided. It tests for a perfect split due to the non-overlapping nature of - * the input classes. - */ -TEST_CASE("PerfectMultiClassSplit", "[DecisionStumpTest]") -{ - const size_t numClasses = 4; - const size_t inpBucketSize = 3; - - mat trainingData; - trainingData = { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 }; - - mat testingData; - testingData = { -6.1, -2.1, 1.1, 5.1 }; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - REQUIRE(predictedLabels(0, 0) == 0); - REQUIRE(predictedLabels(0, 1) == 1); - REQUIRE(predictedLabels(0, 2) == 2); - REQUIRE(predictedLabels(0, 3) == 3); -} - -/** - * This test is for the case when reasonably overlapping, multiple classes are - * provided in the input label set. It tests whether classification takes place - * with a reasonable amount of error due to the overlapping nature of input - * classes. - */ -TEST_CASE("MultiClassSplit", "[DecisionStumpTest]") -{ - const size_t numClasses = 3; - const size_t inpBucketSize = 3; - - mat trainingData; - trainingData = { -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2 }; - - - mat testingData; - testingData = { -6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1 }; - - DecisionStump<> ds(trainingData, labelsIn.row(0), numClasses, inpBucketSize); - - Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - REQUIRE(predictedLabels(0, 0) == 0); - REQUIRE(predictedLabels(0, 1) == 0); - REQUIRE(predictedLabels(0, 2) == 1); - REQUIRE(predictedLabels(0, 3) == 1); - REQUIRE(predictedLabels(0, 4) == 1); - REQUIRE(predictedLabels(0, 5) == 1); - REQUIRE(predictedLabels(0, 6) == 2); - REQUIRE(predictedLabels(0, 7) == 2); -} - -/** - * This tests that the decision stump can learn a good split on a dataset with - * four dimensions that have progressing levels of separation. - */ -TEST_CASE("DimensionSelectionTest", "[DecisionStumpTest]") -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 2500; - - arma::mat dataset(4, 5000); - - // The most separable dimension. - GaussianDistribution g1("-5", "1"); - GaussianDistribution g2("5", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(1, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(1, i) = tmp[0]; - } - - g1 = GaussianDistribution("-3", "1"); - g2 = GaussianDistribution("3", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(3, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(3, i) = tmp[0]; - } - - g1 = GaussianDistribution("-1", "1"); - g2 = GaussianDistribution("1", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(0, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(0, i) = tmp[0]; - } - - // Not separable at all. - g1 = GaussianDistribution("0", "1"); - g2 = GaussianDistribution("0", "1"); - - for (size_t i = 0; i < 2500; ++i) - { - arma::vec tmp = g1.Random(); - dataset(2, i) = tmp[0]; - } - for (size_t i = 2500; i < 5000; ++i) - { - arma::vec tmp = g2.Random(); - dataset(2, i) = tmp[0]; - } - - // Generate the labels. - arma::Row labels(5000); - for (size_t i = 0; i < 2500; ++i) - labels[i] = 0; - for (size_t i = 2500; i < 5000; ++i) - labels[i] = 1; - - // Now create a decision stump. - DecisionStump<> ds(dataset, labels, numClasses, inpBucketSize); - - // Make sure it split on the dimension that is most separable. - REQUIRE(ds.SplitDimension() == 1); - - // Make sure every bin below -1 classifies as label 0, and every bin above 1 - // classifies as label 1 (What happens in [-1, 1] isn't that big a deal.). - for (size_t i = 0; i < ds.Split().n_elem; ++i) - { - if (ds.Split()[i] <= -3.0) - REQUIRE(ds.BinLabels()[i] == 0); - else if (ds.Split()[i] >= 3.0) - REQUIRE(ds.BinLabels()[i] == 1); - } -} - -/** - * Ensure that the default constructor works and that it classifies things as 0 - * always. - */ -TEST_CASE("EmptyConstructorTest", "[DecisionStumpTest]") -{ - DecisionStump<> d; - - arma::mat data = arma::randu(3, 10); - arma::Row labels; - - d.Classify(data, labels); - - for (size_t i = 0; i < 10; ++i) - REQUIRE(labels[i] == 0); - - // Now train on another dataset and make sure something kind of makes sense. - mat trainingData; - trainingData = { -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2 }; - - - mat testingData; - testingData = { -6.1, -5.9, -2.1, -0.7, 2.5, 4.7, 7.2, 9.1 }; - - DecisionStump<> ds(trainingData, labelsIn.row(0), 4, 3); - - Row predictedLabels(testingData.n_cols); - ds.Classify(testingData, predictedLabels); - - REQUIRE(predictedLabels(0, 0) == 0); - REQUIRE(predictedLabels(0, 1) == 0); - REQUIRE(predictedLabels(0, 2) == 1); - REQUIRE(predictedLabels(0, 3) == 1); - REQUIRE(predictedLabels(0, 4) == 1); - REQUIRE(predictedLabels(0, 5) == 1); - REQUIRE(predictedLabels(0, 6) == 2); - REQUIRE(predictedLabels(0, 7) == 2); -} - -/** - * Ensure that a matrix holding ints can be trained. The bigger issue here is - * just compilation. - */ -TEST_CASE("IntTest", "[DecisionStumpTest]") -{ - // Train on a dataset and make sure something kind of makes sense. - imat trainingData; - trainingData = { -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2 }; - - DecisionStump ds(trainingData, labelsIn.row(0), 4, 3); - - imat testingData; - testingData = { -6, -6, -2, -1, 3, 5, 7, 9 }; - - arma::Row predictedLabels; - ds.Classify(testingData, predictedLabels); - - REQUIRE(predictedLabels(0, 0) == 0); - REQUIRE(predictedLabels(0, 1) == 0); - REQUIRE(predictedLabels(0, 2) == 1); - REQUIRE(predictedLabels(0, 3) == 1); - REQUIRE(predictedLabels(0, 4) == 1); - REQUIRE(predictedLabels(0, 5) == 1); - REQUIRE(predictedLabels(0, 6) == 2); - REQUIRE(predictedLabels(0, 7) == 2); -} - -/** - * Test that DecisionStump::Train() returns finite gain. - */ -TEST_CASE("DecisionStumpTrainReturnEntropy", "[DecisionStumpTest]") -{ - const size_t numClasses = 2; - const size_t inpBucketSize = 2; - - mat trainingData; - trainingData = { -1, 1, -2, 2, -3, 3 }; - - // No need to normalize labels here. - Mat labelsIn; - labelsIn = { 0, 1, 0, 1, 0, 1 }; - - arma::Row weights = arma::ones>(labelsIn.n_elem); - - // Train a simple decision stump without weights. - DecisionStump<> ds; - double gain = ds.Train(trainingData, labelsIn.row(0), numClasses, - inpBucketSize); - - REQUIRE(std::isfinite(gain) == true); - - // Train decision stump with weights. - DecisionStump<> wds; - gain = wds.Train(trainingData, labelsIn.row(0), weights, numClasses, - inpBucketSize); - - REQUIRE(std::isfinite(gain) == true); -} From 42ab241eb9beca2051128e58481b5dbc9291fb94 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 16 Dec 2020 19:13:20 -0500 Subject: [PATCH 356/550] Make sure all state values are set to zero on reset. This will avoid unnecessary reallocations with Armadillo 10. --- .../methods/ann/layer/fast_lstm_impl.hpp | 39 ++++++----------- src/mlpack/methods/ann/layer/lstm_impl.hpp | 43 +++++++------------ 2 files changed, 29 insertions(+), 53 deletions(-) diff --git a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp index 752b132ae4..c72416bdeb 100644 --- a/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/fast_lstm_impl.hpp @@ -163,33 +163,20 @@ void FastLSTM::ResetCell(const size_t size) gradientStep = batchSize * size - 1; const size_t rhoBatchSize = size * batchSize; - if (gate.is_empty() || gate.n_cols != rhoBatchSize) - { - gate.set_size(4 * outSize, rhoBatchSize); - gateActivation.set_size(outSize * 3, rhoBatchSize); - stateActivation.set_size(outSize, rhoBatchSize); - cellActivation.set_size(outSize, rhoBatchSize); - prevError.set_size(4 * outSize, batchSize); - if (prevOutput.is_empty()) - { - prevOutput = arma::zeros(outSize, batchSize); - cell = arma::zeros(outSize, size * batchSize); - cellActivationError = arma::zeros(outSize, batchSize); - outParameter = arma::zeros( - outSize, (size + 1) * batchSize); - } - else - { - // To preserve the leading zeros, recreate the object according to given - // size specifications, while preserving the elements as well as the - // layout of the elements. - prevOutput.resize(outSize, batchSize); - cell.resize(outSize, size * batchSize); - cellActivationError.resize(outSize, batchSize); - outParameter.resize(outSize, (size + 1) * batchSize); - } - } + // Make sure all of the matrices we use to store state are at least as large + // as we need. + gate.set_size(4 * outSize, rhoBatchSize); + gateActivation.set_size(outSize * 3, rhoBatchSize); + stateActivation.set_size(outSize, rhoBatchSize); + cellActivation.set_size(outSize, rhoBatchSize); + prevError.set_size(4 * outSize, batchSize); + + // Reset stored state to zeros. + prevOutput.zeros(outSize, batchSize); + cell.zeros(outSize, size * batchSize); + cellActivationError.zeros(outSize, batchSize); + outParameter.zeros(outSize, (size + 1) * batchSize); } template diff --git a/src/mlpack/methods/ann/layer/lstm_impl.hpp b/src/mlpack/methods/ann/layer/lstm_impl.hpp index b1bd784194..c0aa5797be 100644 --- a/src/mlpack/methods/ann/layer/lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/lstm_impl.hpp @@ -145,36 +145,25 @@ void LSTM::ResetCell(const size_t size) gradientStep = batchSize * size - 1; const size_t rhoBatchSize = size * batchSize; - if (inputGate.is_empty() || inputGate.n_cols < rhoBatchSize) - { - inputGate.set_size(outSize, rhoBatchSize); - forgetGate.set_size(outSize, rhoBatchSize); - hiddenLayer.set_size(outSize, rhoBatchSize); - outputGate.set_size(outSize, rhoBatchSize); - inputGateActivation.set_size(outSize, rhoBatchSize); - forgetGateActivation.set_size(outSize, rhoBatchSize); - outputGateActivation.set_size(outSize, rhoBatchSize); - hiddenLayerActivation.set_size(outSize, rhoBatchSize); + // Make sure all of the different matrices we will use to hold parameters are + // at least as large as we need. + inputGate.set_size(outSize, rhoBatchSize); + forgetGate.set_size(outSize, rhoBatchSize); + hiddenLayer.set_size(outSize, rhoBatchSize); + outputGate.set_size(outSize, rhoBatchSize); - cellActivation.set_size(outSize, rhoBatchSize); - prevError.set_size(4 * outSize, batchSize); + inputGateActivation.set_size(outSize, rhoBatchSize); + forgetGateActivation.set_size(outSize, rhoBatchSize); + outputGateActivation.set_size(outSize, rhoBatchSize); + hiddenLayerActivation.set_size(outSize, rhoBatchSize); - if (cell.is_empty()) - { - cell = arma::zeros(outSize, size * batchSize); - outParameter = arma::zeros( - outSize, (size + 1) * batchSize); - } - else - { - // To preserve the leading zeros, recreate the object according to given - // size specifications, while preserving the elements as well as the - // layout of the elements. - cell.resize(outSize, size * batchSize); - outParameter.resize(outSize, (size + 1) * batchSize); - } - } + cellActivation.set_size(outSize, rhoBatchSize); + prevError.set_size(4 * outSize, batchSize); + + // Now reset recurrent values to 0. + cell.zeros(outSize, size * batchSize); + outParameter.zeros(outSize, (size + 1) * batchSize); } template From 6a0bf85cbadd15ecf348cbdfecc851b055539462 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Thu, 17 Dec 2020 10:50:04 +0530 Subject: [PATCH 357/550] Update src/mlpack/methods/ann/util/check_input_shape.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/util/check_input_shape.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp index 44c6d39b11..653c21276a 100644 --- a/src/mlpack/methods/ann/util/check_input_shape.hpp +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -25,7 +25,7 @@ template void CheckInputShape(const T& network, const size_t inputShape, const std::string& functionName) { - for (size_t l=0; l Date: Thu, 17 Dec 2020 10:51:05 +0530 Subject: [PATCH 358/550] Update src/mlpack/methods/ann/util/check_input_shape.hpp Co-authored-by: Ryan Curtin --- src/mlpack/methods/ann/util/check_input_shape.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/ann/util/check_input_shape.hpp b/src/mlpack/methods/ann/util/check_input_shape.hpp index 653c21276a..566c363e3f 100644 --- a/src/mlpack/methods/ann/util/check_input_shape.hpp +++ b/src/mlpack/methods/ann/util/check_input_shape.hpp @@ -38,10 +38,9 @@ void CheckInputShape(const T& network, const size_t inputShape, } else { - std::string estr = functionName + ": "; - estr += "the first layer of the network expects "; - estr += std::to_string(layerInShape) + " elements, "; - estr += "but the input has " + std::to_string(inputShape) + " dimensions! "; + std::string estr = functionName + ": the first layer of the network " + + "expects " + std::to_string(layerInShape) + " elements, but the " + + "input has " + std::to_string(inputShape) + " dimensions!"; throw std::logic_error(estr); } } From f61da066ed769ed3f218236f9cf7feee1603df2c Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 17 Dec 2020 11:00:56 +0530 Subject: [PATCH 359/550] reverting back to REQUIRE_THROWS_AS --- src/mlpack/tests/feedforward_network_test.cpp | 3 +-- src/mlpack/tests/recurrent_network_test.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 45530ea466..8216f2e623 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -942,6 +942,5 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") ens::DE opt(200, 1000, 0.6, 0.8, 1e-5); - REQUIRE_THROWS_MATCHES(model.Train(trainData, trainLabels, opt), - std::logic_error, Catch::Matchers::Message(expectedMsg)); + REQUIRE_THROWS_AS(model.Train(trainData, trainLabels, opt), std::logic_error); } diff --git a/src/mlpack/tests/recurrent_network_test.cpp b/src/mlpack/tests/recurrent_network_test.cpp index d0912802d0..c9159daeff 100644 --- a/src/mlpack/tests/recurrent_network_test.cpp +++ b/src/mlpack/tests/recurrent_network_test.cpp @@ -929,6 +929,5 @@ TEST_CASE("RNNCheckInputShapeTest", "[RecurrentNetworkTest]") StandardSGD opt(0.1, 1, input.n_cols /* 1 epoch */, -100); - REQUIRE_THROWS_MATCHES(model.Train(input, labels, opt), - std::logic_error, Catch::Matchers::Message(expectedMsg)); + REQUIRE_THROWS_AS(model.Train(input, labels, opt), std::logic_error); } From ceb6f7ebed602e14e93851dd54dad41c626aa494 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 17 Dec 2020 11:03:33 +0530 Subject: [PATCH 360/550] fixing bilinear_interpolation.hpp --- src/mlpack/methods/ann/layer/bilinear_interpolation.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp b/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp index 2d611feb19..8595bc4d57 100644 --- a/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp +++ b/src/mlpack/methods/ann/layer/bilinear_interpolation.hpp @@ -119,9 +119,9 @@ class BilinearInterpolation size_t& InDepth() { return depth; } //! Get the shape of the input. - size_t WeightSize() const + size_t InputShape() const { - return InRowSize; + return inRowSize; } /** From 01db8c739b48baf0ed360f663392c8c4fa65c538 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 17 Dec 2020 13:28:48 +0530 Subject: [PATCH 361/550] added InputShape() to multihead_attention, positional_encoding, reparametrization, sequential --- .../methods/ann/layer/multihead_attention.hpp | 5 +++++ .../methods/ann/layer/positional_encoding.hpp | 5 +++++ .../methods/ann/layer/reparametrization.hpp | 5 +++++ src/mlpack/methods/ann/layer/sequential.hpp | 3 +++ .../methods/ann/layer/sequential_impl.hpp | 20 +++++++++++++++++++ 5 files changed, 38 insertions(+) diff --git a/src/mlpack/methods/ann/layer/multihead_attention.hpp b/src/mlpack/methods/ann/layer/multihead_attention.hpp index 3421fa4183..ec079d197d 100644 --- a/src/mlpack/methods/ann/layer/multihead_attention.hpp +++ b/src/mlpack/methods/ann/layer/multihead_attention.hpp @@ -176,6 +176,11 @@ class MultiheadAttention //! Modify the parameters. OutputDataType& Parameters() { return weights; } + size_t InputShape() const + { + return embedDim * (tgtSeqLen + 2 * srcSeqLen); + } + private: //! Element Type of the input. typedef typename OutputDataType::elem_type ElemType; diff --git a/src/mlpack/methods/ann/layer/positional_encoding.hpp b/src/mlpack/methods/ann/layer/positional_encoding.hpp index 1e6cb445a0..8678426414 100644 --- a/src/mlpack/methods/ann/layer/positional_encoding.hpp +++ b/src/mlpack/methods/ann/layer/positional_encoding.hpp @@ -93,6 +93,11 @@ class PositionalEncoding //! Get the positional encoding vector. InputDataType const& Encoding() const { return positionalEncoding; } + size_t InputShape() const + { + return embedDim * maxSequenceLength; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/reparametrization.hpp b/src/mlpack/methods/ann/layer/reparametrization.hpp index f6e6fe3b7f..65aa96da53 100644 --- a/src/mlpack/methods/ann/layer/reparametrization.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization.hpp @@ -130,6 +130,11 @@ class Reparametrization //! Get the value of the beta hyperparameter. double Beta() const { return beta; } + size_t InputShape() const + { + return 2 * latentSize; + } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/sequential.hpp b/src/mlpack/methods/ann/layer/sequential.hpp index f4466161a0..ebf3c6fd6a 100644 --- a/src/mlpack/methods/ann/layer/sequential.hpp +++ b/src/mlpack/methods/ann/layer/sequential.hpp @@ -23,6 +23,7 @@ #include "../visitor/output_height_visitor.hpp" #include "../visitor/output_parameter_visitor.hpp" #include "../visitor/output_width_visitor.hpp" +#include "../visitor/input_shape_visitor.hpp" #include "layer_types.hpp" #include "add_merge.hpp" @@ -184,6 +185,8 @@ class Sequential //! Modify the gradient. arma::mat& Gradient() { return gradient; } + size_t InputShape() const; + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/sequential_impl.hpp b/src/mlpack/methods/ann/layer/sequential_impl.hpp index 5e9c4cd6f6..26669b3b5e 100644 --- a/src/mlpack/methods/ann/layer/sequential_impl.hpp +++ b/src/mlpack/methods/ann/layer/sequential_impl.hpp @@ -21,6 +21,7 @@ #include "../visitor/gradient_visitor.hpp" #include "../visitor/set_input_height_visitor.hpp" #include "../visitor/set_input_width_visitor.hpp" +#include "../visitor/input_shape_visitor.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { @@ -94,6 +95,25 @@ Sequential< } } +template +template +size_t Sequential(InputDataType, OutputDataType, Residual, CustomLayers...):: +InputShape() const +{ + size_t inputShape = 0; + + for (size_t l = 0; l < network.size(); ++l) + { + if (inputShape == 0) + inputShape = boost::apply_visitor(InShapeVisitor(), network[l]); + else + break; + } + + return inputShape; +} + template template From f2594e52b331e8a523fceb0506af44619ee47702 Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Thu, 17 Dec 2020 14:03:58 +0530 Subject: [PATCH 362/550] changed () to <> in sequential --- src/mlpack/methods/ann/layer/sequential_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/sequential_impl.hpp b/src/mlpack/methods/ann/layer/sequential_impl.hpp index 26669b3b5e..0a89f8be10 100644 --- a/src/mlpack/methods/ann/layer/sequential_impl.hpp +++ b/src/mlpack/methods/ann/layer/sequential_impl.hpp @@ -98,7 +98,7 @@ Sequential< template template -size_t Sequential(InputDataType, OutputDataType, Residual, CustomLayers...):: +size_t Sequential:: InputShape() const { size_t inputShape = 0; From 1d66eb40784133849abdd1b8b6b8542dae8a0342 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 17 Dec 2020 14:38:55 +0530 Subject: [PATCH 363/550] fixing errors --- src/mlpack/methods/ann/layer/sequential_impl.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/sequential_impl.hpp b/src/mlpack/methods/ann/layer/sequential_impl.hpp index 0a89f8be10..1290a15ebb 100644 --- a/src/mlpack/methods/ann/layer/sequential_impl.hpp +++ b/src/mlpack/methods/ann/layer/sequential_impl.hpp @@ -97,7 +97,6 @@ Sequential< template -template size_t Sequential:: InputShape() const { From 846c720a6f270a2a33b300fd6f343ddcfee0be54 Mon Sep 17 00:00:00 2001 From: gauravghati Date: Fri, 18 Dec 2020 10:52:46 +0530 Subject: [PATCH 364/550] weight functions for LSTM, adaptive max and mean pooling --- src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp | 3 +++ src/mlpack/methods/ann/layer/adaptive_mean_pooling.hpp | 3 +++ src/mlpack/methods/ann/layer/lstm.hpp | 3 +++ src/mlpack/methods/ann/layer/lstm_impl.hpp | 3 +-- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp b/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp index b465ca5bb8..29676d05dc 100644 --- a/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp +++ b/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp @@ -114,6 +114,9 @@ class AdaptiveMaxPooling //! Get the output size. size_t OutputSize() const { return poolingLayer.OutputSize(); } + //! Get the size of the weights. + size_t WeightSize() const { return 0; } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/adaptive_mean_pooling.hpp b/src/mlpack/methods/ann/layer/adaptive_mean_pooling.hpp index 25509247d5..46a434ab54 100644 --- a/src/mlpack/methods/ann/layer/adaptive_mean_pooling.hpp +++ b/src/mlpack/methods/ann/layer/adaptive_mean_pooling.hpp @@ -115,6 +115,9 @@ class AdaptiveMeanPooling //! Get the output size. size_t OutputSize() const { return poolingLayer.OutputSize(); } + //! Get the size of the weights. + size_t WeightSize() const { return 0; } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/lstm.hpp b/src/mlpack/methods/ann/layer/lstm.hpp index d535f0ee2b..e2b72f937b 100644 --- a/src/mlpack/methods/ann/layer/lstm.hpp +++ b/src/mlpack/methods/ann/layer/lstm.hpp @@ -183,6 +183,9 @@ class LSTM //! Get the number of output units. size_t OutSize() const { return outSize; } + //! Get the size of the weights. + size_t WeightSize() const { return (4 * outSize * inSize + 7 * outSize + 4 * outSize * outSize); } + /** * Serialize the layer */ diff --git a/src/mlpack/methods/ann/layer/lstm_impl.hpp b/src/mlpack/methods/ann/layer/lstm_impl.hpp index b1bd784194..c3da6c0930 100644 --- a/src/mlpack/methods/ann/layer/lstm_impl.hpp +++ b/src/mlpack/methods/ann/layer/lstm_impl.hpp @@ -123,8 +123,7 @@ LSTM::LSTM( rhoSize(rho), bpttSteps(0) { - weights.set_size(4 * outSize * inSize + 7 * outSize + - 4 * outSize * outSize, 1); + weights.set_size(WeightSize(), 1); } template From 6f68e774d3ab5a644817c4c852c6ad62049b5629 Mon Sep 17 00:00:00 2001 From: gauravghati Date: Fri, 18 Dec 2020 11:09:45 +0530 Subject: [PATCH 365/550] style changes --- src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp b/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp index 29676d05dc..fd080c42dd 100644 --- a/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp +++ b/src/mlpack/methods/ann/layer/adaptive_max_pooling.hpp @@ -114,8 +114,8 @@ class AdaptiveMaxPooling //! Get the output size. size_t OutputSize() const { return poolingLayer.OutputSize(); } - //! Get the size of the weights. - size_t WeightSize() const { return 0; } + //! Get the size of the weights. + size_t WeightSize() const { return 0; } /** * Serialize the layer. From 2147618dfa30ec803692a3c38e738af470a603c1 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Fri, 18 Dec 2020 11:46:20 +0530 Subject: [PATCH 366/550] Update COPYRIGHT.txt --- COPYRIGHT.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 24bf8ae46d..a3581e1d03 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -140,6 +140,7 @@ Copyright: Copyright 2020, Sudhakar Brar Copyright 2020, Alex Nguyen Copyright 2020, Gaurav Ghati + Copyright 2020, Anmolpreet Singh License: BSD-3-clause All rights reserved. From 8f9e632b4b35e56b1bb81bf3c49cead7de869b80 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Fri, 18 Dec 2020 13:18:15 +0530 Subject: [PATCH 367/550] Update doc/guide/build.hpp Co-authored-by: Ryan Curtin --- doc/guide/build.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index dc9f385c92..6a5c64a4ea 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -276,7 +276,7 @@ Now similarly you can run all the binding related tests using: ./bin/mlpack_test "[BindingTests]" @endcode -To run a single test, you can explicitly provide the name of the test, for example, +To run a single test, you can explicitly provide the name of the test; for example, to run BinaryClassificationMetricsTest implemented in cv_test.cpp you can run the following: @code From eb7c5eb5c6022c209a00ea7faf73da2ffcc18653 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Fri, 18 Dec 2020 13:18:22 +0530 Subject: [PATCH 368/550] Update doc/guide/build.hpp Co-authored-by: Ryan Curtin --- doc/guide/build.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 6a5c64a4ea..2aa3e9e17b 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -264,10 +264,10 @@ $ ./bin/mlpack_test "[testname]" @endcode where testname is the name of the test suite. -For example to run all collaborative filtering tests implemented in cv_test.cpp you can run: +For example to run all collaborative filtering tests implemented in cf_test.cpp you can run: @code -./bin/mlpack_test "[CVTest]" +./bin/mlpack_test "[CFTest]" @endcode Now similarly you can run all the binding related tests using: From dd442ac6b15e981fc1778ad36efa6d1b2edcbd3d Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Fri, 18 Dec 2020 13:28:44 +0530 Subject: [PATCH 369/550] Update README.md I am changing the URL of link to the Catch2 GitHub repository as the earlier one was not working. --- src/mlpack/tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/README.md b/src/mlpack/tests/README.md index ea61fe08a8..03a58b4bfd 100644 --- a/src/mlpack/tests/README.md +++ b/src/mlpack/tests/README.md @@ -43,4 +43,4 @@ To run a single test, you can explicitly provide the name of the test, for examp `./bin/mlpack_test BinaryClassificationMetricsTest` -Catch2 provides many other features like filter, checkout the [Catch2 reference section](docs/Readme.md#top) - for more details. +Catch2 provides many other features like filter, checkout the [Catch2 reference section](https://github.com/catchorg) - for more details. From 2d07ed063f7ccaf61a45f049e6abe7d6e0f404d2 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:06:18 +0530 Subject: [PATCH 370/550] Update README.md --- src/mlpack/tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/README.md b/src/mlpack/tests/README.md index 03a58b4bfd..a8f9fee22d 100644 --- a/src/mlpack/tests/README.md +++ b/src/mlpack/tests/README.md @@ -43,4 +43,4 @@ To run a single test, you can explicitly provide the name of the test, for examp `./bin/mlpack_test BinaryClassificationMetricsTest` -Catch2 provides many other features like filter, checkout the [Catch2 reference section](https://github.com/catchorg) - for more details. +Catch2 provides many other features like filter, checkout the [Catch2 reference section](https://github.com/catchorg/Catch2/blob/devel/docs/Readme.md#top) - for more details. From 3b9c05ed65c79a2f139972943d89360295150740 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Fri, 18 Dec 2020 23:22:13 +0530 Subject: [PATCH 371/550] Update src/mlpack/methods/pca/pca.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/pca/pca.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/pca/pca.hpp b/src/mlpack/methods/pca/pca.hpp index ae973f27cb..feae5322a5 100644 --- a/src/mlpack/methods/pca/pca.hpp +++ b/src/mlpack/methods/pca/pca.hpp @@ -68,7 +68,7 @@ class PCA void Apply(const arma::mat& data, arma::mat& transformedData, arma::vec& eigVal); -/** + /** * Apply Principal Component Analysis to the provided data set. It is safe * to pass the same matrix reference for both data and transformedData. * @param data Data matrix. From 3c5c2b9ca052bebc3a06ae85566b1dc496393415 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sat, 19 Dec 2020 00:52:57 +0530 Subject: [PATCH 372/550] Update doc/guide/build.hpp Co-authored-by: Ryan Curtin --- doc/guide/build.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 2aa3e9e17b..a7b5d149ad 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -250,7 +250,7 @@ suite. You can build this component with $ make mlpack_test @endcode -We use Catch2 to write our tests +We use Catch2 to write our tests. To run all tests, you can simply run: @code From 8890f43c515f7cf83da80b2e4751e83b335875f2 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sun, 20 Dec 2020 13:09:11 +0530 Subject: [PATCH 373/550] Update pca_impl.hpp made some minor style changes as suggested by @zoq --- src/mlpack/methods/pca/pca_impl.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mlpack/methods/pca/pca_impl.hpp b/src/mlpack/methods/pca/pca_impl.hpp index 2373128320..ce2ecedc66 100644 --- a/src/mlpack/methods/pca/pca_impl.hpp +++ b/src/mlpack/methods/pca/pca_impl.hpp @@ -61,8 +61,7 @@ void PCA::Apply(const arma::mat& data, /** * Apply Principal Component Analysis to the provided data set. - * It creates matrix to store eigenvectors and - that matrix need not to be passed in paramteres + * * @param data - Data matrix * @param transformedData - Data with PCA applied * @param eigVal - contains eigen values in a column vector @@ -75,9 +74,12 @@ void PCA::Apply(const arma::mat& data, arma::mat eigvec; Apply(data, transformedData, eigVal, eigvec); } - /*This is another Overload of apply with only 2 parameteres(data & transformed data) - and it will create eigval and eigvec and store the corresponding values in them - as the source of information are first 2 parameters only. + +/** + * This is another Overload of apply with only 2 parameteres(data & transformed data) + * and it will create eigval and eigvec and store the corresponding values in them + * as the source of information are first 2 parameters only. + * * @param data - Data matrix * @param transformedData - Data with PCA applied */ From be3979c48bfcc884a6b75d2c86761241d2bb7128 Mon Sep 17 00:00:00 2001 From: gauravghati Date: Sun, 20 Dec 2020 20:02:24 +0530 Subject: [PATCH 374/550] added TestCase --- src/mlpack/tests/ann_visitor_test.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mlpack/tests/ann_visitor_test.cpp b/src/mlpack/tests/ann_visitor_test.cpp index f42a0a367e..a0ee1ef2f9 100644 --- a/src/mlpack/tests/ann_visitor_test.cpp +++ b/src/mlpack/tests/ann_visitor_test.cpp @@ -186,3 +186,15 @@ TEST_CASE("WeightSizeVisitorTestForBatchNormLayer", "[ANNVisitorTest]") LayerTypes<> batchNorm = new BatchNorm<>(randomSize); CheckCorrectnessOfWeightSize(batchNorm); } + +/** + * Test that WeightSizeVisitor works properly for LSTM layer. + */ +TEST_CASE("WeightSizeVisitorTestForLSTMLayer", "[ANNVisitorTest]") +{ + size_t randomInSize = arma::randi(arma::distr_param(1, 100)); + size_t randomOutSize = arma::randi(arma::distr_param(1, 100)); + + LayerTypes<> lstm = new LSTM<>(randomInSize, randomOutSize); + CheckCorrectnessOfWeightSize(lstm); +} From d4349b3a5056d958541fe974dbb6ead44f187d27 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 22 Dec 2020 20:11:40 -0500 Subject: [PATCH 375/550] Gonum can't hold ints, so remove slightly confusing documentation. --- .../bindings/go/get_printable_type_impl.hpp | 13 ++------ .../bindings/go/print_type_doc_impl.hpp | 30 ++++--------------- 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/src/mlpack/bindings/go/get_printable_type_impl.hpp b/src/mlpack/bindings/go/get_printable_type_impl.hpp index 2ab074f4cd..da4df3bec9 100644 --- a/src/mlpack/bindings/go/get_printable_type_impl.hpp +++ b/src/mlpack/bindings/go/get_printable_type_impl.hpp @@ -98,17 +98,8 @@ inline std::string GetPrintableType( std::tuple>>::type*) { std::string type = "*mat.Dense"; - if (std::is_same::value) - { - if (T::is_row || T::is_col) - type = "*mat.Dense (1d)"; - } - else if (std::is_same::value) - { - type = "*mat.Dense (with ints)"; - if (T::is_row || T::is_col) - type = "*mat.Dense (1d with ints)"; - } + if (T::is_row || T::is_col) + type = "*mat.Dense (1d)"; return type; } diff --git a/src/mlpack/bindings/go/print_type_doc_impl.hpp b/src/mlpack/bindings/go/print_type_doc_impl.hpp index 55f79b243f..0755f60b8a 100644 --- a/src/mlpack/bindings/go/print_type_doc_impl.hpp +++ b/src/mlpack/bindings/go/print_type_doc_impl.hpp @@ -87,35 +87,15 @@ std::string PrintTypeDoc( util::ParamData& data, const typename std::enable_if::value>::type*) { - if (std::is_same::value) + if (T::is_col || T::is_row) { - if (T::is_col || T::is_row) - { - return "A 1-d gonum Matrix (that is, a Matrix where either the number" - " of rows or number of columns is 1)."; - } - else - { - return "A 2-d gonum Matrix. If the type is not already `float64`, it " - "will be converted."; - } - } - else if (std::is_same::value) - { - if (T::is_col || T::is_row) - { - return "A 1-d gonum Matrix (that is, a Matrix where either the number" - " of rows or number of columns is 1)."; - } - else - { - return "A 2-d gonum Matrix. If the type is not already `int64`, it " - "will be converted."; - } + return "A 1-d gonum Matrix (that is, a Matrix where either the number" + " of rows or number of columns is 1)."; } else { - throw std::invalid_argument("unknown matrix type " + data.cppType); + return "A 2-d gonum Matrix. If the type is not already `float64`, it " + "will be converted."; } } From 58f3a0002cdfbf1292673c2795b2c6fa91ae5afb Mon Sep 17 00:00:00 2001 From: Yashwant Date: Thu, 24 Dec 2020 13:09:38 +0530 Subject: [PATCH 376/550] Scheduled cron GH-action workflow for updating Boost version. --- .github/workflows/update-boost-version.yaml | 81 +++++++++++++++++++++ CMakeLists.txt | 4 +- 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/update-boost-version.yaml diff --git a/.github/workflows/update-boost-version.yaml b/.github/workflows/update-boost-version.yaml new file mode 100644 index 0000000000..32d91fed64 --- /dev/null +++ b/.github/workflows/update-boost-version.yaml @@ -0,0 +1,81 @@ +name: Update Boost Version +on: + workflow_dispatch: + schedule: + - cron: '0 10 * * *' +jobs: + updateBoostVersion: + if: ${{ github.repository == 'mlpack/mlpack' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Build Dependencies + run: | + sudo apt-get update + sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev libcereal-dev + curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo* + cmake . && make && sudo make install && cd .. + + - name: Get Latest Boost Tagged Release + id: boost-version + run: | + # CMake for extracting present boost version. + mkdir build && cd build + cmake .. + + # Ping version information upstream. + BOOST_RELEASE_JSON=$(curl -sL https://api.github.com/repos/boostorg/boost/tags) + FOUND_NEW="NO" + + # Compare present and upstream boost version. + for i in `jq -r .[].name <<< "$BOOST_RELEASE_JSON" | awk '!/.beta/' | \ + grep -Po "(\d+\.)+\d+"` + do + FOUND_SIMILAR="NO" + for j in `grep Boost_ADDITIONAL_VERSIONS_LAST CMakeCache.txt | \ + cut -d "=" -f2 | sed "s/;/ /g"` + do + if [[ "$i" == "$j" ]]; + then + FOUND_SIMILAR="YES" + break + fi + done + if [[ "$FOUND_SIMILAR" != "YES" ]]; + then + FOUND_NEW="YES" + BOOST_VERSION="$BOOST_VERSION\"$i\" " + fi + FOUND_SIMILAR="NO" + for j in `grep Boost_ADDITIONAL_VERSIONS_LAST CMakeCache.txt | \ + cut -d "=" -f2 | sed "s/;/ /g"` + do + if [[ $(echo $i | grep -Po "(\d+)\.\d+") == "$j" ]]; + then + FOUND_SIMILAR="YES" + break + fi + done + if [[ "$FOUND_SIMILAR" != "YES" ]]; + then + FOUND_NEW="YES" + BOOST_VERSION="$BOOST_VERSION\"$(echo $i | grep -Po "(\d+)\.\d+")\" " + fi + done + + # If found the new boost version, then update the CMake script. + if [[ "$FOUND_NEW" == "YES" ]] + then + sed --in-place "s/set(Boost_ADDITIONAL_VERSIONS/set(Boost_ADDITIONAL_VERSIONS\n ${BOOST_VERSION: : -1}/" ../CMakeLists.txt + fi + + - name: Create Pull Request For Boost Version + uses: peter-evans/create-pull-request@v3 + with: + commit-message: Upgrade Boost Version in CMake script. + title: Upgrade Boost Version in CMake script. + body: | + Updates [boostorg/boost](https://github.com/boostorg/boost) in CMake script. + Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request). + labels: update dependencies, automated PR + branch: boost-version-updates diff --git a/CMakeLists.txt b/CMakeLists.txt index a184ca588a..2cc7a64abc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -419,8 +419,8 @@ set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR}) # Unfortunately this configuration variable is necessary and will need to be # updated as time goes on and new versions are released. set(Boost_ADDITIONAL_VERSIONS - "1.74.0" "1.74" - "17.3.0" "17.3" + "1.74.0" "1.74" + "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" From 3bd154bbce53454f53b2322bed934131f590763d Mon Sep 17 00:00:00 2001 From: Yashwant Singh Parihar Date: Thu, 24 Dec 2020 13:28:42 +0530 Subject: [PATCH 377/550] Ahh, forget to delete armadillo folder. --- .github/workflows/update-boost-version.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-boost-version.yaml b/.github/workflows/update-boost-version.yaml index 32d91fed64..c9bb937c37 100644 --- a/.github/workflows/update-boost-version.yaml +++ b/.github/workflows/update-boost-version.yaml @@ -14,7 +14,7 @@ jobs: sudo apt-get update sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev libcereal-dev curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo* - cmake . && make && sudo make install && cd .. + cmake . && make && sudo make install && cd .. && rm -r armadillo* - name: Get Latest Boost Tagged Release id: boost-version From e46a7476d0d558128d85b0620e122fbdf4c2aca6 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Thu, 24 Dec 2020 22:54:18 +0530 Subject: [PATCH 378/550] Added Copy and Move constructors to Multiply Layers --- .../methods/ann/layer/multiply_constant.hpp | 12 +++ .../ann/layer/multiply_constant_impl.hpp | 40 +++++++++ .../methods/ann/layer/multiply_merge.hpp | 12 +++ .../methods/ann/layer/multiply_merge_impl.hpp | 60 ++++++++++++++ src/mlpack/methods/ann/rnn_impl.hpp | 4 +- src/mlpack/tests/ann_layer_test.cpp | 83 +++++++++++++++++++ 6 files changed, 209 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/multiply_constant.hpp b/src/mlpack/methods/ann/layer/multiply_constant.hpp index 5817d26fbf..a9a32a19ac 100644 --- a/src/mlpack/methods/ann/layer/multiply_constant.hpp +++ b/src/mlpack/methods/ann/layer/multiply_constant.hpp @@ -39,6 +39,18 @@ class MultiplyConstant */ MultiplyConstant(const double scalar = 1.0); + //! Copy Constructor + MultiplyConstant(const MultiplyConstant& layer); + + //! Move Constructor + MultiplyConstant(MultiplyConstant&& layer); + + //! Copy assignment operator + MultiplyConstant& operator=(const MultiplyConstant& layer); + + //! Move assignment operator + MultiplyConstant& operator=(MultiplyConstant&& layer); + /** * Ordinary feed forward pass of a neural network. Multiply the input with the * specified constant scalar value. diff --git a/src/mlpack/methods/ann/layer/multiply_constant_impl.hpp b/src/mlpack/methods/ann/layer/multiply_constant_impl.hpp index 7b8cf13e0c..4c02fbd1fa 100644 --- a/src/mlpack/methods/ann/layer/multiply_constant_impl.hpp +++ b/src/mlpack/methods/ann/layer/multiply_constant_impl.hpp @@ -26,6 +26,46 @@ MultiplyConstant::MultiplyConstant( // Nothing to do here. } +template +MultiplyConstant::MultiplyConstant( + const MultiplyConstant& layer) : + scalar(layer.scalar) +{ + // Nothing to do here. +} + +template +MultiplyConstant::MultiplyConstant( + MultiplyConstant&& layer) : + scalar(std::move(layer.scalar)) +{ + // Nothing to do here. +} + +template +MultiplyConstant& +MultiplyConstant::operator=( + const MultiplyConstant& layer) +{ + if (this != &layer) + { + scalar = layer.scalar; + } + return *this; +} + +template +MultiplyConstant& +MultiplyConstant::operator=( + MultiplyConstant&& layer) +{ + if (this != &layer) + { + scalar = std::move(layer.scalar); + } + return *this; +} + template template void MultiplyConstant::Forward( diff --git a/src/mlpack/methods/ann/layer/multiply_merge.hpp b/src/mlpack/methods/ann/layer/multiply_merge.hpp index f459ab2f81..94e4169d52 100644 --- a/src/mlpack/methods/ann/layer/multiply_merge.hpp +++ b/src/mlpack/methods/ann/layer/multiply_merge.hpp @@ -50,6 +50,18 @@ class MultiplyMerge */ MultiplyMerge(const bool model = false, const bool run = true); + //! Copy Constructor + MultiplyMerge(const MultiplyMerge& layer); + + //! Move Constructor + MultiplyMerge(MultiplyMerge&& layer); + + //! Copy assignment operator + MultiplyMerge& operator=(const MultiplyMerge& layer); + + //! Move assignment operator + MultiplyMerge& operator=(MultiplyMerge&& layer); + //! Destructor to release allocated memory. ~MultiplyMerge(); diff --git a/src/mlpack/methods/ann/layer/multiply_merge_impl.hpp b/src/mlpack/methods/ann/layer/multiply_merge_impl.hpp index ee4c8ed917..29cd111482 100644 --- a/src/mlpack/methods/ann/layer/multiply_merge_impl.hpp +++ b/src/mlpack/methods/ann/layer/multiply_merge_impl.hpp @@ -32,6 +32,66 @@ MultiplyMerge::MultiplyMerge( // Nothing to do here. } +template +MultiplyMerge::MultiplyMerge( + const MultiplyMerge& layer) : + model(layer.model), + run(layer.run), + ownsLayer(layer.ownsLayer), + network(layer.network), + weights(layer.weights) +{ + // Nothing to do here. +} + +template +MultiplyMerge::MultiplyMerge( + MultiplyMerge&& layer) : + model(std::move(layer.model)), + run(std::move(layer.run)), + ownsLayer(std::move(layer.ownsLayer)), + network(std::move(layer.network)), + weights(std::move(layer.weights)) +{ + // Nothing to do here. +} + +template +MultiplyMerge& +MultiplyMerge::operator=( + const MultiplyMerge& layer) +{ + if (this != &layer) + { + model = layer.model; + run = layer.run; + ownsLayer = layer.ownsLayer; + network = layer.network; + weights = layer.weights; + } + return *this; +} + +template +MultiplyMerge& +MultiplyMerge::operator=( + MultiplyMerge&& layer) +{ + if (this != &layer) + { + model = std::move(layer.model); + run = std::move(layer.run); + ownsLayer = std::move(layer.ownsLayer); + network = std::move(layer.network); + weights = std::move(layer.weights); + } + return *this; +} + template MultiplyMerge::~MultiplyMerge() diff --git a/src/mlpack/methods/ann/rnn_impl.hpp b/src/mlpack/methods/ann/rnn_impl.hpp index 75749982f5..d734778bef 100644 --- a/src/mlpack/methods/ann/rnn_impl.hpp +++ b/src/mlpack/methods/ann/rnn_impl.hpp @@ -85,10 +85,10 @@ RNN::RNN( targetSize(std::move(network.targetSize)), reset(std::move(network.reset)), single(std::move(network.single)), + network(std::move(network.network)), parameter(std::move(network.parameter)), numFunctions(std::move(network.numFunctions)), - deterministic(std::move(network.deterministic)), - network(std::move(network.network)) + deterministic(std::move(network.deterministic)) { // Nothing to do here. } diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 5471f4be7d..fd718d63ee 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -897,6 +897,39 @@ TEST_CASE("JacobianMultiplyConstantLayerTest", "[ANNLayerTest]") } } +/** + * Check whether copying and moving network with MultiplyConstant is working or + * not. + */ +TEST_CASE("CheckCopyMoveMultiplyConstantTest", "[ANNLayerTest]") +{ + arma::mat input(2, 1000); + input.randu(); + + arma::mat output1; + arma::mat output2; + arma::mat output3; + arma::mat output4; + + MultiplyConstant<> *module1 = new MultiplyConstant<>(3.0); + module1->Forward(input, output1); + + MultiplyConstant<> module2 = *module1; + delete module1; + + module2.Forward(input, output2); + CheckMatrices(output1, output2); + + MultiplyConstant<> *module3 = new MultiplyConstant<>(3.0); + module3->Forward(input, output3); + + MultiplyConstant<> module4(std::move(*module3)); + delete module3; + + module4.Forward(input, output4); + CheckMatrices(output3, output4); +} + /** * Jacobian HardTanH module test. */ @@ -2600,6 +2633,56 @@ TEST_CASE("SimpleMultiplyMergeLayerTest", "[ANNLayerTest]") } } +/** + * Check whether copying and moving network with MultiplyMerge is working or + * not. + */ +TEST_CASE("CheckCopyMoveMultiplyMergeTest", "[ANNLayerTest]") +{ + arma::mat input(10, 1); + input.randu(); + + arma::mat output1; + arma::mat output2; + arma::mat output3; + arma::mat output4; + + const size_t numMergeModules = math::RandInt(2, 10); + + MultiplyMerge<> *module1 = new MultiplyMerge<>(true, false); + for (size_t m = 0; m < numMergeModules; ++m) + { + IdentityLayer<> identityLayer; + identityLayer.Forward(input, identityLayer.OutputParameter()); + + module1->Add >(identityLayer); + } + + module1->Forward(input, output1); + + MultiplyMerge<> module2 = *module1; + delete module1; + + module2.Forward(input, output2); + CheckMatrices(output1, output2); + + MultiplyMerge<> *module3 = new MultiplyMerge<>(true, false); + for (size_t m = 0; m < numMergeModules; ++m) + { + IdentityLayer<> identityLayer; + identityLayer.Forward(input, identityLayer.OutputParameter()); + + module3->Add >(identityLayer); + } + module3->Forward(input, output3); + + MultiplyMerge<> module4(std::move(*module3)); + delete module3; + + module4.Forward(input, output4); + CheckMatrices(output3, output4); +} + /** * Simple Atrous Convolution layer test. */ From 4a827779c942cef1012e01a9e9fd8fbf1616c73a Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Thu, 24 Dec 2020 23:07:55 +0530 Subject: [PATCH 379/550] Disabling bindings by default --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a184ca588a..2ac5a01713 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ if (BUILD_JULIA_BINDINGS) else() set(FORCE_BUILD_JULIA_BINDINGS OFF) endif() -option(BUILD_JULIA_BINDINGS "Build Julia bindings." ON) +option(BUILD_JULIA_BINDINGS "Build Julia bindings." OFF) # Detect whether the user passed BUILD_GO_BINDINGS in order to determine if # we should fail if Go isn't found. @@ -61,7 +61,7 @@ if (BUILD_GO_BINDINGS) else() set(FORCE_BUILD_GO_BINDINGS OFF) endif() -option(BUILD_GO_BINDINGS "Build Go bindings." ON) +option(BUILD_GO_BINDINGS "Build Go bindings." OFF) # If building Go bindings then build go shared libraries. if (BUILD_GO_BINDINGS) @@ -75,7 +75,7 @@ if (BUILD_R_BINDINGS) else() set(FORCE_BUILD_R_BINDINGS OFF) endif() -option(BUILD_R_BINDINGS "Build R bindings." ON) +option(BUILD_R_BINDINGS "Build R bindings." OFF) # Build Markdown bindings for documentation. This is used as part of website # generation. option(BUILD_MARKDOWN_BINDINGS "Build Markdown bindings for website documentation." OFF) From 7ab28e7442b1460291367702dd41dd88c0d0b8c9 Mon Sep 17 00:00:00 2001 From: RishabhGarg108 Date: Fri, 25 Dec 2020 16:34:54 +0530 Subject: [PATCH 380/550] Updated HISTORY.md --- HISTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.md b/HISTORY.md index 4e93d7799c..be50756b4b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,6 @@ ### mlpack ?.?.? ###### ????-??-?? + * Disabled all the bindings by default in cmake (#2782). * Added an implementation to Stratify Data (#2671). * Add `BUILD_DOCS` CMake option to control whether Doxygen documentation is From 00dce30b90084c55ea666a25221ea7c33470b98a Mon Sep 17 00:00:00 2001 From: Rishabh Garg <56191449+RishabhGarg108@users.noreply.github.com> Date: Fri, 25 Dec 2020 18:44:37 +0530 Subject: [PATCH 381/550] Fixed styling Co-authored-by: Marcus Edel --- HISTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.md b/HISTORY.md index be50756b4b..df89bd8be2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ ### mlpack ?.?.? ###### ????-??-?? * Disabled all the bindings by default in cmake (#2782). + * Added an implementation to Stratify Data (#2671). * Add `BUILD_DOCS` CMake option to control whether Doxygen documentation is From a84e483791398643a81b7ee3c1f5cd6c31cfb2ae Mon Sep 17 00:00:00 2001 From: zoq Date: Sat, 26 Dec 2020 10:23:12 +0000 Subject: [PATCH 382/550] Upgrade Boost Version in CMake script. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ba91ea273..e0be77df06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -419,6 +419,7 @@ set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR}) # Unfortunately this configuration variable is necessary and will need to be # updated as time goes on and new versions are released. set(Boost_ADDITIONAL_VERSIONS + "1.75.0" "1.75" "1.74.0" "1.74" "1.73.0" "1.73" "1.72.0" "1.72" From eef10b5fe8930a1e19d865127833a593f765b895 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sun, 27 Dec 2020 12:42:36 +0530 Subject: [PATCH 383/550] Adding Copy and move constructors for Reparametrization Added declarations of Copy and move constructors for Reparametrization. --- src/mlpack/methods/ann/layer/reparametrization.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mlpack/methods/ann/layer/reparametrization.hpp b/src/mlpack/methods/ann/layer/reparametrization.hpp index 65aa96da53..1e7c6daa21 100644 --- a/src/mlpack/methods/ann/layer/reparametrization.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization.hpp @@ -71,6 +71,18 @@ class Reparametrization const bool stochastic = true, const bool includeKl = true, const double beta = 1); + + //! Copy Constructor + Reparametrization(const Reparametrization& layer); + + //! Move Constructor + Reparametrization(Reparametrization&& layer); + + //! Copy assignment operator + Reparametrization& operator=(const Reparametrization& layer); + + //! Move assignment operator + Reparametrization& operator=(Reparametrization&& layer); /** * Ordinary feed forward pass of a neural network, evaluating the function From f8631f77db3edec5f604824d1baa95eed1c3f712 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sun, 27 Dec 2020 13:42:25 +0530 Subject: [PATCH 384/550] Added copy and move constructors for reparamterization definition of copy and move constructors for reparamterization. --- .../ann/layer/reparametrization_impl.hpp | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index 09ac41f5de..d06497ed7c 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -46,7 +46,60 @@ Reparametrization::Reparametrization( << "included." << std::endl; } } + +template +Reparametrization::Reparametrization( + const Reparamterization& layer) : + latentSize(layer.latentSize), + stochastic(layer.stochastic), + includeKl(layer.includeKl), + beta(layer.beta) +{ + //Nothing to do here +} +template +Reparametrization::Reparametrization( + Reparamterization&& layer) : + latentSize(std::move(layer.latentSize)), + stochastic(std::move(layer.stochastic)), + includeKl(std::move(layer.includeKl)), + beta(std::move(layer.beta)) +{ + //Nothing to do here +} + +template +Reparametrization& +Reparametrization:: +opertaor=(const Reparamterization& layer) +{ + if (this != &layer) + { + latentSize = layer.latentSize; + stochastic = layer.stochastic; + includeKl = layer.includeKl; + beta = layer.beta; + } + return *this; +} + +template +Reparametrization& +Reparametrization:: +opertaor=(Reparamterization&& layer) +{ + if (this != &layer) + { + latentSize = std::move(layer.latentSize); + stochastic = std::move(layer.stochastic); + includeKl = std::move(layer.includeKl); + beta = std::move(layer.beta); + } + return *this; +} + + template template void Reparametrization::Forward( From 2ad3225f47d523aad3220e68c6e4d11cea105376 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sun, 27 Dec 2020 15:59:32 +0530 Subject: [PATCH 385/550] Added tests for copy and move constructors of Reparametrization --- src/mlpack/tests/feedforward_network_test.cpp | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index c1399e8bf3..842cd65a53 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -153,6 +153,59 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") CheckMoveFunction<>(model1, trainData, trainLabels, 1); } +/** + * Check whether copying and moving network with Reparametrization is working or not. + */ +TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTest]") +{ + // Load the dataset. + arma::mat trainData; + data::Load("thyroid_train.csv", trainData, true); + + arma::mat trainLabels = trainData.row(trainData.n_rows - 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 + * +-----+ +-----+ +-----+ + * | | | | | | + * | +------>| +------>| | + * | | +>| | +>| | + * +-----+ | +--+--+ | +-----+ + * | | + * Bias | Bias | + * 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 linear3d is working or not. */ From e35ca3096630978fc3c848a5b543431d1b2615d8 Mon Sep 17 00:00:00 2001 From: Omar Shrit Date: Sun, 27 Dec 2020 18:48:27 +0100 Subject: [PATCH 386/550] Fix indentation Signed-off-by: Omar Shrit --- CMake/Findcereal.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMake/Findcereal.cmake b/CMake/Findcereal.cmake index b4d99fe823..aa30354145 100644 --- a/CMake/Findcereal.cmake +++ b/CMake/Findcereal.cmake @@ -35,7 +35,7 @@ if(CEREAL_INCLUDE_DIR) set(CEREAL_VERSION_MAJOR 1) set(CEREAL_VERSION_MINOR 1) set(CEREAL_VERSION_PATCH 2) -elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/cereal.hpp") + elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/cereal.hpp") set(CEREAL_VERSION_MAJOR 1) set(CEREAL_VERSION_MINOR 1) From 266ae6e27b0d72fa547d3cde4a67d0937a781fb5 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Mon, 28 Dec 2020 13:50:06 +0530 Subject: [PATCH 387/550] added no_sanity_checks option to python bindings --- src/mlpack/bindings/python/mlpack/io.pxd | 1 + src/mlpack/bindings/python/mlpack/io_util.hpp | 10 ++++++++++ src/mlpack/bindings/python/print_pyx.cpp | 17 ++++++++++++++++- src/mlpack/bindings/python/py_option.hpp | 4 ++-- src/mlpack/core/util/mlpack_main.hpp | 2 ++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/mlpack/bindings/python/mlpack/io.pxd b/src/mlpack/bindings/python/mlpack/io.pxd index 91d696d011..4a3a838d4c 100644 --- a/src/mlpack/bindings/python/mlpack/io.pxd +++ b/src/mlpack/bindings/python/mlpack/io.pxd @@ -50,3 +50,4 @@ cdef extern from "" \ void DisableBacktrace() nogil except + void ResetTimers() nogil except + void EnableTimers() nogil except + + void SanityCheck[T](T&) nogil except + diff --git a/src/mlpack/bindings/python/mlpack/io_util.hpp b/src/mlpack/bindings/python/mlpack/io_util.hpp index 3a69b06d2d..d2a8bdd4de 100644 --- a/src/mlpack/bindings/python/mlpack/io_util.hpp +++ b/src/mlpack/bindings/python/mlpack/io_util.hpp @@ -163,6 +163,16 @@ inline void EnableTimers() Timer::EnableTiming(); } +/** + * Sanity Check. + */ +template +inline void SanityCheck(T& matrix) +{ + if (matrix.has_nan()) + Log::Fatal << "The input matrix has nan values" << std::endl; +} + } // namespace util } // namespace mlpack diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 87a412346b..4d5bca23e9 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -78,7 +78,7 @@ void PrintPYX(const util::BindingDetails& doc, cout << "from io cimport SetParam, SetParamPtr, SetParamWithInfo, " << "GetParamPtr" << endl; cout << "from io cimport EnableVerbose, DisableVerbose, DisableBacktrace, " - << "ResetTimers, EnableTimers" << endl; + << "ResetTimers, EnableTimers, SanityCheck" << endl; cout << "from matrix_utils import to_matrix, to_matrix_with_info" << endl; cout << "from serialization cimport SerializeIn, SerializeOut" << endl; cout << endl; @@ -206,6 +206,17 @@ void PrintPYX(const util::BindingDetails& doc, << "\'bool'!\")" << endl; cout << endl; + // Determine whether or not we have to do a sanity check. + cout << " if isinstance(no_sanity_checks, bool):" << endl; + cout << " if no_sanity_checks:" << endl; + cout << " SetParam[cbool]( 'no_sanity_checks', " + << "no_sanity_checks)" << endl; + cout << " IO.SetPassed( 'no_sanity_checks')" << endl; + cout << " else:" << endl; + cout << " raise TypeError(" <<"\"'no_sanity_checks\' must have type " + << "\'bool'!\")" << endl; + cout << endl; + // Do any input processing. for (size_t i = 0; i < inputOptions.size(); ++i) { @@ -224,6 +235,10 @@ void PrintPYX(const util::BindingDetails& doc, cout << " IO.SetPassed( '" << d.name << "')" << endl; } + // Before calling mlpackMain(), we do a sanity check if needed. + cout << " if not IO.GetParam[cbool]( 'no_sanity_checks'):" << endl; + cout << " SanityCheck[arma.Mat[double]](IO.GetParam[arma.Mat[double]]( 'training'))" << endl; + // Call the method. cout << " # Call the mlpack program." << endl; cout << " mlpackMain()" << endl; diff --git a/src/mlpack/bindings/python/py_option.hpp b/src/mlpack/bindings/python/py_option.hpp index 98b9f91844..dfad0926aa 100644 --- a/src/mlpack/bindings/python/py_option.hpp +++ b/src/mlpack/bindings/python/py_option.hpp @@ -64,8 +64,8 @@ class PyOption data.required = required; data.input = input; data.loaded = false; - // Only "verbose" and "copy_all_inputs" will be persistent. - if (identifier == "verbose" || identifier == "copy_all_inputs") + // Only "verbose", "copy_all_inputs" and "no_sanity_checks" will be persistent. + if (identifier == "verbose" || identifier == "copy_all_inputs" || identifier == "no_sanity_checks") data.persistent = true; else data.persistent = false; diff --git a/src/mlpack/core/util/mlpack_main.hpp b/src/mlpack/core/util/mlpack_main.hpp index 06f6f8b060..2e2bf6fed0 100644 --- a/src/mlpack/core/util/mlpack_main.hpp +++ b/src/mlpack/core/util/mlpack_main.hpp @@ -230,6 +230,8 @@ PARAM_FLAG("copy_all_inputs", "If specified, all input parameters will be deep" " copied before the method is run. This is useful for debugging problems " "where the input parameters are being modified by the algorithm, but can " "slow down the code.", ""); +PARAM_FLAG("no_sanity_checks", "If specified, the input matrix is checked for" + " nan values.", ""); // Nothing else needs to be defined---the binding will use mlpackMain() as-is. From 41a4cf0caa74862242bd050f79beaae144dcdd98 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 28 Dec 2020 18:22:45 -0500 Subject: [PATCH 388/550] Add missing LICENSE file. --- src/mlpack/bindings/R/mlpack/LICENSE | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/mlpack/bindings/R/mlpack/LICENSE diff --git a/src/mlpack/bindings/R/mlpack/LICENSE b/src/mlpack/bindings/R/mlpack/LICENSE new file mode 100644 index 0000000000..774e59e170 --- /dev/null +++ b/src/mlpack/bindings/R/mlpack/LICENSE @@ -0,0 +1,3 @@ +YEAR: 2020 +COPYRIGHT HOLDER: mlpack Team +ORGANIZATION: mlpack From 71d4e7648073bfc34d3597564c22dbd98c22f280 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Tue, 29 Dec 2020 13:37:12 +0530 Subject: [PATCH 389/550] fixing typos --- src/mlpack/methods/ann/layer/reparametrization_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index d06497ed7c..c23737f1f4 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -49,7 +49,7 @@ Reparametrization::Reparametrization( template Reparametrization::Reparametrization( - const Reparamterization& layer) : + const Reparametrization& layer) : latentSize(layer.latentSize), stochastic(layer.stochastic), includeKl(layer.includeKl), @@ -60,7 +60,7 @@ Reparametrization::Reparametrization( template Reparametrization::Reparametrization( - Reparamterization&& layer) : + Reparametrization&& layer) : latentSize(std::move(layer.latentSize)), stochastic(std::move(layer.stochastic)), includeKl(std::move(layer.includeKl)), @@ -72,7 +72,7 @@ Reparametrization::Reparametrization( template Reparametrization& Reparametrization:: -opertaor=(const Reparamterization& layer) +opertaor=(const Reparametrization& layer) { if (this != &layer) { @@ -87,7 +87,7 @@ opertaor=(const Reparamterization& layer) template Reparametrization& Reparametrization:: -opertaor=(Reparamterization&& layer) +opertaor=(Reparametrization&& layer) { if (this != &layer) { From f1368e25fb1779b6d865daa2956463bf3629a198 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 29 Dec 2020 14:11:22 +0530 Subject: [PATCH 390/550] made no_sanity_checks more general --- src/mlpack/bindings/python/mlpack/io.pxd | 2 +- src/mlpack/bindings/python/mlpack/io_util.hpp | 26 ++++++++++++++++--- src/mlpack/bindings/python/print_pyx.cpp | 4 +-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/mlpack/bindings/python/mlpack/io.pxd b/src/mlpack/bindings/python/mlpack/io.pxd index 4a3a838d4c..b7e77dd82d 100644 --- a/src/mlpack/bindings/python/mlpack/io.pxd +++ b/src/mlpack/bindings/python/mlpack/io.pxd @@ -50,4 +50,4 @@ cdef extern from "" \ void DisableBacktrace() nogil except + void ResetTimers() nogil except + void EnableTimers() nogil except + - void SanityCheck[T](T&) nogil except + + void SanityChecks() nogil except + diff --git a/src/mlpack/bindings/python/mlpack/io_util.hpp b/src/mlpack/bindings/python/mlpack/io_util.hpp index d2a8bdd4de..dd4755cc77 100644 --- a/src/mlpack/bindings/python/mlpack/io_util.hpp +++ b/src/mlpack/bindings/python/mlpack/io_util.hpp @@ -166,11 +166,29 @@ inline void EnableTimers() /** * Sanity Check. */ -template -inline void SanityCheck(T& matrix) +void SanityChecks() { - if (matrix.has_nan()) - Log::Fatal << "The input matrix has nan values" << std::endl; + std::map::iterator itr; + for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr) + { + std::string paramName = itr->first; + std::string paramType = itr->second.cppType; + if (paramType == "arma::mat") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } + else if (paramType == "arma::colvec") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } + else if (paramType == "arma::rowvec") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } + } } } // namespace util diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 4d5bca23e9..562212ee4e 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -78,7 +78,7 @@ void PrintPYX(const util::BindingDetails& doc, cout << "from io cimport SetParam, SetParamPtr, SetParamWithInfo, " << "GetParamPtr" << endl; cout << "from io cimport EnableVerbose, DisableVerbose, DisableBacktrace, " - << "ResetTimers, EnableTimers, SanityCheck" << endl; + << "ResetTimers, EnableTimers, SanityChecks" << endl; cout << "from matrix_utils import to_matrix, to_matrix_with_info" << endl; cout << "from serialization cimport SerializeIn, SerializeOut" << endl; cout << endl; @@ -237,7 +237,7 @@ void PrintPYX(const util::BindingDetails& doc, // Before calling mlpackMain(), we do a sanity check if needed. cout << " if not IO.GetParam[cbool]( 'no_sanity_checks'):" << endl; - cout << " SanityCheck[arma.Mat[double]](IO.GetParam[arma.Mat[double]]( 'training'))" << endl; + cout << " SanityChecks()" << endl; // Call the method. cout << " # Call the mlpack program." << endl; From e730435b1debf1cf6a8f60f7f6c62972ff2b5027 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Tue, 29 Dec 2020 22:46:48 +0530 Subject: [PATCH 391/550] Update feedforward_network_test.cpp --- src/mlpack/tests/feedforward_network_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 842cd65a53..6d53b76b20 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -190,13 +190,13 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes FFN > *model = new FFN >; model->Add >(trainData.n_rows, 8); model->Add >(); - model->Add >(8, 3); + model->Add >(); model->Add >(); FFN > *model1 = new FFN >; model1->Add >(trainData.n_rows, 8); model1->Add >(); - model1->Add >(8, 3); + model1->Add >(); model1->Add >(); // Check whether copy constructor is working or not. From f10b28802706caf94bdf5f6b2f49d1998ecf74f8 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Thu, 31 Dec 2020 01:48:53 +0530 Subject: [PATCH 392/550] Fixed BCE Loss --- .../methods/ann/loss_functions/CMakeLists.txt | 4 +-- ...rror.hpp => binary_cross_entropy_loss.hpp} | 22 +++++++++------- ...hpp => binary_cross_entropy_loss_impl.hpp} | 25 +++++++++++-------- src/mlpack/tests/ann_layer_test.cpp | 6 ++--- src/mlpack/tests/loss_functions_test.cpp | 8 +++--- 5 files changed, 37 insertions(+), 28 deletions(-) rename src/mlpack/methods/ann/loss_functions/{cross_entropy_error.hpp => binary_cross_entropy_loss.hpp} (83%) rename src/mlpack/methods/ann/loss_functions/{cross_entropy_error_impl.hpp => binary_cross_entropy_loss_impl.hpp} (66%) diff --git a/src/mlpack/methods/ann/loss_functions/CMakeLists.txt b/src/mlpack/methods/ann/loss_functions/CMakeLists.txt index 87100de0db..70b570e0ff 100644 --- a/src/mlpack/methods/ann/loss_functions/CMakeLists.txt +++ b/src/mlpack/methods/ann/loss_functions/CMakeLists.txt @@ -1,8 +1,8 @@ # Define the files we need to compile # Anything not in this list will not be compiled into mlpack. set(SOURCES - cross_entropy_error.hpp - cross_entropy_error_impl.hpp + binary_cross_entropy_loss.hpp + binary_cross_entropy_loss_impl.hpp cosine_embedding_loss.hpp cosine_embedding_loss_impl.hpp dice_loss.hpp diff --git a/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp similarity index 83% rename from src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp rename to src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp index e6d077cb6c..4c1758f7d0 100644 --- a/src/mlpack/methods/ann/loss_functions/cross_entropy_error.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp @@ -2,7 +2,7 @@ * @file methods/ann/loss_functions/cross_entropy_error.hpp * @author Konstantin Sidorov * - * Definition of the cross-entropy performance function. + * Definition of the binary-cross-entropy performance function. * * 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 @@ -18,9 +18,8 @@ namespace mlpack { namespace ann /** Artificial Neural Network. */ { /** - * The cross-entropy performance function measures the network's - * performance according to the cross-entropy - * between the input and target distributions. + * The binary-cross-entropy performance function measures the + * Binary Cross Entropy between the target and the output. * * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, * arma::sp_mat or arma::cube). @@ -31,16 +30,16 @@ template < typename InputDataType = arma::mat, typename OutputDataType = arma::mat > -class CrossEntropyError +class BCELoss { public: /** - * Create the CrossEntropyError object. + * Create the BinaryCrossEntropyLoss object. * * @param eps The minimum value used for computing logarithms * and denominators in a numerically stable way. */ - CrossEntropyError(const double eps = 1e-10); + BCELoss(const double eps = 1e-10, const bool reduction = false); /** * Computes the cross-entropy function. @@ -75,6 +74,10 @@ class CrossEntropyError double Eps() const { return eps; } //! Modify the epsilon. double& Eps() { return eps; } + //! Get the reduction. + bool Reduction() const { return reduction; } + //! Set the reduction. + bool& Reduction() { return reduction; } /** * Serialize the layer. @@ -88,12 +91,13 @@ class CrossEntropyError //! The minimum value used for computing logarithms and denominators double eps; -}; // class CrossEntropyError + bool reduction; +}; // class BCELoss } // namespace ann } // namespace mlpack // Include implementation. -#include "cross_entropy_error_impl.hpp" +#include "binary_cross_entropy_loss_impl.hpp" #endif diff --git a/src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp similarity index 66% rename from src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp rename to src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp index cbd88e97da..6254b630b1 100644 --- a/src/mlpack/methods/ann/loss_functions/cross_entropy_error_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp @@ -1,8 +1,8 @@ /** - * @file methods/ann/loss_functions/cross_entropy_error_impl.hpp + * @file methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp * @author Konstantin Sidorov * - * Implementation of the cross-entropy performance function. + * Implementation of the binary-cross-entropy performance function. * * 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 @@ -13,14 +13,14 @@ #define MLPACK_METHODS_ANN_LOSS_FUNCTIONS_CROSS_ENTROPY_ERROR_IMPL_HPP // In case it hasn't yet been included. -#include "cross_entropy_error.hpp" +#include "binary_cross_entropy_loss.hpp" namespace mlpack { namespace ann /** Artificial Neural Network. */ { template -CrossEntropyError::CrossEntropyError( - const double eps) : eps(eps) +BCELoss::BCELoss( + const double eps, const bool reduction) : eps(eps), reduction(reduction) { // Nothing to do here. } @@ -28,17 +28,22 @@ CrossEntropyError::CrossEntropyError( template template typename PredictionType::elem_type -CrossEntropyError::Forward( +BCELoss::Forward( const PredictionType& prediction, const TargetType& target) { - return -arma::accu(target % arma::log(prediction + eps) + - (1. - target) % arma::log(1. - prediction + eps)); + typedef typename PredictionType::elem_type ElemType; + + ElemType loss = -arma::accu(target % arma::log(prediction + eps) + + (1. - target) % arma::log(1. - prediction + eps));; + if(reduction) + loss /= prediction.n_rows; + return loss; } template template -void CrossEntropyError::Backward( +void BCELoss::Backward( const PredictionType& prediction, const TargetType& target, LossType& loss) @@ -48,7 +53,7 @@ void CrossEntropyError::Backward( template template -void CrossEntropyError::serialize( +void BCELoss::serialize( Archive& ar, const uint32_t /* version */) { diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 5471f4be7d..c2dab9f7a0 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -1914,7 +1914,7 @@ TEST_CASE("GradientLookupLayerTest", "[ANNLayerTest]") target(targetWord, i) = 1; } - model = new FFN, GlorotInitialization>(); + model = new FFN, GlorotInitialization>(); model->Predictors() = input; model->Responses() = target; model->Add >(vocabSize, embeddingSize); @@ -1936,7 +1936,7 @@ TEST_CASE("GradientLookupLayerTest", "[ANNLayerTest]") arma::mat& Parameters() { return model->Parameters(); } - FFN, GlorotInitialization>* model; + FFN, GlorotInitialization>* model; arma::mat input, target; const size_t seqLength = 10; diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index b1aac77432..64cd0302f2 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -268,12 +268,12 @@ TEST_CASE("SimpleMeanSquaredErrorTest", "[LossFunctionsTest]") } /* - * Simple test for the cross-entropy error performance function. + * Simple test for the binary-cross-entropy lossfunction. */ -TEST_CASE("SimpleCrossEntropyErrorTest", "[LossFunctionsTest]") +TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") { arma::mat input1, input2, output, target1, target2; - CrossEntropyError<> module(1e-6); + BCELoss<> module(1e-6, false); // Test the Forward function on a user generator input and compare it against // the manually calculated result. From a2785118049880cd61081698abdeb5eb7df94184 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Thu, 31 Dec 2020 03:11:15 +0530 Subject: [PATCH 393/550] minor fix --- .../binary_cross_entropy_loss.hpp | 7 ++++- src/mlpack/tests/loss_functions_test.cpp | 27 ++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp index 4c1758f7d0..3aa2f6353d 100644 --- a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp @@ -38,8 +38,10 @@ class BCELoss * * @param eps The minimum value used for computing logarithms * and denominators in a numerically stable way. + * @param reduction Reduction type. If true, it returns the mean of + * the loss. Else, it returns the sum. */ - BCELoss(const double eps = 1e-10, const bool reduction = false); + BCELoss(const double eps = 1e-10, const bool reduction = true); /** * Computes the cross-entropy function. @@ -74,6 +76,7 @@ class BCELoss double Eps() const { return eps; } //! Modify the epsilon. double& Eps() { return eps; } + //! Get the reduction. bool Reduction() const { return reduction; } //! Set the reduction. @@ -91,6 +94,8 @@ class BCELoss //! The minimum value used for computing logarithms and denominators double eps; + + //! Reduction type. If true, performs mean of loss else sum. bool reduction; }; // class BCELoss diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 64cd0302f2..f4877a051b 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -273,22 +273,26 @@ TEST_CASE("SimpleMeanSquaredErrorTest", "[LossFunctionsTest]") TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") { arma::mat input1, input2, output, target1, target2; - BCELoss<> module(1e-6, false); - + BCELoss<> module1(1e-6, false); + BCELoss<> module2(1e-6, true); // Test the Forward function on a user generator input and compare it against // the manually calculated result. input1 = arma::mat("0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5"); target1 = arma::zeros(1, 8); - double error1 = module.Forward(input1, target1); + double error1 = module1.Forward(input1, target1); REQUIRE(error1 - 8 * std::log(2) == Approx(0.0).margin(2e-5)); + double error2 = module2.Forward(input1, target1); + REQUIRE(error2 - std::log(2) == Approx(0.0).margin(2e-5)); input2 = arma::mat("0 1 1 0 1 0 0 1"); target2 = arma::mat("0 1 1 0 1 0 0 1"); - double error2 = module.Forward(input2, target2); - REQUIRE(error2 == Approx(0.0).margin(1e-5)); + double error3 = module1.Forward(input2, target2); + REQUIRE(error3 == Approx(0.0).margin(1e-5)); + double error4 = module2.Forward(input2, target2); + REQUIRE(error4 == Approx(0.0).margin(1e-5)); // Test the Backward function. - module.Backward(input1, target1, output); + module1.Backward(input1, target1, output); for (double el : output) { // For the 0.5 constant vector we should get 1 / (1 - 0.5) = 2 everywhere. @@ -297,7 +301,16 @@ TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") REQUIRE(output.n_rows == input1.n_rows); REQUIRE(output.n_cols == input1.n_cols); - module.Backward(input2, target2, output); + module2.Backward(input1, target1, output); + for (double el : output) + { + // For the 0.5 constant vector we should get 1 / ((1 - 0.5)*8) = 0.25 everywhere. + REQUIRE(el - 0.25 == Approx(0.0).margin(5e-6)); + } + REQUIRE(output.n_rows == input1.n_rows); + REQUIRE(output.n_cols == input1.n_cols); + + module1.Backward(input2, target2, output); for (size_t i = 0; i < 8; ++i) { double el = output.at(0, i); From 397000df028988fb2c7b88ce6d46e7fdabb09697 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Thu, 31 Dec 2020 04:53:31 +0530 Subject: [PATCH 394/550] changed test case --- src/mlpack/tests/loss_functions_test.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index f4877a051b..14ace430be 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -272,7 +272,7 @@ TEST_CASE("SimpleMeanSquaredErrorTest", "[LossFunctionsTest]") */ TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") { - arma::mat input1, input2, output, target1, target2; + arma::mat input1, input2, input3, output, target1, target2, target3; BCELoss<> module1(1e-6, false); BCELoss<> module2(1e-6, true); // Test the Forward function on a user generator input and compare it against @@ -281,8 +281,13 @@ TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") target1 = arma::zeros(1, 8); double error1 = module1.Forward(input1, target1); REQUIRE(error1 - 8 * std::log(2) == Approx(0.0).margin(2e-5)); - double error2 = module2.Forward(input1, target1); - REQUIRE(error2 - std::log(2) == Approx(0.0).margin(2e-5)); + + input2 = arma::mat("0.5 0.5 0.5 0.5 0.5 0.5"); + target2 = arma::zeros(1, 6); + input2.reshape(2, 3); + target2.reshape(2, 3); + double error2 = module2.Forward(input2, target2); + REQUIRE(error1 - 3 * std::log(2) == Approx(0.0).margin(2e-5)); input2 = arma::mat("0 1 1 0 1 0 0 1"); target2 = arma::mat("0 1 1 0 1 0 0 1"); From 6ce3678b817fd43952018e2f1d95d6de79dbe002 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 31 Dec 2020 14:06:04 +0530 Subject: [PATCH 395/550] Update src/mlpack/methods/ann/layer/reparametrization_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/reparametrization_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index c23737f1f4..ad498d7dfc 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -87,7 +87,7 @@ opertaor=(const Reparametrization& layer) template Reparametrization& Reparametrization:: -opertaor=(Reparametrization&& layer) +operator=(Reparametrization&& layer) { if (this != &layer) { From d4792860e08032ee3576e3b6b0c86238dcb5a2c6 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 31 Dec 2020 14:06:21 +0530 Subject: [PATCH 396/550] Update src/mlpack/methods/ann/layer/reparametrization_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/reparametrization_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index ad498d7dfc..13fa773a1f 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -72,7 +72,7 @@ Reparametrization::Reparametrization( template Reparametrization& Reparametrization:: -opertaor=(const Reparametrization& layer) +operator=(const Reparametrization& layer) { if (this != &layer) { From cc85d2035ff38d52b434e083459809b678dacfa0 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 31 Dec 2020 14:06:33 +0530 Subject: [PATCH 397/550] Update src/mlpack/methods/ann/layer/reparametrization.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/reparametrization.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization.hpp b/src/mlpack/methods/ann/layer/reparametrization.hpp index 1e7c6daa21..f7d41937c7 100644 --- a/src/mlpack/methods/ann/layer/reparametrization.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization.hpp @@ -72,13 +72,13 @@ class Reparametrization const bool includeKl = true, const double beta = 1); - //! Copy Constructor + //! Copy Constructor. Reparametrization(const Reparametrization& layer); - //! Move Constructor + //! Move Constructor. Reparametrization(Reparametrization&& layer); - //! Copy assignment operator + //! Copy assignment operator. Reparametrization& operator=(const Reparametrization& layer); //! Move assignment operator From 6c251721535de91cd72678c954161d4fb5e0f7e0 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Thu, 31 Dec 2020 18:17:24 +0530 Subject: [PATCH 398/550] Made BCELoss to take mean over all elements --- .../ann/loss_functions/binary_cross_entropy_loss_impl.hpp | 2 +- src/mlpack/tests/loss_functions_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp index 6254b630b1..4992abdc1e 100644 --- a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp @@ -37,7 +37,7 @@ BCELoss::Forward( ElemType loss = -arma::accu(target % arma::log(prediction + eps) + (1. - target) % arma::log(1. - prediction + eps));; if(reduction) - loss /= prediction.n_rows; + loss /= prediction.n_elem; return loss; } diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 14ace430be..8b060ca9d9 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -287,7 +287,7 @@ TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") input2.reshape(2, 3); target2.reshape(2, 3); double error2 = module2.Forward(input2, target2); - REQUIRE(error1 - 3 * std::log(2) == Approx(0.0).margin(2e-5)); + REQUIRE(error1 - std::log(2) == Approx(0.0).margin(2e-5)); input2 = arma::mat("0 1 1 0 1 0 0 1"); target2 = arma::mat("0 1 1 0 1 0 0 1"); From fed1c430395319de63041e2c1ea5bf0d8095f601 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Thu, 31 Dec 2020 19:13:06 +0530 Subject: [PATCH 399/550] Made BCELoss to take mean over all elements --- src/mlpack/tests/loss_functions_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 8b060ca9d9..9ef5093e2b 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -287,7 +287,7 @@ TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") input2.reshape(2, 3); target2.reshape(2, 3); double error2 = module2.Forward(input2, target2); - REQUIRE(error1 - std::log(2) == Approx(0.0).margin(2e-5)); + REQUIRE(error2 - std::log(2) == Approx(0.0).margin(2e-5)); input2 = arma::mat("0 1 1 0 1 0 0 1"); target2 = arma::mat("0 1 1 0 1 0 0 1"); From 2955b5d781847365080122a5719f9c5848321656 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Thu, 31 Dec 2020 20:38:47 +0530 Subject: [PATCH 400/550] fixed test case --- src/mlpack/tests/loss_functions_test.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 9ef5093e2b..5a208984dd 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -306,15 +306,6 @@ TEST_CASE("SimpleBinaryCrossEntropyLossTest", "[LossFunctionsTest]") REQUIRE(output.n_rows == input1.n_rows); REQUIRE(output.n_cols == input1.n_cols); - module2.Backward(input1, target1, output); - for (double el : output) - { - // For the 0.5 constant vector we should get 1 / ((1 - 0.5)*8) = 0.25 everywhere. - REQUIRE(el - 0.25 == Approx(0.0).margin(5e-6)); - } - REQUIRE(output.n_rows == input1.n_rows); - REQUIRE(output.n_cols == input1.n_cols); - module1.Backward(input2, target2, output); for (size_t i = 0; i < 8; ++i) { From 6ef1ecac3ac37dc5bafd490a2aea00a39e1c11a5 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 31 Dec 2020 20:44:56 +0530 Subject: [PATCH 401/550] added arma::Mat and categorical data --- src/mlpack/bindings/python/mlpack/io.pxd | 2 +- src/mlpack/bindings/python/mlpack/io_util.hpp | 24 +++++++++++++++++-- src/mlpack/bindings/python/print_pyx.cpp | 4 ++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/mlpack/bindings/python/mlpack/io.pxd b/src/mlpack/bindings/python/mlpack/io.pxd index b7e77dd82d..b7c2d5937a 100644 --- a/src/mlpack/bindings/python/mlpack/io.pxd +++ b/src/mlpack/bindings/python/mlpack/io.pxd @@ -50,4 +50,4 @@ cdef extern from "" \ void DisableBacktrace() nogil except + void ResetTimers() nogil except + void EnableTimers() nogil except + - void SanityChecks() nogil except + + void SanityCheck() nogil except + diff --git a/src/mlpack/bindings/python/mlpack/io_util.hpp b/src/mlpack/bindings/python/mlpack/io_util.hpp index dd4755cc77..8722b90833 100644 --- a/src/mlpack/bindings/python/mlpack/io_util.hpp +++ b/src/mlpack/bindings/python/mlpack/io_util.hpp @@ -15,7 +15,7 @@ #include #include - +#include namespace mlpack { namespace util { @@ -166,7 +166,7 @@ inline void EnableTimers() /** * Sanity Check. */ -void SanityChecks() +void SanityCheck() { std::map::iterator itr; for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr) @@ -178,16 +178,36 @@ void SanityChecks() if (IO::GetParam>(paramName).has_nan()) Log::Fatal << "The input " << paramName << " has nan values." << std::endl; } + else if (paramType == "arma::Mat") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } else if (paramType == "arma::colvec") { if (IO::GetParam>(paramName).has_nan()) Log::Fatal << "The input " << paramName << " has nan values." << std::endl; } + else if (paramType == "arma::Col") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } else if (paramType == "arma::rowvec") { if (IO::GetParam>(paramName).has_nan()) Log::Fatal << "The input " << paramName << " has nan values." << std::endl; } + else if (paramType == "arma::Row") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } + else if (paramType == "std::tuple") + { + if (std::get<1>(IO::GetParam>(paramName)).has_nan()) + Log::Fatal << "The input " << paramName << " has nan values." << std::endl; + } } } diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 562212ee4e..7487f86eda 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -78,7 +78,7 @@ void PrintPYX(const util::BindingDetails& doc, cout << "from io cimport SetParam, SetParamPtr, SetParamWithInfo, " << "GetParamPtr" << endl; cout << "from io cimport EnableVerbose, DisableVerbose, DisableBacktrace, " - << "ResetTimers, EnableTimers, SanityChecks" << endl; + << "ResetTimers, EnableTimers, SanityCheck" << endl; cout << "from matrix_utils import to_matrix, to_matrix_with_info" << endl; cout << "from serialization cimport SerializeIn, SerializeOut" << endl; cout << endl; @@ -237,7 +237,7 @@ void PrintPYX(const util::BindingDetails& doc, // Before calling mlpackMain(), we do a sanity check if needed. cout << " if not IO.GetParam[cbool]( 'no_sanity_checks'):" << endl; - cout << " SanityChecks()" << endl; + cout << " SanityCheck()" << endl; // Call the method. cout << " # Call the mlpack program." << endl; From 22f59329614725bf5754d6c7ebd7cf7f50be041e Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 31 Dec 2020 21:09:57 +0530 Subject: [PATCH 402/550] moved SanityCheck() to IO class and changed no_sanity_checks to check_input_matrices --- src/mlpack/bindings/python/mlpack/io_util.hpp | 48 ------------------- src/mlpack/bindings/python/print_pyx.cpp | 20 ++++---- src/mlpack/bindings/python/py_option.hpp | 2 +- src/mlpack/core/util/io.cpp | 46 ++++++++++++++++++ src/mlpack/core/util/io.hpp | 5 ++ src/mlpack/core/util/mlpack_main.hpp | 4 +- 6 files changed, 64 insertions(+), 61 deletions(-) diff --git a/src/mlpack/bindings/python/mlpack/io_util.hpp b/src/mlpack/bindings/python/mlpack/io_util.hpp index 8722b90833..bf2ab0ee05 100644 --- a/src/mlpack/bindings/python/mlpack/io_util.hpp +++ b/src/mlpack/bindings/python/mlpack/io_util.hpp @@ -163,54 +163,6 @@ inline void EnableTimers() Timer::EnableTiming(); } -/** - * Sanity Check. - */ -void SanityCheck() -{ - std::map::iterator itr; - for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr) - { - std::string paramName = itr->first; - std::string paramType = itr->second.cppType; - if (paramType == "arma::mat") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - else if (paramType == "arma::Mat") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - else if (paramType == "arma::colvec") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - else if (paramType == "arma::Col") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - else if (paramType == "arma::rowvec") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - else if (paramType == "arma::Row") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - else if (paramType == "std::tuple") - { - if (std::get<1>(IO::GetParam>(paramName)).has_nan()) - Log::Fatal << "The input " << paramName << " has nan values." << std::endl; - } - } -} - } // namespace util } // namespace mlpack diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 7487f86eda..7fa76f6b90 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -78,7 +78,7 @@ void PrintPYX(const util::BindingDetails& doc, cout << "from io cimport SetParam, SetParamPtr, SetParamWithInfo, " << "GetParamPtr" << endl; cout << "from io cimport EnableVerbose, DisableVerbose, DisableBacktrace, " - << "ResetTimers, EnableTimers, SanityCheck" << endl; + << "ResetTimers, EnableTimers" << endl; cout << "from matrix_utils import to_matrix, to_matrix_with_info" << endl; cout << "from serialization cimport SerializeIn, SerializeOut" << endl; cout << endl; @@ -206,14 +206,14 @@ void PrintPYX(const util::BindingDetails& doc, << "\'bool'!\")" << endl; cout << endl; - // Determine whether or not we have to do a sanity check. - cout << " if isinstance(no_sanity_checks, bool):" << endl; - cout << " if no_sanity_checks:" << endl; - cout << " SetParam[cbool]( 'no_sanity_checks', " - << "no_sanity_checks)" << endl; - cout << " IO.SetPassed( 'no_sanity_checks')" << endl; + // Determine whether or not we have to check input matrices for NaN values. + cout << " if isinstance(check_input_matrices, bool):" << endl; + cout << " if check_input_matrices:" << endl; + cout << " SetParam[cbool]( 'check_input_matrices', " + << "check_input_matrices)" << endl; + cout << " IO.SetPassed( 'check_input_matrices')" << endl; cout << " else:" << endl; - cout << " raise TypeError(" <<"\"'no_sanity_checks\' must have type " + cout << " raise TypeError(" <<"\"'check_input_matrices\' must have type " << "\'bool'!\")" << endl; cout << endl; @@ -236,8 +236,8 @@ void PrintPYX(const util::BindingDetails& doc, } // Before calling mlpackMain(), we do a sanity check if needed. - cout << " if not IO.GetParam[cbool]( 'no_sanity_checks'):" << endl; - cout << " SanityCheck()" << endl; + cout << " if IO.GetParam[cbool]( 'check_input_matrices'):" << endl; + cout << " IO.SanityCheck()" << endl; // Call the method. cout << " # Call the mlpack program." << endl; diff --git a/src/mlpack/bindings/python/py_option.hpp b/src/mlpack/bindings/python/py_option.hpp index dfad0926aa..f6a544e65b 100644 --- a/src/mlpack/bindings/python/py_option.hpp +++ b/src/mlpack/bindings/python/py_option.hpp @@ -65,7 +65,7 @@ class PyOption data.input = input; data.loaded = false; // Only "verbose", "copy_all_inputs" and "no_sanity_checks" will be persistent. - if (identifier == "verbose" || identifier == "copy_all_inputs" || identifier == "no_sanity_checks") + if (identifier == "verbose" || identifier == "copy_all_inputs" || identifier == "check_input_matrices") data.persistent = true; else data.persistent = false; diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 0c8703c406..f4ed2862ca 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -267,3 +267,49 @@ void IO::ClearSettings() GetSingleton().aliases = persistentAliases; GetSingleton().functionMap = persistentFunctions; } + +void IO::SanityCheck() +{ + std::map::iterator itr; + for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr) + { + std::string paramName = itr->first; + std::string paramType = itr->second.cppType; + if (paramType == "arma::mat") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + else if (paramType == "arma::Mat") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + else if (paramType == "arma::colvec") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + else if (paramType == "arma::Col") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + else if (paramType == "arma::rowvec") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + else if (paramType == "arma::Row") + { + if (IO::GetParam>(paramName).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + else if (paramType == "std::tuple") + { + if (std::get<1>(IO::GetParam>(paramName)).has_nan()) + Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + } + } +} + diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index 427142c897..d927c3b917 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -285,6 +285,11 @@ class IO */ static void ClearSettings(); + /** + * Checks all input matrices for NaN values, if found throws an exception. + */ + static void SanityCheck(); + private: //! Convenience map from alias values to names. std::map aliases; diff --git a/src/mlpack/core/util/mlpack_main.hpp b/src/mlpack/core/util/mlpack_main.hpp index 2e2bf6fed0..0d65513225 100644 --- a/src/mlpack/core/util/mlpack_main.hpp +++ b/src/mlpack/core/util/mlpack_main.hpp @@ -230,8 +230,8 @@ PARAM_FLAG("copy_all_inputs", "If specified, all input parameters will be deep" " copied before the method is run. This is useful for debugging problems " "where the input parameters are being modified by the algorithm, but can " "slow down the code.", ""); -PARAM_FLAG("no_sanity_checks", "If specified, the input matrix is checked for" - " nan values.", ""); +PARAM_FLAG("check_input_matrices", "If specified, the input matrix is checked for" + " NaN values; an exception is thrown if any are found.", ""); // Nothing else needs to be defined---the binding will use mlpackMain() as-is. From 124d39d7e894af56b91b6ae8129d3ecdf6f7718b Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 31 Dec 2020 21:14:52 +0530 Subject: [PATCH 403/550] changed comments --- src/mlpack/bindings/python/print_pyx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 7fa76f6b90..5f22d0759c 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -235,7 +235,7 @@ void PrintPYX(const util::BindingDetails& doc, cout << " IO.SetPassed( '" << d.name << "')" << endl; } - // Before calling mlpackMain(), we do a sanity check if needed. + // Before calling mlpackMain(), we check input matrices for NaN values if needed. cout << " if IO.GetParam[cbool]( 'check_input_matrices'):" << endl; cout << " IO.SanityCheck()" << endl; From e5bfb40c23c4fbada1d1805410087fa94c1123e4 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 31 Dec 2020 22:31:59 +0530 Subject: [PATCH 404/550] wrapped function with Cython --- src/mlpack/bindings/python/mlpack/io.pxd | 4 +++- src/mlpack/bindings/python/print_pyx.cpp | 2 +- src/mlpack/core/util/io.cpp | 3 ++- src/mlpack/core/util/io.hpp | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mlpack/bindings/python/mlpack/io.pxd b/src/mlpack/bindings/python/mlpack/io.pxd index b7c2d5937a..be260d1913 100644 --- a/src/mlpack/bindings/python/mlpack/io.pxd +++ b/src/mlpack/bindings/python/mlpack/io.pxd @@ -38,6 +38,9 @@ cdef extern from "" namespace "mlpack" nogil: @staticmethod void ClearSettings() nogil except + + @staticmethod + void SanityChecks() nogil except + + cdef extern from "" \ namespace "mlpack::util" nogil: void SetParam[T](string, T&) nogil except + @@ -50,4 +53,3 @@ cdef extern from "" \ void DisableBacktrace() nogil except + void ResetTimers() nogil except + void EnableTimers() nogil except + - void SanityCheck() nogil except + diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 5f22d0759c..b79c9501c5 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -237,7 +237,7 @@ void PrintPYX(const util::BindingDetails& doc, // Before calling mlpackMain(), we check input matrices for NaN values if needed. cout << " if IO.GetParam[cbool]( 'check_input_matrices'):" << endl; - cout << " IO.SanityCheck()" << endl; + cout << " IO.SanityChecks()" << endl; // Call the method. cout << " # Call the mlpack program." << endl; diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index f4ed2862ca..24591285dc 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -268,9 +268,10 @@ void IO::ClearSettings() GetSingleton().functionMap = persistentFunctions; } -void IO::SanityCheck() +void IO::SanityChecks() { std::map::iterator itr; + for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr) { std::string paramName = itr->first; diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index d927c3b917..3bb9b24f1b 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -288,7 +288,7 @@ class IO /** * Checks all input matrices for NaN values, if found throws an exception. */ - static void SanityCheck(); + static void SanityChecks(); private: //! Convenience map from alias values to names. From c3ff8d3e621d3e0535945f979d680a30a2e8413a Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 31 Dec 2020 23:58:40 +0530 Subject: [PATCH 405/550] indentation removed --- src/mlpack/bindings/python/mlpack/io.pxd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/bindings/python/mlpack/io.pxd b/src/mlpack/bindings/python/mlpack/io.pxd index be260d1913..7517c4e4cc 100644 --- a/src/mlpack/bindings/python/mlpack/io.pxd +++ b/src/mlpack/bindings/python/mlpack/io.pxd @@ -38,8 +38,8 @@ cdef extern from "" namespace "mlpack" nogil: @staticmethod void ClearSettings() nogil except + - @staticmethod - void SanityChecks() nogil except + + @staticmethod + void SanityChecks() nogil except + cdef extern from "" \ namespace "mlpack::util" nogil: From d259e253e8e5c9239377b248a46b1ef2c6d3066b Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Fri, 1 Jan 2021 11:25:45 +0530 Subject: [PATCH 406/550] Added bracer lists to ann_layer_test.cpp --- src/mlpack/tests/ann_layer_test.cpp | 220 +++++++++++++--------------- 1 file changed, 102 insertions(+), 118 deletions(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index 5471f4be7d..e47b03ed09 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -2123,9 +2123,9 @@ TEST_CASE("BilinearInterpolationLayerParametersTest", "[ANNLayerTest]") TEST_CASE("BatchNormTest", "[ANNLayerTest]") { arma::mat input, output; - input << 5.1 << 3.5 << 1.4 << arma::endr - << 4.9 << 3.0 << 1.4 << arma::endr - << 4.7 << 3.2 << 1.3 << arma::endr; + input = { { 5.1, 3.5, 1.4 }, + { 4.9, 3.0, 1.4 }, + { 4.7, 3.2, 1.3 } }; // BatchNorm layer with average parameter set to true. BatchNorm<> model(input.n_rows); @@ -2141,9 +2141,9 @@ TEST_CASE("BatchNormTest", "[ANNLayerTest]") // Value calculates using torch.nn.BatchNorm2d(momentum = None). arma::mat result; - result << 1.1658 << 0.1100 << -1.2758 << arma::endr - << 1.2579 << -0.0699 << -1.1880 << arma::endr - << 1.1737 << 0.0958 << -1.2695 << arma::endr; + result = { { 1.1658, 0.1100, -1.2758 }, + { 1.2579, -0.0699, -1.1880}, + { 1.1737, 0.0958, -1.2695 } }; CheckMatrices(output, result, 1e-1); @@ -2153,35 +2153,27 @@ TEST_CASE("BatchNormTest", "[ANNLayerTest]") // Values calculated using torch.nn.BatchNorm2d(momentum = None). output = model.TrainingMean(); - result << 3.33333333 << arma::endr - << 3.1 << arma::endr - << 3.06666666 << arma::endr; + result = arma::mat({ 3.33333333, 3.1, 3.06666666 }).t(); CheckMatrices(output, result, 1e-1); // Values calculated using torch.nn.BatchNorm2d(). output = model2.TrainingMean(); - result << 0.3333 << arma::endr - << 0.3100 << arma::endr - << 0.3067 << arma::endr; + result = arma::mat({ 0.3333, 0.3100, 0.3067 }).t(); CheckMatrices(output, result, 1e-1); result.clear(); // Values calculated using torch.nn.BatchNorm2d(momentum = None). output = model.TrainingVariance(); - result << 3.4433 << arma::endr - << 3.0700 << arma::endr - << 2.9033 << arma::endr; + result = arma::mat({ 3.4433, 3.0700, 2.9033 }).t(); CheckMatrices(output, result, 1e-1); result.clear(); // Values calculated using torch.nn.BatchNorm2d(). output = model2.TrainingVariance(); - result << 1.2443 << arma::endr - << 1.2070 << arma::endr - << 1.1903 << arma::endr; + result = arma::mat({ 1.2443, 1.2070, 1.1903 }).t(); CheckMatrices(output, result, 1e-1); result.clear(); @@ -2191,9 +2183,9 @@ TEST_CASE("BatchNormTest", "[ANNLayerTest]") model.Forward(input, output); // Values calculated using torch.nn.BatchNorm2d(momentum = None). - result << 0.9521 << 0.0898 << -1.0419 << arma::endr - << 1.0273 << -0.0571 << -0.9702 << arma::endr - << 0.9586 << 0.0783 << -1.0368 << arma::endr; + result = { { 0.9521, 0.0898, -1.0419 }, + { 1.0273, -0.0571, -0.9702 }, + { 0.9586, 0.0783, -1.0368 } }; CheckMatrices(output, result, 1e-1); @@ -2201,9 +2193,10 @@ TEST_CASE("BatchNormTest", "[ANNLayerTest]") model2.Deterministic() = true; model2.Forward(input, output); - result << 4.2731 << 2.8388 << 0.9562 << arma::endr - << 4.1779 << 2.4485 << 0.9921 << arma::endr - << 4.0268 << 2.6519 << 0.9105 << arma::endr; + result = { { 4.2731, 2.8388, 0.9562 }, + { 4.1779, 2.4485, 0.9921 }, + { 4.0268, 2.6519, 0.9105 } }; + CheckMatrices(output, result, 1e-1); } @@ -2792,30 +2785,30 @@ TEST_CASE("AtrousConvolutionLayerPaddingTest", "[ANNLayerTest]") TEST_CASE("LayerNormTest", "[ANNLayerTest]") { arma::mat input, output; - input << 5.1 << 3.5 << arma::endr - << 4.9 << 3.0 << arma::endr - << 4.7 << 3.2 << arma::endr; + input = { { 5.1, 3.5 }, + { 4.9, 3.0 }, + { 4.7, 3.2 } }; LayerNorm<> model(input.n_rows); model.Reset(); model.Forward(input, output); arma::mat result; - result << 1.2247 << 1.2978 << arma::endr - << 0 << -1.1355 << arma::endr - << -1.2247 << -0.1622 << arma::endr; + result = { { 1.2247, 1.2978 }, + { 0, -1.1355 }, + { -1.2247, -0.1622 } }; CheckMatrices(output, result, 1e-1); result.clear(); output = model.Mean(); - result << 4.9000 << 3.2333 << arma::endr; + result = { 4.9000, 3.2333 }; CheckMatrices(output, result, 1e-1); result.clear(); output = model.Variance(); - result << 0.0267 << 0.0422 << arma::endr; + result = { 0.0267, 0.0422 }; CheckMatrices(output, result, 1e-1); } @@ -4122,25 +4115,25 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") // The input test matrix is of the form 3 x 2 x 4 x 1 where // number of images are 3 and number of feature maps are 2. input = arma::mat(8, 3); - input << 1 << 446 << 42 << arma::endr - << 2 << 16 << 63 << arma::endr - << 3 << 13 << 63 << arma::endr - << 4 << 21 << 21 << arma::endr - << 1 << 13 << 11 << arma::endr - << 32 << 45 << 42 << arma::endr - << 22 << 16 << 63 << arma::endr - << 32 << 13 << 42 << arma::endr; + input = { { 1, 446, 42 }, + { 2, 16, 63 }, + { 3, 13, 63 }, + { 4, 21, 21 }, + { 1, 13, 11 }, + { 32, 45, 42 }, + { 22, 16, 63 }, + { 32, 13, 42 } }; // Output calculated using torch.nn.BatchNorm2d(). result = arma::mat(8, 3); - result << -0.4786 << 3.2634 << -0.1338 << arma::endr - << -0.4702 << -0.3525 << 0.0427 << arma::endr - << -0.4618 << -0.3777 << 0.0427 << arma::endr - << -0.4534 << -0.3104 << -0.3104 << arma::endr - << -1.5429 << -0.8486 << -0.9643 << arma::endr - << 0.2507 << 1.0029 << 0.8293 << arma::endr - << -0.3279 << -0.675 << 2.0443 << arma::endr - << 0.2507 << -0.8486 << 0.8293 << arma::endr; + result = { { -0.4786, 3.2634, -0.1338 }, + { -0.4702, -0.3525, 0.0427 }, + { -0.4618, -0.3777, 0.0427 }, + { -0.4534, -0.3104, -0.3104 }, + { -1.5429, -0.8486, -0.9643 }, + { 0.2507, 1.0029, 0.8293 }, + { -0.3279, -0.675, 2.0443 }, + { 0.2507 , -0.8486 , 0.8293 } }; // Check correctness of batch normalization. BatchNorm<> module1(2, 1e-5, false, 0.1); @@ -4188,14 +4181,14 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") result.clear(); result = arma::mat(8, 3); - result << -0.12195 << 11.20426 << 0.92158 << arma::endr - << -0.0965 << 0.259824 << 1.4560 << arma::endr - << -0.071054 << 0.183567 << 1.45607 << arma::endr - << -0.045601<< 0.3870852 << 0.38708 << arma::endr - << -0.305288 << 1.7683 << 1.4227 << arma::endr - << 5.05166 << 7.29812<< 6.7797 << arma::endr - << 3.323614 << 2.2867 << 10.4086 << arma::endr - << 5.05166 << 1.7683 << 6.7797 << arma::endr; + result = { { -0.12195, 11.20426, 0.92158 }, + { -0.0965, 0.259824, 1.4560 }, + { -0.071054, 0.183567, 1.45607 }, + { -0.045601, 0.3870852, 0.38708 }, + { -0.305288, 1.7683, 1.4227 }, + { 5.05166, 7.29812, 6.7797 }, + { 3.323614, 2.2867, 10.4086 }, + { 5.05166, 1.7683, 6.7797 } }; CheckMatrices(result, deterministicOutput, 1e-1); @@ -4209,19 +4202,19 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") // The input test matrix is of the form 2 x 2 x 3 x 1 where // number of images are 2 and number of feature maps are 2. input = arma::mat(6, 2); - input << 12 << 443 << arma::endr - << 134 << 45 << arma::endr - << 11 << 13 << arma::endr - << 14 << 55 << arma::endr - << 110 << 4 << arma::endr - << 1 << 45 << arma::endr; + input = { { 12, 443 }, + { 134, 45 }, + { 11, 13 }, + { 14, 55 }, + { 110, 4 }, + { 1, 45 } }; - result << -0.629337 << 2.14791 << arma::endr - << 0.156797 << -0.416694 << arma::endr - << -0.63578 << -0.622893 << arma::endr - << -0.637481 << 0.4440386 << arma::endr - << 1.894857 << -0.901267 << arma::endr - << -0.980402 << 0.180253 << arma::endr; + result = { { -0.629337, 2.14791 }, + { 0.156797, -0.416694 }, + { -0.63578, -0.622893 }, + { -0.637481, 0.4440386 }, + { 1.894857, -0.901267 }, + { -0.980402, 0.180253 } }; module1.Forward(input, output); CheckMatrices(result, output, 1e-3); @@ -4257,12 +4250,12 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") module1.Forward(input, deterministicOutput); result.clear(); - result << -0.06388436 << 6.524754114 << arma::endr - << 1.799655281 << 0.44047968 << arma::endr - << -0.07913291 << -0.04784981 << arma::endr - << 0.5405045 << 3.4210097 << arma::endr - << 7.2851023 << -0.1620577 << arma::endr - << -0.37282639 << 2.7184474 << arma::endr; + result = { { -0.06388436, 6.524754114 }, + { 1.799655281, 0.44047968 }, + { -0.07913291, -0.04784981 }, + { 0.5405045, 3.4210097 }, + { 7.2851023, -0.1620577 }, + { -0.37282639, 2.7184474 } }; // Calculated using torch.nn.BatchNorm2d(). CheckMatrices(result, deterministicOutput, 1e-1); @@ -4330,14 +4323,14 @@ TEST_CASE("ConvolutionLayerTestCase", "[ANNLayerTest]") // The input test matrix is of the form 3 x 2 x 4 x 1 where // number of images are 3 and number of feature maps are 2. input = arma::mat(8, 3); - input << 1 << 446 << 42 << arma::endr - << 2 << 16 << 63 << arma::endr - << 3 << 13 << 63 << arma::endr - << 4 << 21 << 21 << arma::endr - << 1 << 13 << 11 << arma::endr - << 32 << 45 << 42 << arma::endr - << 22 << 16 << 63 << arma::endr - << 32 << 13 << 42 << arma::endr; + input = { { 1, 446, 42 }, + { 2, 16, 63 }, + { 3, 13, 63 }, + { 4, 21, 21 }, + { 1, 13, 11 }, + { 32, 45, 42 }, + { 22, 16 , 63 }, + { 32, 13 , 42 } }; Convolution<> layer(2, 4, 1, 1, 1, 1, 0, 0, 4, 1); layer.Reset(); @@ -4503,60 +4496,51 @@ TEST_CASE("SpatialDropoutLayerTest", "[ANNLayerTest]") SpatialDropout<> module(3, 0.2); // Input is a batch of 2 images, each of size (2,2) and having 4 channels. - input << 0.4963 << 0.0885 << 0.7682 << 0.1320 << 0.3074 << 0.4901 << 0.6341 - << 0.8964 << 0.4556 << 0.3489 << 0.6323 << 0.4017 << arma::endr; + input = { 0.4963, 0.0885, 0.7682, 0.1320, 0.3074, 0.4901, 0.6341, 0.8964, + 0.4556, 0.3489, 0.6323, 0.4017 }; - gy << 1 << 3 << 2 << 4 << 5 << 7 << 6 << 8 - << 9 << 11 << 10 << 12 << arma::endr; + gy = { 1, 3, 2, 4, 5, 7, 6, 8, 9, 11, 10, 12 }; // Following values have been calculated using torch.nn.Dropout2d(p=0.2). - temp << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 - << 0 << 0 << 0 << 0 << arma::endr; + temp = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; outputsExpected.row(0) = temp; - temp << 0 << 0 << 0 << 0 << 0.3842 << 0.6126 << 0.7926 << 1.1205 - << 0.5695 << 0.4361 << 0.7904 << 0.5021 << arma::endr; + temp = { 0, 0, 0, 0, 0.3842, 0.6126, 0.7926, 1.1205, 0.5695, 0.4361, 0.7904, + 0.5021 }; outputsExpected.row(1) = temp; - temp << 0.6204 << 0.1106 << 0.9603 << 0.1650 << 0 << 0 << 0 << 0 - << 0.5695 << 0.4361 << 0.7904 << 0.5021 << arma::endr; + temp = { 0.6204, 0.1106, 0.9603, 0.1650, 0, 0, 0, 0, 0.5695, 0.4361, + 0.7904, 0.5021 }; outputsExpected.row(2) = temp; - temp << 0.6204 << 0.1106 << 0.9603 << 0.1650 << 0.3842 << 0.6126 - << 0.7926 << 1.1205 << 0 << 0 << 0 << 0 << arma::endr; + temp = { 0.6204, 0.1106, 0.9603, 0.1650, 0.3842, 0.6126, 0.7926, 1.1205, 0, + 0, 0, 0 }; outputsExpected.row(3) = temp; - temp << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 - << 0.5695 << 0.4361 << 0.7904 << 0.5021 << arma::endr; + temp = { 0, 0, 0, 0, 0, 0, 0, 0, 0.5695, 0.4361, 0.7904, 0.5021 }; outputsExpected.row(4) = temp; - temp << 0 << 0 << 0 << 0 << 0.3842 << 0.6126 << 0.7926 << 1.1205 - << 0 << 0 << 0 << 0 << arma::endr; + temp = { 0, 0, 0, 0, 0.3842, 0.6126, 0.7926, 1.1205, 0, 0, 0, 0 }; outputsExpected.row(5) = temp; - temp << 0.6204 << 0.1106 << 0.9603 << 0.1650 << 0 << 0 << 0 << 0 - << 0 << 0 << 0 << 0 << arma::endr; + temp = { 0.6204, 0.1106, 0.9603, 0.1650, 0, 0, 0, 0, 0, 0, 0, 0 }; outputsExpected.row(6) = temp; - temp << 0.6204 << 0.1106 << 0.9603 << 0.1650 << 0.3842 << 0.6126 << 0.7926 - << 1.1205 << 0.5695 << 0.4361 << 0.7904 << 0.5021 << arma::endr; + temp = { 0.6204, 0.1106, 0.9603, 0.1650, 0.3842, 0.6126, 0.7926, 1.1205, + 0.5695, 0.4361, 0.7904, 0.5021 }; outputsExpected.row(7) = temp; - temp << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 - << 0 << 0 << 0 << 0 << arma::endr; + temp = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; gsExpected.row(0) = temp; - temp << 0 << 0 << 0 << 0 << 6.2500 << 8.7500 << 7.5000 << 10.0000 - << 11.2500 << 13.7500 << 12.5000 << 15.0000 << arma::endr; + temp = { 0, 0, 0, 0, 6.2500, 8.7500, 7.5000, 10.0000, 11.2500, 13.7500, + 12.5000, 15.0000 }; gsExpected.row(1) = temp; - temp << 1.2500 << 3.7500 << 2.5000 << 5.0000 << 0 << 0 << 0 << 0 - << 11.2500 << 13.7500 << 12.5000 << 15.0000 << arma::endr; + temp = { 1.2500, 3.7500, 2.5000, 5.0000, 0, 0, 0, 0, 11.2500, 13.7500, + 12.5000, 15.0000 }; gsExpected.row(2) = temp; - temp << 1.2500 << 3.7500 << 2.5000 << 5.0000 << 6.2500 << 8.7500 - << 7.5000 << 10.0000 << 0 << 0 << 0 << 0 << arma::endr; + temp = { 1.2500, 3.7500, 2.5000, 5.0000, 6.2500, 8.7500, 7.5000, 10.0000, 0, + 0, 0, 0 }; gsExpected.row(3) = temp; - temp << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 - << 11.2500 << 13.7500 << 12.5000 << 15.0000 << arma::endr; + temp = { 0, 0, 0, 0, 0, 0, 0, 0, 11.2500, 13.7500, 12.5000, 15.0000 }; gsExpected.row(4) = temp; - temp << 0 << 0 << 0 << 0 << 6.2500 << 8.7500 << 7.5000 << 10.0000 - << 0 << 0 << 0 << 0 << arma::endr; + temp = { 0, 0, 0, 0, 6.2500, 8.7500, 7.5000, 10.0000, 0, 0, 0, 0 }; gsExpected.row(5) = temp; - temp << 1.2500 << 3.7500 << 2.5000 << 5.0000 << 0 << 0 << 0 << 0 - << 0 << 0 << 0 << 0 << arma::endr; + temp = { 1.2500, 3.7500, 2.5000, 5.0000, 0, 0, 0, 0, 0, 0, 0, 0 }; gsExpected.row(6) = temp; - temp << 1.2500 << 3.7500 << 2.5000 << 5.0000 << 6.2500 << 8.7500 << 7.5000 - << 10.0000 << 11.2500 << 13.7500 << 12.5000 << 15.0000 << arma::endr; + temp = { 1.2500, 3.7500, 2.5000, 5.0000, 6.2500, 8.7500, 7.5000, 10.0000, + 11.2500, 13.7500, 12.5000, 15.0000 }; gsExpected.row(7) = temp; input = input.t(); From ee31b0ea9ed0a326b0e527939f6831dc5a05ab88 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Fri, 1 Jan 2021 13:16:11 +0530 Subject: [PATCH 407/550] Fix for static analysis checks --- src/mlpack/tests/ann_layer_test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index e47b03ed09..eff640827b 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -4114,7 +4114,6 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") // The input test matrix is of the form 3 x 2 x 4 x 1 where // number of images are 3 and number of feature maps are 2. - input = arma::mat(8, 3); input = { { 1, 446, 42 }, { 2, 16, 63 }, { 3, 13, 63 }, @@ -4125,7 +4124,6 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") { 32, 13, 42 } }; // Output calculated using torch.nn.BatchNorm2d(). - result = arma::mat(8, 3); result = { { -0.4786, 3.2634, -0.1338 }, { -0.4702, -0.3525, 0.0427 }, { -0.4618, -0.3777, 0.0427 }, @@ -4180,7 +4178,6 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") module1.Forward(input, deterministicOutput); result.clear(); - result = arma::mat(8, 3); result = { { -0.12195, 11.20426, 0.92158 }, { -0.0965, 0.259824, 1.4560 }, { -0.071054, 0.183567, 1.45607 }, @@ -4201,7 +4198,6 @@ TEST_CASE("BatchNormWithMinBatchesTest", "[ANNLayerTest]") // The input test matrix is of the form 2 x 2 x 3 x 1 where // number of images are 2 and number of feature maps are 2. - input = arma::mat(6, 2); input = { { 12, 443 }, { 134, 45 }, { 11, 13 }, From ae71523713f4ab05a3ad97f53e31c7d9ca8658f7 Mon Sep 17 00:00:00 2001 From: Yashwants19 Date: Fri, 1 Jan 2021 10:20:18 +0000 Subject: [PATCH 408/550] Upgrade Catch to 2.13.4 --- src/mlpack/tests/catch.hpp | 40 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/mlpack/tests/catch.hpp b/src/mlpack/tests/catch.hpp index 2a2d77a27f..0384171ae4 100644 --- a/src/mlpack/tests/catch.hpp +++ b/src/mlpack/tests/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v2.13.3 - * Generated: 2020-10-31 18:20:31.045274 + * Catch v2.13.4 + * Generated: 2020-12-29 14:48:00.116107 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved. @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 3 +#define CATCH_VERSION_PATCH 4 #ifdef __clang__ # pragma clang system_header @@ -14126,24 +14126,28 @@ namespace Catch { namespace { struct TestHasher { - explicit TestHasher(Catch::SimplePcg32& rng_instance) { - basis = rng_instance(); - basis <<= 32; - basis |= rng_instance(); - } + using hash_t = uint64_t; - uint64_t basis; + explicit TestHasher( hash_t hashSuffix ): + m_hashSuffix{ hashSuffix } {} - uint64_t operator()(TestCase const& t) const { - // Modified FNV-1a hash - static constexpr uint64_t prime = 1099511628211; - uint64_t hash = basis; - for (const char c : t.name) { + uint32_t operator()( TestCase const& t ) const { + // FNV-1a hash with multiplication fold. + const hash_t prime = 1099511628211u; + hash_t hash = 14695981039346656037u; + for ( const char c : t.name ) { hash ^= c; hash *= prime; } - return hash; + hash ^= m_hashSuffix; + hash *= prime; + const uint32_t low{ static_cast( hash ) }; + const uint32_t high{ static_cast( hash >> 32 ) }; + return low * high; } + + private: + hash_t m_hashSuffix; }; } // end unnamed namespace @@ -14161,9 +14165,9 @@ namespace Catch { case RunTests::InRandomOrder: { seedRng( config ); - TestHasher h( rng() ); + TestHasher h{ config.rngSeed() }; - using hashedTest = std::pair; + using hashedTest = std::pair; std::vector indexed_tests; indexed_tests.reserve( unsortedTestCases.size() ); @@ -15316,7 +15320,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 3, "", 0 ); + static Version version( 2, 13, 4, "", 0 ); return version; } From a6fe99668a3688070ccb738bf1e04c020a8def90 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Fri, 1 Jan 2021 16:20:49 +0530 Subject: [PATCH 409/550] Another fix for the static analysis checks --- src/mlpack/tests/ann_layer_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index eff640827b..67b01fbc99 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -4318,7 +4318,6 @@ TEST_CASE("ConvolutionLayerTestCase", "[ANNLayerTest]") // The input test matrix is of the form 3 x 2 x 4 x 1 where // number of images are 3 and number of feature maps are 2. - input = arma::mat(8, 3); input = { { 1, 446, 42 }, { 2, 16, 63 }, { 3, 13, 63 }, From 112e0f3a73c5c9bc3f0573cb31fc074eb906ca76 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Sat, 2 Jan 2021 10:23:46 +0530 Subject: [PATCH 410/550] Added braced lists to files --- src/mlpack/tests/cv_test.cpp | 10 ++--- src/mlpack/tests/metric_test.cpp | 68 ++++++++++++++++---------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/mlpack/tests/cv_test.cpp b/src/mlpack/tests/cv_test.cpp index 9294790661..75f1e87998 100644 --- a/src/mlpack/tests/cv_test.cpp +++ b/src/mlpack/tests/cv_test.cpp @@ -199,13 +199,13 @@ TEST_CASE("AdjR2ScoreTest", "[CVTest]") // Making two variables that define the linear function is // f(x1, x2) = x1 + x2. arma::mat X; - X << 1 << 2 << 3 << 4 << 5 << 6 << arma::endr - << 2 << 3 << 4 << 5 << 6 << 7 << arma::endr; + X = { { 1, 2, 3, 4, 5, 6 }, + { 2, 3, 4, 5, 6, 7 } }; arma::rowvec Y; - Y << 3 << 5 << 7 << 9 << 11 << 13; - + Y = { 3, 5, 7, 9, 11, 13 }; + LinearRegression lr(X, Y); - + // Theoretically Adjusted R squared should be equal 1 double expAdjR2 = 1; REQUIRE(std::abs(R2Score::Evaluate(lr, X, Y) - expAdjR2) diff --git a/src/mlpack/tests/metric_test.cpp b/src/mlpack/tests/metric_test.cpp index db3f164650..99f12c3ed9 100644 --- a/src/mlpack/tests/metric_test.cpp +++ b/src/mlpack/tests/metric_test.cpp @@ -31,10 +31,10 @@ TEST_CASE("L1MetricTest", "[MetricTest]") b1.randn(); arma::Col a2(5); - a2 << 1 << 2 << 1 << 0 << 5; + a2 = { 1, 2, 1, 0, 5 }; arma::Col b2(5); - b2 << 2 << 5 << 2 << 0 << 1; + b2 = { 2, 5, 2, 0, 1 }; ManhattanDistance lMetric; @@ -57,10 +57,10 @@ TEST_CASE("L2MetricTest", "[MetricTest]") b1.randn(); arma::vec a2(5); - a2 << 1 << 2 << 1 << 0 << 5; + a2 = { 1, 2, 1, 0, 5 }; arma::vec b2(5); - b2 << 2 << 5 << 2 << 0 << 1; + b2 = { 2, 5, 2, 0, 1 }; EuclideanDistance lMetric; @@ -83,10 +83,10 @@ TEST_CASE("LINFMetricTest", "[MetricTest]") b1.randn(); arma::Col a2(5); - a2 << 1 << 2 << 1 << 0 << 5; + a2 = { 1, 2, 1, 0, 5 }; arma::Col b2(5); - b2 << 2 << 5 << 2 << 0 << 1; + b2 = { 2, 5, 2, 0, 1 }; ChebyshevDistance lMetric; @@ -103,34 +103,34 @@ TEST_CASE("LINFMetricTest", "[MetricTest]") TEST_CASE("IoUMetricTest", "[MetricTest]") { arma::vec bbox1(4), bbox2(4); - bbox1 << 1 << 2 << 100 << 200; - bbox2 << 1 << 2 << 100 << 200; + bbox1 = { 1, 2, 100, 200 }; + bbox2 = { 1, 2, 100, 200 }; // IoU of same bounding boxes equals 1.0. REQUIRE(1.0 == Approx(IoU<>::Evaluate(bbox1, bbox2)).epsilon(1e-6)); // Use coordinate system to represent bounding boxes. // Bounding boxes represent {x0, y0, x1, y1}. - bbox1 << 39 << 63 << 203 << 112; - bbox2 << 54 << 66 << 198 << 114; + bbox1 = { 39, 63, 203, 112 }; + bbox2 = { 54, 66, 198, 114 }; // Value calculated using Python interpreter. REQUIRE(IoU::Evaluate(bbox1, bbox2) == Approx(0.7980093).epsilon(1e-6)); - bbox1 << 31 << 69 << 201 << 125; - bbox2 << 18 << 63 << 235 << 135; + bbox1 = { 31, 69, 201, 125 }; + bbox2 = { 18, 63, 235, 135 }; // Value calculated using Python interpreter. REQUIRE(IoU::Evaluate(bbox1, bbox2) == Approx(0.612479577).epsilon(1e-6)); // Use hieght - width representation of bounding boxes. // Bounding boxes represent {x0, y0, h, w}. - bbox1 << 49 << 75 << 154 << 50; - bbox2 << 42 << 78 << 144 << 48; + bbox1 = { 49, 75, 154, 50 }; + bbox2 = { 42, 78, 144, 48 }; // Value calculated using Python interpreter. REQUIRE(IoU<>::Evaluate(bbox1, bbox2) == Approx(0.7898879).epsilon(1e-6)); - bbox1 << 35 << 51 << 161 << 59; - bbox2 << 36 << 60 << 144 << 48; + bbox1 = { 35, 51, 161, 59 }; + bbox2 = { 36, 60, 144, 48 }; // Value calculated using Python interpreter. REQUIRE(IoU<>::Evaluate(bbox1, bbox2) == Approx(0.7309670).epsilon(1e-6)); } @@ -144,9 +144,9 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Set values of each bounding box. // Use coordinate system to represent bounding boxes. // Bounding boxes represent {x0, y0, x1, y1}. - bbox1 << 0.5 << 0.5 << 41.0 << 31.0; - bbox2 << 1.0 << 1.0 << 42.0 << 22.0; - bbox3 << 10.0 << 13.0 << 90.0 << 100.0; + bbox1 = { 0.5, 0.5, 41.0, 31.0 }; + bbox2 = { 1.0, 1.0, 42.0, 22.0 }; + bbox3 = { 10.0, 13.0, 90.0, 100.0 }; // Fill bounding box. bbox.insert_cols(0, bbox3); @@ -155,7 +155,7 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Fill confidence scores for each bounding box. arma::vec confidenceScores(3); - confidenceScores << 0.7 << 0.6 << 0.4; + confidenceScores = { 0.7, 0.6, 0.4 }; // Selected bounding box using torchvision.ops.nms(). desiredBoundingBox.insert_cols(0, bbox3); @@ -164,7 +164,7 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Selected indices of bounding boxes using // torchvision.ops.nms(). desiredIndices = arma::ucolvec(2); - desiredIndices << 0 << 2; + desiredIndices = { 0, 2 }; // Evaluate the bounding box. NMS::Evaluate(bbox, confidenceScores, @@ -190,7 +190,7 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") bbox.insert_cols(0, bbox1); bbox.insert_cols(0, bbox2); bbox.insert_cols(0, bbox1); - confidenceScores << 1.0 << 0.6 << 0.9; + confidenceScores = { 1.0, 0.6, 0.9 }; // Output calculated using using torchvision.ops.nms(). desiredBoundingBox.insert_cols(0, bbox2); @@ -212,9 +212,9 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Use coordinate system to represent bounding boxes. // Bounding boxes represent {x0, y0, x1, y1}. - bbox1 << 39 << 63 << 203 << 112; - bbox2 << 31 << 69 << 201 << 125; - bbox3 << 54 << 66 << 198 << 114; + bbox1 = { 39, 63, 203, 112 }; + bbox2 = { 31, 69, 201, 125 }; + bbox3 = { 54, 66, 198, 114 }; // Fill bounding box. bbox.insert_cols(0, bbox3); @@ -222,7 +222,7 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") bbox.insert_cols(0, bbox1); // Fill confidence scores of bounding boxes. - confidenceScores << 1.0 << 0.6 << 0.9; + confidenceScores = { 1.0, 0.6, 0.9 }; // Selected bounding box using torchvision.ops.nms(). desiredBoundingBox.insert_cols(0, bbox2); @@ -245,9 +245,9 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Set values of each bounding box. // Use coordinate system to represent bounding boxes. // Bounding boxes represent {x0, y0, h, w}. - bbox1 << 0.0 << 0.0 << 41.0 << 31.0; - bbox2 << 1.0 << 1.0 << 41.0 << 21.0; - bbox3 << 10.0 << 13.0 << 80.0 << 87.0; + bbox1 = { 0.0, 0.0, 41.0, 31.0 }; + bbox2 = { 1.0, 1.0, 41.0, 21.0 }; + bbox3 = { 10.0, 13.0, 80.0, 87.0 }; // Fill bounding box. bbox.insert_cols(0, bbox3); @@ -255,7 +255,7 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") bbox.insert_cols(0, bbox1); // Fill confidence scores for each bounding box. - confidenceScores << 0.7 << 0.6 << 0.4; + confidenceScores = { 0.7, 0.6, 0.4 }; // Selected bounding box using torchvision.ops.nms(). desiredBoundingBox.insert_cols(0, bbox3); @@ -277,9 +277,9 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Use coordinate system to represent bounding boxes. // Bounding boxes represent {x0, y0, h, w}. - bbox1 << 39 << 63 << 164 << 49; - bbox2 << 31 << 69 << 170 << 56; - bbox3 << 54 << 66 << 144 << 48; + bbox1 = { 39, 63, 164, 49 }; + bbox2 = { 31, 69, 170, 56 }; + bbox3 = { 54, 66, 144, 48 }; // Fill bounding box. bbox.insert_cols(0, bbox3); @@ -287,7 +287,7 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") bbox.insert_cols(0, bbox1); // Fill confidence scores of bounding boxes. - confidenceScores << 1.0 << 0.6 << 0.4; + confidenceScores = { 1.0, 0.6, 0.4 }; // Selected bounding box using torchvision.ops.nms(). desiredBoundingBox.insert_cols(0, bbox2); From f29baecfbfd487cbccae7fb16676dd4a73485541 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sat, 2 Jan 2021 12:39:04 +0530 Subject: [PATCH 411/550] Update feedforward_network_test.cpp I have changed the test network with stochastic option to be off so that randomization was leading to different predictions. --- src/mlpack/tests/feedforward_network_test.cpp | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 6d53b76b20..acb99a063f 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -167,36 +167,17 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes /* * 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 - * +-----+ +-----+ +-----+ - * | | | | | | - * | +------>| +------>| | - * | | +>| | +>| | - * +-----+ | +--+--+ | +-----+ - * | | - * Bias | Bias | - * Layer | Layer | - * +-----+ | +-----+ | - * | | | | | | - * | +-----+ | +-----+ - * | | | | - * +-----+ +-----+ + * followed by a linear layer and then a reparametrization layer */ FFN > *model = new FFN >; - model->Add >(trainData.n_rows, 8); - model->Add >(); - model->Add >(); + model1->Add >(trainData.n_rows, 8); + model1->Add >(4,false,true,1); model->Add >(); FFN > *model1 = new FFN >; model1->Add >(trainData.n_rows, 8); - model1->Add >(); - model1->Add >(); + model1->Add >(4,false,true,1); model1->Add >(); // Check whether copy constructor is working or not. From ee889c79c29728de27065183bc8d0e9beb83d569 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 2 Jan 2021 12:48:40 +0530 Subject: [PATCH 412/550] removed iostream --- src/mlpack/bindings/python/mlpack/io_util.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/bindings/python/mlpack/io_util.hpp b/src/mlpack/bindings/python/mlpack/io_util.hpp index bf2ab0ee05..3a69b06d2d 100644 --- a/src/mlpack/bindings/python/mlpack/io_util.hpp +++ b/src/mlpack/bindings/python/mlpack/io_util.hpp @@ -15,7 +15,7 @@ #include #include -#include + namespace mlpack { namespace util { From 8a8f0eaeca13ef9fcaa2cb29e44964d2369c9402 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 2 Jan 2021 12:51:27 +0530 Subject: [PATCH 413/550] changed name from SanityChecks() to CheckInputMatrices() --- src/mlpack/bindings/python/print_pyx.cpp | 2 +- src/mlpack/core/util/io.cpp | 2 +- src/mlpack/core/util/io.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index b79c9501c5..5248b6b0be 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -237,7 +237,7 @@ void PrintPYX(const util::BindingDetails& doc, // Before calling mlpackMain(), we check input matrices for NaN values if needed. cout << " if IO.GetParam[cbool]( 'check_input_matrices'):" << endl; - cout << " IO.SanityChecks()" << endl; + cout << " IO.CheckInputMatrices()" << endl; // Call the method. cout << " # Call the mlpack program." << endl; diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 24591285dc..fc2e310e4b 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -268,7 +268,7 @@ void IO::ClearSettings() GetSingleton().functionMap = persistentFunctions; } -void IO::SanityChecks() +void IO::CheckInputMatrices() { std::map::iterator itr; diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index 3bb9b24f1b..d4f5cc7a17 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -288,7 +288,7 @@ class IO /** * Checks all input matrices for NaN values, if found throws an exception. */ - static void SanityChecks(); + static void CheckInputMatrices(); private: //! Convenience map from alias values to names. From 62c9f50e5c945952606a61cee9a947bbd3d43aa6 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 2 Jan 2021 13:03:57 +0530 Subject: [PATCH 414/550] made single block in print_pyx.cpp --- src/mlpack/bindings/python/print_pyx.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/mlpack/bindings/python/print_pyx.cpp b/src/mlpack/bindings/python/print_pyx.cpp index 5248b6b0be..6853c969da 100644 --- a/src/mlpack/bindings/python/print_pyx.cpp +++ b/src/mlpack/bindings/python/print_pyx.cpp @@ -206,17 +206,6 @@ void PrintPYX(const util::BindingDetails& doc, << "\'bool'!\")" << endl; cout << endl; - // Determine whether or not we have to check input matrices for NaN values. - cout << " if isinstance(check_input_matrices, bool):" << endl; - cout << " if check_input_matrices:" << endl; - cout << " SetParam[cbool]( 'check_input_matrices', " - << "check_input_matrices)" << endl; - cout << " IO.SetPassed( 'check_input_matrices')" << endl; - cout << " else:" << endl; - cout << " raise TypeError(" <<"\"'check_input_matrices\' must have type " - << "\'bool'!\")" << endl; - cout << endl; - // Do any input processing. for (size_t i = 0; i < inputOptions.size(); ++i) { @@ -235,8 +224,14 @@ void PrintPYX(const util::BindingDetails& doc, cout << " IO.SetPassed( '" << d.name << "')" << endl; } + // Checking the type of check_input_matrices parameter. + cout << " if not isinstance(check_input_matrices, bool):" << endl; + cout << " raise TypeError(" <<"\"'check_input_matrices\' must have type " + << "\'bool'!\")" << endl; + cout << endl; + // Before calling mlpackMain(), we check input matrices for NaN values if needed. - cout << " if IO.GetParam[cbool]( 'check_input_matrices'):" << endl; + cout << " if check_input_matrices:" << endl; cout << " IO.CheckInputMatrices()" << endl; // Call the method. From be82a0d85ce714d8c865125b8a1d24b080478161 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 2 Jan 2021 13:15:28 +0530 Subject: [PATCH 415/550] reduced num of chars per line in io.cpp --- src/mlpack/core/util/io.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index fc2e310e4b..4e1771e705 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -270,46 +270,48 @@ void IO::ClearSettings() void IO::CheckInputMatrices() { + typedef typename std::tuple TupleType; std::map::iterator itr; for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr) { std::string paramName = itr->first; std::string paramType = itr->second.cppType; + std::string errMsg = "The input " + paramName + " has NaN values."; if (paramType == "arma::mat") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + Log::Fatal << errMsg << std::endl; } else if (paramType == "arma::Mat") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + Log::Fatal << errMsg << std::endl; } else if (paramType == "arma::colvec") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + Log::Fatal << errMsg << std::endl; } else if (paramType == "arma::Col") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + Log::Fatal << errMsg << std::endl; } else if (paramType == "arma::rowvec") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + Log::Fatal << errMsg << std::endl; } else if (paramType == "arma::Row") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + Log::Fatal << errMsg << std::endl; } else if (paramType == "std::tuple") { - if (std::get<1>(IO::GetParam>(paramName)).has_nan()) - Log::Fatal << "The input " << paramName << " has NaN values." << std::endl; + if (std::get<1>(IO::GetParam(paramName)).has_nan()) + Log::Fatal << errMsg << std::endl; } } } From 990ef5347ad1aff53e3587e59efcb1ea272db868 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 2 Jan 2021 13:20:02 +0530 Subject: [PATCH 416/550] reduced num of chars per line in py_option.hpp --- src/mlpack/bindings/python/py_option.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mlpack/bindings/python/py_option.hpp b/src/mlpack/bindings/python/py_option.hpp index f6a544e65b..0a62afc709 100644 --- a/src/mlpack/bindings/python/py_option.hpp +++ b/src/mlpack/bindings/python/py_option.hpp @@ -64,8 +64,10 @@ class PyOption data.required = required; data.input = input; data.loaded = false; - // Only "verbose", "copy_all_inputs" and "no_sanity_checks" will be persistent. - if (identifier == "verbose" || identifier == "copy_all_inputs" || identifier == "check_input_matrices") + // Only "verbose", "copy_all_inputs" and "check_input_matrices" + // will be persistent. + if (identifier == "verbose" || identifier == "copy_all_inputs" || + identifier == "check_input_matrices") data.persistent = true; else data.persistent = false; From 7d6a2093dd07108f65ff5f76801b8a6736c9f4ee Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 2 Jan 2021 15:05:16 +0530 Subject: [PATCH 417/550] changed function name while wrapping --- src/mlpack/bindings/python/mlpack/io.pxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/bindings/python/mlpack/io.pxd b/src/mlpack/bindings/python/mlpack/io.pxd index 7517c4e4cc..67961d59c9 100644 --- a/src/mlpack/bindings/python/mlpack/io.pxd +++ b/src/mlpack/bindings/python/mlpack/io.pxd @@ -39,7 +39,7 @@ cdef extern from "" namespace "mlpack" nogil: void ClearSettings() nogil except + @staticmethod - void SanityChecks() nogil except + + void CheckInputMatrices() nogil except + cdef extern from "" \ namespace "mlpack::util" nogil: From 2e91fdfc529182cdf04b188b204c151fcbdaea4d Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Sat, 2 Jan 2021 19:41:07 +0530 Subject: [PATCH 418/550] fixing typos --- src/mlpack/tests/feedforward_network_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index acb99a063f..06ca879d98 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -171,8 +171,8 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes */ FFN > *model = new FFN >; - model1->Add >(trainData.n_rows, 8); - model1->Add >(4,false,true,1); + model->Add >(trainData.n_rows, 8); + model->Add >(4,false,true,1); model->Add >(); FFN > *model1 = new FFN >; From 49f53e67f8c18e66a1396f02ec15af605a126f05 Mon Sep 17 00:00:00 2001 From: Ayush Date: Sat, 2 Jan 2021 20:06:53 +0530 Subject: [PATCH 419/550] WeightSize function for multihead_attention, multiply_constant and multiply_merge --- .../methods/ann/layer/multihead_attention.hpp | 3 +++ .../ann/layer/multihead_attention_impl.hpp | 2 +- .../methods/ann/layer/multiply_constant.hpp | 3 +++ src/mlpack/methods/ann/layer/multiply_merge.hpp | 3 +++ src/mlpack/tests/ann_visitor_test.cpp | 16 ++++++++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/multihead_attention.hpp b/src/mlpack/methods/ann/layer/multihead_attention.hpp index ec079d197d..0c2713c0e8 100644 --- a/src/mlpack/methods/ann/layer/multihead_attention.hpp +++ b/src/mlpack/methods/ann/layer/multihead_attention.hpp @@ -120,6 +120,9 @@ class MultiheadAttention const arma::Mat& error, arma::Mat& gradient); + //! Get the size of the weights. + size_t WeightSize() const { return (4 * (embedDim + 1) * embedDim); } + /** * Serialize the layer. */ diff --git a/src/mlpack/methods/ann/layer/multihead_attention_impl.hpp b/src/mlpack/methods/ann/layer/multihead_attention_impl.hpp index d2da8788e9..3d687d93af 100644 --- a/src/mlpack/methods/ann/layer/multihead_attention_impl.hpp +++ b/src/mlpack/methods/ann/layer/multihead_attention_impl.hpp @@ -54,7 +54,7 @@ MultiheadAttention( } headDim = embedDim / numHeads; - weights.set_size(4 * (embedDim + 1) * embedDim, 1); + weights.set_size(WeightSize(), 1); } template MultiheadAttentionLayer = new MultiheadAttention<>(randomtgtSeqLen, + randomsrcSeqLen, randomembedDim, randomnumHeads); + + CheckCorrectnessOfWeightSize(MultiheadAttentionLayer); +} From 777c9ad899b02c3b04ddd476f4c095d821182923 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sun, 3 Jan 2021 00:24:08 +0530 Subject: [PATCH 420/550] Fixed few issues --- .../ann/loss_functions/binary_cross_entropy_loss.hpp | 10 ++++++++++ src/mlpack/tests/ann_layer_test.cpp | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp index 3aa2f6353d..5e0baf0116 100644 --- a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp @@ -105,4 +105,14 @@ class BCELoss // Include implementation. #include "binary_cross_entropy_loss_impl.hpp" +/** + * Adding alias of BCELoss. + */ +template < + typename InputDataType = arma::mat, + typename OutputDataType = arma::mat +> +using CrossEntropyError = BCELoss< + InputDataType, OutputDataType>; + #endif diff --git a/src/mlpack/tests/ann_layer_test.cpp b/src/mlpack/tests/ann_layer_test.cpp index c2dab9f7a0..c10811c084 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -1914,7 +1914,7 @@ TEST_CASE("GradientLookupLayerTest", "[ANNLayerTest]") target(targetWord, i) = 1; } - model = new FFN, GlorotInitialization>(); + model = new FFN, GlorotInitialization>(BCELoss<>(false)); model->Predictors() = input; model->Responses() = target; model->Add >(vocabSize, embeddingSize); From 2be61b05a1473e187e33d768cb890993b27885ad Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sun, 3 Jan 2021 01:23:06 +0530 Subject: [PATCH 421/550] Fixed few issues --- .../ann/loss_functions/binary_cross_entropy_loss.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp index 5e0baf0116..cc114da81f 100644 --- a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss.hpp @@ -99,12 +99,6 @@ class BCELoss bool reduction; }; // class BCELoss -} // namespace ann -} // namespace mlpack - -// Include implementation. -#include "binary_cross_entropy_loss_impl.hpp" - /** * Adding alias of BCELoss. */ @@ -115,4 +109,10 @@ template < using CrossEntropyError = BCELoss< InputDataType, OutputDataType>; +} // namespace ann +} // namespace mlpack + +// Include implementation. +#include "binary_cross_entropy_loss_impl.hpp" + #endif From f1fb7bf0a0445a6afdde15748f0e35fd5ec3c238 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sun, 3 Jan 2021 02:40:15 +0530 Subject: [PATCH 422/550] Fixed few issues --- 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 c10811c084..00ddbed5e7 100644 --- a/src/mlpack/tests/ann_layer_test.cpp +++ b/src/mlpack/tests/ann_layer_test.cpp @@ -1914,7 +1914,7 @@ TEST_CASE("GradientLookupLayerTest", "[ANNLayerTest]") target(targetWord, i) = 1; } - model = new FFN, GlorotInitialization>(BCELoss<>(false)); + model = new FFN, GlorotInitialization>(BCELoss<>(1e-10, false)); model->Predictors() = input; model->Responses() = target; model->Add >(vocabSize, embeddingSize); From 2dd75c45fb993f1e15d228d140150471a2a2980d Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sun, 3 Jan 2021 08:09:22 +0530 Subject: [PATCH 423/550] Fixec backward pass for reduction --- .../ann/loss_functions/binary_cross_entropy_loss_impl.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp index 4992abdc1e..5fc48d5c5a 100644 --- a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp @@ -49,6 +49,8 @@ void BCELoss::Backward( LossType& loss) { loss = (1. - target) / (1. - prediction + eps) - target / (prediction + eps); + if(reduction) + loss /= prediction.n_elem; } template From 46940109b7657a6c8a2eaa53cfbf4810b6cba1c5 Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Mon, 4 Jan 2021 02:02:46 +0530 Subject: [PATCH 424/550] Minor code quality fix --- .../ann/loss_functions/binary_cross_entropy_loss_impl.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp index 5fc48d5c5a..89e7aaf1c2 100644 --- a/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/binary_cross_entropy_loss_impl.hpp @@ -35,8 +35,8 @@ BCELoss::Forward( typedef typename PredictionType::elem_type ElemType; ElemType loss = -arma::accu(target % arma::log(prediction + eps) + - (1. - target) % arma::log(1. - prediction + eps));; - if(reduction) + (1. - target) % arma::log(1. - prediction + eps)); + if (reduction) loss /= prediction.n_elem; return loss; } @@ -49,7 +49,7 @@ void BCELoss::Backward( LossType& loss) { loss = (1. - target) / (1. - prediction + eps) - target / (prediction + eps); - if(reduction) + if (reduction) loss /= prediction.n_elem; } From bc5fc040cbd3daa1f09e2ed11e5eb1834eeb7c52 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 3 Jan 2021 16:50:35 -0500 Subject: [PATCH 425/550] First attempt at a solution. --- src/mlpack/bindings/python/CMakeLists.txt | 10 ++++++++-- src/mlpack/bindings/python/PythonInstall.cmake | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/mlpack/bindings/python/CMakeLists.txt b/src/mlpack/bindings/python/CMakeLists.txt index 65490997c3..c36a026590 100644 --- a/src/mlpack/bindings/python/CMakeLists.txt +++ b/src/mlpack/bindings/python/CMakeLists.txt @@ -214,14 +214,20 @@ add_custom_command(TARGET python POST_BUILD add_dependencies(python python_configured) # Configure installation script file. +if (NOT PYTHON_INSTALL_PREFIX) + set(PYTHON_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +endif () + execute_process(COMMAND ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/print_python_version.py" "${CMAKE_INSTALL_PREFIX}" + "${CMAKE_CURRENT_SOURCE_DIR}/print_python_version.py" + "${PYTHON_INSTALL_PREFIX}" OUTPUT_VARIABLE CMAKE_PYTHON_PATH) string(STRIP "${CMAKE_PYTHON_PATH}" CMAKE_PYTHON_PATH) install(CODE "set(ENV{PYTHONPATH} ${CMAKE_PYTHON_PATH})") install(CODE "set(PYTHON_EXECUTABLE \"${PYTHON_EXECUTABLE}\")") install(CODE "set(CMAKE_BINARY_DIR \"${CMAKE_BINARY_DIR}\")") -install(CODE "set(CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\")") + +install(CODE "set(PYTHON_INSTALL_PREFIX \"${PYTHON_INSTALL_PREFIX}\")") install(CODE "execute_process(COMMAND mkdir -p $ENV{DESTDIR}${CMAKE_PYTHON_PATH})") install(SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/PythonInstall.cmake") diff --git a/src/mlpack/bindings/python/PythonInstall.cmake b/src/mlpack/bindings/python/PythonInstall.cmake index 881b48344a..6e25fb926e 100644 --- a/src/mlpack/bindings/python/PythonInstall.cmake +++ b/src/mlpack/bindings/python/PythonInstall.cmake @@ -5,13 +5,13 @@ if (DEFINED ENV{DESTDIR}) execute_process(COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py" install - --prefix=${CMAKE_INSTALL_PREFIX} --root=$ENV{DESTDIR} + --prefix=${PYTHON_INSTALL_PREFIX} --root=$ENV{DESTDIR} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/" RESULT_VARIABLE setup_res) else () execute_process(COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py" install - --prefix=${CMAKE_INSTALL_PREFIX} + --prefix=${PYTHON_INSTALL_PREFIX} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/" RESULT_VARIABLE setup_res) endif () From c8c7e6594d9abb3411b45e52d4910250084c2bd8 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 3 Jan 2021 20:38:52 -0500 Subject: [PATCH 426/550] Update documentation for new CMake option. --- HISTORY.md | 3 +++ README.md | 1 + doc/guide/build.hpp | 1 + 3 files changed, 5 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 7529a3ee86..9bb5fc29ff 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,9 @@ * Add finalizers to Julia binding model types to fix memory handling (#2756). + * Add `PYTHON_INSTALL_PREFIX` CMake option to specify installation root for + Python bindings. + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. diff --git a/README.md b/README.md index 610e4f6d33..bb8ba1be6c 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,7 @@ Options are specified with the -D flag. The allowed options include: BUILD_CLI_EXECUTABLES=(ON/OFF): whether or not to build command-line programs BUILD_PYTHON_BINDINGS=(ON/OFF): whether or not to build Python bindings PYTHON_EXECUTABLE=(/path/to/python_version): Path to specific Python executable + PYTHON_INSTALL_PREFIX=(/path/to/python/): Path to root of Python installation BUILD_JULIA_BINDINGS=(ON/OFF): whether or not to build Julia bindings JULIA_EXECUTABLE=(/path/to/julia): Path to specific Julia executable BUILD_GO_BINDINGS=(ON/OFF): whether or not to build Go bindings diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index a7b5d149ad..d889652e81 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -190,6 +190,7 @@ The full list of options mlpack allows: - BUILD_WITH_COVERAGE=(ON/OFF): Build with support for code coverage tools (gcc only) (default OFF) - PYTHON_EXECUTABLE=(/path/to/python_version): Path to specific Python executable + - PYTHON_INSTALL_PREFIX=(/path/to/python/): Path to root of Python installation - JULIA_EXECUTABLE=(/path/to/julia): Path to specific Julia executable - BUILD_MARKDOWN_BINDINGS=(ON/OFF): Build Markdown bindings for website documentation (default OFF) From b1b26d1ef8900bddc2bc94c5b96e281779fb882c Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Tue, 5 Jan 2021 18:43:50 +0530 Subject: [PATCH 427/550] Review fixes --- src/mlpack/tests/metric_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/tests/metric_test.cpp b/src/mlpack/tests/metric_test.cpp index 99f12c3ed9..7103c7867f 100644 --- a/src/mlpack/tests/metric_test.cpp +++ b/src/mlpack/tests/metric_test.cpp @@ -163,7 +163,6 @@ TEST_CASE("NMSMetricTest", "[MetricTest]") // Selected indices of bounding boxes using // torchvision.ops.nms(). - desiredIndices = arma::ucolvec(2); desiredIndices = { 0, 2 }; // Evaluate the bounding box. From c3307b2ad91f354e727145d9479563834671ca48 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 5 Jan 2021 13:01:08 -0500 Subject: [PATCH 428/550] Remove use of boost::visitor in NSModel. --- .../methods/neighbor_search/kfn_main.cpp | 4 +- .../methods/neighbor_search/knn_main.cpp | 3 +- .../neighbor_search/neighbor_search.hpp | 13 +- .../methods/neighbor_search/ns_model.hpp | 517 ++++++++------ .../methods/neighbor_search/ns_model_impl.hpp | 651 ++++++++++-------- src/mlpack/tests/aknn_test.cpp | 16 +- src/mlpack/tests/knn_test.cpp | 44 +- 7 files changed, 687 insertions(+), 561 deletions(-) diff --git a/src/mlpack/methods/neighbor_search/kfn_main.cpp b/src/mlpack/methods/neighbor_search/kfn_main.cpp index 73b9dbd64f..65f3083d56 100644 --- a/src/mlpack/methods/neighbor_search/kfn_main.cpp +++ b/src/mlpack/methods/neighbor_search/kfn_main.cpp @@ -237,14 +237,14 @@ static void mlpackMain() kfn->TreeType() = tree; kfn->RandomBasis() = randomBasis; + kfn->LeafSize() = size_t(lsInt); Log::Info << "Using reference data from " << IO::GetPrintableParam("reference") << "." << endl; arma::mat referenceSet = std::move(IO::GetParam("reference")); - kfn->BuildModel(std::move(referenceSet), size_t(lsInt), searchMode, - epsilon); + kfn->BuildModel(std::move(referenceSet), searchMode, epsilon); } else { diff --git a/src/mlpack/methods/neighbor_search/knn_main.cpp b/src/mlpack/methods/neighbor_search/knn_main.cpp index 9f643ecd61..87ca2203b0 100644 --- a/src/mlpack/methods/neighbor_search/knn_main.cpp +++ b/src/mlpack/methods/neighbor_search/knn_main.cpp @@ -261,8 +261,7 @@ static void mlpackMain() arma::mat referenceSet = std::move(IO::GetParam("reference")); - knn->BuildModel(std::move(referenceSet), size_t(lsInt), searchMode, - epsilon); + knn->BuildModel(std::move(referenceSet), searchMode, epsilon); } else { diff --git a/src/mlpack/methods/neighbor_search/neighbor_search.hpp b/src/mlpack/methods/neighbor_search/neighbor_search.hpp index 1475970af6..2476e0484a 100644 --- a/src/mlpack/methods/neighbor_search/neighbor_search.hpp +++ b/src/mlpack/methods/neighbor_search/neighbor_search.hpp @@ -31,8 +31,13 @@ namespace mlpack { namespace neighbor { // Forward declaration. -template -class TrainVisitor; +template class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +class LeafSizeNSWrapper; //! NeighborSearchMode represents the different neighbor search modes available. enum NeighborSearchMode @@ -359,8 +364,8 @@ class NeighborSearch bool treeNeedsReset; //! The NSModel class should have access to internal members. - template - friend class TrainVisitor; + friend class LeafSizeNSWrapper; }; // class NeighborSearch } // namespace neighbor diff --git a/src/mlpack/methods/neighbor_search/ns_model.hpp b/src/mlpack/methods/neighbor_search/ns_model.hpp index 981d0f9be9..c88b6226cd 100644 --- a/src/mlpack/methods/neighbor_search/ns_model.hpp +++ b/src/mlpack/methods/neighbor_search/ns_model.hpp @@ -4,8 +4,9 @@ * * This is a model for nearest or furthest neighbor search. It is useful in * that it provides an easy way to serialize a model, abstracts away the - * different types of trees, and also reflects the NeighborSearch API and - * automatically directs to the right tree type. + * different types of trees, and also (roughly) reflects the NeighborSearch API and + * automatically directs to the right tree type. It is meant to be used by the + * knn and kfn bindings. * * 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 @@ -20,218 +21,302 @@ #include #include #include -#include #include "neighbor_search.hpp" namespace mlpack { namespace neighbor { /** - * Alias template for euclidean neighbor search. + * NSWrapperBase is a base wrapper class for holding all NeighborSearch types + * supported by NSModel. All NeighborSearch type wrappers inherit from this + * class, allowing a simple interface via inheritance for all the different + * types we want to support. + */ +class NSWrapperBase +{ + public: + //! Create the NSWrapperBase object. The base class does not hold anything, + //! so this constructor does not do anything. + NSWrapperBase() { } + + //! Create a new NSWrapperBase that is the same as this one. This function + //! will properly handle polymorphism. + virtual NSWrapperBase* Clone() const = 0; + + //! Destruct the NSWrapperBase (nothing to do). + virtual ~NSWrapperBase() { }; + + //! Return a reference to the dataset. + virtual const arma::mat& Dataset() const = 0; + + //! Get the search mode. + virtual NeighborSearchMode SearchMode() const = 0; + //! Modify the search modem + virtual NeighborSearchMode& SearchMode() = 0; + + //! Get the approximation parameter epsilon. + virtual double Epsilon() const = 0; + //! Modify the approximation parameter epsilon. + virtual double& Epsilon() = 0; + + //! Train the NeighborSearch model with the given parameters. + virtual void Train(arma::mat&& referenceSet, + const size_t leafSize, + const double tau, + const double rho) = 0; + + //! Perform bichromatic neighbor search (i.e. search with a separate query + //! set). + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize, + const double rho) = 0; + + //! Perform monochromatic neighbor search (i.e. use the reference set as the + //! query set). + virtual void Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances) = 0; +}; + +/** + * NSWrapper is a wrapper class for most NeighborSearch types. */ template class TreeType> -using NSType = NeighborSearch, - arma::mat>::template DualTreeTraverser>; - -/** - * MonoSearchVisitor executes a monochromatic neighbor search on the given - * NSType. We don't make any difference for different instantiations of NSType. - */ -class MonoSearchVisitor : public boost::static_visitor + typename TreeMatType> class TreeType, + template class DualTreeTraversalType = + TreeType, + arma::mat>::template DualTreeTraverser, + template class SingleTreeTraversalType = + TreeType, + arma::mat>::template SingleTreeTraverser> +class NSWrapper : public NSWrapperBase { - private: - //! Number of neighbors to search for. - const size_t k; - //! Result matrix for neighbors. - arma::Mat& neighbors; - //! Result matrix for distances. - arma::mat& distances; - public: - //! Perform monochromatic nearest neighbor search. - template - void operator()(NSType* ns) const; + //! Construct the NSWrapper object, initializing the internally-held + //! NeighborSearch object. + NSWrapper(const NeighborSearchMode searchMode, + const double epsilon) : + ns(searchMode, epsilon) + { + // Nothing else to do. + } - //! Construct the MonoSearchVisitor object with the given parameters. - MonoSearchVisitor(const size_t k, - arma::Mat& neighbors, - arma::mat& distances) : - k(k), - neighbors(neighbors), - distances(distances) - {}; + //! Delete the NSWrapper object. + virtual ~NSWrapper() { } + + //! Create a copy of this NSWrapper object. This correctly handles + //! polymorphism. + virtual NSWrapper* Clone() const { return new NSWrapper(*this); } + + //! Get a reference to the reference set. + const arma::mat& Dataset() const { return ns.ReferenceSet(); } + + //! Get the search mode. + NeighborSearchMode SearchMode() const { return ns.SearchMode(); } + //! Modify the search mode. + NeighborSearchMode& SearchMode() { return ns.SearchMode(); } + + //! Get epsilon, the approximation parameter. + double Epsilon() const { return ns.Epsilon(); } + //! Modify epsilon, the approximation parameter. + double& Epsilon() { return ns.Epsilon(); } + + //! Train the model with the given options. For NSWrapper, we ignore the + //! extra parameters. + virtual void Train(arma::mat&& referenceSet, + const size_t /* leafSize */, + const double /* tau */, + const double /* rho */); + + //! Perform bichromatic neighbor search (i.e. search with a separate query + //! set). For NSWrapper, we ignore the extra parameters. + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t /* leafSize */, + const double /* rho */); + + //! Perform monochromatic neighbor search (i.e. use the reference set as the + //! query set). + virtual void Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances); + + //! Serialize the NeighborSearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(ns)); + } + + protected: + // Convenience typedef for the neighbor search type held by this class. + typedef NeighborSearch NSType; + + //! The instantiated NeighborSearch object that we are wrapping. + NSType ns; }; /** - * BiSearchVisitor executes a bichromatic neighbor search on the given NSType. - * We use template specialization to differentiate those tree types that - * accept leafSize as a parameter. In these cases, before doing neighbor search, - * a query tree with proper leafSize is built from the querySet. + * LeafSizeNSWrapper wraps any NeighborSearch types that take a leaf size for + * tree construction. The implementations of Train() and Search() take the leaf + * size into account. + */ +template class TreeType, + template class DualTreeTraversalType = + TreeType, + arma::mat>::template DualTreeTraverser, + template class SingleTreeTraversalType = + TreeType, + arma::mat>::template SingleTreeTraverser> +class LeafSizeNSWrapper : + public NSWrapper +{ + public: + //! Construct the LeafSizeNSWrapper by delegating to the NSWrapper + //! constructor. + LeafSizeNSWrapper(const NeighborSearchMode searchMode, + const double epsilon) : + NSWrapper(searchMode, epsilon) + { + // Nothing to do. + } + + //! Delete the LeafSizeNSWrapper. + virtual ~LeafSizeNSWrapper() { } + + //! Return a copy of the LeafSizeNSWrapper. + virtual LeafSizeNSWrapper* Clone() const + { + return new LeafSizeNSWrapper(*this); + } + + //! Train a model with the given parameters. This overload uses leafSize but + //! ignores the other parameters. + virtual void Train(arma::mat&& referenceSet, + const size_t leafSize, + const double /* tau */, + const double /* rho */); + + //! Perform bichromatic search (e.g. search with a separate query set). This + //! overload uses the leaf size, but ignores the other parameters. + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize, + const double /* rho */); + + //! Serialize the NeighborSearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(ns)); + } + + protected: + using NSWrapper::ns; +}; + +/** + * The SpillNSWrapper class wraps the NeighborSearch class when the spill tree + * is used. */ template -class BiSearchVisitor : public boost::static_visitor -{ - private: - //! The query set for the bichromatic search. - const arma::mat& querySet; - //! The number of neighbors to search for. - const size_t k; - //! The result matrix for neighbors. - arma::Mat& neighbors; - //! The result matrix for distances. - arma::mat& distances; - //! The number of points in a leaf (for BinarySpaceTrees). - const size_t leafSize; - //! Overlapping size (for spill trees). - const double tau; - //! Balance threshold (for spill trees). - const double rho; - - //! Bichromatic neighbor search on the given NSType considering the leafSize. - template - void SearchLeaf(NSType* ns) const; - - public: - //! Alias template necessary for visual c++ compiler. - template class TreeType> - using NSTypeT = NSType; - - //! Default Bichromatic neighbor search on the given NSType instance. - template class TreeType> - void operator()(NSTypeT* ns) const; - - //! Bichromatic neighbor search on the given NSType specialized for KDTrees. - void operator()(NSTypeT* ns) const; - - //! Bichromatic neighbor search on the given NSType specialized for BallTrees. - void operator()(NSTypeT* ns) const; - - //! Bichromatic neighbor search specialized for SPTrees. - void operator()(SpillKNN* ns) const; - - //! Bichromatic neighbor search specialized for octrees. - void operator()(NSTypeT* ns) const; - - //! Construct the BiSearchVisitor. - BiSearchVisitor(const arma::mat& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, - const size_t leafSize, - const double tau, - const double rho); -}; - -/** - * TrainVisitor sets the reference set to a new reference set on the given - * NSType. We use template specialization to differentiate those tree types that - * accept leafSize as a parameter. In these cases, a reference tree with proper - * leafSize is built from the referenceSet. - */ -template -class TrainVisitor : public boost::static_visitor -{ - private: - //! The reference set to use for training. - arma::mat&& referenceSet; - //! The leaf size, used only by BinarySpaceTree. - size_t leafSize; - //! Overlapping size (for spill trees). - const double tau; - //! Balance threshold (for spill trees). - const double rho; - - //! Train on the given NSType considering the leafSize. - template - void TrainLeaf(NSType* ns) const; - - public: - //! Alias template necessary for visual c++ compiler. - template class TreeType> - using NSTypeT = NSType; - - //! Default Train on the given NSType instance. - template class TreeType> - void operator()(NSTypeT* ns) const; - - //! Train on the given NSType specialized for KDTrees. - void operator()(NSTypeT* ns) const; - - //! Train on the given NSType specialized for BallTrees. - void operator()(NSTypeT* ns) const; - - //! Train specialized for SPTrees. - void operator()(SpillKNN* ns) const; - - //! Train specialized for octrees. - void operator()(NSTypeT* ns) const; - - //! Construct the TrainVisitor object with the given reference set, leafSize - //! for BinarySpaceTrees, and tau and rho for spill trees. - TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize, - const double tau, - const double rho); -}; - -/** - * SearchModeVisitor exposes the SearchMode() method of the given NSType. - */ -class SearchModeVisitor : public boost::static_visitor +class SpillNSWrapper : + public NSWrapper< + SortPolicy, + tree::SPTree, + tree::SPTree, + arma::mat>::template DefeatistDualTreeTraverser, + tree::SPTree, + arma::mat>::template DefeatistSingleTreeTraverser> { public: - //! Return the search mode. - template - NeighborSearchMode& operator()(NSType* ns) const; -}; + //! Construct the SpillNSWrapper. + SpillNSWrapper(const NeighborSearchMode searchMode, + const double epsilon) : + NSWrapper< + SortPolicy, + tree::SPTree, + tree::SPTree, + arma::mat>::template DefeatistDualTreeTraverser, + tree::SPTree, + arma::mat>::template DefeatistSingleTreeTraverser>( + searchMode, epsilon) + { + // Nothing to do. + } -/** - * EpsilonVisitor exposes the Epsilon method of the given NSType. - */ -class EpsilonVisitor : public boost::static_visitor -{ - public: - //! Return epsilon, the approximation parameter. - template - double& operator()(NSType *ns) const; -}; + //! Destruct the SpillNSWrapper. + virtual ~SpillNSWrapper() { } -/** - * ReferenceSetVisitor exposes the referenceSet of the given NSType. - */ -class ReferenceSetVisitor : public boost::static_visitor -{ - public: - //! Return the reference set. - template - const arma::mat& operator()(NSType *ns) const; -}; + //! Return a copy of the SpillNSWrapper. + virtual SpillNSWrapper* Clone() const { return new SpillNSWrapper(*this); } -/** - * DeleteVisitor deletes the given NSType instance. - */ -class DeleteVisitor : public boost::static_visitor -{ - public: - //! Delete the NSType object. - template - void operator()(NSType *ns) const; + //! Train the model using the given parameters. + virtual void Train(arma::mat&& referenceSet, + const size_t leafSize, + const double tau, + const double rho); + + //! Perform bichromatic search (i.e. search with a different query set) using + //! the given parameters. + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize, + const double rho); + + //! Serialize the NeighborSearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(ns)); + } + + protected: + using NSWrapper< + SortPolicy, + tree::SPTree, + tree::SPTree, + arma::mat>::template DefeatistDualTreeTraverser, + tree::SPTree, + arma::mat>::template DefeatistSingleTreeTraverser>::ns; }; /** @@ -272,39 +357,20 @@ class NSModel //! Tree type considered for neighbor search. TreeTypes treeType; - //! For tree types that accept the maxLeafSize parameter. - size_t leafSize; - - //! Overlapping size (for spill trees). - double tau; - //! Balance threshold (for spill trees). - double rho; - //! If true, random projections are used. bool randomBasis; //! This is the random projection matrix; only used if randomBasis is true. arma::mat q; + size_t leafSize; + double tau; + double rho; + /** - * nSearch holds an instance of the NeigborSearch class for the current + * nSearch holds an instance of the NeighborSearch class for the current * treeType. It is initialized every time BuildModel is executed. - * We access to the contained value through the visitor classes defined above. */ - boost::variant*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - NSType*, - SpillKNN*, - NSType*, - NSType*> nSearch; + NSWrapperBase* nSearch; public: /** @@ -359,22 +425,22 @@ class NSModel NeighborSearchMode SearchMode() const; NeighborSearchMode& SearchMode(); - //! Expose Epsilon. - double Epsilon() const; - double& Epsilon(); - - //! Expose leafSize. + //! Expose LeafSize. size_t LeafSize() const { return leafSize; } size_t& LeafSize() { return leafSize; } - //! Expose tau. + //! Expose Tau. double Tau() const { return tau; } double& Tau() { return tau; } - //! Expose rho. + //! Expose Rho. double Rho() const { return rho; } double& Rho() { return rho; } + //! Expose Epsilon. + double Epsilon() const; + double& Epsilon(); + //! Expose treeType. TreeTypes TreeType() const { return treeType; } TreeTypes& TreeType() { return treeType; } @@ -383,9 +449,12 @@ class NSModel bool RandomBasis() const { return randomBasis; } bool& RandomBasis() { return randomBasis; } + //! Initialize the model type. (This does not perform any training.) + void InitializeModel(const NeighborSearchMode searchMode, + const double epsilon); + //! Build the reference tree. void BuildModel(arma::mat&& referenceSet, - const size_t leafSize, const NeighborSearchMode searchMode, const double epsilon = 0); diff --git a/src/mlpack/methods/neighbor_search/ns_model_impl.hpp b/src/mlpack/methods/neighbor_search/ns_model_impl.hpp index 8c90aa9ec8..319fb652af 100644 --- a/src/mlpack/methods/neighbor_search/ns_model_impl.hpp +++ b/src/mlpack/methods/neighbor_search/ns_model_impl.hpp @@ -21,107 +21,121 @@ namespace mlpack { namespace neighbor { -//! Monochromatic neighbor search on the given NSType instance. -template -void MonoSearchVisitor::operator()(NSType *ns) const -{ - if (ns) - return ns->Search(k, neighbors, distances); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Save parameters for bichromatic neighbor search. -template -BiSearchVisitor::BiSearchVisitor(const arma::mat& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, - const size_t leafSize, - const double tau, - const double rho) : - querySet(querySet), - k(k), - neighbors(neighbors), - distances(distances), - leafSize(leafSize), - tau(tau), - rho(rho) -{} - -//! Default Bichromatic neighbor search on the given NSType instance. -template -template class TreeType> -void BiSearchVisitor::operator()(NSTypeT* ns) const + typename TreeMatType> class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +void NSWrapper< + SortPolicy, TreeType, DualTreeTraversalType, SingleTreeTraversalType +>::Train(arma::mat&& referenceSet, + const size_t /* leafSize */, + const double /* tau */, + const double /* rho */) { - if (ns) - return ns->Search(querySet, k, neighbors, distances); - throw std::runtime_error("no neighbor search model initialized"); + ns.Train(std::move(referenceSet)); } -//! Bichromatic neighbor search on the given NSType specialized for KDTrees. -template -void BiSearchVisitor::operator()(NSTypeT* ns) const +//! Perform bichromatic neighbor search (i.e. search with a separate query +//! set). For NSWrapper, we ignore the extra parameters. +template class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +void NSWrapper< + SortPolicy, TreeType, DualTreeTraversalType, SingleTreeTraversalType +>::Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t /* leafSize */, + const double /* rho */) { - if (ns) - return SearchLeaf(ns); - throw std::runtime_error("no neighbor search model initialized"); + ns.Search(std::move(querySet), k, neighbors, distances); } -//! Bichromatic neighbor search on the given NSType specialized for BallTrees. -template -void BiSearchVisitor::operator()(NSTypeT* ns) const +//! Perform monochromatic neighbor search (i.e. use the reference set as the +//! query set). +template class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +void NSWrapper< + SortPolicy, TreeType, DualTreeTraversalType, SingleTreeTraversalType +>::Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances) { - if (ns) - return SearchLeaf(ns); - throw std::runtime_error("no neighbor search model initialized"); + ns.Search(k, neighbors, distances); } -//! Bichromatic neighbor search specialized for SPTrees. -template -void BiSearchVisitor::operator()(SpillKNN* ns) const +//! Train a model with the given parameters. This overload uses leafSize but +//! ignores the other parameters. +template class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +void LeafSizeNSWrapper< + SortPolicy, TreeType, DualTreeTraversalType, SingleTreeTraversalType +>::Train(arma::mat&& referenceSet, + const size_t leafSize, + const double /* tau */, + const double /* rho */) { - if (ns) + if (ns.SearchMode() == NAIVE_MODE) { - if (ns->SearchMode() == DUAL_TREE_MODE) - { - // For Dual Tree Search on SpillTrees, the queryTree must be built with - // non overlapping (tau = 0). - typename SpillKNN::Tree queryTree(std::move(querySet), 0 /* tau*/, - leafSize, rho); - ns->Search(queryTree, k, neighbors, distances); - } - else - ns->Search(querySet, k, neighbors, distances); + ns.Train(std::move(referenceSet)); } else - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Bichromatic neighbor search specialized for octrees. -template -void BiSearchVisitor::operator()(NSTypeT* ns) const -{ - if (ns) - return SearchLeaf(ns); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Bichromatic neighbor search on the given NSType considering the leafSize. -template -template -void BiSearchVisitor::SearchLeaf(NSType* ns) const -{ - if (ns->SearchMode() == DUAL_TREE_MODE) { + // Build the tree with the specified leaf size. + std::vector oldFromNewReferences; + typename decltype(ns)::Tree referenceTree(std::move(referenceSet), + oldFromNewReferences, leafSize); + ns.Train(std::move(referenceTree)); + ns.oldFromNewReferences = std::move(oldFromNewReferences); + } +} + +//! Perform bichromatic search (e.g. search with a separate query set). This +//! overload uses the leaf size, but ignores the other parameters. +template class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +void LeafSizeNSWrapper< + SortPolicy, TreeType, DualTreeTraversalType, SingleTreeTraversalType +>::Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize, + const double /* rho */) +{ + if (ns.SearchMode() == DUAL_TREE_MODE) + { + // We actually have to do the mapping of query points ourselves, since the + // NeighborSearch class does not provide a way for us to specify the leaf + // size when building the query tree. (Therefore we must also build the + // query tree manually.) std::vector oldFromNewQueries; - typename NSType::Tree queryTree(std::move(querySet), oldFromNewQueries, - leafSize); + typename decltype(ns)::Tree queryTree(std::move(querySet), + oldFromNewQueries, leafSize); arma::Mat neighborsOut; arma::mat distancesOut; - ns->Search(queryTree, k, neighborsOut, distancesOut); + ns.Search(queryTree, k, neighborsOut, distancesOut); // Unmap the query points. distances.set_size(distancesOut.n_rows, distancesOut.n_cols); @@ -133,131 +147,47 @@ void BiSearchVisitor::SearchLeaf(NSType* ns) const } } else - ns->Search(querySet, k, neighbors, distances); + { + ns.Search(querySet, k, neighbors, distances); + } } -//! Save parameters for Train. +//! Train the model using the given parameters. template -TrainVisitor::TrainVisitor(arma::mat&& referenceSet, +void SpillNSWrapper::Train(arma::mat&& referenceSet, const size_t leafSize, const double tau, - const double rho) : - referenceSet(std::move(referenceSet)), - leafSize(leafSize), - tau(tau), - rho(rho) -{} - -//! Default Train on the given NSType instance. -template -template class TreeType> -void TrainVisitor::operator()(NSTypeT* ns) const + const double rho) { - if (ns) - return ns->Train(std::move(referenceSet)); - throw std::runtime_error("no neighbor search model initialized"); + typename decltype(ns)::Tree tree(std::move(referenceSet), tau, leafSize, + rho); + ns.Train(std::move(tree)); } -//! Train on the given NSType specialized for KDTrees. +//! Perform bichromatic search (i.e. search with a different query set) using +//! the given parameters. template -void TrainVisitor::operator()(NSTypeT* ns) const +void SpillNSWrapper::Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize, + const double rho) { - if (ns) - return TrainLeaf(ns); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Train on the given NSType specialized for BallTrees. -template -void TrainVisitor::operator()(NSTypeT* ns) const -{ - if (ns) - return TrainLeaf(ns); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Train specialized for SPTrees. -template -void TrainVisitor::operator()(SpillKNN* ns) const -{ - if (ns) + if (ns.SearchMode() == DUAL_TREE_MODE) { - if (ns->SearchMode() == NAIVE_MODE) - ns->Train(std::move(referenceSet)); - else - { - typename SpillKNN::Tree tree(std::move(referenceSet), tau, leafSize, rho); - ns->Train(std::move(tree)); - } + // For Dual Tree Search on SpillTrees, the queryTree must be built with + // non overlapping (tau = 0). + typename decltype(ns)::Tree queryTree(std::move(querySet), 0 /* tau */, + leafSize, rho); + ns.Search(queryTree, k, neighbors, distances); } - else - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Train specialized for Octrees. -template -void TrainVisitor::operator()(NSTypeT* ns) const -{ - if (ns) - return TrainLeaf(ns); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Train on the given NSType considering the leafSize. -template -template -void TrainVisitor::TrainLeaf(NSType* ns) const -{ - if (ns->SearchMode() == NAIVE_MODE) - ns->Train(std::move(referenceSet)); else { - std::vector oldFromNewReferences; - typename NSType::Tree referenceTree(std::move(referenceSet), - oldFromNewReferences, leafSize); - ns->Train(std::move(referenceTree)); - // Set the mappings. - ns->oldFromNewReferences = std::move(oldFromNewReferences); + ns.Search(querySet, k, neighbors, distances); } } -//! Return the search mode. -template -NeighborSearchMode& SearchModeVisitor::operator()(NSType* ns) const -{ - if (ns) - return ns->SearchMode(); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Expose the Epsilon method of the given NSType. -template -double& EpsilonVisitor::operator()(NSType* ns) const -{ - if (ns) - return ns->Epsilon(); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Expose the referenceSet of the given NSType. -template -const arma::mat& ReferenceSetVisitor::operator()(NSType* ns) const -{ - if (ns) - return ns->ReferenceSet(); - throw std::runtime_error("no neighbor search model initialized"); -} - -//! Clean memory, if necessary. -template -void DeleteVisitor::operator()(NSType* ns) const -{ - if (ns) - delete ns; -} - /** * Initialize the NSModel with the given type and whether or not a random * basis should be used. @@ -265,10 +195,11 @@ void DeleteVisitor::operator()(NSType* ns) const template NSModel::NSModel(TreeTypes treeType, bool randomBasis) : treeType(treeType), + randomBasis(randomBasis), leafSize(20), - tau(0), + tau(0.0), rho(0.7), - randomBasis(randomBasis) + nSearch(NULL) { // Nothing to do. } @@ -276,12 +207,12 @@ NSModel::NSModel(TreeTypes treeType, bool randomBasis) : template NSModel::NSModel(const NSModel& other) : treeType(other.treeType), + randomBasis(other.randomBasis), + q(other.q), leafSize(other.leafSize), tau(other.tau), rho(other.rho), - randomBasis(other.randomBasis), - q(other.q), - nSearch(other.nSearch) + nSearch(other.nSearch->Clone()) { // Nothing to do. } @@ -289,34 +220,37 @@ NSModel::NSModel(const NSModel& other) : template NSModel::NSModel(NSModel&& other) : treeType(other.treeType), + randomBasis(other.randomBasis), + q(std::move(other.q)), leafSize(other.leafSize), tau(other.tau), rho(other.rho), - randomBasis(other.randomBasis), - q(std::move(other.q)), nSearch(other.nSearch) { // Reset parameters of the other model. other.treeType = TreeTypes::KD_TREE; - other.leafSize = 20; - other.tau = 0; - other.rho = 0.7; other.randomBasis = false; - other.nSearch = decltype(other.nSearch)(); + other.leafSize = 20; + other.tau = 0.0; + other.rho = 0.7; + other.nSearch = NULL; } template NSModel& NSModel::operator=(const NSModel& other) { - boost::apply_visitor(DeleteVisitor(), nSearch); + if (this != &other) + { + delete nSearch; - treeType = other.treeType; - leafSize = other.leafSize; - tau = other.tau; - rho = other.rho; - randomBasis = other.randomBasis; - q = other.q; - nSearch = other.nSearch; + treeType = other.treeType; + randomBasis = other.randomBasis; + q = other.q; + leafSize = other.leafSize; + tau = other.tau; + rho = other.rho; + nSearch = other.nSearch->Clone(); + } return *this; } @@ -324,24 +258,26 @@ NSModel& NSModel::operator=(const NSModel& other) template NSModel& NSModel::operator=(NSModel&& other) { - boost::apply_visitor(DeleteVisitor(), nSearch); + if (this != &other) + { + delete nSearch; - treeType = other.treeType; - leafSize = other.leafSize; - tau = other.tau; - rho = other.rho; - randomBasis = other.randomBasis; - q = std::move(other.q); - // Copy the pointer and type. - nSearch = other.nSearch; + treeType = other.treeType; + randomBasis = other.randomBasis; + q = std::move(other.q); + leafSize = other.leafSize; + tau = other.tau; + rho = other.rho; + nSearch = other.nSearch; - // Reset parameters of the other model. - other.treeType = TreeTypes::KD_TREE; - other.leafSize = 20; - other.tau = 0; - other.rho = 0.7; - other.randomBasis = false; - other.nSearch = decltype(other.nSearch)(); + // Reset parameters of the other model. + other.treeType = TreeTypes::KD_TREE; + other.randomBasis = false; + other.leafSize = 20; + other.tau = 0.0; + other.rho = 0.7; + other.nSearch = NULL; + } return *this; } @@ -350,7 +286,7 @@ NSModel& NSModel::operator=(NSModel&& other) template NSModel::~NSModel() { - boost::apply_visitor(DeleteVisitor(), nSearch); + delete nSearch; } //! Serialize the kNN model. @@ -359,60 +295,236 @@ template void NSModel::serialize(Archive& ar, const uint32_t /* version */) { ar(CEREAL_NVP(treeType)); + ar(CEREAL_NVP(randomBasis)); + ar(CEREAL_NVP(q)); ar(CEREAL_NVP(leafSize)); ar(CEREAL_NVP(tau)); ar(CEREAL_NVP(rho)); - ar(CEREAL_NVP(randomBasis)); - ar(CEREAL_NVP(q)); // This should never happen, but just in case, be clean with memory. if (cereal::is_loading()) - boost::apply_visitor(DeleteVisitor(), nSearch); + InitializeModel(DUAL_TREE_MODE, 0.0); // Values will be overwritten. - ar(CEREAL_VARIANT_POINTER(nSearch)); + // Avoid polymorphic serialization by explicitly serializing the correct type. + switch (treeType) + { + case KD_TREE: + { + LeafSizeNSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case COVER_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case R_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case R_STAR_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case BALL_TREE: + { + LeafSizeNSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case X_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case HILBERT_R_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case R_PLUS_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case R_PLUS_PLUS_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case SPILL_TREE: + { + SpillNSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case VP_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case RP_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case MAX_RP_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case UB_TREE: + { + NSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case OCTREE: + { + LeafSizeNSWrapper& typedSearch = + dynamic_cast&>(*nSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + } } //! Expose the dataset. template const arma::mat& NSModel::Dataset() const { - return boost::apply_visitor(ReferenceSetVisitor(), nSearch); + return nSearch->Dataset(); } //! Access the search mode. template NeighborSearchMode NSModel::SearchMode() const { - return boost::apply_visitor(SearchModeVisitor(), nSearch); + return nSearch->SearchMode(); } //! Modify the search mode. template NeighborSearchMode& NSModel::SearchMode() { - return boost::apply_visitor(SearchModeVisitor(), nSearch); + return nSearch->SearchMode(); } template double NSModel::Epsilon() const { - return boost::apply_visitor(EpsilonVisitor(), nSearch); + return nSearch->Epsilon(); } template double& NSModel::Epsilon() { - return boost::apply_visitor(EpsilonVisitor(), nSearch); + return nSearch->Epsilon(); +} + +//! Initialize a model given the tree type. (No training happens here.) +template +void NSModel::InitializeModel(const NeighborSearchMode searchMode, + const double epsilon) +{ + // Clear existing memory. + if (nSearch) + delete nSearch; + + switch (treeType) + { + case KD_TREE: + nSearch = new LeafSizeNSWrapper(searchMode, + epsilon); + break; + case COVER_TREE: + nSearch = new NSWrapper(searchMode, + epsilon); + break; + case R_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case R_STAR_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case BALL_TREE: + nSearch = new LeafSizeNSWrapper(searchMode, + epsilon); + break; + case X_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case HILBERT_R_TREE: + nSearch = new NSWrapper(searchMode, + epsilon); + break; + case R_PLUS_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case R_PLUS_PLUS_TREE: + nSearch = new NSWrapper(searchMode, + epsilon); + break; + case VP_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case RP_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case MAX_RP_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case SPILL_TREE: + nSearch = new SpillNSWrapper(searchMode, epsilon); + break; + case UB_TREE: + nSearch = new NSWrapper(searchMode, epsilon); + break; + case OCTREE: + nSearch = new LeafSizeNSWrapper(searchMode, + epsilon); + break; + } + } //! Build the reference tree. template void NSModel::BuildModel(arma::mat&& referenceSet, - const size_t leafSize, const NeighborSearchMode searchMode, const double epsilon) { - this->leafSize = leafSize; // Initialize random basis if necessary. if (randomBasis) { @@ -445,9 +557,6 @@ void NSModel::BuildModel(arma::mat&& referenceSet, } } - // Clean memory, if necessary. - boost::apply_visitor(DeleteVisitor(), nSearch); - // Do we need to modify the reference set? if (randomBasis) referenceSet = q * referenceSet; @@ -458,59 +567,8 @@ void NSModel::BuildModel(arma::mat&& referenceSet, Log::Info << "Building reference tree..." << std::endl; } - switch (treeType) - { - case KD_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case COVER_TREE: - nSearch = new NSType(searchMode, - epsilon); - break; - case R_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case R_STAR_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case BALL_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case X_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case HILBERT_R_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case R_PLUS_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case R_PLUS_PLUS_TREE: - nSearch = new NSType(searchMode, - epsilon); - break; - case VP_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case RP_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case MAX_RP_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case SPILL_TREE: - nSearch = new SpillKNN(searchMode, epsilon); - break; - case UB_TREE: - nSearch = new NSType(searchMode, epsilon); - break; - case OCTREE: - nSearch = new NSType(searchMode, epsilon); - break; - } - - TrainVisitor tn(std::move(referenceSet), leafSize, tau, rho); - boost::apply_visitor(tn, nSearch); + InitializeModel(searchMode, epsilon); + nSearch->Train(std::move(referenceSet), leafSize, tau, rho); if (searchMode != NAIVE_MODE) { @@ -549,9 +607,7 @@ void NSModel::Search(arma::mat&& querySet, break; } - BiSearchVisitor search(querySet, k, neighbors, distances, - leafSize, tau, rho); - boost::apply_visitor(search, nSearch); + nSearch->Search(std::move(querySet), k, neighbors, distances, leafSize, rho); } //! Perform neighbor search. @@ -583,8 +639,7 @@ void NSModel::Search(const size_t k, Log::Info << "Maximum of " << Epsilon() * 100 << "% relative error." << std::endl; - MonoSearchVisitor search(k, neighbors, distances); - boost::apply_visitor(search, nSearch); + nSearch->Search(k, neighbors, distances); } //! Get the name of the tree type. diff --git a/src/mlpack/tests/aknn_test.cpp b/src/mlpack/tests/aknn_test.cpp index 37b5e820da..9358b57de7 100644 --- a/src/mlpack/tests/aknn_test.cpp +++ b/src/mlpack/tests/aknn_test.cpp @@ -370,14 +370,13 @@ TEST_CASE("AKNNModelTest", "[AKNNTest]") // We only have std::move() constructors so make a copy of our data. arma::mat referenceCopy(referenceData); arma::mat queryCopy(queryData); + models[i].LeafSize() = 20; if (j == 0) - models[i].BuildModel(std::move(referenceCopy), 20, DUAL_TREE_MODE, - 0.05); + models[i].BuildModel(std::move(referenceCopy), DUAL_TREE_MODE, 0.05); if (j == 1) - models[i].BuildModel(std::move(referenceCopy), 20, - SINGLE_TREE_MODE, 0.05); + models[i].BuildModel(std::move(referenceCopy), SINGLE_TREE_MODE, 0.05); if (j == 2) - models[i].BuildModel(std::move(referenceCopy), 20, NAIVE_MODE); + models[i].BuildModel(std::move(referenceCopy), NAIVE_MODE); arma::Mat neighborsApprox; arma::mat distancesApprox; @@ -448,12 +447,11 @@ TEST_CASE("AKNNModelMonochromaticTest", "[AKNNTest]") { // We only have a std::move() constructor... so copy the data. arma::mat referenceCopy(referenceData); + models[i].LeafSize() = 20; if (j == 0) - models[i].BuildModel(std::move(referenceCopy), 20, DUAL_TREE_MODE, - 0.05); + models[i].BuildModel(std::move(referenceCopy), DUAL_TREE_MODE, 0.05); if (j == 1) - models[i].BuildModel(std::move(referenceCopy), 20, - SINGLE_TREE_MODE, 0.05); + models[i].BuildModel(std::move(referenceCopy), SINGLE_TREE_MODE, 0.05); arma::Mat neighborsApprox; arma::mat distancesApprox; diff --git a/src/mlpack/tests/knn_test.cpp b/src/mlpack/tests/knn_test.cpp index 7e84700843..31f1daf056 100644 --- a/src/mlpack/tests/knn_test.cpp +++ b/src/mlpack/tests/knn_test.cpp @@ -1112,28 +1112,28 @@ TEST_CASE("KNNModelTest", "[KNNTest]") // We only have std::move() constructors so make a copy of our data. arma::mat referenceCopy(referenceData); arma::mat queryCopy(queryData); + models[i].LeafSize() = 20; if (j == 0) - models[i].BuildModel(std::move(referenceCopy), 20, DUAL_TREE_MODE); + models[i].BuildModel(std::move(referenceCopy), DUAL_TREE_MODE); if (j == 1) - models[i].BuildModel(std::move(referenceCopy), 20, - SINGLE_TREE_MODE); + models[i].BuildModel(std::move(referenceCopy), SINGLE_TREE_MODE); if (j == 2) - models[i].BuildModel(std::move(referenceCopy), 20, NAIVE_MODE); + models[i].BuildModel(std::move(referenceCopy), NAIVE_MODE); arma::Mat neighbors; arma::mat distances; models[i].Search(std::move(queryCopy), 3, neighbors, distances); - REQUIRE(neighbors.n_rows ==baselineNeighbors.n_rows); - REQUIRE(neighbors.n_cols ==baselineNeighbors.n_cols); - REQUIRE(neighbors.n_elem ==baselineNeighbors.n_elem); - REQUIRE(distances.n_rows ==baselineDistances.n_rows); - REQUIRE(distances.n_cols ==baselineDistances.n_cols); - REQUIRE(distances.n_elem ==baselineDistances.n_elem); + REQUIRE(neighbors.n_rows == baselineNeighbors.n_rows); + REQUIRE(neighbors.n_cols == baselineNeighbors.n_cols); + REQUIRE(neighbors.n_elem == baselineNeighbors.n_elem); + REQUIRE(distances.n_rows == baselineDistances.n_rows); + REQUIRE(distances.n_cols == baselineDistances.n_cols); + REQUIRE(distances.n_elem == baselineDistances.n_elem); for (size_t k = 0; k < distances.n_elem; ++k) { - REQUIRE(neighbors[k] ==baselineNeighbors[k]); + REQUIRE(neighbors[k] == baselineNeighbors[k]); if (std::abs(baselineDistances[k]) < 1e-5) REQUIRE(distances[k] == Approx(0.0).margin(1e-7)); else @@ -1194,28 +1194,28 @@ TEST_CASE("KNNModelMonochromaticTest", "[KNNTest]") { // We only have a std::move() constructor... so copy the data. arma::mat referenceCopy(referenceData); + models[i].LeafSize() = 20; if (j == 0) - models[i].BuildModel(std::move(referenceCopy), 20, DUAL_TREE_MODE); + models[i].BuildModel(std::move(referenceCopy), DUAL_TREE_MODE); if (j == 1) - models[i].BuildModel(std::move(referenceCopy), 20, - SINGLE_TREE_MODE); + models[i].BuildModel(std::move(referenceCopy), SINGLE_TREE_MODE); if (j == 2) - models[i].BuildModel(std::move(referenceCopy), 20, NAIVE_MODE); + models[i].BuildModel(std::move(referenceCopy), NAIVE_MODE); arma::Mat neighbors; arma::mat distances; models[i].Search(3, neighbors, distances); - REQUIRE(neighbors.n_rows ==baselineNeighbors.n_rows); - REQUIRE(neighbors.n_cols ==baselineNeighbors.n_cols); - REQUIRE(neighbors.n_elem ==baselineNeighbors.n_elem); - REQUIRE(distances.n_rows ==baselineDistances.n_rows); - REQUIRE(distances.n_cols ==baselineDistances.n_cols); - REQUIRE(distances.n_elem ==baselineDistances.n_elem); + REQUIRE(neighbors.n_rows == baselineNeighbors.n_rows); + REQUIRE(neighbors.n_cols == baselineNeighbors.n_cols); + REQUIRE(neighbors.n_elem == baselineNeighbors.n_elem); + REQUIRE(distances.n_rows == baselineDistances.n_rows); + REQUIRE(distances.n_cols == baselineDistances.n_cols); + REQUIRE(distances.n_elem == baselineDistances.n_elem); for (size_t k = 0; k < distances.n_elem; ++k) { - REQUIRE(neighbors[k] ==baselineNeighbors[k]); + REQUIRE(neighbors[k] == baselineNeighbors[k]); if (std::abs(baselineDistances[k]) < 1e-5) REQUIRE(distances[k] == Approx(0.0).margin(1e-7)); else From d0a28cf70919fab97d12d1192b1de3de58643c5b Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 6 Jan 2021 00:12:09 +0530 Subject: [PATCH 429/550] Update src/mlpack/tests/feedforward_network_test.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 06ca879d98..38ebc5e769 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -172,7 +172,7 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes FFN > *model = new FFN >; model->Add >(trainData.n_rows, 8); - model->Add >(4,false,true,1); + model->Add >(4, false, true, 1); model->Add >(); FFN > *model1 = new FFN >; From de440b94b1987deee891302fbf74dc35db46d899 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 6 Jan 2021 00:12:19 +0530 Subject: [PATCH 430/550] Update src/mlpack/tests/feedforward_network_test.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 38ebc5e769..b4c245e8ce 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -167,7 +167,7 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes /* * Construct a feed forward network with trainData.n_rows input nodes, - * followed by a linear layer and then a reparametrization layer + * followed by a linear layer and then a reparametrization layer. */ FFN > *model = new FFN >; From ae39dcc06f93738b9b6b5907b11793e58412000e Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 6 Jan 2021 00:12:33 +0530 Subject: [PATCH 431/550] Update src/mlpack/tests/feedforward_network_test.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/feedforward_network_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index b4c245e8ce..2a5e1b3a27 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -177,7 +177,7 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes FFN > *model1 = new FFN >; model1->Add >(trainData.n_rows, 8); - model1->Add >(4,false,true,1); + model1->Add >(4, false, true, 1); model1->Add >(); // Check whether copy constructor is working or not. From e64932fe29ddfb7ece7c1cbcaf284951c39d85f7 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 6 Jan 2021 00:23:27 +0530 Subject: [PATCH 432/550] fixed indentation --- .../ann/layer/reparametrization_impl.hpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index 13fa773a1f..bce8ac3f7c 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -74,14 +74,14 @@ Reparametrization& Reparametrization:: operator=(const Reparametrization& layer) { - if (this != &layer) - { - latentSize = layer.latentSize; - stochastic = layer.stochastic; - includeKl = layer.includeKl; - beta = layer.beta; - } - return *this; + if (this != &layer) + { + latentSize = layer.latentSize; + stochastic = layer.stochastic; + includeKl = layer.includeKl; + beta = layer.beta; + } + return *this; } template @@ -89,14 +89,14 @@ Reparametrization& Reparametrization:: operator=(Reparametrization&& layer) { - if (this != &layer) - { - latentSize = std::move(layer.latentSize); - stochastic = std::move(layer.stochastic); - includeKl = std::move(layer.includeKl); - beta = std::move(layer.beta); - } - return *this; + if (this != &layer) + { + latentSize = std::move(layer.latentSize); + stochastic = std::move(layer.stochastic); + includeKl = std::move(layer.includeKl); + beta = std::move(layer.beta); + } + return *this; } From 8462fc20bde74dba00c2c7145a26875e141ca2cb Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Wed, 6 Jan 2021 00:29:22 +0530 Subject: [PATCH 433/550] updated method description --- src/mlpack/methods/pca/pca_impl.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mlpack/methods/pca/pca_impl.hpp b/src/mlpack/methods/pca/pca_impl.hpp index ce2ecedc66..a122cd7159 100644 --- a/src/mlpack/methods/pca/pca_impl.hpp +++ b/src/mlpack/methods/pca/pca_impl.hpp @@ -76,9 +76,7 @@ void PCA::Apply(const arma::mat& data, } /** - * This is another Overload of apply with only 2 parameteres(data & transformed data) - * and it will create eigval and eigvec and store the corresponding values in them - * as the source of information are first 2 parameters only. + * Apply Principal Component Analysis to the provided data set. * * @param data - Data matrix * @param transformedData - Data with PCA applied From 116c534a2b57a778a02b07bb7736206f2ba14858 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 5 Jan 2021 14:45:06 -0500 Subject: [PATCH 434/550] Fix missing parenthesis. --- src/mlpack/bindings/R/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index a6e8ee16e1..13f171140d 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -230,7 +230,7 @@ if (BUILD_R_BINDINGS) install(CODE "execute_process( COMMAND R CMD INSTALL mlpack_${PACKAGE_VERSION}.tar.gz - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})" ) add_dependencies(R r_build) From 43c62e830a60361e3ff41fb233aa2fe2c539a664 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 5 Jan 2021 14:45:28 -0500 Subject: [PATCH 435/550] Update issue number. --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9bb5fc29ff..918c95a59f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -14,7 +14,7 @@ * Add finalizers to Julia binding model types to fix memory handling (#2756). * Add `PYTHON_INSTALL_PREFIX` CMake option to specify installation root for - Python bindings. + Python bindings (#2797). ### mlpack 3.4.2 ###### 2020-10-26 From 4976ef4a12d840f0c2fa53bc7e1f358c006c2f93 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 7 Jan 2021 16:02:59 +0530 Subject: [PATCH 436/550] Update src/mlpack/methods/ann/layer/reparametrization.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/reparametrization.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization.hpp b/src/mlpack/methods/ann/layer/reparametrization.hpp index f7d41937c7..a526d746bf 100644 --- a/src/mlpack/methods/ann/layer/reparametrization.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization.hpp @@ -81,7 +81,7 @@ class Reparametrization //! Copy assignment operator. Reparametrization& operator=(const Reparametrization& layer); - //! Move assignment operator + //! Move assignment operator. Reparametrization& operator=(Reparametrization&& layer); /** From 36b5db85578270e7b83a72bf967ea62c073ba39c Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 7 Jan 2021 16:03:17 +0530 Subject: [PATCH 437/550] Update src/mlpack/methods/ann/layer/reparametrization_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/reparametrization_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index bce8ac3f7c..ec3f53ecf6 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -55,7 +55,7 @@ Reparametrization::Reparametrization( includeKl(layer.includeKl), beta(layer.beta) { - //Nothing to do here + // Nothing to do here. } template From cabee7d6a081301b81f13b5a813eab5f7f1d74a3 Mon Sep 17 00:00:00 2001 From: Anmolpreet Singh <54476451+Anmol2001@users.noreply.github.com> Date: Thu, 7 Jan 2021 16:03:33 +0530 Subject: [PATCH 438/550] Update src/mlpack/methods/ann/layer/reparametrization_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/reparametrization_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp index ec3f53ecf6..cef6a32b0d 100644 --- a/src/mlpack/methods/ann/layer/reparametrization_impl.hpp +++ b/src/mlpack/methods/ann/layer/reparametrization_impl.hpp @@ -66,7 +66,7 @@ Reparametrization::Reparametrization( includeKl(std::move(layer.includeKl)), beta(std::move(layer.beta)) { - //Nothing to do here + // Nothing to do here. } template From fe6facd9b47c3b7c06f5d7b010208c3ad7174ea1 Mon Sep 17 00:00:00 2001 From: ayushsingh11 <30299945+ayushsingh11@users.noreply.github.com> Date: Sat, 9 Jan 2021 11:44:55 +0530 Subject: [PATCH 439/550] Minor Fix - Removed redundant () --- src/mlpack/methods/ann/layer/multihead_attention.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/multihead_attention.hpp b/src/mlpack/methods/ann/layer/multihead_attention.hpp index 0c2713c0e8..0d7506ea51 100644 --- a/src/mlpack/methods/ann/layer/multihead_attention.hpp +++ b/src/mlpack/methods/ann/layer/multihead_attention.hpp @@ -121,7 +121,7 @@ class MultiheadAttention arma::Mat& gradient); //! Get the size of the weights. - size_t WeightSize() const { return (4 * (embedDim + 1) * embedDim); } + size_t WeightSize() const { return 4 * (embedDim + 1) * embedDim; } /** * Serialize the layer. From 2b1778ab7aa5221a976d81dce6b8ca3a524459e3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 9 Jan 2021 21:48:21 -0500 Subject: [PATCH 440/550] Clarify comments. --- src/mlpack/methods/neighbor_search/ns_model.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/neighbor_search/ns_model.hpp b/src/mlpack/methods/neighbor_search/ns_model.hpp index c88b6226cd..b13918fa7d 100644 --- a/src/mlpack/methods/neighbor_search/ns_model.hpp +++ b/src/mlpack/methods/neighbor_search/ns_model.hpp @@ -4,9 +4,9 @@ * * This is a model for nearest or furthest neighbor search. It is useful in * that it provides an easy way to serialize a model, abstracts away the - * different types of trees, and also (roughly) reflects the NeighborSearch API and - * automatically directs to the right tree type. It is meant to be used by the - * knn and kfn bindings. + * different types of trees, and also (roughly) reflects the NeighborSearch API + * and automatically directs to the right tree type. It is meant to be used by + * the knn and kfn bindings. * * 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 From f0e570f5b4901dc0584f570f3170b7c19692e77b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 9 Jan 2021 21:48:46 -0500 Subject: [PATCH 441/550] Refactor RAModel to not use boost::visitor. --- src/mlpack/methods/rann/CMakeLists.txt | 1 + src/mlpack/methods/rann/krann_main.cpp | 39 +- src/mlpack/methods/rann/ra_model.cpp | 234 ++++++++ src/mlpack/methods/rann/ra_model.hpp | 474 +++++++-------- src/mlpack/methods/rann/ra_model_impl.hpp | 662 ++++----------------- src/mlpack/methods/rann/ra_search.hpp | 9 +- src/mlpack/tests/krann_search_test.cpp | 44 +- src/mlpack/tests/main_tests/krann_test.cpp | 42 +- 8 files changed, 650 insertions(+), 855 deletions(-) create mode 100644 src/mlpack/methods/rann/ra_model.cpp diff --git a/src/mlpack/methods/rann/CMakeLists.txt b/src/mlpack/methods/rann/CMakeLists.txt index 99e838b459..42a70dbc26 100644 --- a/src/mlpack/methods/rann/CMakeLists.txt +++ b/src/mlpack/methods/rann/CMakeLists.txt @@ -23,6 +23,7 @@ set(SOURCES # model ra_model.hpp ra_model_impl.hpp + ra_model.cpp ) # add directory name to sources diff --git a/src/mlpack/methods/rann/krann_main.cpp b/src/mlpack/methods/rann/krann_main.cpp index 9d830f5fff..0ed34fd0f2 100644 --- a/src/mlpack/methods/rann/krann_main.cpp +++ b/src/mlpack/methods/rann/krann_main.cpp @@ -25,9 +25,6 @@ using namespace mlpack::tree; using namespace mlpack::metric; using namespace mlpack::util; -// Convenience typedef. -typedef RAModel RANNModel; - // Program Name. BINDING_NAME("K-Rank-Approximate-Nearest-Neighbors (kRANN)"); @@ -86,8 +83,8 @@ PARAM_MATRIX_OUT("distances", "Matrix to output distances into.", "d"); PARAM_UMATRIX_OUT("neighbors", "Matrix to output neighbors into.", "n"); // The option exists to load or save models. -PARAM_MODEL_IN(RANNModel, "input_model", "Pre-trained kNN model.", "m"); -PARAM_MODEL_OUT(RANNModel, "output_model", "If specified, the kNN model will be" +PARAM_MODEL_IN(RAModel, "input_model", "Pre-trained kNN model.", "m"); +PARAM_MODEL_OUT(RAModel, "output_model", "If specified, the kNN model will be" " output here.", "M"); // The user may specify a query file of query points and a number of nearest @@ -170,12 +167,12 @@ static void mlpackMain() "alpha must be in range [0.0, 1.0]"); // We either have to load the reference data, or we have to load the model. - RANNModel* rann; + RAModel* rann; const bool naive = IO::HasParam("naive"); const bool singleMode = IO::HasParam("single_mode"); if (IO::HasParam("reference")) { - rann = new RANNModel(); + rann = new RAModel(); // Get all the parameters. const string treeType = IO::GetParam("tree_type"); @@ -184,27 +181,27 @@ static void mlpackMain() "unknown tree type"); const bool randomBasis = IO::HasParam("random_basis"); - RANNModel::TreeTypes tree = RANNModel::KD_TREE; + RAModel::TreeTypes tree = RAModel::KD_TREE; if (treeType == "kd") - tree = RANNModel::KD_TREE; + tree = RAModel::KD_TREE; else if (treeType == "cover") - tree = RANNModel::COVER_TREE; + tree = RAModel::COVER_TREE; else if (treeType == "r") - tree = RANNModel::R_TREE; + tree = RAModel::R_TREE; else if (treeType == "r-star") - tree = RANNModel::R_STAR_TREE; + tree = RAModel::R_STAR_TREE; else if (treeType == "x") - tree = RANNModel::X_TREE; + tree = RAModel::X_TREE; else if (treeType == "hilbert-r") - tree = RANNModel::HILBERT_R_TREE; + tree = RAModel::HILBERT_R_TREE; else if (treeType == "r-plus") - tree = RANNModel::R_PLUS_TREE; + tree = RAModel::R_PLUS_TREE; else if (treeType == "r-plus-plus") - tree = RANNModel::R_PLUS_PLUS_TREE; + tree = RAModel::R_PLUS_PLUS_TREE; else if (treeType == "ub") - tree = RANNModel::UB_TREE; + tree = RAModel::UB_TREE; else if (treeType == "oct") - tree = RANNModel::OCTREE; + tree = RAModel::OCTREE; rann->TreeType() = tree; rann->RandomBasis() = randomBasis; @@ -218,10 +215,10 @@ static void mlpackMain() else { // Load the model from file. - rann = IO::GetParam("input_model"); + rann = IO::GetParam("input_model"); Log::Info << "Using rank-approximate kNN model from '" - << IO::GetPrintableParam("input_model") << "' (trained on " + << IO::GetPrintableParam("input_model") << "' (trained on " << rann->Dataset().n_rows << "x" << rann->Dataset().n_cols << " dataset)." << endl; @@ -285,5 +282,5 @@ static void mlpackMain() } // Save the output model. - IO::GetParam("output_model") = rann; + IO::GetParam("output_model") = rann; } diff --git a/src/mlpack/methods/rann/ra_model.cpp b/src/mlpack/methods/rann/ra_model.cpp new file mode 100644 index 0000000000..a6a997a22c --- /dev/null +++ b/src/mlpack/methods/rann/ra_model.cpp @@ -0,0 +1,234 @@ +/** + * @file methods/rann/ra_model.cpp + * @author Ryan Curtin + * + * Implementation of the RAModel 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. + */ +#include "ra_model.hpp" +#include + +namespace mlpack { +namespace neighbor { + +RAModel::RAModel(const TreeTypes treeType, const bool randomBasis) : + treeType(treeType), + leafSize(20), + randomBasis(randomBasis), + raSearch(NULL) +{ + // Nothing to do. +} + +// Copy constructor. +RAModel::RAModel(const RAModel& other) : + treeType(other.treeType), + leafSize(other.leafSize), + randomBasis(other.randomBasis), + q(other.q), + raSearch(other.raSearch->Clone()) +{ + // Nothing to do. +} + +// Move constructor. +RAModel::RAModel(RAModel&& other) : + treeType(other.treeType), + leafSize(other.leafSize), + randomBasis(other.randomBasis), + q(std::move(other.q)), + raSearch(std::move(other.raSearch)) +{ + // Clear other model. + other.treeType = TreeTypes::KD_TREE; + other.leafSize = 20; + other.randomBasis = false; +} + +// Copy operator. +RAModel& RAModel::operator=(const RAModel& other) +{ + if (this != &other) + { + // Clear current model. + delete raSearch; + + treeType = other.treeType; + leafSize = other.leafSize; + randomBasis = other.randomBasis; + q = other.q; + raSearch = other.raSearch->Clone(); + } + + return *this; +} + +RAModel& RAModel::operator=(RAModel&& other) +{ + if (this != &other) + { + // Clear current model. + delete raSearch; + + treeType = other.treeType; + leafSize = other.leafSize; + randomBasis = other.randomBasis; + q = std::move(other.q); + raSearch = std::move(other.raSearch); + + // Reset other model. + other.treeType = TreeTypes::KD_TREE; + other.leafSize = 20; + other.randomBasis = false; + } + + return *this; +} + +// Clean memory, if necessary +RAModel::~RAModel() +{ + delete raSearch; +} + +void RAModel::BuildModel(arma::mat&& referenceSet, + const size_t leafSize, + const bool naive, + const bool singleMode) +{ + // Initialize random basis, if necessary. + if (randomBasis) + { + Log::Info << "Creating random basis..." << std::endl; + math::RandomBasis(q, referenceSet.n_rows); + } + + // Clean memory, if necessary. + delete raSearch; + + this->leafSize = leafSize; + + if (randomBasis) + referenceSet = q * referenceSet; + + if (!naive) + { + Timer::Start("tree_building"); + Log::Info << "Building reference tree..." << std::endl; + } + + switch (treeType) + { + case KD_TREE: + raSearch = new LeafSizeRAWrapper(naive, singleMode); + break; + case COVER_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case R_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case R_STAR_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case X_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case HILBERT_R_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case R_PLUS_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case R_PLUS_PLUS_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case UB_TREE: + raSearch = new RAWrapper(naive, singleMode); + break; + case OCTREE: + raSearch = new LeafSizeRAWrapper(naive, singleMode); + break; + } + + raSearch->Train(std::move(referenceSet), leafSize); + + if (!naive) + { + Timer::Stop("tree_building"); + Log::Info << "Tree built." << std::endl; + } +} + +void RAModel::Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances) +{ + // Apply the random basis if necessary. + if (randomBasis) + querySet = q * querySet; + + Log::Info << "Searching for " << k << " approximate nearest neighbors with "; + if (!Naive() && !SingleMode()) + Log::Info << "dual-tree rank-approximate " << TreeName() << " search..."; + else if (!Naive()) + Log::Info << "single-tree rank-approximate " << TreeName() << " search..."; + else + Log::Info << "brute-force (naive) rank-approximate search..."; + Log::Info << std::endl; + + raSearch->Search(std::move(querySet), k, neighbors, distances, leafSize); +} + +void RAModel::Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances) +{ + Log::Info << "Searching for " << k << " approximate nearest neighbors with "; + if (!Naive() && !SingleMode()) + Log::Info << "dual-tree rank-approximate " << TreeName() << " search..."; + else if (!Naive()) + Log::Info << "single-tree rank-approximate " << TreeName() << " search..."; + else + Log::Info << "brute-force (naive) rank-approximate search..."; + Log::Info << std::endl; + + raSearch->Search(k, neighbors, distances); +} + +std::string RAModel::TreeName() const +{ + switch (treeType) + { + case KD_TREE: + return "kd-tree"; + case COVER_TREE: + return "cover tree"; + case R_TREE: + return "R tree"; + case R_STAR_TREE: + return "R* tree"; + case X_TREE: + return "X tree"; + case HILBERT_R_TREE: + return "Hilbert R tree"; + case R_PLUS_TREE: + return "R+ tree"; + case R_PLUS_PLUS_TREE: + return "R++ tree"; + case UB_TREE: + return "UB tree"; + case OCTREE: + return "octree"; + default: + return "unknown tree"; + } +} + +} // namespace neighbor +} // namespace mlpack diff --git a/src/mlpack/methods/rann/ra_model.hpp b/src/mlpack/methods/rann/ra_model.hpp index ed32d4a352..afe42bf3da 100644 --- a/src/mlpack/methods/rann/ra_model.hpp +++ b/src/mlpack/methods/rann/ra_model.hpp @@ -25,238 +25,228 @@ namespace mlpack { namespace neighbor { /** - * Alias template for RASearch + * RAWrapperBase is a base wrapper class for holding all RASearch types + * supported by RAModel. All RASearch type wrappers inherit from this class, + * allowing a simple interface via inheritance for all the different types we + * want to support. */ -template& neighbors, + arma::mat& distances, + const size_t leafSize) = 0; + + //! Perform monochromatic rank-approximate nearest neighbor search (i.e. a + //! search with the reference set as the query set). + virtual void Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances) = 0; +}; + +/** + * RAWrapper is a wrapper class for most RASearch types. + */ +template class TreeType> -using RAType = RASearch; - -/** - * MonoSearchVisitor executes a monochromatic neighbor search on the given - * RAType. We don't make any difference for different instantiation of RAType. - */ -class MonoSearchVisitor : public boost::static_visitor +class RAWrapper : public RAWrapperBase { - private: - //! Number of neighbors to search for. - const size_t k; - //! Result matrix for neighbors. - arma::Mat& neighbors; - //! Result matrix for distances. - arma::mat& distances; - public: - //! Perform monochromatic nearest neighbor search. - template - void operator()(RAType* ra) const; + //! Construct the RAWrapper object, initializing the internally-held RASearch + //! object. + RAWrapper(const bool singleMode, const bool naive) : + ra(singleMode, naive) + { + // Nothing else to do. + } - //! Construct the MonoSearchVisitor object with the given parameters. - MonoSearchVisitor(const size_t k, - arma::Mat& neighbors, - arma::mat& distances) : - k(k), - neighbors(neighbors), - distances(distances) - {}; + //! Delete the RAWrapper object. + virtual ~RAWrapper() { } + + //! Create a copy of this RAWrapper object. This correctly handles + //! polymorphism. + virtual RAWrapper* Clone() const { return new RAWrapper(*this); } + + //! Get a reference to the reference set. + const arma::mat& Dataset() const { return ra.ReferenceSet(); } + + //! Get the single sample limit. + size_t SingleSampleLimit() const { return ra.SingleSampleLimit(); } + //! Modify the single sample limit. + size_t& SingleSampleLimit() { return ra.SingleSampleLimit(); } + + //! Get whether to do exact search at the first leaf. + bool FirstLeafExact() const { return ra.FirstLeafExact(); } + //! Modify whether to do exact search at the first leaf. + bool& FirstLeafExact() { return ra.FirstLeafExact(); } + + //! Get whether to do sampling at leaves. + bool SampleAtLeaves() const { return ra.SampleAtLeaves(); } + //! Modify whether to do sampling at leaves. + bool& SampleAtLeaves() { return ra.SampleAtLeaves(); } + + //! Get the value of alpha. + double Alpha() const { return ra.Alpha(); } + //! Modify the value of alpha. + double& Alpha() { return ra.Alpha(); } + + //! Get the value of tau. + double Tau() const { return ra.Tau(); } + //! Modify the value of tau. + double& Tau() { return ra.Tau(); } + + //! Get whether single-tree search is being used. + bool SingleMode() const { return ra.SingleMode(); } + //! Modify whether single-tree search is being used. + bool& SingleMode() { return ra.SingleMode(); } + + //! Get whether naive search is being used. + bool Naive() const { return ra.Naive(); } + //! Modify whether naive search is being used. + bool& Naive() { return ra.Naive(); } + + //! Train the model. For RAWrapper, we ignore the leaf size. + virtual void Train(arma::mat&& referenceSet, + const size_t /* leafSize */); + + //! Perform bichromatic neighbor search (i.e. search with a separate query + //! set). For RAWrapper, we ignore the leaf size. + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t /* leafSize */); + + //! Perform monochromatic neighbor search (i.e. search where the reference set + //! is used as the query set). + virtual void Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances); + + //! Serialize the RASearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(ra)); + } + + protected: + typedef RASearch RAType; + + //! The instantiated RASearch object that we are wrapping. + RAType ra; }; /** - * BiSearchVisitor executes a bichromatic neighbor search on the given RAType. - * We use template specialization to differentiate those tree types types that - * accept leafSize as a parameter. In these cases, before doing neighbor search - * a query tree with proper leafSize is built from the querySet. + * LeafSizeRAWrapper wraps any RASearch type that needs to be able to take the + * leaf size into account when building trees. The implementations of Train() + * and bichromatic Search() take this leaf size into account. */ -template -class BiSearchVisitor : public boost::static_visitor -{ - private: - //! The query set for the bichromatic search. - const arma::mat& querySet; - //! The number of neighbors to search for. - const size_t k; - //! The results matrix for neighbors. - arma::Mat& neighbors; - //! The result matrix for distances. - arma::mat& distances; - //! The number of points in a leaf (for BinarySpaceTrees). - const size_t leafSize; - - //! Bichromatic neighbor search on the given RAType considering leafSize. - template - void SearchLeaf(RAType* ra) const; - - public: - //! Alias template necessary for visual c++ compiler. - template class TreeType> - using RATypeT = RAType; - - //! Default Bichromatic neighbor search on the given RAType instance. - template class TreeType> - void operator()(RATypeT* ra) const; - - //! Bichromatic search on the given RAType specialized for KDTrees. - void operator()(RATypeT* ra) const; - - //! Bichromatic search on the given RAType specialized for octrees. - void operator()(RATypeT* ra) const; - - //! Construct the BiSearchVisitor. - BiSearchVisitor(const arma::mat& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, - const size_t leafSize); -}; - -/** - * TrainVisitor sets the reference set to a new reference set on the given - * RAType. We use template specialization to differentiate those trees that - * accept leafSize as a parameter. In these cases, a reference tree with proper - * leafSize is built from the referenceSet. - */ -template -class TrainVisitor : public boost::static_visitor -{ - private: - //! The reference set to use for training. - arma::mat&& referenceSet; - //! The leaf size, used only by BinarySpaceTree. - size_t leafSize; - - //! Train on the given RAType considering the leafSize. - template - void TrainLeaf(RAType* ra) const; - - public: - //! Alias template necessary for visual c++ compiler. - template class TreeType> - using RATypeT = RAType; - - //! Default Train on the given RAType instance. - template class TreeType> - void operator()(RATypeT* ra) const; - - //! Train on the given RAType specialized for KDTrees. - void operator()(RATypeT* ra) const; - - //! Train on the given RAType specialized for Octrees. - void operator()(RATypeT* ra) const; - - //! Construct the TrainVisitor object with the given reference set, leafSize - //! for BinarySpaceTrees. - TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize); -}; - -/** - * Exposes the SingleSampleLimit() method of the given RAType. - */ -class SingleSampleLimitVisitor : public boost::static_visitor +template class TreeType> +class LeafSizeRAWrapper : public RAWrapper { public: - template - size_t& operator()(RAType* ra) const; -}; + //! Construct the LeafSizeRAWrapper by delegating to the RAWrapper + //! constructor. + LeafSizeRAWrapper(const bool singleMode, const bool naive) : + RAWrapper(singleMode, naive) + { + // Nothing else to do. + } -/** - * Exposes the FirstLeafExact() method of the given RAType. - */ -class FirstLeafExactVisitor : public boost::static_visitor -{ - public: - template - bool& operator()(RAType* ra) const; -}; + //! Delete the LeafSizeRAWrapper. + virtual ~LeafSizeRAWrapper() { } -/** - * Exposes the SampleAtLeaves() method of the given RAType. - */ -class SampleAtLeavesVisitor : public boost::static_visitor -{ - public: - //! Return SampleAtLeaves (whether or not sampling is done at leaves). - template - bool& operator()(RAType *) const; -}; + //! Return a copy of the LeafSizeRAWrapper. + virtual LeafSizeRAWrapper* Clone() const + { + return new LeafSizeRAWrapper(*this); + } -/** - * Exposes the Alpha() method of the given RAType. - */ -class AlphaVisitor : public boost::static_visitor -{ - public: - //! Return Alpha parameter. - template - double& operator()(RAType* ra) const; -}; + //! Train a model with the given parameters. This overload uses leafSize. + virtual void Train(arma::mat&& referenceSet, + const size_t leafSize); -/** - * Exposes the Tau() method of the given RAType. - */ -class TauVisitor : public boost::static_visitor -{ - public: - //! Get a reference to the Tau parameter. - template - double& operator()(RAType* ra) const; -}; + //! Perform bichromatic search (e.g. search with a separate query set). This + //! overload takes the leaf size into account to build the query tree. + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize); -/** - * Exposes the SingleMode() method of the given RAType. - */ -class SingleModeVisitor : public boost::static_visitor -{ - public: - //! Get a reference to the SingleMode parameter of the given RASearch object. - template - bool& operator()(RAType* ra) const; -}; + //! Serialize the RASearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(ra)); + } -/** - * Exposes the referenceSet of the given RAType. - */ -class ReferenceSetVisitor : public boost::static_visitor -{ - public: - //! Return the reference set. - template - const arma::mat& operator()(RAType* ra) const; -}; - -/** - * DeleteVisitor deletes the give RAType Instance. - */ -class DeleteVisitor : public boost::static_visitor -{ - public: - //! Delete the RAType Object. - template void operator()(RAType* ra) const; -}; - -/** - * NaiveVisitor exposes the Naive() method of the given RAType. - */ -class NaiveVisitor : public boost::static_visitor -{ - public: - /** - * Get a reference to the naive parameter of the given RASearch object. - */ - template - bool& operator()(RAType* ra) const; + protected: + using RAWrapper::ra; }; /** @@ -264,10 +254,7 @@ class NaiveVisitor : public boost::static_visitor * away the TreeType parameter and allowing it to be specified at runtime in * this class. This class is written for the sake of the 'allkrann' program, * but is not necessarily restricted to that use. - * - * @param SortPolicy Sorting policy for neighbor searching (see RASearch). */ -template class RAModel { public: @@ -301,16 +288,7 @@ class RAModel arma::mat q; //! The rank-approximate model. - boost::variant*, - RAType*, - RAType*, - RAType*, - RAType*, - RAType*, - RAType*, - RAType*, - RAType*, - RAType*> raSearch; + RAWrapperBase* raSearch; public: /** @@ -355,58 +333,58 @@ class RAModel void serialize(Archive& ar, const uint32_t /* version */); //! Expose the dataset. - const arma::mat& Dataset() const; + const arma::mat& Dataset() const { return raSearch->Dataset(); } //! Get whether or not single-tree search is being used. - bool SingleMode() const; + bool SingleMode() const { return raSearch->SingleMode(); } //! Modify whether or not single-tree search is being used. - bool& SingleMode(); + bool& SingleMode() { return raSearch->SingleMode(); } //! Get whether or not naive search is being used. - bool Naive() const; + bool Naive() const { return raSearch->Naive(); } //! Modify whether or not naive search is being used. - bool& Naive(); + bool& Naive() { return raSearch->Naive(); } //! Get the rank-approximation in percentile of the data. - double Tau() const; + double Tau() const { return raSearch->Tau(); } //! Modify the rank-approximation in percentile of the data. - double& Tau(); + double& Tau() { return raSearch->Tau(); } //! Get the desired success probability. - double Alpha() const; + double Alpha() const { return raSearch->Alpha(); } //! Modify the desired success probability. - double& Alpha(); + double& Alpha() { return raSearch->Alpha(); } //! Get whether or not sampling is done at the leaves. - bool SampleAtLeaves() const; + bool SampleAtLeaves() const { return raSearch->SampleAtLeaves(); } //! Modify whether or not sampling is done at the leaves. - bool& SampleAtLeaves(); + bool& SampleAtLeaves() { return raSearch->SampleAtLeaves(); } //! Get whether or not we traverse to the first leaf without approximation. - bool FirstLeafExact() const; + bool FirstLeafExact() const { return raSearch->FirstLeafExact(); } //! Modify whether or not we traverse to the first leaf without approximation. - bool& FirstLeafExact(); + bool& FirstLeafExact() { return raSearch->FirstLeafExact(); } //! Get the limit on the size of a node that can be approximated. - size_t SingleSampleLimit() const; + size_t SingleSampleLimit() const { return raSearch->SingleSampleLimit(); } //! Modify the limit on the size of a node that can be approximation. - size_t& SingleSampleLimit(); + size_t& SingleSampleLimit() { return raSearch->SingleSampleLimit(); } //! Get the leaf size (only relevant when the kd-tree is used). - size_t LeafSize() const; + size_t LeafSize() const { return leafSize; } //! Modify the leaf size (only relevant when the kd-tree is used). - size_t& LeafSize(); + size_t& LeafSize() { return leafSize; } //! Get the type of tree being used. - TreeTypes TreeType() const; + TreeTypes TreeType() const { return treeType; } //! Modify the type of tree being used. - TreeTypes& TreeType(); + TreeTypes& TreeType() { return treeType; } //! Get whether or not a random basis is being used. - bool RandomBasis() const; + bool RandomBasis() const { return randomBasis; } //! Modify whether or not a random basis is being used. Be sure to rebuild //! the model using BuildModel(). - bool& RandomBasis(); + bool& RandomBasis() { return randomBasis; } //! Build the reference tree. void BuildModel(arma::mat&& referenceSet, diff --git a/src/mlpack/methods/rann/ra_model_impl.hpp b/src/mlpack/methods/rann/ra_model_impl.hpp index 3b27bfa2d6..6955bd9f46 100644 --- a/src/mlpack/methods/rann/ra_model_impl.hpp +++ b/src/mlpack/methods/rann/ra_model_impl.hpp @@ -19,78 +19,87 @@ namespace mlpack { namespace neighbor { -//! Monochromatic search for the given RAType instance. -template -void MonoSearchVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->Search(k, neighbors, distances); - throw std::runtime_error("no rank-approximate model initialized"); -} - -//! Save the parameters for the rank-approximate search. -template -BiSearchVisitor::BiSearchVisitor(const arma::mat& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, - const size_t leafSize) : - querySet(querySet), - k(k), - neighbors(neighbors), - distances(distances), - leafSize(leafSize) -{}; - -//! Default Bichromatic search on the given RAType instance. -template template class TreeType> -void BiSearchVisitor::operator()(RATypeT* ra) const +void RAWrapper::Train(arma::mat&& referenceSet, + const size_t /* leafSize */) { - if (ra) - return ra->Search(querySet, k, neighbors, distances); - throw std::runtime_error("no rank-approximate model initialized"); + ra.Train(std::move(referenceSet)); } -//! Bichromatic search on the given RAType specialized for KDTrees. -template -void BiSearchVisitor::operator()(RATypeT* ra) const +template class TreeType> +void RAWrapper::Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t /* leafSize */) { - if (ra) - return SearchLeaf(ra); - throw std::runtime_error("no rank-approximate search model initialized"); + ra.Search(querySet, k, neighbors, distances); } -//! Bichromatic search on the given RAType specialized for Octrees. -template -void BiSearchVisitor::operator()(RATypeT* ra) const +template class TreeType> +void RAWrapper::Search(const size_t k, + arma::Mat& neighbors, + arma::mat& distances) { - if (ra) - return SearchLeaf(ra); - throw std::runtime_error("no rank-approximate search model initialized"); + ra.Search(k, neighbors, distances); } -//! Bichromatic search on the given RAType considering the leafSize. -template -template -void BiSearchVisitor::SearchLeaf(RAType* ra) const +template class TreeType> +void LeafSizeRAWrapper::Train(arma::mat&& referenceSet, + const size_t leafSize) { - if (!ra->Naive() && !ra->SingleMode()) + // Build tree, if necessary. + if (ra.Naive()) { - // Build a second tree and search + ra.Train(std::move(referenceSet)); + } + else + { + std::vector oldFromNewReferences; + typename decltype(ra)::Tree* tree = + new typename decltype(ra)::Tree(std::move(referenceSet), + oldFromNewReferences, + leafSize); + ra.Train(tree); + + // Give the model ownership of the tree and the mappings. + ra.treeOwner = true; + ra.oldFromNewReferences = std::move(oldFromNewReferences); + } +} + +template class TreeType> +void LeafSizeRAWrapper::Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize) +{ + if (!ra.Naive() && !ra.SingleMode()) + { + // Build a second tree and search, taking the leaf size into account. Timer::Start("tree_building"); Log::Info << "Building query tree...."<< std::endl; std::vector oldFromNewQueries; - typename RAType::Tree queryTree(std::move(querySet), oldFromNewQueries, - leafSize); - Log::Info << "Tree Built." << std::endl; + typename decltype(ra)::Tree queryTree(std::move(querySet), + oldFromNewQueries, + leafSize); + Log::Info << "Tree built." << std::endl; Timer::Stop("tree_building"); arma::Mat neighborsOut; arma::mat distancesOut; - ra->Search(&queryTree, k, neighborsOut, distancesOut); + ra.Search(&queryTree, k, neighborsOut, distancesOut); // Unmap the query points. distances.set_size(distancesOut.n_rows, distancesOut.n_cols); @@ -104,236 +113,12 @@ void BiSearchVisitor::SearchLeaf(RAType* ra) const else { // Search without building a second tree. - ra->Search(querySet, k, neighbors, distances); + ra.Search(querySet, k, neighbors, distances); } } -//! Save parameters for the Train. -template -TrainVisitor::TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize) : - referenceSet(std::move(referenceSet)), - leafSize(leafSize) -{}; - -//! Default Train on the given RAType instance. -template -template class TreeType> -void TrainVisitor::operator()(RATypeT* ra) const -{ - if (ra) - return ra->Train(std::move(referenceSet)); - throw std::runtime_error("no rank-approximate search model initialized"); -} - -//! Train on the given RAType specialized for KDTrees. -template -void TrainVisitor::operator()(RATypeT* ra) const -{ - if (ra) - return TrainLeaf(ra); - throw std::runtime_error("no rank-approximate search model initialized"); -} - -//! Train on the given RAType specialized for Octrees. -template -void TrainVisitor::operator()(RATypeT* ra) const -{ - if (ra) - return TrainLeaf(ra); - throw std::runtime_error("no rank-approximate search model is initialized"); -} - -//! Train on the given RAType considering the leafSize. -template -template -void TrainVisitor::TrainLeaf(RAType* ra) const -{ - // Build tree, if necessary - if (ra->Naive()) - { - ra->Train(std::move(referenceSet)); - } - else - { - std::vector oldFromNewReferences; - typename RAType::Tree* tree = - new typename RAType::Tree(std::move(referenceSet), oldFromNewReferences, - leafSize); - ra->Train(tree); - - // Give the model ownership of the tree and the mappings. - ra->treeOwner = true; - ra->oldFromNewReferences = std::move(oldFromNewReferences); - } -} - -//! Exposes the SingleSampleLimit() method of the given RAType. -template -size_t& SingleSampleLimitVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->SingleSampleLimit(); - throw std::runtime_error("no rank-approximate search model is initialized"); -} - -//! Exposes the FirstLeafExact() method of the given RAType. -template -bool& FirstLeafExactVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->FirstLeafExact(); - throw std::runtime_error("no rank-approximate search model is initialized"); -} - -//! Exposes the SampleAtLeaves() method of the given RAType. -template -bool& SampleAtLeavesVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->SampleAtLeaves(); - throw std::runtime_error("no rank-approximate search model is initialized"); -} - -//! Exposes the Alpha() method of the given RAType instance. -template -double& AlphaVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->Alpha(); - throw std::runtime_error("no rank-approximate model is initialized"); -} - -//! Exposes the Tau() method of the given RAType instance. -template -double& TauVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->Tau(); - throw std::runtime_error("no rank-approximate model is initialized"); -} - -//! Exposes the SingleMode() method of the given RAType. -template -bool& SingleModeVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->SingleMode(); - throw std::runtime_error("no rank-approximate model is initialized"); -} - -//! Exposes the referenceSet of the given RAType. -template -const arma::mat& ReferenceSetVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->ReferenceSet(); - throw std::runtime_error("no rank-approximate model is initialized"); -} - -//! Exposes the Naive() method of the given RAType instance. -template -bool& NaiveVisitor::operator()(RAType* ra) const -{ - if (ra) - return ra->Naive(); - throw std::runtime_error("no rank-approximate search model is initialized"); -} - -//! For cleaning memory -template -void DeleteVisitor::operator()(RSType* rs) const -{ - if (rs) - delete rs; -} - -template -RAModel::RAModel(const TreeTypes treeType, const bool randomBasis) : - treeType(treeType), - leafSize(20), - randomBasis(randomBasis) -{ - // Nothing to do. -} - -// Copy constructor. -template -RAModel::RAModel(const RAModel& other) : - treeType(other.treeType), - leafSize(other.leafSize), - randomBasis(other.randomBasis), - q(other.q), - raSearch(other.raSearch) -{ - // Nothing to do. -} - -// Move constructor. -template -RAModel::RAModel(RAModel&& other) : - treeType(other.treeType), - leafSize(other.leafSize), - randomBasis(other.randomBasis), - q(std::move(other.q)), - raSearch(std::move(other.raSearch)) -{ - // Clear other model. - other.treeType = TreeTypes::KD_TREE; - other.leafSize = 20; - other.randomBasis = false; - other.raSearch = decltype(other.raSearch)(); -} - -// Copy operator. -template -RAModel& RAModel::operator=(const RAModel& other) -{ - // Clear current model. - boost::apply_visitor(DeleteVisitor(), raSearch); - - treeType = other.treeType; - leafSize = other.leafSize; - randomBasis = other.randomBasis; - q = other.q; - raSearch = other.raSearch; - - return *this; -} - -template -RAModel& RAModel::operator=(RAModel&& other) -{ - boost::apply_visitor(DeleteVisitor(), raSearch); - - treeType = other.treeType; - leafSize = other.leafSize; - randomBasis = other.randomBasis; - q = std::move(other.q); - raSearch = std::move(other.raSearch); - - // Reset other model. - other.treeType = TreeTypes::KD_TREE; - other.leafSize = 20; - other.randomBasis = false; - other.raSearch = decltype(other.raSearch)(); - - return *this; -} - -// Clean memory, if necessary -template -RAModel::~RAModel() -{ - boost::apply_visitor(DeleteVisitor(), raSearch); -} - -template template -void RAModel::serialize(Archive& ar, - const uint32_t /* version */) +void RAModel::serialize(Archive& ar, const uint32_t /* version */) { ar(CEREAL_NVP(treeType)); ar(CEREAL_NVP(randomBasis)); @@ -342,281 +127,82 @@ void RAModel::serialize(Archive& ar, // This should never happen, but just in case, be clean with memory. if (cereal::is_loading()) { - boost::apply_visitor(DeleteVisitor(), raSearch); - } - - // We only need to serialize one of the kRANN objects. - ar(CEREAL_VARIANT_POINTER(raSearch)); -} - -template -const arma::mat& RAModel::Dataset() const -{ - return boost::apply_visitor(ReferenceSetVisitor(), raSearch); -} - -template -bool RAModel::Naive() const -{ - return boost::apply_visitor(NaiveVisitor(), raSearch); -} - -template -bool& RAModel::Naive() -{ - return boost::apply_visitor(NaiveVisitor(), raSearch); -} - -template -bool RAModel::SingleMode() const -{ - return boost::apply_visitor(SingleModeVisitor(), raSearch); -} - -template -bool& RAModel::SingleMode() -{ - return boost::apply_visitor(SingleModeVisitor(), raSearch); -} - -template -double RAModel::Tau() const -{ - return boost::apply_visitor(TauVisitor(), raSearch); -} - -template -double& RAModel::Tau() -{ - return boost::apply_visitor(TauVisitor(), raSearch); -} - -template -double RAModel::Alpha() const -{ - return boost::apply_visitor(AlphaVisitor(), raSearch); -} - -template -double& RAModel::Alpha() -{ - return boost::apply_visitor(AlphaVisitor(), raSearch); -} - -template -bool RAModel::SampleAtLeaves() const -{ - return boost::apply_visitor(SampleAtLeavesVisitor(), raSearch); -} - -template -bool& RAModel::SampleAtLeaves() -{ - return boost::apply_visitor(SampleAtLeavesVisitor(), raSearch); -} - -template -bool RAModel::FirstLeafExact() const -{ - return boost::apply_visitor(FirstLeafExactVisitor(), raSearch); -} - -template -bool& RAModel::FirstLeafExact() -{ - return boost::apply_visitor(FirstLeafExactVisitor(), raSearch); -} - -template -size_t RAModel::SingleSampleLimit() const -{ - return boost::apply_visitor(SingleSampleLimitVisitor(), raSearch); -} - -template -size_t& RAModel::SingleSampleLimit() -{ - return boost::apply_visitor(SingleSampleLimitVisitor(), raSearch); -} - -template -size_t RAModel::LeafSize() const -{ - return leafSize; -} - -template -size_t& RAModel::LeafSize() -{ - return leafSize; -} - -template -typename RAModel::TreeTypes RAModel::TreeType() const -{ - return treeType; -} - -template -typename RAModel::TreeTypes& RAModel::TreeType() -{ - return treeType; -} - -template -bool RAModel::RandomBasis() const -{ - return randomBasis; -} - -template -bool& RAModel::RandomBasis() -{ - return randomBasis; -} - -template -void RAModel::BuildModel(arma::mat&& referenceSet, - const size_t leafSize, - const bool naive, - const bool singleMode) -{ - // Initialize random basis, if necessary. - if (randomBasis) - { - Log::Info << "Creating random basis..." << std::endl; - math::RandomBasis(q, referenceSet.n_rows); - } - - // Clean memory, if necessary. - boost::apply_visitor(DeleteVisitor(), raSearch); - - this->leafSize = leafSize; - - if (randomBasis) - referenceSet = q * referenceSet; - - if (!naive) - { - Timer::Start("tree_building"); - Log::Info << "Building reference tree..." << std::endl; + delete raSearch; } + // Avoid polymorphic serialization by explicitly serializing the correct type. switch (treeType) { case KD_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + LeafSizeRAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case COVER_TREE: - raSearch = new RAType(naive, - singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case R_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case R_STAR_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case X_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case HILBERT_R_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case R_PLUS_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case R_PLUS_PLUS_TREE: - raSearch = new RAType(naive, - singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case UB_TREE: - raSearch = new RAType(naive, singleMode); - break; + { + RAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } case OCTREE: - raSearch = new RAType(naive, singleMode); - break; - } - - TrainVisitor tn(std::move(referenceSet), leafSize); - boost::apply_visitor(tn, raSearch); - - if (!naive) - { - Timer::Stop("tree_building"); - Log::Info << "Tree built." << std::endl; - } -} - -template -void RAModel::Search(arma::mat&& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances) -{ - // Apply the random basis if necessary. - if (randomBasis) - querySet = q * querySet; - - Log::Info << "Searching for " << k << " approximate nearest neighbors with "; - if (!Naive() && !SingleMode()) - Log::Info << "dual-tree rank-approximate " << TreeName() << " search..."; - else if (!Naive()) - Log::Info << "single-tree rank-approximate " << TreeName() << " search..."; - else - Log::Info << "brute-force (naive) rank-approximate search..."; - Log::Info << std::endl; - - BiSearchVisitor search(querySet, k, neighbors, distances, - leafSize); - boost::apply_visitor(search, raSearch); -} - -template -void RAModel::Search(const size_t k, - arma::Mat& neighbors, - arma::mat& distances) -{ - Log::Info << "Searching for " << k << " approximate nearest neighbors with "; - if (!Naive() && !SingleMode()) - Log::Info << "dual-tree rank-approximate " << TreeName() << " search..."; - else if (!Naive()) - Log::Info << "single-tree rank-approximate " << TreeName() << " search..."; - else - Log::Info << "brute-force (naive) rank-approximate search..."; - Log::Info << std::endl; - - MonoSearchVisitor search(k, neighbors, distances); - boost::apply_visitor(search, raSearch); -} - -template -std::string RAModel::TreeName() const -{ - switch (treeType) - { - case KD_TREE: - return "kd-tree"; - case COVER_TREE: - return "cover tree"; - case R_TREE: - return "R tree"; - case R_STAR_TREE: - return "R* tree"; - case X_TREE: - return "X tree"; - case HILBERT_R_TREE: - return "Hilbert R tree"; - case R_PLUS_TREE: - return "R+ tree"; - case R_PLUS_PLUS_TREE: - return "R++ tree"; - case UB_TREE: - return "UB tree"; - case OCTREE: - return "octree"; - default: - return "unknown tree"; + { + LeafSizeRAWrapper& typedSearch = + dynamic_cast&>(*raSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } } } diff --git a/src/mlpack/methods/rann/ra_search.hpp b/src/mlpack/methods/rann/ra_search.hpp index da3f61c48d..634260c213 100644 --- a/src/mlpack/methods/rann/ra_search.hpp +++ b/src/mlpack/methods/rann/ra_search.hpp @@ -39,8 +39,10 @@ namespace mlpack { namespace neighbor { // Forward declaration. -template -class TrainVisitor; +template class TreeType> +class LeafSizeRAWrapper; /** * The RASearch class: This class provides a generic manner to perform @@ -394,8 +396,7 @@ class RASearch MetricType metric; //! For access to mappings when building models. - template - friend class TrainVisitor; + friend class LeafSizeRAWrapper; }; // class RASearch } // namespace neighbor diff --git a/src/mlpack/tests/krann_search_test.cpp b/src/mlpack/tests/krann_search_test.cpp index 4efa022776..411e08a025 100644 --- a/src/mlpack/tests/krann_search_test.cpp +++ b/src/mlpack/tests/krann_search_test.cpp @@ -620,34 +620,32 @@ TEST_CASE("RAModelTest", "[KRANNTest]") { // Ensure that we can build an RAModel and get correct // results. - typedef RAModel KNNModel; - arma::mat queryData, referenceData; data::Load("rann_test_r_3_900.csv", referenceData, true); data::Load("rann_test_q_3_100.csv", queryData, true); // Build all the possible models. - KNNModel models[20]; - models[0] = KNNModel(KNNModel::TreeTypes::KD_TREE, false); - models[1] = KNNModel(KNNModel::TreeTypes::KD_TREE, true); - models[2] = KNNModel(KNNModel::TreeTypes::COVER_TREE, false); - models[3] = KNNModel(KNNModel::TreeTypes::COVER_TREE, true); - models[4] = KNNModel(KNNModel::TreeTypes::R_TREE, false); - models[5] = KNNModel(KNNModel::TreeTypes::R_TREE, true); - models[6] = KNNModel(KNNModel::TreeTypes::R_STAR_TREE, false); - models[7] = KNNModel(KNNModel::TreeTypes::R_STAR_TREE, true); - models[8] = KNNModel(KNNModel::TreeTypes::X_TREE, false); - models[9] = KNNModel(KNNModel::TreeTypes::X_TREE, true); - models[10] = KNNModel(KNNModel::TreeTypes::HILBERT_R_TREE, false); - models[11] = KNNModel(KNNModel::TreeTypes::HILBERT_R_TREE, true); - models[12] = KNNModel(KNNModel::TreeTypes::R_PLUS_TREE, false); - models[13] = KNNModel(KNNModel::TreeTypes::R_PLUS_TREE, true); - models[14] = KNNModel(KNNModel::TreeTypes::R_PLUS_PLUS_TREE, false); - models[15] = KNNModel(KNNModel::TreeTypes::R_PLUS_PLUS_TREE, true); - models[16] = KNNModel(KNNModel::TreeTypes::UB_TREE, false); - models[17] = KNNModel(KNNModel::TreeTypes::UB_TREE, true); - models[18] = KNNModel(KNNModel::TreeTypes::OCTREE, false); - models[19] = KNNModel(KNNModel::TreeTypes::OCTREE, true); + RAModel models[20]; + models[0] = RAModel(RAModel::TreeTypes::KD_TREE, false); + models[1] = RAModel(RAModel::TreeTypes::KD_TREE, true); + models[2] = RAModel(RAModel::TreeTypes::COVER_TREE, false); + models[3] = RAModel(RAModel::TreeTypes::COVER_TREE, true); + models[4] = RAModel(RAModel::TreeTypes::R_TREE, false); + models[5] = RAModel(RAModel::TreeTypes::R_TREE, true); + models[6] = RAModel(RAModel::TreeTypes::R_STAR_TREE, false); + models[7] = RAModel(RAModel::TreeTypes::R_STAR_TREE, true); + models[8] = RAModel(RAModel::TreeTypes::X_TREE, false); + models[9] = RAModel(RAModel::TreeTypes::X_TREE, true); + models[10] = RAModel(RAModel::TreeTypes::HILBERT_R_TREE, false); + models[11] = RAModel(RAModel::TreeTypes::HILBERT_R_TREE, true); + models[12] = RAModel(RAModel::TreeTypes::R_PLUS_TREE, false); + models[13] = RAModel(RAModel::TreeTypes::R_PLUS_TREE, true); + models[14] = RAModel(RAModel::TreeTypes::R_PLUS_PLUS_TREE, false); + models[15] = RAModel(RAModel::TreeTypes::R_PLUS_PLUS_TREE, true); + models[16] = RAModel(RAModel::TreeTypes::UB_TREE, false); + models[17] = RAModel(RAModel::TreeTypes::UB_TREE, true); + models[18] = RAModel(RAModel::TreeTypes::OCTREE, false); + models[19] = RAModel(RAModel::TreeTypes::OCTREE, true); arma::Mat qrRanks; data::Load("rann_test_qr_ranks.csv", qrRanks, true, false); // No transpose. diff --git a/src/mlpack/tests/main_tests/krann_test.cpp b/src/mlpack/tests/main_tests/krann_test.cpp index b61044f104..57cb0905d6 100644 --- a/src/mlpack/tests/main_tests/krann_test.cpp +++ b/src/mlpack/tests/main_tests/krann_test.cpp @@ -192,7 +192,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNRefModelTest", // Input pre-trained model. SetInputParam("input_model", - std::move(IO::GetParam("output_model"))); + std::move(IO::GetParam("output_model"))); Log::Fatal.ignoreInput = true; REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error); @@ -285,10 +285,10 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNModelReuseTest", arma::Mat neighbors; arma::mat distances; - RANNModel* output_model; + RAModel* output_model; neighbors = std::move(IO::GetParam>("neighbors")); distances = std::move(IO::GetParam("distances")); - output_model = std::move(IO::GetParam("output_model")); + output_model = std::move(IO::GetParam("output_model")); // Reset passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -324,8 +324,8 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentLeafSizes", mlpack::math::FixedRandomSeed(); mlpackMain(); - RANNModel* output_model; - output_model = std::move(IO::GetParam("output_model")); + RAModel* output_model; + output_model = std::move(IO::GetParam("output_model")); // Reset passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -341,7 +341,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentLeafSizes", // Check that initial output matrices and the output matrices using // saved model are equal. CHECK(output_model->LeafSize() == (int) 1); - CHECK(IO::GetParam("output_model")->LeafSize() == (int) 10); + CHECK(IO::GetParam("output_model")->LeafSize() == (int) 10); delete output_model; } @@ -361,8 +361,8 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentTau", mlpack::math::FixedRandomSeed(); mlpackMain(); - RANNModel* output_model; - output_model = std::move(IO::GetParam("output_model")); + RAModel* output_model; + output_model = std::move(IO::GetParam("output_model")); // Reset the passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -378,7 +378,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentTau", // Check that initial output matrices and the output matrices using // saved model are equal CHECK(output_model->Tau() == (double) 5); - CHECK(IO::GetParam("output_model")->Tau() == + CHECK(IO::GetParam("output_model")->Tau() == (double) 10); delete output_model; } @@ -399,8 +399,8 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentAlpha", mlpack::math::FixedRandomSeed(); mlpackMain(); - RANNModel* output_model; - output_model = std::move(IO::GetParam("output_model")); + RAModel* output_model; + output_model = std::move(IO::GetParam("output_model")); // Reset the passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -416,7 +416,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentAlpha", // Check that initial output matrices and the output matrices using // saved model are equal CHECK(output_model->Alpha() == (double) 0.95); - CHECK(IO::GetParam("output_model")->Alpha() == + CHECK(IO::GetParam("output_model")->Alpha() == (double) 0.80); delete output_model; } @@ -437,8 +437,8 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentTreeType", mlpack::math::FixedRandomSeed(); mlpackMain(); - RANNModel* output_model; - output_model = std::move(IO::GetParam("output_model")); + RAModel* output_model; + output_model = std::move(IO::GetParam("output_model")); // Reset the passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -455,7 +455,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentTreeType", // saved model are equal const bool check = output_model->TreeType() == 0; CHECK(check == true); - CHECK(IO::GetParam("output_model")->TreeType() == + CHECK(IO::GetParam("output_model")->TreeType() == 8); delete output_model; } @@ -476,8 +476,8 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentSingleSampleLimit", mlpack::math::FixedRandomSeed(); mlpackMain(); - RANNModel* output_model; - output_model = std::move(IO::GetParam("output_model")); + RAModel* output_model; + output_model = std::move(IO::GetParam("output_model")); // Reset passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -492,7 +492,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentSingleSampleLimit", // Check that initial output matrices and the output matrices using // saved model are equal. - CHECK(IO::GetParam("output_model")->SingleSampleLimit() == + CHECK(IO::GetParam("output_model")->SingleSampleLimit() == (int) 15); CHECK(output_model->SingleSampleLimit() == (int) 20); delete output_model; @@ -514,8 +514,8 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentSampleAtLeaves", mlpack::math::FixedRandomSeed(); mlpackMain(); - RANNModel* output_model; - output_model = std::move(IO::GetParam("output_model")); + RAModel* output_model; + output_model = std::move(IO::GetParam("output_model")); // Reset passed parameters. IO::GetSingleton().Parameters()["reference"].wasPassed = false; @@ -530,7 +530,7 @@ TEST_CASE_METHOD(KRANNTestFixture, "KRANNDifferentSampleAtLeaves", // Check that initial output matrices and the output matrices using // saved model are equal. - CHECK(IO::GetParam("output_model")->SampleAtLeaves() == + CHECK(IO::GetParam("output_model")->SampleAtLeaves() == (bool) true); CHECK(output_model->SampleAtLeaves() == (bool) false); delete output_model; From aeaf7528bead4d352c0bb9ca5aa9f99b845ffcbd Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 9 Jan 2021 21:49:02 -0500 Subject: [PATCH 442/550] Remove boost::visitor header. --- src/mlpack/methods/rann/ra_model.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlpack/methods/rann/ra_model.hpp b/src/mlpack/methods/rann/ra_model.hpp index afe42bf3da..8ed91a9c9b 100644 --- a/src/mlpack/methods/rann/ra_model.hpp +++ b/src/mlpack/methods/rann/ra_model.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include "ra_search.hpp" namespace mlpack { From dcac51194eae04b31ce5c6b7b5adc3204ee40933 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sat, 9 Jan 2021 22:10:04 -0500 Subject: [PATCH 443/550] Partial work on RSModel. --- src/mlpack/methods/range_search/rs_model.hpp | 347 +++++++++--------- .../methods/range_search/rs_model_impl.hpp | 257 ++++--------- 2 files changed, 238 insertions(+), 366 deletions(-) diff --git a/src/mlpack/methods/range_search/rs_model.hpp b/src/mlpack/methods/range_search/rs_model.hpp index ab71f20a21..bf1f6b98f4 100644 --- a/src/mlpack/methods/range_search/rs_model.hpp +++ b/src/mlpack/methods/range_search/rs_model.hpp @@ -27,189 +27,183 @@ namespace mlpack { namespace range { /** - * Alias template for Range Search. + * RSWrapperBase is a base wrapper class for holding all RangeSearch types + * supported by RSModel. All RangeSearch type wrappers inherit from this class, + * allowing a simple interface via inheritance for all the different types we + * want to support. + */ +class RSWrapperBase +{ + public: + //! Create the RSWrapperBase object. The base class does not hold anything, + //! so this constructor does nothing. + RSWrapperBase() { } + + //! Create a new RSWrapperBase that is the same as this one. This function + //! will properly handle polymorphism. + virtual RSWrapperBase* Clone() const = 0; + + //! Destruct the RSWrapperBase (nothing to do). + virtual ~RSWrapperBase() { } + + //! Get the dataset. + const arma::mat& Dataset() const = 0; + + //! Get whether single-tree search is being used. + bool SingleMode() const = 0; + //! Modify whether single-tree search is being used. + bool& SingleMode() = 0; + + //! Get whether naive search is being used. + bool Naive() const = 0; + //! Modify whether naive search is being used. + bool& Naive() = 0; + + //! Train the model (build the reference tree if needed). + virtual void Train(arma::mat&& referenceSet, + const size_t leafSize) = 0; + + //! Perform bichromatic range search (i.e. a search with a separate query + //! set). + virtual void Search(arma::mat&& querySet, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances, + const size_t leafSize) = 0; + + //! Perform monochromatic range search (i.e. a search with the reference set + //! as the query set). + virtual void Search(const math::Range& range, + std::vector>& neighbors, + std::vector>& distances) = 0; +}; + +/** + * RSWrapper is a wrapper class for most RangeSearch types. */ template class TreeType> -using RSType = RangeSearch; - -/** - * MonoSearchVisitor executes a monochromatic range search on the given - * RSType. Range Search is performed on the reference set itself, no querySet. - */ -class MonoSearchVisitor : public boost::static_visitor +class RSWrapper : public RSWrapperBase { - private: - //! The range to search for. - const math::Range& range; - //! Output neighbors. - std::vector>& neighbors; - //! Output distances. - std::vector>& distances; - public: - //! Perform monochromatic search with the given RangeSearch object. - template - void operator()(RSType* rs) const; + //! Create the RSWrapper object. + RSWrapper(const bool singleMode, const bool naive) : + ra(singleMode, naive) + { + // Nothing else to do. + } - //! Construct the MonoSearchVisitor with the given parameters. - MonoSearchVisitor(const math::Range& range, - std::vector>& neighbors, - std::vector>& distances): - range(range), - neighbors(neighbors), - distances(distances) - {}; + //! Create a new RSWrapper that is the same as this one. This function + //! will properly handle polymorphism. + virtual RSWrapper* Clone() const { return new RSWrapper(*this); } + + //! Destruct the RSWrapper (nothing to do). + virtual ~RSWrapper() { } + + //! Get the dataset. + const arma::mat& Dataset() const { return rs.ReferenceSet(); } + + //! Get whether single-tree search is being used. + bool SingleMode() const { return rs.SingleMode(); } + //! Modify whether single-tree search is being used. + bool& SingleMode() { return rs.SingleMode(); } + + //! Get whether naive search is being used. + bool Naive() const { return rs.Naive(); } + //! Modify whether naive search is being used. + bool& Naive() { return rs.Naive(); } + + //! Train the model (build the reference tree if needed). This ignores the + //! leaf size. + virtual void Train(arma::mat&& referenceSet, + const size_t /* leafSize */); + + //! Perform bichromatic range search (i.e. a search with a separate query + //! set). This ignores the leaf size. + virtual void Search(arma::mat&& querySet, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances, + const size_t /* leafSize */); + + //! Perform monochromatic range search (i.e. a search with the reference set + //! as the query set). + virtual void Search(const math::Range& range, + std::vector>& neighbors, + std::vector>& distances); + + //! Serialize the RangeSearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(rs)); + } + + protected: + typedef RangeSearch RSType; + + //! The instantiated RangeSearch object that we are wrapping. + RSType rs; }; /** - * BiSearchVisitor executes a bichromatic range search on the given RSType. - * We use template specialization to differentiate those tree types that - * accept leafSize as a parameter. In these cases, before doing range search, - * a query tree with proper leafSize is built from the querySet. + * LeafSizeRSWrapper wraps any RangeSearch type that needs to be able to take + * the leaf size into account when building trees. The implementations of + * Train() and bichromatic Search() take this leaf size into account. */ -class BiSearchVisitor : public boost::static_visitor +template class TreeType> +class LeafSizeRSWrapper : public RSWrapper { - private: - //! The query set for the bichromatic search. - const arma::mat& querySet; - //! Range to search neighbours for. - const math::Range& range; - //! The result vector for neighbors. - std::vector>& neighbors; - //! The result vector for distances. - std::vector>& distances; - //! The number of points in a leaf (for BinarySpaceTrees). - const size_t leafSize; - - //! Bichromatic range search on the given RSType considering the leafSize. - template - void SearchLeaf(RSType* rs) const; - public: - //! Alias template necessary for visual c++ compiler. - template class TreeType> - using RSTypeT = RSType; + //! Construct the LeafSizeRSWrapper by delegating to the RSWrapper + //! constructor. + LeafSizeRSWrapper(const bool singleMode, const bool naive) : + RSWrapper(singleMode, naive) + { + // Nothing else to do. + } - //! Default Bichromatic range search on the given RSType instance. - template class TreeType> - void operator()(RSTypeT* rs) const; + //! Delete the LeafSizeRSWrapper. + virtual ~LeafSizeRSWrapper() { } - //! Bichromatic range search on the given RSType specialized for KDTrees. - void operator()(RSTypeT* rs) const; + //! Return a copy of the LeafSizeRSWrapper. + virtual LeafSizeRSWrapper* Clone() const + { + return new LeafSizeRSWrapper(*this); + } - //! Bichromatic range search on the given RSType specialized for BallTrees. - void operator()(RSTypeT* rs) const; + //! Train a model with the given parameters. This overload uses leafSize. + virtual void Train(arma::mat&& referenceSet, + const size_t leafSize); - //! Bichromatic range search specialized for octrees. - void operator()(RSTypeT* rs) const; + //! Perform bichromatic search (e.g. search with a separate query set). This + //! overload takes the leaf size into account when building the query tree. + virtual void Search(arma::mat&& querySet, + const size_t k, + arma::Mat& neighbors, + arma::mat& distances, + const size_t leafSize); - //! Construct the BiSearchVisitor. - BiSearchVisitor(const arma::mat& querySet, - const math::Range& range, - std::vector>& neighbors, - std::vector>& distances, - const size_t leafSize); + //! Serialize the RangeSearch model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(rs)); + } + + protected: + using RSWrapper::rs; }; /** - * TrainVisitor sets the reference set to a new reference set on the given - * RSType. We use template specialization to differentiate those tree types that - * accept leafSize as a parameter. In these cases, a reference tree with proper - * leafSize is built from the referenceSet. + * The RSModel class provides an abstraction for the RangeSearch class, + * abstracting away the TreeType parameter and allowing it to be specified at + * runtime. This class is written for the sake of the `range_search` binding, + * but is not necessarily restricted to that usage. */ -class TrainVisitor : public boost::static_visitor -{ - private: - //! The reference set to use for training. - arma::mat&& referenceSet; - //! The leaf size, used only by BinarySpaceTree. - size_t leafSize; - //! Train on the given RsType considering the leafSize. - template - void TrainLeaf(RSType* rs) const; - - public: - //! Alias template necessary for visual c++ compiler. - template class TreeType> - using RSTypeT = RSType; - - //! Default Train on the given RSType instance. - template class TreeType> - void operator()(RSTypeT* rs) const; - - //! Train on the given RSType specialized for KDTrees. - void operator()(RSTypeT* rs) const; - - //! Train on the given RSType specialized for BallTrees. - void operator()(RSTypeT* rs) const; - - //! Train specialized for octrees. - void operator()(RSTypeT* rs) const; - - //! Construct the TrainVisitor object with the given reference set, leafSize - TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize); -}; - -/** - * ReferenceSetVisitor exposes the referenceSet of the given RSType. - */ -class ReferenceSetVisitor : public boost::static_visitor -{ - public: - //! Return the reference set. - template - const arma::mat& operator()(RSType* rs) const; -}; - -/** - * DeleteVisitor deletes the given RSType instance. - */ -class DeleteVisitor : public boost::static_visitor -{ - public: - //! Delete the RSType object. - template - void operator()(RSType* rs) const; -}; - -/** - * SingleModeVisitor exposes the SingleMode() method of the given RSType. - */ -class SingleModeVisitor : public boost::static_visitor -{ - public: - /** - * Get a reference to the singleMode parameter of the given RangeSeach - * object. - */ - template - bool& operator()(RSType* rs) const; -}; - -/** - * NaiveVisitor exposes the Naive() method of the given RSType. - */ -class NaiveVisitor : public boost::static_visitor -{ - public: - /** - * Get a reference to the naive parameter of the given RangeSearch object. - */ - template - bool& operator()(RSType* rs) const; -}; - class RSModel { public: @@ -232,7 +226,10 @@ class RSModel }; private: + //! The type of tree we are using. TreeTypes treeType; + //! (Only used for some tree types.) The leaf size to use when building a + //! tree. size_t leafSize; //! If true, we randomly project the data into a new basis before search. @@ -243,22 +240,8 @@ class RSModel /** * rSearch holds an instance of the RangeSearch class for the current * treeType. It is initialized every time BuildModel is executed. - * We access to the contained value through the visitor classes defined above. */ - boost::variant*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*, - RSType*> rSearch; + RSWrapperBase* rSearch; public: /** @@ -304,17 +287,17 @@ class RSModel void serialize(Archive& ar, const uint32_t /* version */); //! Expose the dataset. - const arma::mat& Dataset() const; + const arma::mat& Dataset() const { return rSearch->Dataset(); } //! Get whether the model is in single-tree search mode. - bool SingleMode() const; + bool SingleMode() const { return rSearch->SingleMode(); } //! Modify whether the model is in single-tree search mode. - bool& SingleMode(); + bool& SingleMode() { return rSearch->SingleMode(); } //! Get whether the model is in naive search mode. - bool Naive() const; + bool Naive() const { return rSearch->Naive(); } //! Modify whether the model is in naive search mode. - bool& Naive(); + bool& Naive() { return rSearch->Naive(); } //! Get the leaf size (applicable to everything but the cover tree). size_t LeafSize() const { return leafSize; } @@ -390,7 +373,7 @@ class RSModel } // namespace range } // namespace mlpack -// Include implementation (of serialize() and inline functions). +// Include implementation (of serialize() and templated wrapper classes). #include "rs_model_impl.hpp" #endif diff --git a/src/mlpack/methods/range_search/rs_model_impl.hpp b/src/mlpack/methods/range_search/rs_model_impl.hpp index ea94903104..983029c4fb 100644 --- a/src/mlpack/methods/range_search/rs_model_impl.hpp +++ b/src/mlpack/methods/range_search/rs_model_impl.hpp @@ -24,27 +24,28 @@ namespace range { * Initialize the RSModel with the given tree type and whether or not a random * basis should be used. */ -inline RSModel::RSModel(TreeTypes treeType, bool randomBasis) : +RSModel::RSModel(TreeTypes treeType, bool randomBasis) : treeType(treeType), leafSize(0), - randomBasis(randomBasis) + randomBasis(randomBasis), + rSearch(NULL) { // Nothing to do. } // Copy constructor. -inline RSModel::RSModel(const RSModel& other) : +RSModel::RSModel(const RSModel& other) : treeType(other.treeType), leafSize(other.leafSize), randomBasis(other.randomBasis), q(other.q), - rSearch(other.rSearch) + rSearch(other.rSearch->Clone()) { // Nothing to do. } // Move constructor. -inline RSModel::RSModel(RSModel&& other) : +RSModel::RSModel(RSModel&& other) : treeType(other.treeType), leafSize(other.leafSize), randomBasis(other.randomBasis), @@ -55,32 +56,56 @@ inline RSModel::RSModel(RSModel&& other) : other.treeType = TreeTypes::KD_TREE; other.leafSize = 0; other.randomBasis = false; - other.rSearch = decltype(other.rSearch)(); } -inline RSModel& RSModel::operator=(RSModel other) +// Copy operator. +RSModel& RSModel::operator=(const RSModel& other) { - boost::apply_visitor(DeleteVisitor(), rSearch); + if (this != &other) + { + delete rSearch; - treeType = other.treeType; - leafSize = other.leafSize; - randomBasis = other.randomBasis; - q = std::move(other.q); - rSearch = std::move(other.rSearch); + treeType = other.treeType; + leafSize = other.leafSize; + randomBasis = other.randomBasis; + q = other.q; + rSearch = other.rSearch->Clone(); + } + + return *this; +} + +// Move operator. +RSModel& RSModel::operator=(RSModel&& other) +{ + if (this != &other) + { + delete rSearch; + + treeType = other.treeType; + leafSize = other.leafSize; + randomBasis = other.randomBasis; + q = std::move(other.q); + rSearch = std::move(other.rSearch); + + other.treeType = TreeTypes::KD_TREE; + other.leafSize = 0; + other.randomBasis = false; + } return *this; } // Clean memory, if necessary. -inline RSModel::~RSModel() +RSModel::~RSModel() { - boost::apply_visitor(DeleteVisitor(), rSearch); + delete rSearch; } -inline void RSModel::BuildModel(arma::mat&& referenceSet, - const size_t leafSize, - const bool naive, - const bool singleMode) +void RSModel::BuildModel(arma::mat&& referenceSet, + const size_t leafSize, + const bool naive, + const bool singleMode) { // Initialize random basis if necessary. if (randomBasis) @@ -92,7 +117,7 @@ inline void RSModel::BuildModel(arma::mat&& referenceSet, this->leafSize = leafSize; // Clean memory, if necessary. - boost::apply_visitor(DeleteVisitor(), rSearch); + delete rSearch; // Do we need to modify the reference set? if (randomBasis) @@ -107,64 +132,63 @@ inline void RSModel::BuildModel(arma::mat&& referenceSet, switch (treeType) { case KD_TREE: - rSearch = new RSType (naive, singleMode); + rSearch = new LeafSizeRSWrapper(naive, singleMode); break; case COVER_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case R_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case R_STAR_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case BALL_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new LeafSizeRSWrapper(naive, singleMode); break; case X_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case HILBERT_R_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case R_PLUS_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case R_PLUS_PLUS_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case VP_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case RP_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case MAX_RP_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case UB_TREE: - rSearch = new RSType(naive, singleMode); + rSearch = new RSWrapper(naive, singleMode); break; case OCTREE: - rSearch = new RSType(naive, singleMode); + rSearch = new LeafSizeRSWrapper(naive, singleMode); break; } - TrainVisitor tn(std::move(referenceSet), leafSize); - boost::apply_visitor(tn, rSearch); + rSearch->Train(std::move(referenceSet), leafSize); if (!naive) { @@ -174,10 +198,10 @@ inline void RSModel::BuildModel(arma::mat&& referenceSet, } // Perform range search. -inline void RSModel::Search(arma::mat&& querySet, - const math::Range& range, - std::vector>& neighbors, - std::vector>& distances) +void RSModel::Search(arma::mat&& querySet, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances) { // We may need to map the query set randomly. if (randomBasis) @@ -192,16 +216,13 @@ inline void RSModel::Search(arma::mat&& querySet, else Log::Info << "brute-force (naive) search..." << std::endl; - - BiSearchVisitor search(querySet, range, neighbors, distances, - leafSize); - boost::apply_visitor(search, rSearch); + rSearch->Search(std::move(querySet), range, neighbors, distances, leafSize); } // Perform range search (monochromatic case). -inline void RSModel::Search(const math::Range& range, - std::vector>& neighbors, - std::vector>& distances) +void RSModel::Search(const math::Range& range, + std::vector>& neighbors, + std::vector>& distances) { Log::Info << "Search for points in the range [" << range.Lo() << ", " << range.Hi() << "] with "; @@ -212,12 +233,11 @@ inline void RSModel::Search(const math::Range& range, else Log::Info << "brute-force (naive) search..." << std::endl; - MonoSearchVisitor search(range, neighbors, distances); - boost::apply_visitor(search, rSearch); + rSearch->Search(range, neighbors, distances); } // Get the name of the tree type. -inline std::string RSModel::TreeName() const +std::string RSModel::TreeName() const { switch (treeType) { @@ -255,34 +275,11 @@ inline std::string RSModel::TreeName() const } // Clean memory. -inline void RSModel::CleanMemory() +void RSModel::CleanMemory() { - boost::apply_visitor(DeleteVisitor(), rSearch); + delete rSearch; } -//! Monochromatic range search on the given RSType instance. -template -void MonoSearchVisitor::operator()(RSType* rs) const -{ - if (rs) - return rs->Search(range, neighbors, distances); - throw std::runtime_error("no range search model initialized"); -} - -//! Save parameters for bichromatic range search. -inline BiSearchVisitor::BiSearchVisitor( - const arma::mat& querySet, - const math::Range& range, - std::vector>& neighbors, - std::vector>& distances, - const size_t leafSize) : - querySet(querySet), - range(range), - neighbors(neighbors), - distances(distances), - leafSize(leafSize) -{} - //! Default Bichromatic range search on the given RSType instance. template* rs) const throw std::runtime_error("no range search model initialized"); } -//! Bichromatic range search on the given RSType specialized for KDTrees. -inline void BiSearchVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return SearchLeaf(rs); - throw std::runtime_error("no range search model initialized"); -} - -//! Bichromatic range search on the given RSType specialized for BallTrees. -inline void BiSearchVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return SearchLeaf(rs); - throw std::runtime_error("no range search model initialized"); -} - -//! Bichromatic range search specialized for Ocrees. -inline void BiSearchVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return SearchLeaf(rs); - throw std::runtime_error("no range search model initialized"); -} - //! Bichromatic range search on the given RSType considering the leafSize. template void BiSearchVisitor::SearchLeaf(RSType* rs) const @@ -368,30 +341,6 @@ void TrainVisitor::operator()(RSTypeT* rs) const throw std::runtime_error("no range search model initialized"); } -//! Train on the given RSType specialized for KDTrees. -inline void TrainVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return TrainLeaf(rs); - throw std::runtime_error("no range search model initialized"); -} - -//! Train on the given RSType specialized for BallTrees. -inline void TrainVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return TrainLeaf(rs); - throw std::runtime_error("no range search model initialized"); -} - -//! Train specialized for Octrees. -inline void TrainVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return TrainLeaf(rs); - throw std::runtime_error("no range search model initialized"); -} - //! Train on the given RSType considering the leafSize. template void TrainVisitor::TrainLeaf(RSType* rs) const @@ -412,41 +361,6 @@ void TrainVisitor::TrainLeaf(RSType* rs) const } } -//! Expose the referenceSet of the given RSType. -template -const arma::mat& ReferenceSetVisitor::operator()(RSType* rs) const -{ - if (rs) - return rs->ReferenceSet(); - throw std::runtime_error("no range search model initialized"); -} - -//! For cleaning memory -template -void DeleteVisitor::operator()(RSType* rs) const -{ - if (rs) - delete rs; -} - -//! Return whether single mode enabled -template -bool& SingleModeVisitor::operator()(RSType* rs) const -{ - if (rs) - return rs->SingleMode(); - throw std::runtime_error("no range search model initialized"); -} - -//! Exposes Naive() function of given RSType -template -bool& NaiveVisitor::operator()(RSType* rs) const -{ - if (rs) - return rs->Naive(); - throw std::runtime_error("no range search model initialized"); -} - // Serialize the model. template void RSModel::serialize(Archive& ar, const uint32_t /* version */) @@ -457,37 +371,12 @@ void RSModel::serialize(Archive& ar, const uint32_t /* version */) // This should never happen, but just in case... if (cereal::is_loading()) - boost::apply_visitor(DeleteVisitor(), rSearch); + delete rSearch; // We'll only need to serialize one of the model objects, based on the type. ar(CEREAL_VARIANT_POINTER(rSearch)); } -inline const arma::mat& RSModel::Dataset() const -{ - return boost::apply_visitor(ReferenceSetVisitor(), rSearch); -} - -inline bool RSModel::SingleMode() const -{ - return boost::apply_visitor(SingleModeVisitor(), rSearch); -} - -inline bool& RSModel::SingleMode() -{ - return boost::apply_visitor(SingleModeVisitor(), rSearch); -} - -inline bool RSModel::Naive() const -{ - return boost::apply_visitor(NaiveVisitor(), rSearch); -} - -inline bool& RSModel::Naive() -{ - return boost::apply_visitor(NaiveVisitor(), rSearch); -} - } // namespace range } // namespace mlpack From 0cb7e6427312a64f1b65fcd241015242b2b58f7b Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 10 Jan 2021 11:13:24 -0500 Subject: [PATCH 444/550] Remove boost::visitor from RSModel. --- .../methods/range_search/CMakeLists.txt | 1 + .../methods/range_search/range_search.hpp | 7 +- src/mlpack/methods/range_search/rs_model.cpp | 280 ++++++++++ src/mlpack/methods/range_search/rs_model.hpp | 64 +-- .../methods/range_search/rs_model_impl.hpp | 487 +++++++----------- 5 files changed, 495 insertions(+), 344 deletions(-) create mode 100644 src/mlpack/methods/range_search/rs_model.cpp diff --git a/src/mlpack/methods/range_search/CMakeLists.txt b/src/mlpack/methods/range_search/CMakeLists.txt index 0a1912b6b4..8a0ff5925f 100644 --- a/src/mlpack/methods/range_search/CMakeLists.txt +++ b/src/mlpack/methods/range_search/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES range_search_stat.hpp rs_model.hpp rs_model_impl.hpp + rs_model.cpp ) # Add directory name to sources. diff --git a/src/mlpack/methods/range_search/range_search.hpp b/src/mlpack/methods/range_search/range_search.hpp index 06575005ac..257401d064 100644 --- a/src/mlpack/methods/range_search/range_search.hpp +++ b/src/mlpack/methods/range_search/range_search.hpp @@ -22,7 +22,10 @@ namespace mlpack { namespace range /** Range-search routines. */ { //! Forward declaration. -class TrainVisitor; +template class TreeType> +class LeafSizeRSWrapper; /** * The RangeSearch class is a template class for performing range searches. It @@ -310,7 +313,7 @@ class RangeSearch size_t scores; //! For access to mappings when building models. - friend class TrainVisitor; + friend class LeafSizeRSWrapper; }; } // namespace range diff --git a/src/mlpack/methods/range_search/rs_model.cpp b/src/mlpack/methods/range_search/rs_model.cpp new file mode 100644 index 0000000000..fdf3cd2128 --- /dev/null +++ b/src/mlpack/methods/range_search/rs_model.cpp @@ -0,0 +1,280 @@ +/** + * @file methods/range_search/rs_model_impl.hpp + * @author Ryan Curtin + * + * Implementation of serialize() and inline functions for RSModel. + * + * 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. + */ +#include "rs_model.hpp" + +#include + +namespace mlpack { +namespace range { + +/** + * Initialize the RSModel with the given tree type and whether or not a random + * basis should be used. + */ +RSModel::RSModel(TreeTypes treeType, bool randomBasis) : + treeType(treeType), + leafSize(0), + randomBasis(randomBasis), + rSearch(NULL) +{ + // Nothing to do. +} + +// Copy constructor. +RSModel::RSModel(const RSModel& other) : + treeType(other.treeType), + leafSize(other.leafSize), + randomBasis(other.randomBasis), + q(other.q), + rSearch(other.rSearch->Clone()) +{ + // Nothing to do. +} + +// Move constructor. +RSModel::RSModel(RSModel&& other) : + treeType(other.treeType), + leafSize(other.leafSize), + randomBasis(other.randomBasis), + q(std::move(other.q)), + rSearch(std::move(other.rSearch)) +{ + // Reset other model. + other.treeType = TreeTypes::KD_TREE; + other.leafSize = 0; + other.randomBasis = false; +} + +// Copy operator. +RSModel& RSModel::operator=(const RSModel& other) +{ + if (this != &other) + { + delete rSearch; + + treeType = other.treeType; + leafSize = other.leafSize; + randomBasis = other.randomBasis; + q = other.q; + rSearch = other.rSearch->Clone(); + } + + return *this; +} + +// Move operator. +RSModel& RSModel::operator=(RSModel&& other) +{ + if (this != &other) + { + delete rSearch; + + treeType = other.treeType; + leafSize = other.leafSize; + randomBasis = other.randomBasis; + q = std::move(other.q); + rSearch = std::move(other.rSearch); + + other.treeType = TreeTypes::KD_TREE; + other.leafSize = 0; + other.randomBasis = false; + } + + return *this; +} + +// Clean memory, if necessary. +RSModel::~RSModel() +{ + delete rSearch; +} + +void RSModel::BuildModel(arma::mat&& referenceSet, + const size_t leafSize, + const bool naive, + const bool singleMode) +{ + // Initialize random basis if necessary. + if (randomBasis) + { + Log::Info << "Creating random basis..." << std::endl; + math::RandomBasis(q, referenceSet.n_rows); + } + + this->leafSize = leafSize; + + // Clean memory, if necessary. + delete rSearch; + + // Do we need to modify the reference set? + if (randomBasis) + referenceSet = q * referenceSet; + + if (!naive) + { + Timer::Start("tree_building"); + Log::Info << "Building reference tree..." << std::endl; + } + + switch (treeType) + { + case KD_TREE: + rSearch = new LeafSizeRSWrapper(naive, singleMode); + break; + + case COVER_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case R_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case R_STAR_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case BALL_TREE: + rSearch = new LeafSizeRSWrapper(naive, singleMode); + break; + + case X_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case HILBERT_R_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case R_PLUS_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case R_PLUS_PLUS_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case VP_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case RP_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case MAX_RP_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case UB_TREE: + rSearch = new RSWrapper(naive, singleMode); + break; + + case OCTREE: + rSearch = new LeafSizeRSWrapper(naive, singleMode); + break; + } + + rSearch->Train(std::move(referenceSet), leafSize); + + if (!naive) + { + Timer::Stop("tree_building"); + Log::Info << "Tree built." << std::endl; + } +} + +// Perform range search. +void RSModel::Search(arma::mat&& querySet, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances) +{ + // We may need to map the query set randomly. + if (randomBasis) + querySet = q * querySet; + + Log::Info << "Search for points in the range [" << range.Lo() << ", " + << range.Hi() << "] with "; + if (!Naive() && !SingleMode()) + Log::Info << "dual-tree " << TreeName() << " search..." << std::endl; + else if (!Naive()) + Log::Info << "single-tree " << TreeName() << " search..." << std::endl; + else + Log::Info << "brute-force (naive) search..." << std::endl; + + rSearch->Search(std::move(querySet), range, neighbors, distances, leafSize); +} + +// Perform range search (monochromatic case). +void RSModel::Search(const math::Range& range, + std::vector>& neighbors, + std::vector>& distances) +{ + Log::Info << "Search for points in the range [" << range.Lo() << ", " + << range.Hi() << "] with "; + if (!Naive() && !SingleMode()) + Log::Info << "dual-tree " << TreeName() << " search..." << std::endl; + else if (!Naive()) + Log::Info << "single-tree " << TreeName() << " search..." << std::endl; + else + Log::Info << "brute-force (naive) search..." << std::endl; + + rSearch->Search(range, neighbors, distances); +} + +// Get the name of the tree type. +std::string RSModel::TreeName() const +{ + switch (treeType) + { + case KD_TREE: + return "kd-tree"; + case COVER_TREE: + return "cover tree"; + case R_TREE: + return "R tree"; + case R_STAR_TREE: + return "R* tree"; + case BALL_TREE: + return "ball tree"; + case X_TREE: + return "X tree"; + case HILBERT_R_TREE: + return "Hilbert R tree"; + case R_PLUS_TREE: + return "R+ tree"; + case R_PLUS_PLUS_TREE: + return "R++ tree"; + case VP_TREE: + return "vantage point tree"; + case RP_TREE: + return "random projection tree (mean split)"; + case MAX_RP_TREE: + return "random projection tree (max split)"; + case UB_TREE: + return "UB tree"; + case OCTREE: + return "octree"; + default: + return "unknown tree"; + } +} + +// Clean memory. +void RSModel::CleanMemory() +{ + delete rSearch; +} + +} // namespace range +} // namespace mlpack diff --git a/src/mlpack/methods/range_search/rs_model.hpp b/src/mlpack/methods/range_search/rs_model.hpp index bf1f6b98f4..12638c2836 100644 --- a/src/mlpack/methods/range_search/rs_model.hpp +++ b/src/mlpack/methods/range_search/rs_model.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include "range_search.hpp" @@ -47,17 +46,17 @@ class RSWrapperBase virtual ~RSWrapperBase() { } //! Get the dataset. - const arma::mat& Dataset() const = 0; + virtual const arma::mat& Dataset() const = 0; //! Get whether single-tree search is being used. - bool SingleMode() const = 0; + virtual bool SingleMode() const = 0; //! Modify whether single-tree search is being used. - bool& SingleMode() = 0; + virtual bool& SingleMode() = 0; //! Get whether naive search is being used. - bool Naive() const = 0; + virtual bool Naive() const = 0; //! Modify whether naive search is being used. - bool& Naive() = 0; + virtual bool& Naive() = 0; //! Train the model (build the reference tree if needed). virtual void Train(arma::mat&& referenceSet, @@ -89,7 +88,7 @@ class RSWrapper : public RSWrapperBase public: //! Create the RSWrapper object. RSWrapper(const bool singleMode, const bool naive) : - ra(singleMode, naive) + rs(singleMode, naive) { // Nothing else to do. } @@ -182,9 +181,9 @@ class LeafSizeRSWrapper : public RSWrapper //! Perform bichromatic search (e.g. search with a separate query set). This //! overload takes the leaf size into account when building the query tree. virtual void Search(arma::mat&& querySet, - const size_t k, - arma::Mat& neighbors, - arma::mat& distances, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances, const size_t leafSize); //! Serialize the RangeSearch model. @@ -225,25 +224,6 @@ class RSModel OCTREE }; - private: - //! The type of tree we are using. - TreeTypes treeType; - //! (Only used for some tree types.) The leaf size to use when building a - //! tree. - size_t leafSize; - - //! If true, we randomly project the data into a new basis before search. - bool randomBasis; - //! Random projection matrix. - arma::mat q; - - /** - * rSearch holds an instance of the RangeSearch class for the current - * treeType. It is initialized every time BuildModel is executed. - */ - RSWrapperBase* rSearch; - - public: /** * Initialize the RSModel with the given type and whether or not a random * basis should be used. @@ -271,11 +251,16 @@ class RSModel /** * Copy the given RSModel. * - * Use std::move to pass in the model if the old copy is no longer needed. + * @param other RSModel to copy. + */ + RSModel& operator=(const RSModel& other); + + /** + * Take ownership of the given RSModel's data. * * @param other RSModel to copy. */ - RSModel& operator=(RSModel other); + RSModel& operator=(RSModel&& other); /** * Clean memory, if necessary. @@ -358,6 +343,23 @@ class RSModel std::vector>& distances); private: + //! The type of tree we are using. + TreeTypes treeType; + //! (Only used for some tree types.) The leaf size to use when building a + //! tree. + size_t leafSize; + + //! If true, we randomly project the data into a new basis before search. + bool randomBasis; + //! Random projection matrix. + arma::mat q; + + /** + * rSearch holds an instance of the RangeSearch class for the current + * treeType. It is initialized every time BuildModel is executed. + */ + RSWrapperBase* rSearch; + /** * Return a string representing the name of the tree. This is used for * logging output. diff --git a/src/mlpack/methods/range_search/rs_model_impl.hpp b/src/mlpack/methods/range_search/rs_model_impl.hpp index 983029c4fb..2df060f977 100644 --- a/src/mlpack/methods/range_search/rs_model_impl.hpp +++ b/src/mlpack/methods/range_search/rs_model_impl.hpp @@ -20,295 +20,87 @@ namespace mlpack { namespace range { -/** - * Initialize the RSModel with the given tree type and whether or not a random - * basis should be used. - */ -RSModel::RSModel(TreeTypes treeType, bool randomBasis) : - treeType(treeType), - leafSize(0), - randomBasis(randomBasis), - rSearch(NULL) -{ - // Nothing to do. -} - -// Copy constructor. -RSModel::RSModel(const RSModel& other) : - treeType(other.treeType), - leafSize(other.leafSize), - randomBasis(other.randomBasis), - q(other.q), - rSearch(other.rSearch->Clone()) -{ - // Nothing to do. -} - -// Move constructor. -RSModel::RSModel(RSModel&& other) : - treeType(other.treeType), - leafSize(other.leafSize), - randomBasis(other.randomBasis), - q(std::move(other.q)), - rSearch(std::move(other.rSearch)) -{ - // Reset other model. - other.treeType = TreeTypes::KD_TREE; - other.leafSize = 0; - other.randomBasis = false; -} - -// Copy operator. -RSModel& RSModel::operator=(const RSModel& other) -{ - if (this != &other) - { - delete rSearch; - - treeType = other.treeType; - leafSize = other.leafSize; - randomBasis = other.randomBasis; - q = other.q; - rSearch = other.rSearch->Clone(); - } - - return *this; -} - -// Move operator. -RSModel& RSModel::operator=(RSModel&& other) -{ - if (this != &other) - { - delete rSearch; - - treeType = other.treeType; - leafSize = other.leafSize; - randomBasis = other.randomBasis; - q = std::move(other.q); - rSearch = std::move(other.rSearch); - - other.treeType = TreeTypes::KD_TREE; - other.leafSize = 0; - other.randomBasis = false; - } - - return *this; -} - -// Clean memory, if necessary. -RSModel::~RSModel() -{ - delete rSearch; -} - -void RSModel::BuildModel(arma::mat&& referenceSet, - const size_t leafSize, - const bool naive, - const bool singleMode) -{ - // Initialize random basis if necessary. - if (randomBasis) - { - Log::Info << "Creating random basis..." << std::endl; - math::RandomBasis(q, referenceSet.n_rows); - } - - this->leafSize = leafSize; - - // Clean memory, if necessary. - delete rSearch; - - // Do we need to modify the reference set? - if (randomBasis) - referenceSet = q * referenceSet; - - if (!naive) - { - Timer::Start("tree_building"); - Log::Info << "Building reference tree..." << std::endl; - } - - switch (treeType) - { - case KD_TREE: - rSearch = new LeafSizeRSWrapper(naive, singleMode); - break; - - case COVER_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case R_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case R_STAR_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case BALL_TREE: - rSearch = new LeafSizeRSWrapper(naive, singleMode); - break; - - case X_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case HILBERT_R_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case R_PLUS_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case R_PLUS_PLUS_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case VP_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case RP_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case MAX_RP_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case UB_TREE: - rSearch = new RSWrapper(naive, singleMode); - break; - - case OCTREE: - rSearch = new LeafSizeRSWrapper(naive, singleMode); - break; - } - - rSearch->Train(std::move(referenceSet), leafSize); - - if (!naive) - { - Timer::Stop("tree_building"); - Log::Info << "Tree built." << std::endl; - } -} - -// Perform range search. -void RSModel::Search(arma::mat&& querySet, - const math::Range& range, - std::vector>& neighbors, - std::vector>& distances) -{ - // We may need to map the query set randomly. - if (randomBasis) - querySet = q * querySet; - - Log::Info << "Search for points in the range [" << range.Lo() << ", " - << range.Hi() << "] with "; - if (!Naive() && !SingleMode()) - Log::Info << "dual-tree " << TreeName() << " search..." << std::endl; - else if (!Naive()) - Log::Info << "single-tree " << TreeName() << " search..." << std::endl; - else - Log::Info << "brute-force (naive) search..." << std::endl; - - rSearch->Search(std::move(querySet), range, neighbors, distances, leafSize); -} - -// Perform range search (monochromatic case). -void RSModel::Search(const math::Range& range, - std::vector>& neighbors, - std::vector>& distances) -{ - Log::Info << "Search for points in the range [" << range.Lo() << ", " - << range.Hi() << "] with "; - if (!Naive() && !SingleMode()) - Log::Info << "dual-tree " << TreeName() << " search..." << std::endl; - else if (!Naive()) - Log::Info << "single-tree " << TreeName() << " search..." << std::endl; - else - Log::Info << "brute-force (naive) search..." << std::endl; - - rSearch->Search(range, neighbors, distances); -} - -// Get the name of the tree type. -std::string RSModel::TreeName() const -{ - switch (treeType) - { - case KD_TREE: - return "kd-tree"; - case COVER_TREE: - return "cover tree"; - case R_TREE: - return "R tree"; - case R_STAR_TREE: - return "R* tree"; - case BALL_TREE: - return "ball tree"; - case X_TREE: - return "X tree"; - case HILBERT_R_TREE: - return "Hilbert R tree"; - case R_PLUS_TREE: - return "R+ tree"; - case R_PLUS_PLUS_TREE: - return "R++ tree"; - case VP_TREE: - return "vantage point tree"; - case RP_TREE: - return "random projection tree (mean split)"; - case MAX_RP_TREE: - return "random projection tree (max split)"; - case UB_TREE: - return "UB tree"; - case OCTREE: - return "octree"; - default: - return "unknown tree"; - } -} - -// Clean memory. -void RSModel::CleanMemory() -{ - delete rSearch; -} - -//! Default Bichromatic range search on the given RSType instance. template class TreeType> -void BiSearchVisitor::operator()(RSTypeT* rs) const +void RSWrapper::Train(arma::mat&& referenceSet, + const size_t /* leafSize */) { - if (rs) - return rs->Search(querySet, range, neighbors, distances); - throw std::runtime_error("no range search model initialized"); + rs.Train(std::move(referenceSet)); } -//! Bichromatic range search on the given RSType considering the leafSize. -template -void BiSearchVisitor::SearchLeaf(RSType* rs) const +template class TreeType> +void RSWrapper::Search(arma::mat&& querySet, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances, + const size_t /* leafSize */) { - if (!rs->Naive() && !rs->SingleMode()) + rs.Search(std::move(querySet), range, neighbors, distances); +} + +template class TreeType> +void RSWrapper::Search(const math::Range& range, + std::vector>& neighbors, + std::vector>& distances) +{ + rs.Search(range, neighbors, distances); +} + +template class TreeType> +void LeafSizeRSWrapper::Train(arma::mat&& referenceSet, + const size_t leafSize) +{ + if (rs.Naive()) + { + rs.Train(std::move(referenceSet)); + } + else + { + std::vector oldFromNewReferences; + typename decltype(rs)::Tree* tree = + new typename decltype(rs)::Tree(std::move(referenceSet), + oldFromNewReferences, + leafSize); + rs.Train(tree); + + // Give the model ownership of the tree and the mappings. + rs.treeOwner = true; + rs.oldFromNewReferences = std::move(oldFromNewReferences); + } +} + +template class TreeType> +void LeafSizeRSWrapper::Search( + arma::mat&& querySet, + const math::Range& range, + std::vector>& neighbors, + std::vector>& distances, + const size_t leafSize) +{ + if (!rs.Naive() && !rs.SingleMode()) { // Build a second tree and search. Timer::Start("tree_building"); Log::Info << "Building query tree..." << std::endl; std::vector oldFromNewQueries; - typename RSType::Tree queryTree(std::move(querySet), oldFromNewQueries, - leafSize); + typename decltype(rs)::Tree queryTree(std::move(querySet), + oldFromNewQueries, + leafSize); Log::Info << "Tree built." << std::endl; Timer::Stop("tree_building"); std::vector> neighborsOut; std::vector> distancesOut; - rs->Search(&queryTree, range, neighborsOut, distancesOut); + rs.Search(&queryTree, range, neighborsOut, distancesOut); // Remap the query points. neighbors.resize(queryTree.Dataset().n_cols); @@ -319,45 +111,9 @@ void BiSearchVisitor::SearchLeaf(RSType* rs) const distances[oldFromNewQueries[i]] = distancesOut[i]; } } - else - rs->Search(querySet, range, neighbors, distances); -} - -//! Save parameters for Train. -inline TrainVisitor::TrainVisitor(arma::mat&& referenceSet, - const size_t leafSize) : - referenceSet(std::move(referenceSet)), - leafSize(leafSize) -{} - -//! Default Train on the given RSType instance. -template class TreeType> -void TrainVisitor::operator()(RSTypeT* rs) const -{ - if (rs) - return rs->Train(std::move(referenceSet)); - throw std::runtime_error("no range search model initialized"); -} - -//! Train on the given RSType considering the leafSize. -template -void TrainVisitor::TrainLeaf(RSType* rs) const -{ - if (rs->Naive()) - rs->Train(std::move(referenceSet)); else { - std::vector oldFromNewReferences; - typename RSType::Tree* tree = - new typename RSType::Tree(std::move(referenceSet), oldFromNewReferences, - leafSize); - rs->Train(tree); - - // Give the model ownership of the tree and the mappings. - rs->treeOwner = true; - rs->oldFromNewReferences = std::move(oldFromNewReferences); + rs.Search(std::move(querySet), range, neighbors, distances); } } @@ -373,8 +129,117 @@ void RSModel::serialize(Archive& ar, const uint32_t /* version */) if (cereal::is_loading()) delete rSearch; - // We'll only need to serialize one of the model objects, based on the type. - ar(CEREAL_VARIANT_POINTER(rSearch)); + // Avoid polymorphic serialization by explicitly serializing the correct type. + switch (treeType) + { + case KD_TREE: + { + LeafSizeRSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case COVER_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case R_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case R_STAR_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case BALL_TREE: + { + LeafSizeRSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case X_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case HILBERT_R_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case R_PLUS_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case R_PLUS_PLUS_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case VP_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case RP_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + + case MAX_RP_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case UB_TREE: + { + RSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + case OCTREE: + { + LeafSizeRSWrapper& typedSearch = + dynamic_cast&>(*rSearch); + ar(CEREAL_NVP(typedSearch)); + break; + } + } } } // namespace range From c83c6421cf37c74118183e7231d0b00e0faef685 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 10 Jan 2021 12:22:29 -0500 Subject: [PATCH 445/550] Fix name of file in comment. --- src/mlpack/methods/range_search/rs_model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/range_search/rs_model.cpp b/src/mlpack/methods/range_search/rs_model.cpp index fdf3cd2128..807a347ee4 100644 --- a/src/mlpack/methods/range_search/rs_model.cpp +++ b/src/mlpack/methods/range_search/rs_model.cpp @@ -1,5 +1,5 @@ /** - * @file methods/range_search/rs_model_impl.hpp + * @file methods/range_search/rs_model.cpp * @author Ryan Curtin * * Implementation of serialize() and inline functions for RSModel. From f216b9b3ef3ff259f0d6fdcf0759efae56d594bc Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 10 Jan 2021 13:05:14 -0500 Subject: [PATCH 446/550] Remove boost::visitor from KDEModel. --- src/mlpack/methods/kde/CMakeLists.txt | 1 + src/mlpack/methods/kde/kde_model.cpp | 312 ++++++++++ src/mlpack/methods/kde/kde_model.hpp | 464 +++++---------- src/mlpack/methods/kde/kde_model_impl.hpp | 673 ++++------------------ 4 files changed, 572 insertions(+), 878 deletions(-) create mode 100644 src/mlpack/methods/kde/kde_model.cpp diff --git a/src/mlpack/methods/kde/CMakeLists.txt b/src/mlpack/methods/kde/CMakeLists.txt index 31dacaee43..81bee212e3 100644 --- a/src/mlpack/methods/kde/CMakeLists.txt +++ b/src/mlpack/methods/kde/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES kde_stat.hpp kde_model.hpp kde_model_impl.hpp + kde_model.cpp ) # Add directory name to sources. diff --git a/src/mlpack/methods/kde/kde_model.cpp b/src/mlpack/methods/kde/kde_model.cpp new file mode 100644 index 0000000000..552f1b4058 --- /dev/null +++ b/src/mlpack/methods/kde/kde_model.cpp @@ -0,0 +1,312 @@ +/** + * @file methods/kde/kde_model.cpp + * @author Roberto Hueso + * + * Implementation of KDE Model. + * + * 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. + */ +#include "kde_model.hpp" + +namespace mlpack { +namespace kde { + +//! Initialize the KDEModel with the given parameters. +KDEModel::KDEModel(const double bandwidth, + const double relError, + const double absError, + const KernelTypes kernelType, + const TreeTypes treeType, + const bool monteCarlo, + const double mcProb, + const size_t initialSampleSize, + const double mcEntryCoef, + const double mcBreakCoef) : + bandwidth(bandwidth), + relError(relError), + absError(absError), + kernelType(kernelType), + treeType(treeType), + monteCarlo(monteCarlo), + mcProb(mcProb), + initialSampleSize(initialSampleSize), + mcEntryCoef(mcEntryCoef), + mcBreakCoef(mcBreakCoef), + kdeModel(NULL) +{ + // Nothing to do. +} + +// Copy constructor. +KDEModel::KDEModel(const KDEModel& other) : + bandwidth(other.bandwidth), + relError(other.relError), + absError(other.absError), + kernelType(other.kernelType), + treeType(other.treeType), + monteCarlo(other.monteCarlo), + mcProb(other.mcProb), + initialSampleSize(other.initialSampleSize), + mcEntryCoef(other.mcEntryCoef), + mcBreakCoef(other.mcBreakCoef), + kdeModel(other.kdeModel->Clone()) +{ + // Nothing to do. +} + +// Move constructor. +KDEModel::KDEModel(KDEModel&& other) : + bandwidth(other.bandwidth), + relError(other.relError), + absError(other.absError), + kernelType(other.kernelType), + treeType(other.treeType), + monteCarlo(other.monteCarlo), + mcProb(other.mcProb), + initialSampleSize(other.initialSampleSize), + mcEntryCoef(other.mcEntryCoef), + mcBreakCoef(other.mcBreakCoef), + kdeModel(std::move(other.kdeModel)) +{ + // Reset other model. + other.bandwidth = 1.0; + other.relError = KDEDefaultParams::relError; + other.absError = KDEDefaultParams::absError; + other.kernelType = KernelTypes::GAUSSIAN_KERNEL; + other.treeType = TreeTypes::KD_TREE; + other.monteCarlo = KDEDefaultParams::monteCarlo; + other.mcProb = KDEDefaultParams::mcProb; + other.initialSampleSize = KDEDefaultParams::initialSampleSize; + other.mcEntryCoef = KDEDefaultParams::mcEntryCoef; + other.mcBreakCoef = KDEDefaultParams::mcBreakCoef; +} + +KDEModel& KDEModel::operator=(const KDEModel& other) +{ + if (this != &other) + { + delete kdeModel; + + bandwidth = other.bandwidth; + relError = other.relError; + absError = other.absError; + kernelType = other.kernelType; + treeType = other.treeType; + monteCarlo = other.monteCarlo; + mcProb = other.mcProb; + initialSampleSize = other.initialSampleSize; + mcEntryCoef = other.mcEntryCoef; + mcBreakCoef = other.mcBreakCoef; + kdeModel = other.kdeModel->Clone(); + } + + return *this; +} + +KDEModel& KDEModel::operator=(KDEModel&& other) +{ + if (this != &other) + { + delete kdeModel; + + bandwidth = other.bandwidth; + relError = other.relError; + absError = other.absError; + kernelType = other.kernelType; + treeType = other.treeType; + monteCarlo = other.monteCarlo; + mcProb = other.mcProb; + initialSampleSize = other.initialSampleSize; + mcEntryCoef = other.mcEntryCoef; + mcBreakCoef = other.mcBreakCoef; + kdeModel = std::move(other.kdeModel); + + // Reset other model. + other.bandwidth = 1.0; + other.relError = KDEDefaultParams::relError; + other.absError = KDEDefaultParams::absError; + other.kernelType = KernelTypes::GAUSSIAN_KERNEL; + other.treeType = TreeTypes::KD_TREE; + other.monteCarlo = KDEDefaultParams::monteCarlo; + other.mcProb = KDEDefaultParams::mcProb; + other.initialSampleSize = KDEDefaultParams::initialSampleSize; + other.mcEntryCoef = KDEDefaultParams::mcEntryCoef; + other.mcBreakCoef = KDEDefaultParams::mcBreakCoef; + } + + return *this; +} + +// Clean memory. +KDEModel::~KDEModel() +{ + delete kdeModel; +} + +template class TreeType> +KDEWrapperBase* BuildModelHelper(const KDEModel::KernelTypes kernelType, + const double relError, + const double absError, + const double bandwidth) +{ + switch (kernelType) + { + case KDEModel::GAUSSIAN_KERNEL: + return new KDEWrapper( + relError, absError, kernel::GaussianKernel(bandwidth)); + + case KDEModel::EPANECHNIKOV_KERNEL: + return new KDEWrapper( + relError, absError, kernel::EpanechnikovKernel(bandwidth)); + + case KDEModel::LAPLACIAN_KERNEL: + return new KDEWrapper( + relError, absError, kernel::LaplacianKernel(bandwidth)); + + case KDEModel::SPHERICAL_KERNEL: + return new KDEWrapper( + relError, absError, kernel::SphericalKernel(bandwidth)); + + case KDEModel::TRIANGULAR_KERNEL: + return new KDEWrapper( + relError, absError, kernel::TriangularKernel(bandwidth)); + } + + // This should never happen. + return NULL; +} + +void KDEModel::BuildModel(arma::mat&& referenceSet) +{ + // Clean memory, if necessary. + delete kdeModel; + + // Build the actual model. + switch (treeType) + { + case KD_TREE: + kdeModel = BuildModelHelper(kernelType, relError, absError, + bandwidth); + break; + + case BALL_TREE: + kdeModel = BuildModelHelper(kernelType, relError, + absError, bandwidth); + break; + + case COVER_TREE: + kdeModel = BuildModelHelper(kernelType, relError, + absError, bandwidth); + break; + + case OCTREE: + kdeModel = BuildModelHelper(kernelType, relError, absError, + bandwidth); + break; + + case R_TREE: + kdeModel = BuildModelHelper(kernelType, relError, absError, + bandwidth); + break; + } + + // Set whether to use Monte Carlo estimations or not. + kdeModel->MonteCarlo() = monteCarlo; + + // Set Monte Carlo probability. + kdeModel->MCProb(mcProb); + + // Set Monte Carlo initial sample size. + kdeModel->MCInitialSampleSize() = initialSampleSize; + + // Set Monte Carlo entry coefficient. + kdeModel->MCEntryCoef(mcEntryCoef); + + // Set Monte Carlo break coefficient. + kdeModel->MCBreakCoef(mcBreakCoef); + + // Train the model. + kdeModel->Train(std::move(referenceSet)); +} + +// Perform bichromatic evaluation. +void KDEModel::Evaluate(arma::mat&& querySet, arma::vec& estimates) +{ + kdeModel->Evaluate(std::move(querySet), estimates); +} + +// Perform monochromatic evaluation. +void KDEModel::Evaluate(arma::vec& estimates) +{ + kdeModel->Evaluate(estimates); +} + +// Clean memory. +void KDEModel::CleanMemory() +{ + delete kdeModel; +} + +// Modify model kernel bandwidth. +void KDEModel::Bandwidth(const double newBandwidth) +{ + bandwidth = newBandwidth; + kdeModel->Bandwidth(bandwidth); +} + +// Modify model relative error tolerance. +void KDEModel::RelativeError(const double newRelError) +{ + relError = newRelError; + kdeModel->RelativeError(relError); +} + +// Modify model absolute error tolerance. +void KDEModel::AbsoluteError(const double newAbsError) +{ + absError = newAbsError; + kdeModel->AbsoluteError(absError); +} + +// Modify whether Monte Carlo estimations will be used. +void KDEModel::MonteCarlo(const bool newMonteCarlo) +{ + monteCarlo = newMonteCarlo; + kdeModel->MonteCarlo() = monteCarlo; +} + +// Modify model Monte Carlo probability. +void KDEModel::MCProbability(const double newMCProb) +{ + mcProb = newMCProb; + kdeModel->MCProb(mcProb); +} + +// Modify model Monte Carlo initial sample size. +void KDEModel::MCInitialSampleSize(const size_t newSampleSize) +{ + initialSampleSize = newSampleSize; + kdeModel->MCInitialSampleSize() = initialSampleSize; +} + +// Modify model Monte Carlo entry coefficient. +void KDEModel::MCEntryCoefficient(const double newEntryCoef) +{ + mcEntryCoef = newEntryCoef; + kdeModel->MCEntryCoef(mcEntryCoef); +} + +// Modify model Monte Carlo break coefficient. +void KDEModel::MCBreakCoefficient(const double newBreakCoef) +{ + mcBreakCoef = newBreakCoef; + kdeModel->MCBreakCoef(mcBreakCoef); +} + +} // namespace kde +} // namespace mlpack diff --git a/src/mlpack/methods/kde/kde_model.hpp b/src/mlpack/methods/kde/kde_model.hpp index 220213ba5e..c2f93ba181 100644 --- a/src/mlpack/methods/kde/kde_model.hpp +++ b/src/mlpack/methods/kde/kde_model.hpp @@ -22,28 +22,11 @@ #include // Remaining includes. -#include #include "kde.hpp" namespace mlpack { namespace kde { -//! Alias template. -template class TreeType> -using KDEType = KDE::template DualTreeTraverser, - TreeType::template SingleTreeTraverser>; - /** * KernelNormalizer holds a set of methods to normalize estimations applying * in each case the appropiate kernel normalizer function. @@ -81,284 +64,168 @@ class KernelNormalizer }; /** - * DualMonoKDE computes a Kernel Density Estimation on the given KDEType. - * It performs a monochromatic KDE. + * KDEWrapperBase is a base wrapper class for holding all KDE types supported by + * KDEModel. All KDE type wrappers inheirt from this class, allowing a simple + * interface via inheritance for all the different types we want to support. */ -class DualMonoKDE : public boost::static_visitor +class KDEWrapperBase { - private: - //! Vector to store the KDE results. - arma::vec& estimations; - public: - //! Alias template necessary for Visual C++ compiler. - template class TreeType> - using KDETypeT = KDEType; + //! Create the KDEWrapperBase object. The base class does not hold anything, + //! so this constructor does nothing. + KDEWrapperBase() { } - //! Default DualMonoKDE on some KDEType. - template class TreeType> - void operator()(KDETypeT* kde) const; + //! Create a new KDEWrapperBase that is the same as this one. This function + //! will properly handle polymorphism. + virtual KDEWrapperBase* Clone() const = 0; - // TODO Implement specific cases where a leaf size can be selected. + //! Destruct the KDEWrapperBase (nothing to do). + virtual ~KDEWrapperBase() { } - //! DualMonoKDE constructor. - DualMonoKDE(arma::vec& estimations); + //! Modify the bandwidth of the kernel. + virtual void Bandwidth(const double bw) = 0; + + //! Modify the relative error tolerance. + virtual void RelativeError(const double relError) = 0; + + //! Modify the absolute error tolerance. + virtual void AbsoluteError(const double absError) = 0; + + //! Get whether Monte Carlo search is being used. + virtual bool MonteCarlo() const = 0; + //! Modify whether Monte Carlo search is being used. + virtual bool& MonteCarlo() = 0; + + //! Modify the Monte Carlo probability. + virtual void MCProb(const double mcProb) = 0; + + //! Get the Monte Carlo sample size. + virtual size_t MCInitialSampleSize() const = 0; + //! Modify the Monte Carlo sample size. + virtual size_t& MCInitialSampleSize() = 0; + + //! Modify the Monte Carlo entry coefficient. + virtual void MCEntryCoef(const double entryCoef) = 0; + + //! Modify the Monte Carlo break coefficient. + virtual void MCBreakCoef(const double breakCoef) = 0; + + //! Get the search mode. + virtual KDEMode Mode() const = 0; + //! Modify the search mode. + virtual KDEMode& Mode() = 0; + + //! Train the model (build the tree). + virtual void Train(arma::mat&& referenceSet) = 0; + + //! Perform bichromatic KDE (i.e. KDE with a separate query set). + virtual void Evaluate(arma::mat&& querySet, + arma::vec& estimates) = 0; + + //! Perform monochromatic KDE (i.e. with the reference set as the query set). + virtual void Evaluate(arma::vec& estimates) = 0; }; /** - * DualBiKDE computes a Kernel Density Estimation on the given KDEType. - * It performs a bichromatic KDE. + * KDEWrapper is a wrapper class for all KDE types supported by KDEModel. It + * can be extended with new child classes if new functionality for certain types + * is needed. */ -class DualBiKDE : public boost::static_visitor +template class TreeType> +class KDEWrapper : public KDEWrapperBase { - private: - //! Query set dimensionality. - const size_t dimension; - - //! The query set for the KDE. - const arma::mat& querySet; - - //! Vector to store the KDE results. - arma::vec& estimations; - public: - //! Alias template necessary for Visual C++ compiler. - template class TreeType> - using KDETypeT = KDEType; + //! Create the KDEWrapper object, initializing the internally-held KDE object. + KDEWrapper(const double relError, + const double absError, + const KernelType& kernel) : + kde(relError, absError, kernel) + { + // Nothing left to do. + } - //! Default DualBiKDE on some KDEType. - template class TreeType> - void operator()(KDETypeT* kde) const; + //! Create a new KDEWrapper that is the same as this one. This function + //! will properly handle polymorphism. + virtual KDEWrapper* Clone() const { return new KDEWrapper(*this); } - // TODO Implement specific cases where a leaf size can be selected. + //! Destruct the KDEWrapper (nothing to do). + virtual ~KDEWrapper() { } - //! DualBiKDE constructor. Takes ownership of the given querySet. - DualBiKDE(arma::mat&& querySet, arma::vec& estimations); + //! Modify the bandwidth of the kernel. + virtual void Bandwidth(const double bw) { kde.Kernel() = KernelType(bw); } + + //! Modify the relative error tolerance. + virtual void RelativeError(const double eps) { kde.RelativeError(eps); } + + //! Modify the absolute error tolerance. + virtual void AbsoluteError(const double eps) { kde.AbsoluteError(eps); } + + //! Get whether Monte Carlo search is being used. + virtual bool MonteCarlo() const { return kde.MonteCarlo(); } + //! Modify whether Monte Carlo search is being used. + virtual bool& MonteCarlo() { return kde.MonteCarlo(); } + + //! Modify the Monte Carlo probability. + virtual void MCProb(const double mcProb) { kde.MCProb(mcProb); } + + //! Get the Monte Carlo sample size. + virtual size_t MCInitialSampleSize() const + { + return kde.MCInitialSampleSize(); + } + //! Modify the Monte Carlo sample size. + virtual size_t& MCInitialSampleSize() + { + return kde.MCInitialSampleSize(); + } + + //! Modify the Monte Carlo entry coefficient. + virtual void MCEntryCoef(const double e) { kde.MCEntryCoef(e); } + + //! Modify the Monte Carlo break coefficient. + virtual void MCBreakCoef(const double b) { kde.MCBreakCoef(b); } + + //! Get the search mode. + virtual KDEMode Mode() const { return kde.Mode(); } + //! Modify the search mode. + virtual KDEMode& Mode() { return kde.Mode(); } + + //! Train the model (build the tree). + virtual void Train(arma::mat&& referenceSet); + + //! Perform bichromatic KDE (i.e. KDE with a separate query set). + virtual void Evaluate(arma::mat&& querySet, + arma::vec& estimates); + + //! Perform monochromatic KDE (i.e. with the reference set as the query set). + virtual void Evaluate(arma::vec& estimates); + + //! Serialize the KDE model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(kde)); + } + + protected: + typedef KDE KDEType; + + //! The instantiated KDE object that we are wrapping. + KDEType kde; }; /** - * TrainVisitor trains a given KDEType using a reference set. + * The KDEModel provides an abstraction for the KDE class, abstracting away the + * KernelType and TreeType parameters and allowing those to be specified at + * runtime. This class is written for the sake of the `kde` binding, but it is + * not necessarily restricted to that usage. */ -class TrainVisitor : public boost::static_visitor -{ - private: - //! The reference set used for training. - arma::mat&& referenceSet; - - public: - //! Default TrainVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - // TODO Implement specific cases where a leaf size can be selected. - - //! TrainVisitor constructor. Takes ownership of the given referenceSet. - TrainVisitor(arma::mat&& referenceSet); -}; - -/** - * BandwidthVisitor modifies the bandwidth of a KDEType kernel. - */ -class BandwidthVisitor : public boost::static_visitor -{ - private: - //! Relative error tolerance. - const double bandwidth; - - public: - //! Default BandwidthVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! BandwidthVisitor constructor. - BandwidthVisitor(const double bandwidth); -}; - -/** - * RelErrorVisitor modifies relative error tolerance for a KDEType. - */ -class RelErrorVisitor : public boost::static_visitor -{ - private: - //! Relative error tolerance. - const double relError; - - public: - //! Default RelErrorVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! RelErrorVisitor constructor. - RelErrorVisitor(const double relError); -}; - -/** - * AbsErrorVisitor modifies absolute error tolerance for a KDEType. - */ -class AbsErrorVisitor : public boost::static_visitor -{ - private: - //! Absolute error tolerance. - const double absError; - - public: - //! Default AbsErrorVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! AbsErrorVisitor constructor. - AbsErrorVisitor(const double absError); -}; - -/** - * MonteCarloVisitor activates or deactivates Monte Carlo for a given KDEType. - */ -class MonteCarloVisitor : public boost::static_visitor -{ - private: - //! Whether to use Monte Carlo estimations or not. - const bool monteCarlo; - - public: - //! Default MonteCarloVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! MonteCarloVisitor constructor. - MonteCarloVisitor(const bool monteCarlo); -}; - -/** - * MCProbabilityVisitor sets the Monte Carlo probability for a given KDEType. - */ -class MCProbabilityVisitor : public boost::static_visitor -{ - private: - //! Monte Carlo probability. - const double probability; - - public: - //! Default MCProbabilityVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! MCProbabilityVisitor constructor. - MCProbabilityVisitor(const double probability); -}; - -/** - * MCSampleSizeVisitor sets the Monte Carlo intial sample size for a given - * KDEType. - */ -class MCSampleSizeVisitor : public boost::static_visitor -{ - private: - //! Monte Carlo sample size. - const size_t sampleSize; - - public: - //! Default MCSampleSizeVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! MCSampleSizeVisitor constructor. - MCSampleSizeVisitor(const size_t sampleSize); -}; - -/** - * MCEntryCoefVisitor sets the Monte Carlo entry coefficient. - */ -class MCEntryCoefVisitor : public boost::static_visitor -{ - private: - //! Monte Carlo entry coefficient. - const double entryCoef; - - public: - //! Default MCEntryCoefVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! MCEntryCoefVisitor constructor. - MCEntryCoefVisitor(const double entryCoef); -}; - -/** - * MCBreakCoefVisitor sets the Monte Carlo break coefficient. - */ -class MCBreakCoefVisitor : public boost::static_visitor -{ - private: - //! Monte Carlo break coefficient. - const double breakCoef; - - public: - //! Default MCBreakCoefVisitor on some KDEType. - template class TreeType> - void operator()(KDEType* kde) const; - - //! MCBreakCoefVisitor constructor. - MCBreakCoefVisitor(const double breakCoef); -}; - -/** - * ModeVisitor exposes the Mode() method of the KDEType. - */ -class ModeVisitor : public boost::static_visitor -{ - public: - //! Return mode of KDEType instance. - template - KDEMode& operator()(KDEType* kde) const; -}; - -class DeleteVisitor : public boost::static_visitor -{ - public: - //! Delete KDEType instance. - template - void operator()(KDEType* kde) const; -}; - class KDEModel { public: @@ -413,34 +280,10 @@ class KDEModel double mcBreakCoef; /** - * kdeModel holds an instance of each possible combination of KernelType and - * TreeType. It is initialized using BuildModel. + * kdeModel holds whatever KDE type we are using. It is initialized using the + * `BuildModel()` method. */ - boost::variant*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*, - KDEType*> kdeModel; + KDEWrapperBase* kdeModel; public: /** @@ -487,11 +330,16 @@ class KDEModel /** * Copy the given model. * - * Use std::move if the object to copy is no longer needed. - * * @param other KDEModel to copy. */ - KDEModel& operator=(KDEModel other); + KDEModel& operator=(const KDEModel& other); + + /** + * Take ownership of the contents of the given model. + * + * @param other KDEModel to take ownership of. + */ + KDEModel& operator=(KDEModel&& other); //! Destroy the KDEModel object. ~KDEModel(); @@ -561,10 +409,10 @@ class KDEModel void MCBreakCoefficient(const double newBreakCoef); //! Get the mode of the model. - KDEMode Mode() const; + KDEMode Mode() const { return kdeModel->Mode(); } //! Modify the mode of the model. - KDEMode& Mode(); + KDEMode& Mode() { return kdeModel->Mode(); } /** * Build the KDE model with the given parameters and then trains it with the diff --git a/src/mlpack/methods/kde/kde_model_impl.hpp b/src/mlpack/methods/kde/kde_model_impl.hpp index 4b59e7657a..bc00f1d50b 100644 --- a/src/mlpack/methods/kde/kde_model_impl.hpp +++ b/src/mlpack/methods/kde/kde_model_impl.hpp @@ -18,521 +18,96 @@ namespace mlpack { namespace kde { -//! Initialize the KDEModel with the given parameters. -inline KDEModel::KDEModel(const double bandwidth, - const double relError, - const double absError, - const KernelTypes kernelType, - const TreeTypes treeType, - const bool monteCarlo, - const double mcProb, - const size_t initialSampleSize, - const double mcEntryCoef, - const double mcBreakCoef) : - bandwidth(bandwidth), - relError(relError), - absError(absError), - kernelType(kernelType), - treeType(treeType), - monteCarlo(monteCarlo), - mcProb(mcProb), - initialSampleSize(initialSampleSize), - mcEntryCoef(mcEntryCoef), - mcBreakCoef(mcBreakCoef) -{ - // Nothing to do. -} - -// Copy constructor. -inline KDEModel::KDEModel(const KDEModel& other) : - bandwidth(other.bandwidth), - relError(other.relError), - absError(other.absError), - kernelType(other.kernelType), - treeType(other.treeType), - monteCarlo(other.monteCarlo), - mcProb(other.mcProb), - initialSampleSize(other.initialSampleSize), - mcEntryCoef(other.mcEntryCoef), - mcBreakCoef(other.mcBreakCoef) -{ - // Nothing to do. -} - -// Move constructor. -inline KDEModel::KDEModel(KDEModel&& other) : - bandwidth(other.bandwidth), - relError(other.relError), - absError(other.absError), - kernelType(other.kernelType), - treeType(other.treeType), - monteCarlo(other.monteCarlo), - mcProb(other.mcProb), - initialSampleSize(other.initialSampleSize), - mcEntryCoef(other.mcEntryCoef), - mcBreakCoef(other.mcBreakCoef), - kdeModel(std::move(other.kdeModel)) -{ - // Reset other model. - other.bandwidth = 1.0; - other.relError = KDEDefaultParams::relError; - other.absError = KDEDefaultParams::absError; - other.kernelType = KernelTypes::GAUSSIAN_KERNEL; - other.treeType = TreeTypes::KD_TREE; - other.monteCarlo = KDEDefaultParams::monteCarlo; - other.mcProb = KDEDefaultParams::mcProb; - other.initialSampleSize = KDEDefaultParams::initialSampleSize; - other.mcEntryCoef = KDEDefaultParams::mcEntryCoef; - other.mcBreakCoef = KDEDefaultParams::mcBreakCoef; - other.kdeModel = decltype(other.kdeModel)(); -} - -inline KDEModel& KDEModel::operator=(KDEModel other) -{ - boost::apply_visitor(DeleteVisitor(), kdeModel); - bandwidth = other.bandwidth; - relError = other.relError; - absError = other.absError; - kernelType = other.kernelType; - treeType = other.treeType; - monteCarlo = other.monteCarlo; - mcProb = other.mcProb; - initialSampleSize = other.initialSampleSize; - mcEntryCoef = other.mcEntryCoef; - mcBreakCoef = other.mcBreakCoef; - kdeModel = std::move(other.kdeModel); - return *this; -} - -// Clean memory. -inline KDEModel::~KDEModel() -{ - boost::apply_visitor(DeleteVisitor(), kdeModel); -} - -inline void KDEModel::BuildModel(arma::mat&& referenceSet) -{ - // Clean memory, if necessary. - boost::apply_visitor(DeleteVisitor(), kdeModel); - - // Build the actual model. - if (kernelType == GAUSSIAN_KERNEL && treeType == KD_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::GaussianKernel(bandwidth)); - } - else if (kernelType == GAUSSIAN_KERNEL && treeType == BALL_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::GaussianKernel(bandwidth)); - } - else if (kernelType == GAUSSIAN_KERNEL && treeType == COVER_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::GaussianKernel(bandwidth)); - } - else if (kernelType == GAUSSIAN_KERNEL && treeType == OCTREE) - { - kdeModel = new KDEType - (relError, absError, kernel::GaussianKernel(bandwidth)); - } - else if (kernelType == GAUSSIAN_KERNEL && treeType == R_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::GaussianKernel(bandwidth)); - } - else if (kernelType == EPANECHNIKOV_KERNEL && treeType == KD_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::EpanechnikovKernel(bandwidth)); - } - else if (kernelType == EPANECHNIKOV_KERNEL && treeType == BALL_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::EpanechnikovKernel(bandwidth)); - } - else if (kernelType == EPANECHNIKOV_KERNEL && treeType == COVER_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::EpanechnikovKernel(bandwidth)); - } - else if (kernelType == EPANECHNIKOV_KERNEL && treeType == OCTREE) - { - kdeModel = new KDEType - (relError, absError, kernel::EpanechnikovKernel(bandwidth)); - } - else if (kernelType == EPANECHNIKOV_KERNEL && treeType == R_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::EpanechnikovKernel(bandwidth)); - } - else if (kernelType == LAPLACIAN_KERNEL && treeType == KD_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::LaplacianKernel(bandwidth)); - } - else if (kernelType == LAPLACIAN_KERNEL && treeType == BALL_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::LaplacianKernel(bandwidth)); - } - else if (kernelType == LAPLACIAN_KERNEL && treeType == COVER_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::LaplacianKernel(bandwidth)); - } - else if (kernelType == LAPLACIAN_KERNEL && treeType == OCTREE) - { - kdeModel = new KDEType - (relError, absError, kernel::LaplacianKernel(bandwidth)); - } - else if (kernelType == LAPLACIAN_KERNEL && treeType == R_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::LaplacianKernel(bandwidth)); - } - else if (kernelType == SPHERICAL_KERNEL && treeType == KD_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::SphericalKernel(bandwidth)); - } - else if (kernelType == SPHERICAL_KERNEL && treeType == BALL_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::SphericalKernel(bandwidth)); - } - else if (kernelType == SPHERICAL_KERNEL && treeType == COVER_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::SphericalKernel(bandwidth)); - } - else if (kernelType == SPHERICAL_KERNEL && treeType == OCTREE) - { - kdeModel = new KDEType - (relError, absError, kernel::SphericalKernel(bandwidth)); - } - else if (kernelType == SPHERICAL_KERNEL && treeType == R_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::SphericalKernel(bandwidth)); - } - else if (kernelType == TRIANGULAR_KERNEL && treeType == KD_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::TriangularKernel(bandwidth)); - } - else if (kernelType == TRIANGULAR_KERNEL && treeType == BALL_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::TriangularKernel(bandwidth)); - } - else if (kernelType == TRIANGULAR_KERNEL && treeType == COVER_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::TriangularKernel(bandwidth)); - } - else if (kernelType == TRIANGULAR_KERNEL && treeType == OCTREE) - { - kdeModel = new KDEType - (relError, absError, kernel::TriangularKernel(bandwidth)); - } - else if (kernelType == TRIANGULAR_KERNEL && treeType == R_TREE) - { - kdeModel = new KDEType - (relError, absError, kernel::TriangularKernel(bandwidth)); - } - - // Set whether to use Monte Carlo estimations or not. - MonteCarloVisitor MCVisitor(monteCarlo); - boost::apply_visitor(MCVisitor, kdeModel); - - // Set Monte Carlo probability. - MCProbabilityVisitor probabilityVisitor(mcProb); - boost::apply_visitor(probabilityVisitor, kdeModel); - - // Set Monte Carlo initial sample size. - MCSampleSizeVisitor sampleSizeVisitor(initialSampleSize); - boost::apply_visitor(sampleSizeVisitor, kdeModel); - - // Set Monte Carlo entry coefficient. - MCEntryCoefVisitor entryCoefficientVisitor(mcEntryCoef); - boost::apply_visitor(entryCoefficientVisitor, kdeModel); - - // Set Monte Carlo break coefficient. - MCBreakCoefVisitor breakCoefficientVisitor(mcBreakCoef); - boost::apply_visitor(breakCoefficientVisitor, kdeModel); - - // Train the model. - TrainVisitor train(std::move(referenceSet)); - boost::apply_visitor(train, kdeModel); -} - -// Perform bichromatic evaluation. -inline void KDEModel::Evaluate(arma::mat&& querySet, arma::vec& estimations) -{ - Log::Info << "Evaluating KDE..." << std::endl; - DualBiKDE eval(std::move(querySet), estimations); - boost::apply_visitor(eval, kdeModel); -} - -// Perform monochromatic evaluation. -inline void KDEModel::Evaluate(arma::vec& estimations) -{ - Log::Info << "Evaluating KDE..." << std::endl; - DualMonoKDE eval(estimations); - boost::apply_visitor(eval, kdeModel); -} - -// Clean memory. -inline void KDEModel::CleanMemory() -{ - boost::apply_visitor(DeleteVisitor(), kdeModel); -} - -// Parameters for KDE evaluation. -DualMonoKDE::DualMonoKDE(arma::vec& estimations): - estimations(estimations) -{} - -// Default KDE evaluation. +//! Train the model (build the tree). template class TreeType> -void DualMonoKDE::operator()(KDETypeT* kde) const +void KDEWrapper::Train(arma::mat&& referenceSet) { - if (kde) + kde.Train(std::move(referenceSet)); +} + +//! Perform bichromatic KDE (i.e. KDE with a separate query set). +template class TreeType> +void KDEWrapper::Evaluate(arma::mat&& querySet, + arma::vec& estimates) +{ + const size_t dimension = querySet.n_rows; + kde.Evaluate(std::move(querySet), estimates); + KernelNormalizer::ApplyNormalizer(kde.Kernel(), + dimension, + estimates); +} + +//! Perform monochromatic KDE (i.e. with the reference set as the query set). +template class TreeType> +void KDEWrapper::Evaluate(arma::vec& estimates) +{ + kde.Evaluate(estimates); + const size_t dimension = kde.ReferenceTree()->Dataset().n_rows; + KernelNormalizer::ApplyNormalizer(kde.Kernel(), + dimension, + estimates); +} + +template class TreeType, + typename Archive> +void SerializationHelper(Archive& ar, + KDEWrapperBase* kdeModel, + const KDEModel::KernelTypes kernelType) +{ + switch (kernelType) { - kde->Evaluate(estimations); - const size_t dimension = (kde->ReferenceTree())->Dataset().n_rows; - KernelNormalizer::ApplyNormalizer(kde->Kernel(), - dimension, - estimations); + case KDEModel::GAUSSIAN_KERNEL: + { + KDEWrapper& typedModel = + dynamic_cast&>(*kdeModel); + ar(CEREAL_NVP(typedModel)); + break; + } + case KDEModel::EPANECHNIKOV_KERNEL: + { + KDEWrapper& typedModel = + dynamic_cast&>(*kdeModel); + ar(CEREAL_NVP(typedModel)); + break; + } + case KDEModel::LAPLACIAN_KERNEL: + { + KDEWrapper& typedModel = + dynamic_cast&>(*kdeModel); + ar(CEREAL_NVP(typedModel)); + break; + } + case KDEModel::SPHERICAL_KERNEL: + { + KDEWrapper& typedModel = + dynamic_cast&>(*kdeModel); + ar(CEREAL_NVP(typedModel)); + break; + } + case KDEModel::TRIANGULAR_KERNEL: + { + KDEWrapper& typedModel = + dynamic_cast&>(*kdeModel); + ar(CEREAL_NVP(typedModel)); + break; + } } - else - { - throw std::runtime_error("no KDE model initialized"); - } -} - -// Parameters for KDE evaluation. -DualBiKDE::DualBiKDE(arma::mat&& querySet, arma::vec& estimations): - dimension(querySet.n_rows), - querySet(std::move(querySet)), - estimations(estimations) -{} - -// Default KDE evaluation. -template class TreeType> -void DualBiKDE::operator()(KDETypeT* kde) const -{ - if (kde) - { - kde->Evaluate(std::move(querySet), estimations); - KernelNormalizer::ApplyNormalizer(kde->Kernel(), - dimension, - estimations); - } - else - { - throw std::runtime_error("no KDE model initialized"); - } -} - -// Parameters for Train. -TrainVisitor::TrainVisitor(arma::mat&& referenceSet) : - referenceSet(std::move(referenceSet)) -{} - -// Default Train. -template class TreeType> -void TrainVisitor::operator()(KDEType* kde) const -{ - Log::Info << "Training KDE model..." << std::endl; - if (kde) - kde->Train(std::move(referenceSet)); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Modify kernel bandwidth. -BandwidthVisitor::BandwidthVisitor(const double bandwidth) : - bandwidth(bandwidth) -{} - -// Default modify kernel bandwidth. -template class TreeType> -void BandwidthVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->Kernel() = KernelType(bandwidth); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Modify relative error tolerance. -RelErrorVisitor::RelErrorVisitor(const double relError) : - relError(relError) -{} - -// Default modify relative error tolerance. -template class TreeType> -void RelErrorVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->RelativeError(relError); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Modify absolute error tolerance. -AbsErrorVisitor::AbsErrorVisitor(const double absError) : - absError(absError) -{} - -// Default modify absolute error tolerance. -template class TreeType> -void AbsErrorVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->AbsoluteError(absError); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Activate or deactivate Monte Carlo. -MonteCarloVisitor::MonteCarloVisitor(const bool monteCarlo) : - monteCarlo(monteCarlo) -{} - -// Default activate or deactivate Monte Carlo. -template class TreeType> -void MonteCarloVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->MonteCarlo() = monteCarlo; - else - throw std::runtime_error("no KDE model initialized"); -} - -// Set Monte Carlo probability. -MCProbabilityVisitor::MCProbabilityVisitor(const double probability) : - probability(probability) -{} - -// Default probability for Monte Carlo. -template class TreeType> -void MCProbabilityVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->MCProb(probability); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Set Monte Carlo sample size. -MCSampleSizeVisitor::MCSampleSizeVisitor(const size_t sampleSize) : - sampleSize(sampleSize) -{} - -// Default sample size for Monte Carlo. -template class TreeType> -void MCSampleSizeVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->MCInitialSampleSize() = sampleSize; - else - throw std::runtime_error("no KDE model initialized"); -} - -// Set Monte Carlo entry coefficient. -MCEntryCoefVisitor::MCEntryCoefVisitor(const double entryCoef) : - entryCoef(entryCoef) -{} - -// Default entry coefficient for Monte Carlo. -template class TreeType> -void MCEntryCoefVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->MCEntryCoef(entryCoef); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Set Monte Carlo break coefficient. -MCBreakCoefVisitor::MCBreakCoefVisitor(const double breakCoef) : - breakCoef(breakCoef) -{} - -// Default break coefficient for Monte Carlo. -template class TreeType> -void MCBreakCoefVisitor::operator()(KDEType* kde) const -{ - if (kde) - kde->MCBreakCoef(breakCoef); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Delete model. -template -void DeleteVisitor::operator()(KDEType* kde) const -{ - if (kde) - delete kde; -} - -// Mode of model. -template -KDEMode& ModeVisitor::operator()(KDEType* kde) const -{ - if (kde) - return kde->Mode(); - else - throw std::runtime_error("no KDE model initialized"); -} - -// Get mode of model. -KDEMode KDEModel::Mode() const -{ - return boost::apply_visitor(ModeVisitor(), kdeModel); -} - -// Modify mode of model. -KDEMode& KDEModel::Mode() -{ - return boost::apply_visitor(ModeVisitor(), kdeModel); } // Serialize the model. @@ -560,73 +135,31 @@ void KDEModel::serialize(Archive& ar, const uint32_t /* version */) } if (cereal::is_loading()) - boost::apply_visitor(DeleteVisitor(), kdeModel); + delete kdeModel; - ar(CEREAL_VARIANT_POINTER(kdeModel)); -} + // Avoid polymorphism in serialization by serializing directly by the type. + switch (treeType) + { + case KD_TREE: + SerializationHelper(ar, kdeModel, kernelType); + break; -// Modify model kernel bandwidth. -void KDEModel::Bandwidth(const double newBandwidth) -{ - bandwidth = newBandwidth; - BandwidthVisitor bandwidthVisitor(newBandwidth); - boost::apply_visitor(bandwidthVisitor, kdeModel); -} + case BALL_TREE: + SerializationHelper(ar, kdeModel, kernelType); + break; -// Modify model relative error tolerance. -void KDEModel::RelativeError(const double newRelError) -{ - relError = newRelError; - RelErrorVisitor relErrorVisitor(newRelError); - boost::apply_visitor(relErrorVisitor, kdeModel); -} + case COVER_TREE: + SerializationHelper(ar, kdeModel, kernelType); + break; -// Modify model absolute error tolerance. -void KDEModel::AbsoluteError(const double newAbsError) -{ - absError = newAbsError; - AbsErrorVisitor absErrorVisitor(newAbsError); - boost::apply_visitor(absErrorVisitor, kdeModel); -} + case OCTREE: + SerializationHelper(ar, kdeModel, kernelType); + break; -// Modify whether Monte Carlo estimations will be used. -void KDEModel::MonteCarlo(const bool newMonteCarlo) -{ - monteCarlo = newMonteCarlo; - MonteCarloVisitor monteCarloVisitor(newMonteCarlo); - boost::apply_visitor(monteCarloVisitor, kdeModel); -} - -// Modify model Monte Carlo probability. -void KDEModel::MCProbability(const double newMCProb) -{ - mcProb = newMCProb; - MCProbabilityVisitor mcProbVisitor(newMCProb); - boost::apply_visitor(mcProbVisitor, kdeModel); -} - -// Modify model Monte Carlo initial sample size. -void KDEModel::MCInitialSampleSize(const size_t newSampleSize) -{ - initialSampleSize = newSampleSize; - MCSampleSizeVisitor mcSampleSizeVisitor(newSampleSize); - boost::apply_visitor(mcSampleSizeVisitor, kdeModel); -} - -// Modify model Monte Carlo entry coefficient. -void KDEModel::MCEntryCoefficient(const double newEntryCoef) -{ - mcEntryCoef = newEntryCoef; - MCEntryCoefVisitor mcEntryCoefVisitor(newEntryCoef); - boost::apply_visitor(mcEntryCoefVisitor, kdeModel); -} - -// Modify model Monte Carlo break coefficient. -void KDEModel::MCBreakCoefficient(const double newBreakCoef) -{ - mcBreakCoef = newBreakCoef; - MCBreakCoefVisitor mcBreakCoefVisitor(newBreakCoef); - boost::apply_visitor(mcBreakCoefVisitor, kdeModel); + case R_TREE: + SerializationHelper(ar, kdeModel, kernelType); + break; + } } } // namespace kde From 47c340bf1fe511ec5f900057ce92eacb6f4949cd Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 09:44:44 -0500 Subject: [PATCH 447/550] Fix serialization initialization. --- src/mlpack/methods/kde/kde_model.cpp | 33 +++++++----- src/mlpack/methods/kde/kde_model.hpp | 5 ++ src/mlpack/methods/kde/kde_model_impl.hpp | 2 +- src/mlpack/methods/range_search/rs_model.cpp | 51 ++++++++++--------- src/mlpack/methods/range_search/rs_model.hpp | 5 ++ .../methods/range_search/rs_model_impl.hpp | 2 +- src/mlpack/methods/rann/ra_model.cpp | 49 ++++++++++-------- src/mlpack/methods/rann/ra_model.hpp | 3 ++ src/mlpack/methods/rann/ra_model_impl.hpp | 4 +- 9 files changed, 90 insertions(+), 64 deletions(-) diff --git a/src/mlpack/methods/kde/kde_model.cpp b/src/mlpack/methods/kde/kde_model.cpp index 552f1b4058..7a78c78df5 100644 --- a/src/mlpack/methods/kde/kde_model.cpp +++ b/src/mlpack/methods/kde/kde_model.cpp @@ -149,10 +149,10 @@ KDEModel::~KDEModel() template class TreeType> -KDEWrapperBase* BuildModelHelper(const KDEModel::KernelTypes kernelType, - const double relError, - const double absError, - const double bandwidth) +KDEWrapperBase* InitializeModelHelper(const KDEModel::KernelTypes kernelType, + const double relError, + const double absError, + const double bandwidth) { switch (kernelType) { @@ -181,7 +181,7 @@ KDEWrapperBase* BuildModelHelper(const KDEModel::KernelTypes kernelType, return NULL; } -void KDEModel::BuildModel(arma::mat&& referenceSet) +void KDEModel::InitializeModel() { // Clean memory, if necessary. delete kdeModel; @@ -190,30 +190,35 @@ void KDEModel::BuildModel(arma::mat&& referenceSet) switch (treeType) { case KD_TREE: - kdeModel = BuildModelHelper(kernelType, relError, absError, - bandwidth); + kdeModel = InitializeModelHelper(kernelType, relError, + absError, bandwidth); break; case BALL_TREE: - kdeModel = BuildModelHelper(kernelType, relError, + kdeModel = InitializeModelHelper(kernelType, relError, absError, bandwidth); break; case COVER_TREE: - kdeModel = BuildModelHelper(kernelType, relError, - absError, bandwidth); + kdeModel = InitializeModelHelper(kernelType, + relError, absError, bandwidth); break; case OCTREE: - kdeModel = BuildModelHelper(kernelType, relError, absError, - bandwidth); + kdeModel = InitializeModelHelper(kernelType, relError, + absError, bandwidth); break; case R_TREE: - kdeModel = BuildModelHelper(kernelType, relError, absError, - bandwidth); + kdeModel = InitializeModelHelper(kernelType, relError, + absError, bandwidth); break; } +} + +void KDEModel::BuildModel(arma::mat&& referenceSet) +{ + InitializeModel(); // Set whether to use Monte Carlo estimations or not. kdeModel->MonteCarlo() = monteCarlo; diff --git a/src/mlpack/methods/kde/kde_model.hpp b/src/mlpack/methods/kde/kde_model.hpp index c2f93ba181..48b06c6382 100644 --- a/src/mlpack/methods/kde/kde_model.hpp +++ b/src/mlpack/methods/kde/kde_model.hpp @@ -414,6 +414,11 @@ class KDEModel //! Modify the mode of the model. KDEMode& Mode() { return kdeModel->Mode(); } + /** + * Initialize the KDE model. + */ + void InitializeModel(); + /** * Build the KDE model with the given parameters and then trains it with the * given reference data. diff --git a/src/mlpack/methods/kde/kde_model_impl.hpp b/src/mlpack/methods/kde/kde_model_impl.hpp index bc00f1d50b..325b071cb3 100644 --- a/src/mlpack/methods/kde/kde_model_impl.hpp +++ b/src/mlpack/methods/kde/kde_model_impl.hpp @@ -135,7 +135,7 @@ void KDEModel::serialize(Archive& ar, const uint32_t /* version */) } if (cereal::is_loading()) - delete kdeModel; + InitializeModel(); // Values will be overwritten. // Avoid polymorphism in serialization by serializing directly by the type. switch (treeType) diff --git a/src/mlpack/methods/range_search/rs_model.cpp b/src/mlpack/methods/range_search/rs_model.cpp index 807a347ee4..33308cee35 100644 --- a/src/mlpack/methods/range_search/rs_model.cpp +++ b/src/mlpack/methods/range_search/rs_model.cpp @@ -98,33 +98,11 @@ RSModel::~RSModel() delete rSearch; } -void RSModel::BuildModel(arma::mat&& referenceSet, - const size_t leafSize, - const bool naive, - const bool singleMode) +void RSModel::InitializeModel(const bool naive, const bool singleMode) { - // Initialize random basis if necessary. - if (randomBasis) - { - Log::Info << "Creating random basis..." << std::endl; - math::RandomBasis(q, referenceSet.n_rows); - } - - this->leafSize = leafSize; - // Clean memory, if necessary. delete rSearch; - // Do we need to modify the reference set? - if (randomBasis) - referenceSet = q * referenceSet; - - if (!naive) - { - Timer::Start("tree_building"); - Log::Info << "Building reference tree..." << std::endl; - } - switch (treeType) { case KD_TREE: @@ -183,6 +161,33 @@ void RSModel::BuildModel(arma::mat&& referenceSet, rSearch = new LeafSizeRSWrapper(naive, singleMode); break; } +} + +void RSModel::BuildModel(arma::mat&& referenceSet, + const size_t leafSize, + const bool naive, + const bool singleMode) +{ + // Initialize random basis if necessary. + if (randomBasis) + { + Log::Info << "Creating random basis..." << std::endl; + math::RandomBasis(q, referenceSet.n_rows); + } + + this->leafSize = leafSize; + + // Do we need to modify the reference set? + if (randomBasis) + referenceSet = q * referenceSet; + + if (!naive) + { + Timer::Start("tree_building"); + Log::Info << "Building reference tree..." << std::endl; + } + + InitializeModel(naive, singleMode); rSearch->Train(std::move(referenceSet), leafSize); diff --git a/src/mlpack/methods/range_search/rs_model.hpp b/src/mlpack/methods/range_search/rs_model.hpp index 12638c2836..430274cd9b 100644 --- a/src/mlpack/methods/range_search/rs_model.hpp +++ b/src/mlpack/methods/range_search/rs_model.hpp @@ -300,6 +300,11 @@ class RSModel //! been built). bool& RandomBasis() { return randomBasis; } + /** + * Allocate the memory for the range search model. + */ + void InitializeModel(const bool naive, const bool singleMode); + /** * Build the reference tree on the given dataset with the given parameters. * This takes possession of the reference set to avoid a copy. diff --git a/src/mlpack/methods/range_search/rs_model_impl.hpp b/src/mlpack/methods/range_search/rs_model_impl.hpp index 2df060f977..a59180e1b2 100644 --- a/src/mlpack/methods/range_search/rs_model_impl.hpp +++ b/src/mlpack/methods/range_search/rs_model_impl.hpp @@ -127,7 +127,7 @@ void RSModel::serialize(Archive& ar, const uint32_t /* version */) // This should never happen, but just in case... if (cereal::is_loading()) - delete rSearch; + InitializeModel(false, false); // Values will be overwritten. // Avoid polymorphic serialization by explicitly serializing the correct type. switch (treeType) diff --git a/src/mlpack/methods/rann/ra_model.cpp b/src/mlpack/methods/rann/ra_model.cpp index a6a997a22c..6342acf6b4 100644 --- a/src/mlpack/methods/rann/ra_model.cpp +++ b/src/mlpack/methods/rann/ra_model.cpp @@ -95,32 +95,11 @@ RAModel::~RAModel() delete raSearch; } -void RAModel::BuildModel(arma::mat&& referenceSet, - const size_t leafSize, - const bool naive, - const bool singleMode) +void RAModel::InitializeModel(const bool naive, const bool singleMode) { - // Initialize random basis, if necessary. - if (randomBasis) - { - Log::Info << "Creating random basis..." << std::endl; - math::RandomBasis(q, referenceSet.n_rows); - } - // Clean memory, if necessary. delete raSearch; - this->leafSize = leafSize; - - if (randomBasis) - referenceSet = q * referenceSet; - - if (!naive) - { - Timer::Start("tree_building"); - Log::Info << "Building reference tree..." << std::endl; - } - switch (treeType) { case KD_TREE: @@ -154,6 +133,32 @@ void RAModel::BuildModel(arma::mat&& referenceSet, raSearch = new LeafSizeRAWrapper(naive, singleMode); break; } +} + +void RAModel::BuildModel(arma::mat&& referenceSet, + const size_t leafSize, + const bool naive, + const bool singleMode) +{ + // Initialize random basis, if necessary. + if (randomBasis) + { + Log::Info << "Creating random basis..." << std::endl; + math::RandomBasis(q, referenceSet.n_rows); + } + + this->leafSize = leafSize; + + if (randomBasis) + referenceSet = q * referenceSet; + + if (!naive) + { + Timer::Start("tree_building"); + Log::Info << "Building reference tree..." << std::endl; + } + + InitializeModel(naive, singleMode); raSearch->Train(std::move(referenceSet), leafSize); diff --git a/src/mlpack/methods/rann/ra_model.hpp b/src/mlpack/methods/rann/ra_model.hpp index 8ed91a9c9b..572d599a0d 100644 --- a/src/mlpack/methods/rann/ra_model.hpp +++ b/src/mlpack/methods/rann/ra_model.hpp @@ -385,6 +385,9 @@ class RAModel //! the model using BuildModel(). bool& RandomBasis() { return randomBasis; } + //! Initialize the model's memory. + void InitializeModel(const bool naive, const bool singleMode); + //! Build the reference tree. void BuildModel(arma::mat&& referenceSet, const size_t leafSize, diff --git a/src/mlpack/methods/rann/ra_model_impl.hpp b/src/mlpack/methods/rann/ra_model_impl.hpp index 6955bd9f46..c986c4570c 100644 --- a/src/mlpack/methods/rann/ra_model_impl.hpp +++ b/src/mlpack/methods/rann/ra_model_impl.hpp @@ -126,9 +126,7 @@ void RAModel::serialize(Archive& ar, const uint32_t /* version */) // This should never happen, but just in case, be clean with memory. if (cereal::is_loading()) - { - delete raSearch; - } + InitializeModel(false, false); // Values will be overwritten. // Avoid polymorphic serialization by explicitly serializing the correct type. switch (treeType) From 06950dd1b581a9f6968e12d1e0e217b1ffa91620 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 09:45:18 -0500 Subject: [PATCH 448/550] Remove boost::visitor from mlpack::cf. --- src/mlpack/methods/cf/CMakeLists.txt | 1 + src/mlpack/methods/cf/cf_main.cpp | 437 ++++++++------------- src/mlpack/methods/cf/cf_model.cpp | 207 ++++++++++ src/mlpack/methods/cf/cf_model.hpp | 325 +++++++++------- src/mlpack/methods/cf/cf_model_impl.hpp | 496 ++++++++++++++++-------- src/mlpack/tests/main_tests/cf_test.cpp | 63 ++- 6 files changed, 925 insertions(+), 604 deletions(-) create mode 100644 src/mlpack/methods/cf/cf_model.cpp diff --git a/src/mlpack/methods/cf/CMakeLists.txt b/src/mlpack/methods/cf/CMakeLists.txt index a7c552ae28..c59a4f12ed 100644 --- a/src/mlpack/methods/cf/CMakeLists.txt +++ b/src/mlpack/methods/cf/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCES cf_impl.hpp cf_model.hpp cf_model_impl.hpp + cf_model.cpp svd_wrapper.hpp svd_wrapper_impl.hpp ) diff --git a/src/mlpack/methods/cf/cf_main.cpp b/src/mlpack/methods/cf/cf_main.cpp index 760ddf107d..f4aa8e14b7 100644 --- a/src/mlpack/methods/cf/cf_main.cpp +++ b/src/mlpack/methods/cf/cf_main.cpp @@ -194,279 +194,6 @@ PARAM_STRING_IN("interpolation", "Algorithm used for weight interpolation.", PARAM_STRING_IN("neighbor_search", "Algorithm used for neighbor search.", "S", "euclidean"); -template -void ComputeRecommendations(CFModel* cf, - const size_t numRecs, - arma::Mat& recommendations) -{ - // Reading users. - if (IO::HasParam("query")) - { - // User matrix. - arma::Mat users = - std::move(IO::GetParam>("query")); - if (users.n_rows > 1) - users = users.t(); - if (users.n_rows > 1) - Log::Fatal << "List of query users must be one-dimensional!" - << std::endl; - - Log::Info << "Generating recommendations for " - << users.n_elem << " users." - << endl; - - cf->GetRecommendations - (numRecs, recommendations, users.row(0).t()); - } - else - { - Log::Info << "Generating recommendations for all users." << endl; - cf->GetRecommendations - (numRecs, recommendations); - } -} - -template -void ComputeRecommendations(CFModel* cf, - const size_t numRecs, - arma::Mat& recommendations) -{ - // Verify the Interpolation algorithms. - RequireParamInSet("interpolation", { "average", - "regression", "similarity" }, true, "unknown interpolation algorithm"); - - // Taking Interpolation Alternatives - const string interpolationAlgorithm = IO::GetParam("interpolation"); - - // Determining the Interpolation Algorithm - if (interpolationAlgorithm == "average") - { - ComputeRecommendations - (cf, numRecs, recommendations); - } - else if (interpolationAlgorithm == "regression") - { - ComputeRecommendations - (cf, numRecs, recommendations); - } - else if (interpolationAlgorithm == "similarity") - { - ComputeRecommendations - (cf, numRecs, recommendations); - } -} - -void ComputeRecommendations(CFModel* cf, - const size_t numRecs, - arma::Mat& recommendations) -{ - // Verifying the Neighbor Search algorithms - RequireParamInSet("neighbor_search", { "cosine", - "euclidean", "pearson" }, true, "unknown neighbor search algorithm"); - - // Taking Neighbor Search alternatives - const string neighborSearchAlgorithm = IO::GetParam - ("neighbor_search"); - - - // Determining the Neighbor Search Algorithms - if (neighborSearchAlgorithm == "cosine") - { - ComputeRecommendations(cf, numRecs, recommendations); - } - else if (neighborSearchAlgorithm == "euclidean") - { - ComputeRecommendations(cf, numRecs, recommendations); - } - else if (neighborSearchAlgorithm == "pearson") - { - ComputeRecommendations(cf, numRecs, recommendations); - } -} - -template -void ComputeRMSE(CFModel* cf) -{ - // Now, compute each test point. - arma::mat testData = std::move(IO::GetParam("test")); - - // Assemble the combination matrix to get RMSE value. - arma::Mat combinations(2, testData.n_cols); - for (size_t i = 0; i < testData.n_cols; ++i) - { - combinations(0, i) = size_t(testData(0, i)); - combinations(1, i) = size_t(testData(1, i)); - } - - // Now compute the RMSE. - arma::vec predictions; - cf->Predict - (combinations, predictions); - - // Compute the root of the sum of the squared errors, divide by the number of - // points to get the RMSE. It turns out this is just the L2-norm divided by - // the square root of the number of points, if we interpret the predictions - // and the true values as vectors. - const double rmse = arma::norm(predictions - testData.row(2).t(), 2) / - std::sqrt((double) testData.n_cols); - - Log::Info << "RMSE is " << rmse << "." << endl; -} - -template -void ComputeRMSE(CFModel* cf) -{ - // Verifying the Interpolation algorithms - RequireParamInSet("interpolation", { "average", - "regression", "similarity" }, true, "unknown interpolation algorithm"); - - // Taking Interpolation Alternatives - const string interpolationAlgorithm = IO::GetParam("interpolation"); - - if (interpolationAlgorithm == "average") - { - ComputeRMSE(cf); - } - else if (interpolationAlgorithm == "regression") - { - ComputeRMSE(cf); - } - else if (interpolationAlgorithm == "similarity") - { - ComputeRMSE(cf); - } -} - -void ComputeRMSE(CFModel* cf) -{ - // Verifying the Neighbor Search algorithms - RequireParamInSet("neighbor_search", { "cosine", - "euclidean", "pearson" }, true, "unknown neighbor search algorithm"); - - // Taking Neighbor Search alternatives - const string neighborSearchAlgorithm = IO::GetParam - ("neighbor_search"); - - if (neighborSearchAlgorithm == "cosine") - { - ComputeRMSE(cf); - } - else if (neighborSearchAlgorithm == "euclidean") - { - ComputeRMSE(cf); - } - else if (neighborSearchAlgorithm == "pearson") - { - ComputeRMSE(cf); - } -} - -void PerformAction(CFModel* c) -{ - if (IO::HasParam("query") || IO::HasParam("all_user_recommendations")) - { - // Get parameters for generating recommendations. - const size_t numRecs = (size_t) IO::GetParam("recommendations"); - - // Get the recommendations. - arma::Mat recommendations; - ComputeRecommendations(c, numRecs, recommendations); - - // Save the output. - IO::GetParam>("output") = recommendations; - } - - if (IO::HasParam("test")) - ComputeRMSE(c); - - IO::GetParam("output_model") = c; -} - -template -void PerformAction(arma::mat& dataset, - const size_t rank, - const size_t maxIterations, - const double minResidue) -{ - const size_t neighborhood = (size_t) IO::GetParam("neighborhood"); - - // Make sure the normalization strategy is valid. - RequireParamInSet("normalization", { "overall_mean", "item_mean", - "user_mean", "z_score", "none" }, true, "unknown normalization type"); - - CFModel* c = new CFModel(); - - const string normalizationType = IO::GetParam("normalization"); - - c->template Train(dataset, neighborhood, rank, - maxIterations, minResidue, IO::HasParam("iteration_only_termination"), - normalizationType); - - try - { - PerformAction(c); - } - catch (std::exception& e) - { - // Clean the memory before throwing completely. - delete c; - throw; - } -} - -void AssembleFactorizerType(const std::string& algorithm, - arma::mat& dataset, - const size_t rank) -{ - const size_t maxIterations = (size_t) IO::GetParam("max_iterations"); - const double minResidue = IO::GetParam("min_residue"); - - if (algorithm == "NMF") - { - PerformAction(dataset, rank, maxIterations, minResidue); - } - else if (algorithm == "BatchSVD") - { - PerformAction(dataset, rank, maxIterations, minResidue); - } - else if (algorithm == "SVDIncompleteIncremental") - { - PerformAction(dataset, rank, maxIterations, - minResidue); - } - else if (algorithm == "SVDCompleteIncremental") - { - PerformAction(dataset, rank, maxIterations, minResidue); - } - else if (algorithm == "RegSVD") - { - ReportIgnoredParam("min_residue", "Regularized SVD terminates only " - "when max_iterations is reached"); - PerformAction(dataset, rank, maxIterations, minResidue); - } - else if (algorithm == "RandSVD") - { - ReportIgnoredParam("min_residue", "Randomized SVD terminates only " - "when max_iterations is reached"); - PerformAction(dataset, rank, maxIterations, - minResidue); - } - else if (algorithm == "BiasSVD") - { - ReportIgnoredParam("min_residue", "Bias SVD terminates only " - "when max_iterations is reached"); - PerformAction(dataset, rank, maxIterations, minResidue); - } - else if (algorithm == "SVDPP") - { - ReportIgnoredParam("min_residue", "SVD++ terminates only " - "when max_iterations is reached"); - PerformAction(dataset, rank, maxIterations, minResidue); - } -} - static void mlpackMain() { if (IO::GetParam("seed") == 0) @@ -496,6 +223,7 @@ static void mlpackMain() "recommendations must be positive"); // Either load from a model, or train a model. + CFModel* cf; if (IO::HasParam("training")) { // Train a model. @@ -523,23 +251,174 @@ static void mlpackMain() // Get parameters. const size_t rank = (size_t) IO::GetParam("rank"); + cf = new CFModel(); + // Perform decomposition to prepare for recommendations. Log::Info << "Performing CF matrix decomposition on dataset..." << endl; const string algo = IO::GetParam("algorithm"); + if (algo == "NMF") + { + cf->DecompositionType() = CFModel::NMF; + } + else if (algo == "BatchSVD") + { + cf->DecompositionType() = CFModel::BATCH_SVD; + } + else if (algo == "SVDIncompleteIncremental") + { + cf->DecompositionType() = CFModel::SVD_INCOMPLETE; + } + else if (algo == "SVDCompleteIncremental") + { + cf->DecompositionType() = CFModel::SVD_COMPLETE; + } + else if (algo == "RegSVD") + { + ReportIgnoredParam("min_residue", "Regularized SVD terminates only " + "when max_iterations is reached"); + cf->DecompositionType() = CFModel::REG_SVD; + } + else if (algo == "RandSVD") + { + ReportIgnoredParam("min_residue", "Randomized SVD terminates only " + "when max_iterations is reached"); + cf->DecompositionType() = CFModel::RANDOMIZED_SVD; + } + else if (algo == "BiasSVD") + { + ReportIgnoredParam("min_residue", "Bias SVD terminates only " + "when max_iterations is reached"); + cf->DecompositionType() = CFModel::BIAS_SVD; + } + else if (algo == "SVDPP") + { + ReportIgnoredParam("min_residue", "SVD++ terminates only " + "when max_iterations is reached"); + cf->DecompositionType() = CFModel::SVD_PLUS_PLUS; + } // Perform the factorization and do whatever the user wanted. - AssembleFactorizerType(algo, dataset, rank); + const size_t neighborhood = (size_t) IO::GetParam("neighborhood"); + + // Make sure the normalization strategy is valid. + RequireParamInSet("normalization", { "overall_mean", "item_mean", + "user_mean", "z_score", "none" }, true, "unknown normalization type"); + + const string normalizationType = IO::GetParam("normalization"); + if (normalizationType == "none") + cf->NormalizationType() = CFModel::NO_NORMALIZATION; + else if (normalizationType == "item_mean") + cf->NormalizationType() = CFModel::ITEM_MEAN_NORMALIZATION; + else if (normalizationType == "user_mean") + cf->NormalizationType() = CFModel::USER_MEAN_NORMALIZATION; + else if (normalizationType == "overall_mean") + cf->NormalizationType() = CFModel::OVERALL_MEAN_NORMALIZATION; + else if (normalizationType == "z_score") + cf->NormalizationType() = CFModel::Z_SCORE_NORMALIZATION; + + cf->Train(dataset, + neighborhood, + rank, + size_t(IO::GetParam("max_iterations")), + IO::GetParam("min_residue"), + IO::HasParam("iteration_only_termination")); } else { // Load from a model after validating parameters. - RequireAtLeastOnePassed({ "query", "all_user_recommendations", - "test" }, true); + RequireAtLeastOnePassed({ "query", "all_user_recommendations", "test" }, + true); // Load an input model. - CFModel* c = std::move(IO::GetParam("input_model")); - - PerformAction(c); + cf = std::move(IO::GetParam("input_model")); } + + // Get the types of the neighbor search method and the interpolation. (These + // may or may not be used.) + NeighborSearchTypes nsType; + RequireParamInSet("neighbor_search", { "cosine", + "euclidean", "pearson" }, true, "unknown neighbor search algorithm"); + if (IO::GetParam("neighbor_search") == "cosine") + nsType = COSINE_SEARCH; + else if (IO::GetParam("neighbor_search") == "euclidean") + nsType = EUCLIDEAN_SEARCH; + else if (IO::GetParam("neighbor_search") == "pearson") + nsType = PEARSON_SEARCH; + + InterpolationTypes interpolationType; + RequireParamInSet("interpolation", { "average", + "regression", "similarity" }, true, "unknown interpolation algorithm"); + if (IO::GetParam("interpolation") == "average") + interpolationType = AVERAGE_INTERPOLATION; + else if (IO::GetParam("interpolation") == "regression") + interpolationType = REGRESSION_INTERPOLATION; + else if (IO::GetParam("interpolation") == "similarity") + interpolationType = SIMILARITY_INTERPOLATION; + + if (IO::HasParam("query") || IO::HasParam("all_user_recommendations")) + { + // Get parameters for generating recommendations. + const size_t numRecs = (size_t) IO::GetParam("recommendations"); + + // Get the recommendations. + arma::Mat recommendations; + + // Reading users. + if (IO::HasParam("query")) + { + // User matrix. + arma::Mat users = + std::move(IO::GetParam>("query")); + if (users.n_rows > 1) + users = users.t(); + if (users.n_rows > 1) + Log::Fatal << "List of query users must be one-dimensional!" + << std::endl; + + Log::Info << "Generating recommendations for " << users.n_elem + << " users." << endl; + + cf->GetRecommendations(nsType, interpolationType, numRecs, + recommendations, users.row(0).t()); + } + else + { + Log::Info << "Generating recommendations for all users." << endl; + cf->GetRecommendations(nsType, interpolationType, numRecs, + recommendations); + } + + // Save the output. + IO::GetParam>("output") = recommendations; + } + + if (IO::HasParam("test")) + { + // Now, compute each test point. + arma::mat testData = std::move(IO::GetParam("test")); + + // Assemble the combination matrix to get RMSE value. + arma::Mat combinations(2, testData.n_cols); + for (size_t i = 0; i < testData.n_cols; ++i) + { + combinations(0, i) = size_t(testData(0, i)); + combinations(1, i) = size_t(testData(1, i)); + } + + // Now compute the RMSE. + arma::vec predictions; + cf->Predict(nsType, interpolationType, combinations, predictions); + + // Compute the root of the sum of the squared errors, divide by the number + // of points to get the RMSE. It turns out this is just the L2-norm divided + // by the square root of the number of points, if we interpret the + // predictions and the true values as vectors. + const double rmse = arma::norm(predictions - testData.row(2).t(), 2) / + std::sqrt((double) testData.n_cols); + + Log::Info << "RMSE is " << rmse << "." << endl; + } + + IO::GetParam("output_model") = cf; } diff --git a/src/mlpack/methods/cf/cf_model.cpp b/src/mlpack/methods/cf/cf_model.cpp new file mode 100644 index 0000000000..226edcf1be --- /dev/null +++ b/src/mlpack/methods/cf/cf_model.cpp @@ -0,0 +1,207 @@ +/** + * @file methods/cf/cf_model_impl.hpp + * @author Wenhao Huang + * + * A serializable CF model, used by the main program. + * + * 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. + */ +#include "cf_model.hpp" + +namespace mlpack { +namespace cf { + +CFModel::CFModel() : + decompositionType(NMF), + normalizationType(NO_NORMALIZATION), + cf(NULL) +{ + // Nothing else to do. +} + +CFModel::CFModel(const CFModel& other) : + decompositionType(other.decompositionType), + normalizationType(other.normalizationType), + cf(other.cf->Clone()) +{ + // Nothing else to do. +} + +CFModel::CFModel(CFModel&& other) : + decompositionType(other.decompositionType), + normalizationType(other.normalizationType), + cf(std::move(other.cf)) +{ + // Reset properties of the other one. + other.decompositionType = NMF; + other.normalizationType = NO_NORMALIZATION; +} + +CFModel& CFModel::operator=(const CFModel& other) +{ + if (this != &other) + { + decompositionType = other.decompositionType; + normalizationType = other.normalizationType; + cf = other.cf->Clone(); + } + + return *this; +} + +CFModel& CFModel::operator=(CFModel&& other) +{ + if (this != &other) + { + decompositionType = other.decompositionType; + normalizationType = other.normalizationType; + cf = std::move(other.cf); + + // Reset the other object. + other.decompositionType = NMF; + other.normalizationType = NO_NORMALIZATION; + } + + return *this; +} + +CFModel::~CFModel() +{ + delete cf; +} + +template +CFWrapperBase* TrainHelper(const DecompositionPolicy& decomposition, + const CFModel::NormalizationTypes normalizationType, + const arma::mat& data, + const size_t numUsersForSimilarity, + const size_t rank, + const size_t maxIterations, + const double minResidue, + const bool mit) +{ + switch (normalizationType) + { + case CFModel::NO_NORMALIZATION: + return new CFWrapper(data, + decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, + mit); + break; + + case CFModel::ITEM_MEAN_NORMALIZATION: + return new CFWrapper(data, + decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, + mit); + break; + + case CFModel::USER_MEAN_NORMALIZATION: + return new CFWrapper(data, + decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, + mit); + break; + + case CFModel::OVERALL_MEAN_NORMALIZATION: + return new CFWrapper(data, + decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, + mit); + break; + + case CFModel::Z_SCORE_NORMALIZATION: + return new CFWrapper(data, + decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, + mit); + break; + } + + // This shouldn't ever happen. + return NULL; +} + +void CFModel::Train(const arma::mat& data, + const size_t numUsersForSimilarity, + const size_t rank, + const size_t maxIterations, + const double minResidue, + const bool mit) +{ + // Delete the current CFType object, if there is one. + delete cf; + + switch (decompositionType) + { + case NMF: + cf = TrainHelper(NMFPolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case BATCH_SVD: + cf = TrainHelper(BatchSVDPolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case RANDOMIZED_SVD: + cf = TrainHelper(RandomizedSVDPolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case REG_SVD: + cf = TrainHelper(RegSVDPolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case SVD_COMPLETE: + cf = TrainHelper(SVDCompletePolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case SVD_INCOMPLETE: + cf = TrainHelper(SVDIncompletePolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case BIAS_SVD: + cf = TrainHelper(BiasSVDPolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + + case SVD_PLUS_PLUS: + cf = TrainHelper(SVDPlusPlusPolicy(), normalizationType, data, + numUsersForSimilarity, rank, maxIterations, minResidue, mit); + break; + } +} + +//! Make predictions. +void CFModel::Predict(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const arma::Mat& combinations, + arma::vec& predictions) +{ + cf->Predict(nsType, interpolationType, combinations, predictions); +} + +//! Compute recommendations for queried users. +void CFModel::GetRecommendations(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations, + const arma::Col& users) +{ + cf->GetRecommendations(nsType, interpolationType, numRecs, recommendations, + users); +} + +//! Compute recommendations for all users. +void CFModel::GetRecommendations(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations) +{ + cf->GetRecommendations(nsType, interpolationType, numRecs, recommendations); +} + +} // namespace cf +} // namespace mlpack diff --git a/src/mlpack/methods/cf/cf_model.hpp b/src/mlpack/methods/cf/cf_model.hpp index 93ff371a02..354f8b51b5 100644 --- a/src/mlpack/methods/cf/cf_model.hpp +++ b/src/mlpack/methods/cf/cf_model.hpp @@ -14,105 +14,146 @@ #define MLPACK_METHODS_CF_CF_MODEL_HPP #include -#include #include "cf.hpp" -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - namespace mlpack { namespace cf { /** - * DeleteVisitor deletes the CFType<> object which is pointed to by the - * variable cf in class CFModel. + * NeighborSearchTypes contains the set of NeighborSearchPolicy classes that are + * usable by CFModel at prediction time. */ -class DeleteVisitor : public boost::static_visitor +enum NeighborSearchTypes { - public: - //! Delete CFType object. - template - void operator()(CFType* c) const; + COSINE_SEARCH, + EUCLIDEAN_SEARCH, + PEARSON_SEARCH }; /** - * GetValueVisitor returns the pointer which points to the CFType object. + * InterpolationTypes contains the set of InterpolationPolicy classes that are + * usable by CFModel at prediction time. */ -class GetValueVisitor : public boost::static_visitor +enum InterpolationTypes { - public: - //! Return stored pointer as void* type. - template - void* operator()(CFType* c) const; + AVERAGE_INTERPOLATION, + REGRESSION_INTERPOLATION, + SIMILARITY_INTERPOLATION }; /** - * PredictVisitor uses the CFType object to make predictions on the given - * combinations of users and items. + * The CFWrapperBase class provides a unified interface that can be used by the + * CFModel class to interact with all different CF types at runtime. All CF + * wrapper types inherit from this base class. */ -template -class PredictVisitor : public boost::static_visitor +class CFWrapperBase { - private: - //! User/item combinations to predict. - const arma::Mat& combinations; - //! Predicted ratings for each user/item combination. - arma::vec& predictions; - public: - //! Predict ratings for each user-item combination. - template - void operator()(CFType* c) const; + //! Create the object. The base class has nothing to hold. + CFWrapperBase() { } - //! Visitor constructor. - PredictVisitor(const arma::Mat& combinations, - arma::vec& predictions); + //! Make a copy of the object. + virtual CFWrapperBase* Clone() const = 0; + + //! Delete the object. + virtual ~CFWrapperBase() { } + + //! Compute predictions for users. + virtual void Predict(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const arma::Mat& combinations, + arma::vec& predictions) = 0; + + //! Compute recommendations for all users. + virtual void GetRecommendations( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations) = 0; + + //! Compute recommendations. + virtual void GetRecommendations( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations, + const arma::Col& users) = 0; }; /** - * RecommendationVisitor uses the CFType object to get recommendations for the - * given users. + * The CFWrapper class wraps the functionality of all CF types. If special + * handling is needed for a future CF type, this class can be extended. */ -template -class RecommendationVisitor : public boost::static_visitor +template +class CFWrapper : public CFWrapperBase { - private: - //! Number of Recommendations. - const size_t numRecs; - //! Recommendations matrix to save recommendations. - arma::Mat& recommendations; - //! Users for which recommendations are to be generated. - const arma::Col& users; - //! Whether users are given. - const bool usersGiven; + protected: + typedef CFType CFModelType; public: - //! Visitor constructor. - RecommendationVisitor(const size_t numRecs, - arma::Mat& recommendations, - const arma::Col& users, - const bool usersGiven); + //! Create the CFWrapper object, using default parameters to initialize the + //! held CF object. + CFWrapper() { } - //! Generates the given number of recommendations. - template - void operator()(CFType* c) const; + //! Create the CFWrapper object, initializing the held CF object. + CFWrapper(const arma::mat& data, + const DecompositionPolicy& decomposition, + const size_t numUsersForSimilarity, + const size_t rank, + const size_t maxIterations, + const size_t minResidue, + const bool mit) : + cf(data, + decomposition, + numUsersForSimilarity, + rank, + maxIterations, + minResidue, + mit) + { + // Nothing else to do. + } + + //! Clone the CFWrapper object. This handles polymorphism correctly. + virtual CFWrapper* Clone() const { return new CFWrapper(*this); } + + //! Destroy the CFWrapper object. + virtual ~CFWrapper() { } + + //! Get the CFType object. + CFModelType& CF() { return cf; } + + //! Compute predictions for users. + virtual void Predict(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const arma::Mat& combinations, + arma::vec& predictions); + + //! Compute recommendations for all users. + virtual void GetRecommendations( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations); + + //! Compute recommendations. + virtual void GetRecommendations( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations, + const arma::Col& users); + + //! Serialize the model. + template + void serialize(Archive& ar, const uint32_t /* version */) + { + ar(CEREAL_NVP(cf)); + } + + protected: + //! This is the CF object that we are wrapping. + CFModelType cf; }; /** @@ -120,98 +161,110 @@ class RecommendationVisitor : public boost::static_visitor */ class CFModel { + public: + enum DecompositionTypes + { + NMF, + BATCH_SVD, + RANDOMIZED_SVD, + REG_SVD, + SVD_COMPLETE, + SVD_INCOMPLETE, + BIAS_SVD, + SVD_PLUS_PLUS + }; + + enum NormalizationTypes + { + NO_NORMALIZATION, + ITEM_MEAN_NORMALIZATION, + USER_MEAN_NORMALIZATION, + OVERALL_MEAN_NORMALIZATION, + Z_SCORE_NORMALIZATION + }; + private: + //! The current decomposition policy type. + DecompositionTypes decompositionType; + //! The current normalization policy type. + NormalizationTypes normalizationType; + /** * cf holds an instance of the CFType class for the current * decompositionPolicy and normalizationType. It is initialized every time - * Train() is executed. We access to the contained value through the visitor - * classes defined above. + * Train() is executed. */ - boost::variant*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*, - CFType*> cf; + CFWrapperBase* cf; public: //! Create an empty CF model. - CFModel() { } + CFModel(); + + //! Create a CF model by copying the given model. + CFModel(const CFModel& other); + + //! Create a CF model by taking ownership of the data of the other model. + CFModel(CFModel&& other); + + //! Make this CF model a copy of the other model. + CFModel& operator=(const CFModel& other); + + //! Make this CF model take ownership of the data of the other model. + CFModel& operator=(CFModel&& other); //! Clean up memory. ~CFModel(); - //! Get the pointer to CFType<> object. - template - const CFType* CFPtr() const; + //! Get the CFWrapperBase object. (Be careful!) + CFWrapperBase* CF() const { return cf; } + + //! Get the decomposition type. + const DecompositionTypes& DecompositionType() const + { + return decompositionType; + } + //! Set the decomposition type. + DecompositionTypes& DecompositionType() + { + return decompositionType; + } + + //! Get the normalization type. + const NormalizationTypes& NormalizationType() const + { + return normalizationType; + } + //! Set the normalization type. + NormalizationTypes& NormalizationType() + { + return normalizationType; + } //! Train the model. - template - void Train(const MatType& data, + void Train(const arma::mat& data, const size_t numUsersForSimilarity, const size_t rank, const size_t maxIterations, const double minResidue, - const bool mit, - const std::string& normalizationType = "none"); + const bool mit); //! Make predictions. - template - void Predict(const arma::Mat& combinations, + void Predict(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const arma::Mat& combinations, arma::vec& predictions); //! Compute recommendations for query users. - template - void GetRecommendations(const size_t numRecs, + void GetRecommendations(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, arma::Mat& recommendations, const arma::Col& users); //! Compute recommendations for all users. - template - void GetRecommendations(const size_t numRecs, + void GetRecommendations(const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, arma::Mat& recommendations); //! Serialize the model. diff --git a/src/mlpack/methods/cf/cf_model_impl.hpp b/src/mlpack/methods/cf/cf_model_impl.hpp index 6df3491e59..fa2634a823 100644 --- a/src/mlpack/methods/cf/cf_model_impl.hpp +++ b/src/mlpack/methods/cf/cf_model_impl.hpp @@ -14,204 +14,364 @@ #include "cf_model.hpp" -#include -#include -#include -#include -#include +#include "interpolation_policies/average_interpolation.hpp" +#include "interpolation_policies/regression_interpolation.hpp" +#include "interpolation_policies/similarity_interpolation.hpp" -using namespace mlpack::cf; +#include "neighbor_search_policies/cosine_search.hpp" +#include "neighbor_search_policies/lmetric_search.hpp" +#include "neighbor_search_policies/pearson_search.hpp" -template -void DeleteVisitor:: -operator()(CFType* c) const +#include "decomposition_policies/batch_svd_method.hpp" +#include "decomposition_policies/bias_svd_method.hpp" +#include "decomposition_policies/nmf_method.hpp" +#include "decomposition_policies/randomized_svd_method.hpp" +#include "decomposition_policies/regularized_svd_method.hpp" +#include "decomposition_policies/svd_complete_method.hpp" +#include "decomposition_policies/svd_incomplete_method.hpp" +#include "decomposition_policies/svdplusplus_method.hpp" + +#include "normalization/no_normalization.hpp" +#include "normalization/overall_mean_normalization.hpp" +#include "normalization/user_mean_normalization.hpp" +#include "normalization/item_mean_normalization.hpp" +#include "normalization/z_score_normalization.hpp" + +namespace mlpack { +namespace cf { + +template +void PredictHelper(CFType& cf, + const InterpolationTypes interpolationType, + const arma::Mat& combinations, + arma::vec& predictions) { - if (c) - delete c; -} - -template -void* GetValueVisitor:: -operator()(CFType* c) const -{ - if (!c) - throw std::runtime_error("no cf model initialized"); - - return (void*) c; -} - -template -PredictVisitor::PredictVisitor( - const arma::Mat& combinations, - arma::vec& predictions) : - combinations(combinations), - predictions(predictions) -{ } - -template -template -void PredictVisitor - ::operator()(CFType* c) const -{ - if (!c) + switch (interpolationType) { - throw std::runtime_error("no cf model initialized"); - return; - } + case AVERAGE_INTERPOLATION: + cf.template Predict(combinations, predictions); + break; - c->template Predict(combinations, predictions); -} + case REGRESSION_INTERPOLATION: + cf.template Predict(combinations, predictions); + break; -template -RecommendationVisitor - ::RecommendationVisitor( - const size_t numRecs, - arma::Mat& recommendations, - const arma::Col& users, - const bool usersGiven) : - numRecs(numRecs), - recommendations(recommendations), - users(users), - usersGiven(usersGiven) -{ } - -template -template -void RecommendationVisitor - ::operator()(CFType* c) const -{ - if (!c) - { - throw std::runtime_error("no cf model initialized"); - return; - } - - if (usersGiven) - c->template GetRecommendations - (numRecs, recommendations, users); - else - c->template GetRecommendations - (numRecs, recommendations); -} - -CFModel::~CFModel() -{ - boost::apply_visitor(DeleteVisitor(), cf); -} - -template -void CFModel::Train(const MatType& data, - const size_t numUsersForSimilarity, - const size_t rank, - const size_t maxIterations, - const double minResidue, - const bool mit, - const std::string& normalization) -{ - // Delete the current CFType object, if there is one. - boost::apply_visitor(DeleteVisitor(), cf); - - // Instantiate a new CFType object. - DecompositionPolicy decomposition; - if (normalization == "overall_mean") - { - cf = new CFType(data, - decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, - mit); - } - else if (normalization == "item_mean") - { - cf = new CFType(data, - decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, - mit); - } - else if (normalization == "user_mean") - { - cf = new CFType(data, - decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, - mit); - } - else if (normalization == "z_score") - { - cf = new CFType(data, - decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, - mit); - } - else if (normalization == "none") - { - cf = new CFType(data, - decomposition, numUsersForSimilarity, rank, maxIterations, minResidue, - mit); - } - else - { - throw std::runtime_error("Unsupported normalization algorithm." - " It should be one of none, overall_mean, " - "item_mean, user_mean or z_score"); + case SIMILARITY_INTERPOLATION: + cf.template Predict(combinations, predictions); + break; } } //! Make predictions. -template -void CFModel::Predict(const arma::Mat& combinations, - arma::vec& predictions) +template +void CFWrapper::Predict( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const arma::Mat& combinations, + arma::vec& predictions) { - PredictVisitor - predict(combinations, predictions); - boost::apply_visitor(predict, cf); + switch (nsType) + { + case COSINE_SEARCH: + PredictHelper(cf, interpolationType, combinations, + predictions); + break; + + case EUCLIDEAN_SEARCH: + PredictHelper(cf, interpolationType, combinations, + predictions); + break; + + case PEARSON_SEARCH: + PredictHelper(cf, interpolationType, combinations, + predictions); + break; + } +} + +template +void GetRecommendationsHelper( + CFType& cf, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations, + const arma::Col& users) +{ + switch (interpolationType) + { + case AVERAGE_INTERPOLATION: + cf.template GetRecommendations( + numRecs, recommendations, users); + break; + + case REGRESSION_INTERPOLATION: + cf.template GetRecommendations( + numRecs, recommendations, users); + break; + + case SIMILARITY_INTERPOLATION: + cf.template GetRecommendations( + numRecs, recommendations, users); + break; + } } //! Compute recommendations for queried users. -template -void CFModel::GetRecommendations(const size_t numRecs, - arma::Mat& recommendations, - const arma::Col& users) +template +void CFWrapper::GetRecommendations( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations, + const arma::Col& users) { - RecommendationVisitor - recommendation(numRecs, recommendations, users, true); - boost::apply_visitor(recommendation, cf); + switch (nsType) + { + case COSINE_SEARCH: + GetRecommendationsHelper(cf, interpolationType, numRecs, + recommendations, users); + break; + + case EUCLIDEAN_SEARCH: + GetRecommendationsHelper(cf, interpolationType, numRecs, + recommendations, users); + break; + + case PEARSON_SEARCH: + GetRecommendationsHelper(cf, interpolationType, numRecs, + recommendations, users); + break; + } +} + +template +void GetRecommendationsHelper( + CFType& cf, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations) +{ + switch (interpolationType) + { + case AVERAGE_INTERPOLATION: + cf.template GetRecommendations( + numRecs, recommendations); + break; + + case REGRESSION_INTERPOLATION: + cf.template GetRecommendations( + numRecs, recommendations); + break; + + case SIMILARITY_INTERPOLATION: + cf.template GetRecommendations( + numRecs, recommendations); + break; + } } //! Compute recommendations for all users. -template -void CFModel::GetRecommendations(const size_t numRecs, - arma::Mat& recommendations) +template +void CFWrapper::GetRecommendations( + const NeighborSearchTypes nsType, + const InterpolationTypes interpolationType, + const size_t numRecs, + arma::Mat& recommendations) { - arma::Col users; - RecommendationVisitor - recommendation(numRecs, recommendations, users, false); - boost::apply_visitor(recommendation, cf); + switch (nsType) + { + case COSINE_SEARCH: + GetRecommendationsHelper(cf, interpolationType, numRecs, + recommendations); + break; + + case EUCLIDEAN_SEARCH: + GetRecommendationsHelper(cf, interpolationType, numRecs, + recommendations); + break; + + case PEARSON_SEARCH: + GetRecommendationsHelper(cf, interpolationType, numRecs, + recommendations); + break; + } } -template -const CFType* CFModel::CFPtr() const +template +CFWrapperBase* InitializeModelHelper( + CFModel::NormalizationTypes normalizationType) { - void* pointer = boost::apply_visitor(GetValueVisitor(), cf); - return (CFType*) pointer; + switch (normalizationType) + { + case CFModel::NO_NORMALIZATION: + return new CFWrapper(); + + case CFModel::ITEM_MEAN_NORMALIZATION: + return new CFWrapper(); + + case CFModel::USER_MEAN_NORMALIZATION: + return new CFWrapper(); + + case CFModel::OVERALL_MEAN_NORMALIZATION: + return new CFWrapper(); + + case CFModel::Z_SCORE_NORMALIZATION: + return new CFWrapper(); + } + + // This shouldn't ever happen. + return NULL; +} + +inline CFWrapperBase* InitializeModel( + CFModel::DecompositionTypes decompositionType, + CFModel::NormalizationTypes normalizationType) +{ + switch (decompositionType) + { + case CFModel::NMF: + return InitializeModelHelper(normalizationType); + + case CFModel::BATCH_SVD: + return InitializeModelHelper(normalizationType); + + case CFModel::RANDOMIZED_SVD: + return InitializeModelHelper(normalizationType); + + case CFModel::REG_SVD: + return InitializeModelHelper(normalizationType); + + case CFModel::SVD_COMPLETE: + return InitializeModelHelper(normalizationType); + + case CFModel::SVD_INCOMPLETE: + return InitializeModelHelper(normalizationType); + + case CFModel::BIAS_SVD: + return InitializeModelHelper(normalizationType); + + case CFModel::SVD_PLUS_PLUS: + return InitializeModelHelper(normalizationType); + } + + // This shouldn't ever happen. + return NULL; +}; + +template +void SerializeHelper(Archive& ar, + CFWrapperBase* cf, + CFModel::NormalizationTypes normalizationType) +{ + switch (normalizationType) + { + case CFModel::NO_NORMALIZATION: + { + CFWrapper& typedModel = + dynamic_cast&>(*cf); + ar(CEREAL_NVP(typedModel)); + break; + } + + case CFModel::ITEM_MEAN_NORMALIZATION: + { + CFWrapper& typedModel = + dynamic_cast&>(*cf); + ar(CEREAL_NVP(typedModel)); + break; + } + + case CFModel::USER_MEAN_NORMALIZATION: + { + CFWrapper& typedModel = + dynamic_cast&>(*cf); + ar(CEREAL_NVP(typedModel)); + break; + } + + case CFModel::OVERALL_MEAN_NORMALIZATION: + { + CFWrapper& typedModel = + dynamic_cast&>(*cf); + ar(CEREAL_NVP(typedModel)); + break; + } + + case CFModel::Z_SCORE_NORMALIZATION: + { + CFWrapper& typedModel = + dynamic_cast&>(*cf); + ar(CEREAL_NVP(typedModel)); + break; + } + } } template void CFModel::serialize(Archive& ar, const uint32_t /* version */) { + ar(CEREAL_NVP(decompositionType)); + ar(CEREAL_NVP(normalizationType)); + // This should never happen, but just in case, be clean with memory. if (cereal::is_loading()) - boost::apply_visitor(DeleteVisitor(), cf); + { + delete cf; + cf = InitializeModel(decompositionType, normalizationType); + } - ar(CEREAL_VARIANT_POINTER(cf)); + // Avoid polymorphic serialization by determining the type directly. + switch (decompositionType) + { + case NMF: + SerializeHelper(ar, cf, normalizationType); + break; + + case BATCH_SVD: + SerializeHelper(ar, cf, normalizationType); + break; + + case RANDOMIZED_SVD: + SerializeHelper(ar, cf, normalizationType); + break; + + case REG_SVD: + SerializeHelper(ar, cf, normalizationType); + break; + + case SVD_COMPLETE: + SerializeHelper(ar, cf, normalizationType); + break; + + case SVD_INCOMPLETE: + SerializeHelper(ar, cf, normalizationType); + break; + + case BIAS_SVD: + SerializeHelper(ar, cf, normalizationType); + break; + + case SVD_PLUS_PLUS: + SerializeHelper(ar, cf, normalizationType); + break; + } } +} // namespace cf +} // namespace mlpack + #endif diff --git a/src/mlpack/tests/main_tests/cf_test.cpp b/src/mlpack/tests/main_tests/cf_test.cpp index b136d9b730..da1c8c77fc 100644 --- a/src/mlpack/tests/main_tests/cf_test.cpp +++ b/src/mlpack/tests/main_tests/cf_test.cpp @@ -213,13 +213,13 @@ TEST_CASE_METHOD(CFTestFixture, "CFModelReuseTest", IO::GetSingleton().Parameters()["algorithm"].wasPassed = false; // Reuse the model to get recommendations. - int recommendations = 3; - const int querySize = 7; + size_t recommendations = 3; + const size_t querySize = 7; Mat query = arma::linspace>(0, querySize - 1, querySize); SetInputParam("query", std::move(query)); - SetInputParam("recommendations", recommendations); + SetInputParam("recommendations", int(recommendations)); SetInputParam("input_model", std::move(IO::GetParam("output_model"))); @@ -261,18 +261,21 @@ TEST_CASE_METHOD(CFTestFixture, "CFRankTest", { mat dataset; data::Load("GroupLensSmall.csv", dataset); - int rank = 7; + size_t rank = 7; SetInputParam("training", std::move(dataset)); - SetInputParam("rank", rank); + SetInputParam("rank", int(rank)); SetInputParam("max_iterations", int(10)); SetInputParam("algorithm", std::string("NMF")); mlpackMain(); const CFModel* outputModel = IO::GetParam("output_model"); + CFType& cf = + dynamic_cast&>(*(outputModel->CF())).CF(); - REQUIRE(outputModel->template CFPtr()->Rank() == rank); + REQUIRE(cf.Rank() == rank); } /** @@ -295,10 +298,13 @@ TEST_CASE_METHOD(CFTestFixture, "CFMinResidueTest", mlpack::math::FixedRandomSeed(); mlpackMain(); - outputModel = IO::GetParam("output_model"); + outputModel = IO::GetParam("output_model"); // By default the main program use NMFPolicy. - const mat w1 = outputModel->template CFPtr()->Decomposition().W(); - const mat h1 = outputModel->template CFPtr()->Decomposition().H(); + CFType& cf = + dynamic_cast&>(*(outputModel->CF())).CF(); + const mat w1 = cf.Decomposition().W(); + const mat h1 = cf.Decomposition().H(); ResetSettings(); @@ -314,15 +320,18 @@ TEST_CASE_METHOD(CFTestFixture, "CFMinResidueTest", outputModel = IO::GetParam("output_model"); // By default the main program use NMFPolicy. - const mat w2 = outputModel->template CFPtr()->Decomposition().W(); - const mat h2 = outputModel->template CFPtr()->Decomposition().H(); + CFType& cf2 = + dynamic_cast&>(*(outputModel->CF())).CF(); + const mat w2 = cf2.Decomposition().W(); + const mat h2 = cf2.Decomposition().H(); // The resulting matrices should be different. REQUIRE((arma::norm(w1 - w2) > 1e-5 || arma::norm(h1 - h2) > 1e-5)); } /** - * Test that itertaion_only_termination is used. + * Test that iteration_only_termination is used. */ TEST_CASE_METHOD(CFTestFixture, "CFIterationOnlyTerminationTest", "[CFMainTest][BindingTests]") @@ -341,10 +350,13 @@ TEST_CASE_METHOD(CFTestFixture, "CFIterationOnlyTerminationTest", mlpack::math::FixedRandomSeed(); mlpackMain(); - outputModel = IO::GetParam("output_model"); + outputModel = IO::GetParam("output_model"); // By default, the main program use NMFPolicy. - const mat w1 = outputModel->template CFPtr()->Decomposition().W(); - const mat h1 = outputModel->template CFPtr()->Decomposition().H(); + CFType& cf = + dynamic_cast&>(*(outputModel->CF())).CF(); + const mat w1 = cf.Decomposition().W(); + const mat h1 = cf.Decomposition().H(); ResetSettings(); @@ -359,8 +371,11 @@ TEST_CASE_METHOD(CFTestFixture, "CFIterationOnlyTerminationTest", outputModel = IO::GetParam("output_model"); // By default, the main program use NMFPolicy. - const mat w2 = outputModel->template CFPtr()->Decomposition().W(); - const mat h2 = outputModel->template CFPtr()->Decomposition().H(); + CFType& cf2 = + dynamic_cast&>(*(outputModel->CF())).CF(); + const mat w2 = cf2.Decomposition().W(); + const mat h2 = cf2.Decomposition().H(); // The resulting matrices should be different. REQUIRE((arma::norm(w1 - w2) > 1e-5 || arma::norm(h1 - h2) > 1e-5)); @@ -387,8 +402,11 @@ TEST_CASE_METHOD(CFTestFixture, "CFMaxIterationsTest", outputModel = IO::GetParam("output_model"); // By default, the main program use NMFPolicy. - const mat w1 = outputModel->template CFPtr()->Decomposition().W(); - const mat h1 = outputModel->template CFPtr()->Decomposition().H(); + CFType& cf = + dynamic_cast&>(*(outputModel->CF())).CF(); + const mat w1 = cf.Decomposition().W(); + const mat h1 = cf.Decomposition().H(); ResetSettings(); @@ -403,8 +421,11 @@ TEST_CASE_METHOD(CFTestFixture, "CFMaxIterationsTest", outputModel = IO::GetParam("output_model"); // By default the main program use NMFPolicy. - const mat w2 = outputModel->template CFPtr()->Decomposition().W(); - const mat h2 = outputModel->template CFPtr()->Decomposition().H(); + CFType& cf2 = + dynamic_cast&>(*(outputModel->CF())).CF(); + const mat w2 = cf2.Decomposition().W(); + const mat h2 = cf2.Decomposition().H(); // The resulting matrices should be different. REQUIRE((arma::norm(w1 - w2) > 1e-5 || arma::norm(h1 - h2) > 1e-5)); From 3ffbfcb4d5b8d0cd4f2e09a100c9d445af246240 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 10:55:47 -0500 Subject: [PATCH 449/550] Fix warning. --- src/mlpack/methods/cf/cf_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/cf/cf_main.cpp b/src/mlpack/methods/cf/cf_main.cpp index f4aa8e14b7..ce083c8c4a 100644 --- a/src/mlpack/methods/cf/cf_main.cpp +++ b/src/mlpack/methods/cf/cf_main.cpp @@ -343,7 +343,7 @@ static void mlpackMain() nsType = COSINE_SEARCH; else if (IO::GetParam("neighbor_search") == "euclidean") nsType = EUCLIDEAN_SEARCH; - else if (IO::GetParam("neighbor_search") == "pearson") + else // if (IO::GetParam("neighbor_search") == "pearson") nsType = PEARSON_SEARCH; InterpolationTypes interpolationType; @@ -353,7 +353,7 @@ static void mlpackMain() interpolationType = AVERAGE_INTERPOLATION; else if (IO::GetParam("interpolation") == "regression") interpolationType = REGRESSION_INTERPOLATION; - else if (IO::GetParam("interpolation") == "similarity") + else // if (IO::GetParam("interpolation") == "similarity") interpolationType = SIMILARITY_INTERPOLATION; if (IO::HasParam("query") || IO::HasParam("all_user_recommendations")) From 38d000059afb3e9a3d13e23b3d67b0acd3dfda6e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 11:08:24 -0500 Subject: [PATCH 450/550] Update history. --- HISTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 7529a3ee86..a5e2fd7732 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,9 @@ * Add finalizers to Julia binding model types to fix memory handling (#2756). + * Removed `boost::visitor` from model classes for `knn`, `kfn`, `cf`, + `range_search`, `krann`, and `kde` bindings (#2803). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. From e2a0ac48fae1a1c63b2f4662d64dabcac664aa24 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 11:08:38 -0500 Subject: [PATCH 451/550] Oh, also, it's a new year. --- COPYRIGHT.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index a3581e1d03..d2d177da71 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -7,7 +7,7 @@ Source: Files: * Copyright: - Copyright 2008-2020, Ryan Curtin + Copyright 2008-2021, Ryan Curtin Copyright 2008-2013, Bill March Copyright 2008-2012, Dongryeol Lee Copyright 2008-2013, Nishant Mehta From 0308fe001dd7142d3b87cabd204e6160541a8720 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 17:19:18 -0500 Subject: [PATCH 452/550] Apply suggestions from code review --- src/mlpack/methods/hmm/hmm.hpp | 5 ++++- src/mlpack/methods/hmm/hmm_impl.hpp | 34 ++++++++++++++--------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/mlpack/methods/hmm/hmm.hpp b/src/mlpack/methods/hmm/hmm.hpp index 3977c823eb..1821083a0e 100644 --- a/src/mlpack/methods/hmm/hmm.hpp +++ b/src/mlpack/methods/hmm/hmm.hpp @@ -305,7 +305,8 @@ class HMM * @return Log scale factor of the given sequence of emission at time t. */ double EmissionLogScaleFactor(const arma::vec& emissionLogProb, - arma::vec& forwardLogProb) const; + arma::vec& forwardLogProb) const; + /** * Compute the log-likelihood of the given emission probability up to time t, * storing the result in logLikelihood. @@ -325,6 +326,7 @@ class HMM double EmissionLogLikelihood(const arma::vec& emissionLogProb, double &logLikelihood, arma::vec& forwardLogProb) const; + /** * Compute the log of the scaling factor of the given data at time t. * To calculate the log-likelihood for the whole sequence, accumulate the @@ -342,6 +344,7 @@ class HMM */ double LogScaleFactor(const arma::vec &data, arma::vec& forwardLogProb) const; + /** * Compute the log-likelihood of the given data up to time t, storing the * result in logLikelihood. diff --git a/src/mlpack/methods/hmm/hmm_impl.hpp b/src/mlpack/methods/hmm/hmm_impl.hpp index 4ddee9895e..d3d1d72e61 100644 --- a/src/mlpack/methods/hmm/hmm_impl.hpp +++ b/src/mlpack/methods/hmm/hmm_impl.hpp @@ -532,19 +532,19 @@ double HMM::EmissionLogScaleFactor( const arma::vec& emissionLogProb, arma::vec& forwardLogProb) const { - double curLogScale; - if (forwardLogProb.empty()) - { - // We are at the start of the sequence (i.e. time t=0). - forwardLogProb = ForwardAtT0(emissionLogProb, curLogScale); - } - else - { - forwardLogProb = ForwardAtTn(emissionLogProb, curLogScale, - forwardLogProb); - } + double curLogScale; + if (forwardLogProb.empty()) + { + // We are at the start of the sequence (i.e. time t=0). + forwardLogProb = ForwardAtT0(emissionLogProb, curLogScale); + } + else + { + forwardLogProb = ForwardAtTn(emissionLogProb, curLogScale, + forwardLogProb); + } - return curLogScale; + return curLogScale; } /** @@ -556,11 +556,11 @@ double HMM::EmissionLogLikelihood( double& logLikelihood, arma::vec& forwardLogProb) const { - bool isStartOfSeq = forwardLogProb.empty(); - double curLogScale = EmissionLogScaleFactor(emissionLogProb, - forwardLogProb); - logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; - return logLikelihood; + bool isStartOfSeq = forwardLogProb.empty(); + double curLogScale = EmissionLogScaleFactor(emissionLogProb, + forwardLogProb); + logLikelihood = isStartOfSeq ? curLogScale : curLogScale + logLikelihood; + return logLikelihood; } /** From cd48b339d31a5451e7a77669e0523a44c1b26368 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 11 Jan 2021 17:43:20 -0500 Subject: [PATCH 453/550] Use CMake to automatically configure LICENSE file. --- src/mlpack/bindings/R/CMakeLists.txt | 36 +++++++++---------- .../bindings/R/mlpack/{LICENSE => LICENSE.in} | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) rename src/mlpack/bindings/R/mlpack/{LICENSE => LICENSE.in} (69%) diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index 830833b614..7352b92918 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -223,9 +223,11 @@ if (BUILD_R_BINDINGS) "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/tests/testthat.R" ) - set(LICENSE_SOURCES - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/LICENSE" - ) + # Configure the license file. + string(TIMESTAMP LICENSE_YEAR "%Y") + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/mlpack/LICENSE.in" + "${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE") + add_custom_target(r_copy ALL) # First we have to create all the required directories for copy. @@ -247,22 +249,22 @@ if (BUILD_R_BINDINGS) # Copy all necessary files for building package. foreach(cpp_file ${CPP_SOURCES}) - add_custom_command(TARGET r_copy PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different - ${cpp_file} - ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/) + add_custom_command(TARGET r_copy PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different + ${cpp_file} + ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/) endforeach() foreach(r_file ${R_SOURCES}) - add_custom_command(TARGET r_copy PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different - ${r_file} - ${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/) + add_custom_command(TARGET r_copy PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different + ${r_file} + ${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/) endforeach() foreach(bindings_file ${BINDINGS_SOURCES}) - add_custom_command(TARGET r_copy PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different - ${bindings_file} - ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R) + add_custom_command(TARGET r_copy PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different + ${bindings_file} + ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R) endforeach() add_custom_command(TARGET r_copy PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different @@ -272,10 +274,6 @@ if (BUILD_R_BINDINGS) COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${R_TESTS_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/mlpack/tests) - add_custom_command(TARGET r_copy PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different - ${LICENSE_SOURCES} - ${CMAKE_CURRENT_BINARY_DIR}/mlpack) # This file will take care of multiple definition of functions in .cpp files. add_custom_command(TARGET r_copy PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E touch diff --git a/src/mlpack/bindings/R/mlpack/LICENSE b/src/mlpack/bindings/R/mlpack/LICENSE.in similarity index 69% rename from src/mlpack/bindings/R/mlpack/LICENSE rename to src/mlpack/bindings/R/mlpack/LICENSE.in index 774e59e170..188ac6207d 100644 --- a/src/mlpack/bindings/R/mlpack/LICENSE +++ b/src/mlpack/bindings/R/mlpack/LICENSE.in @@ -1,3 +1,3 @@ -YEAR: 2020 +YEAR: ${LICENSE_YEAR} COPYRIGHT HOLDER: mlpack Team ORGANIZATION: mlpack From 33fb5d255fd400f1b1b181afdbc30e83df7e2f39 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 12 Jan 2021 08:59:28 -0500 Subject: [PATCH 454/550] Try to work around static code analysis issues. --- src/mlpack/methods/rann/ra_model_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/rann/ra_model_impl.hpp b/src/mlpack/methods/rann/ra_model_impl.hpp index e66b3b268a..443964b91a 100644 --- a/src/mlpack/methods/rann/ra_model_impl.hpp +++ b/src/mlpack/methods/rann/ra_model_impl.hpp @@ -83,8 +83,8 @@ void RABiSearchVisitor::SearchLeaf(RAType* ra) const Timer::Start("tree_building"); Log::Info << "Building query tree...."<< std::endl; std::vector oldFromNewQueries; - typename RAType::Tree queryTree(std::move(querySet), oldFromNewQueries, - leafSize); + typedef typename RAType::Tree TreeType + TreeType queryTree(std::move(querySet), oldFromNewQueries, leafSize); Log::Info << "Tree Built." << std::endl; Timer::Stop("tree_building"); From aeb0f49e9f66282065c6c2b1a2b4e91b16419e6a Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Tue, 12 Jan 2021 20:10:18 +0530 Subject: [PATCH 455/550] added inf functionality and tests --- .../python/tests/test_python_binding.py | 32 +++++++++++++++ src/mlpack/core/util/io.cpp | 39 +++++++++++++++---- src/mlpack/core/util/io.hpp | 2 +- src/mlpack/core/util/mlpack_main.hpp | 2 +- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/mlpack/bindings/python/tests/test_python_binding.py b/src/mlpack/bindings/python/tests/test_python_binding.py index 4d8206b16c..82ddf3dc88 100644 --- a/src/mlpack/bindings/python/tests/test_python_binding.py +++ b/src/mlpack/bindings/python/tests/test_python_binding.py @@ -1336,5 +1336,37 @@ class TestPythonBinding(unittest.TestCase): self.assertEqual(output2['model_bw_out'], 20.0) self.assertEqual(output3['model_bw_out'], 20.0) + def testCheckInputMatricesNaN(self): + """ + Checks that an exception is thrown if the input matrix contains + NaN values. + """ + x = np.random.rand(100, 5) + x[0][0] = np.nan + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + matrix_in=x, + check_input_matrices=True)) + + def testCheckInputMatricesInf(self): + """ + Checks that an exception is thrown if the input matrix contains + inf values. + """ + x = np.random.rand(100, 5) + x[0][0] = np.inf + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + matrix_in=x, + check_input_matrices=True)) + if __name__ == '__main__': unittest.main() diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 4e1771e705..25d800a89d 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -277,41 +277,64 @@ void IO::CheckInputMatrices() { std::string paramName = itr->first; std::string paramType = itr->second.cppType; - std::string errMsg = "The input " + paramName + " has NaN values."; + std::string errMsg1 = "The input " + paramName + " has NaN values."; + std::string errMsg2 = "The input " + paramName + " has inf values."; + if (paramType == "arma::mat") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::Mat") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::colvec") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::Col") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::rowvec") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::Row") { if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "std::tuple") { if (std::get<1>(IO::GetParam(paramName)).has_nan()) - Log::Fatal << errMsg << std::endl; + Log::Fatal << errMsg1 << std::endl; + + if (std::get<1>(IO::GetParam(paramName)).has_inf()) + Log::Fatal << errMsg2 << std::endl; } } } diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index d4f5cc7a17..a435fc0121 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -286,7 +286,7 @@ class IO static void ClearSettings(); /** - * Checks all input matrices for NaN values, if found throws an exception. + * Checks all input matrices for NaN and inf values, if found throws an exception. */ static void CheckInputMatrices(); diff --git a/src/mlpack/core/util/mlpack_main.hpp b/src/mlpack/core/util/mlpack_main.hpp index 0d65513225..34f8689e1a 100644 --- a/src/mlpack/core/util/mlpack_main.hpp +++ b/src/mlpack/core/util/mlpack_main.hpp @@ -231,7 +231,7 @@ PARAM_FLAG("copy_all_inputs", "If specified, all input parameters will be deep" "where the input parameters are being modified by the algorithm, but can " "slow down the code.", ""); PARAM_FLAG("check_input_matrices", "If specified, the input matrix is checked for" - " NaN values; an exception is thrown if any are found.", ""); + " NaN and inf values; an exception is thrown if any are found.", ""); // Nothing else needs to be defined---the binding will use mlpackMain() as-is. From bfff19e88dea9eb903b4b5508b8d8b00f96782a4 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 13 Jan 2021 00:34:48 +0530 Subject: [PATCH 456/550] fixed indentations, random indices in tests, changed comments --- src/mlpack/bindings/python/py_option.hpp | 2 +- .../python/tests/test_python_binding.py | 8 +++++-- src/mlpack/core/util/io.cpp | 24 +++++++++---------- src/mlpack/core/util/io.hpp | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/mlpack/bindings/python/py_option.hpp b/src/mlpack/bindings/python/py_option.hpp index 0a62afc709..b3d8519f84 100644 --- a/src/mlpack/bindings/python/py_option.hpp +++ b/src/mlpack/bindings/python/py_option.hpp @@ -65,7 +65,7 @@ class PyOption data.input = input; data.loaded = false; // Only "verbose", "copy_all_inputs" and "check_input_matrices" - // will be persistent. + // will be persistent. if (identifier == "verbose" || identifier == "copy_all_inputs" || identifier == "check_input_matrices") data.persistent = true; diff --git a/src/mlpack/bindings/python/tests/test_python_binding.py b/src/mlpack/bindings/python/tests/test_python_binding.py index 82ddf3dc88..f6beffa483 100644 --- a/src/mlpack/bindings/python/tests/test_python_binding.py +++ b/src/mlpack/bindings/python/tests/test_python_binding.py @@ -1342,7 +1342,9 @@ class TestPythonBinding(unittest.TestCase): NaN values. """ x = np.random.rand(100, 5) - x[0][0] = np.nan + a = np.random.randint(low=0, high=100) + b = np.random.randint(low=0, high=5) + x[a][b] = np.nan self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, @@ -1358,7 +1360,9 @@ class TestPythonBinding(unittest.TestCase): inf values. """ x = np.random.rand(100, 5) - x[0][0] = np.inf + a = np.random.randint(low=0, high=100) + b = np.random.randint(low=0, high=5) + x[a][b] = np.inf self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 25d800a89d..9de3825595 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -293,48 +293,48 @@ void IO::CheckInputMatrices() if (IO::GetParam>(paramName).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::colvec") { if (IO::GetParam>(paramName).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::Col") { if (IO::GetParam>(paramName).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::rowvec") { if (IO::GetParam>(paramName).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::Row") { if (IO::GetParam>(paramName).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; + if (IO::GetParam>(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "std::tuple") { if (std::get<1>(IO::GetParam(paramName)).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (std::get<1>(IO::GetParam(paramName)).has_inf()) - Log::Fatal << errMsg2 << std::endl; + if (std::get<1>(IO::GetParam(paramName)).has_inf()) + Log::Fatal << errMsg2 << std::endl; } } } diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index a435fc0121..dbe75da481 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -286,7 +286,7 @@ class IO static void ClearSettings(); /** - * Checks all input matrices for NaN and inf values, if found throws an exception. + * Checks all input matrices for NaN and inf values, exits if found any. */ static void CheckInputMatrices(); From 7056aebcdf8dac50aeba1004154761190d7640df Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 13 Jan 2021 00:38:25 +0530 Subject: [PATCH 457/550] fixed indent --- src/mlpack/core/util/io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 9de3825595..fcd6a002e2 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -286,7 +286,7 @@ void IO::CheckInputMatrices() Log::Fatal << errMsg1 << std::endl; if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; + Log::Fatal << errMsg2 << std::endl; } else if (paramType == "arma::Mat") { From 4de66bbf0ad0cdb4a7a82ad7e7e6f8eef728d7e6 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 12 Jan 2021 20:22:00 -0500 Subject: [PATCH 458/550] Um, right, C++ needs semicolons... --- src/mlpack/methods/rann/ra_model_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/rann/ra_model_impl.hpp b/src/mlpack/methods/rann/ra_model_impl.hpp index 443964b91a..30bed21c01 100644 --- a/src/mlpack/methods/rann/ra_model_impl.hpp +++ b/src/mlpack/methods/rann/ra_model_impl.hpp @@ -83,7 +83,7 @@ void RABiSearchVisitor::SearchLeaf(RAType* ra) const Timer::Start("tree_building"); Log::Info << "Building query tree...."<< std::endl; std::vector oldFromNewQueries; - typedef typename RAType::Tree TreeType + typedef typename RAType::Tree TreeType; TreeType queryTree(std::move(querySet), oldFromNewQueries, leafSize); Log::Info << "Tree Built." << std::endl; Timer::Stop("tree_building"); From f385522a5218fb644fced6ca164e137b098ab77e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Tue, 12 Jan 2021 20:25:42 -0500 Subject: [PATCH 459/550] Update src/mlpack/bindings/R/CMakeLists.txt Co-authored-by: Yashwant Singh Parihar --- src/mlpack/bindings/R/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index 13f171140d..f5f6907159 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -229,7 +229,7 @@ if (BUILD_R_BINDINGS) # Installation script for the packagae. install(CODE "execute_process( - COMMAND R CMD INSTALL mlpack_${PACKAGE_VERSION}.tar.gz + COMMAND ${R_EXECUTABLE} CMD INSTALL mlpack_${PACKAGE_VERSION}.tar.gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})" ) From 5e0a3472cd4e9ae012026a37f31caa50d02e1f93 Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Wed, 13 Jan 2021 12:05:12 +0530 Subject: [PATCH 460/550] added templated utility function --- src/mlpack/core/util/io.cpp | 58 ++++---------------------------- src/mlpack/core/util/io.hpp | 8 +++++ src/mlpack/core/util/io_impl.hpp | 13 +++++++ 3 files changed, 28 insertions(+), 51 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index fcd6a002e2..2f1b4792ad 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -277,65 +277,21 @@ void IO::CheckInputMatrices() { std::string paramName = itr->first; std::string paramType = itr->second.cppType; - std::string errMsg1 = "The input " + paramName + " has NaN values."; - std::string errMsg2 = "The input " + paramName + " has inf values."; if (paramType == "arma::mat") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>(paramName); else if (paramType == "arma::Mat") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>(paramName); else if (paramType == "arma::colvec") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>(paramName); else if (paramType == "arma::Col") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>(paramName); else if (paramType == "arma::rowvec") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>(paramName); else if (paramType == "arma::Row") - { - if (IO::GetParam>(paramName).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam>(paramName).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>(paramName); else if (paramType == "std::tuple") - { - if (std::get<1>(IO::GetParam(paramName)).has_nan()) - Log::Fatal << errMsg1 << std::endl; - - if (std::get<1>(IO::GetParam(paramName)).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix(paramName); } } diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index dbe75da481..0633fd8c5d 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -285,6 +285,14 @@ class IO */ static void ClearSettings(); + /** + * Utility function for CheckInputMatrices(). + * + * @param matrix Matrix to check for NaN or Inf values. + */ + template + static void CheckInputMatrix(T& matrix); + /** * Checks all input matrices for NaN and inf values, exits if found any. */ diff --git a/src/mlpack/core/util/io_impl.hpp b/src/mlpack/core/util/io_impl.hpp index feb892325c..e40d5824dc 100644 --- a/src/mlpack/core/util/io_impl.hpp +++ b/src/mlpack/core/util/io_impl.hpp @@ -145,6 +145,19 @@ T& IO::GetRawParam(const std::string& identifier) } } +template +void CheckInputMatrix(const std::string paramName) +{ + std::string errMsg1 = "The input " + paramName + " has NaN values."; + std::string errMsg2 = "The input " + paramName + " has inf values."; + + if (IO::GetParam(paramName).has_nan()) + Log::Fatal << errMsg1 << std::endl; + + if (IO::GetParam(paramName).has_inf()) + Log::Fatal << errMsg2 << std::endl; +} + } // namespace mlpack #endif From dc398bfb6418e045bfa84040c812b57a881e6712 Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Wed, 13 Jan 2021 12:11:51 +0530 Subject: [PATCH 461/550] fixing errors --- src/mlpack/core/util/io.hpp | 4 ++-- src/mlpack/core/util/io_impl.hpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index 0633fd8c5d..26571659d4 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -288,10 +288,10 @@ class IO /** * Utility function for CheckInputMatrices(). * - * @param matrix Matrix to check for NaN or Inf values. + * @param identifier Name of the parameter in question. */ template - static void CheckInputMatrix(T& matrix); + static void CheckInputMatrix(const std::string& identifier); /** * Checks all input matrices for NaN and inf values, exits if found any. diff --git a/src/mlpack/core/util/io_impl.hpp b/src/mlpack/core/util/io_impl.hpp index e40d5824dc..59a68418c3 100644 --- a/src/mlpack/core/util/io_impl.hpp +++ b/src/mlpack/core/util/io_impl.hpp @@ -146,15 +146,15 @@ T& IO::GetRawParam(const std::string& identifier) } template -void CheckInputMatrix(const std::string paramName) +void CheckInputMatrix(const std::string& identifier) { - std::string errMsg1 = "The input " + paramName + " has NaN values."; - std::string errMsg2 = "The input " + paramName + " has inf values."; + std::string errMsg1 = "The input " + identifier + " has NaN values."; + std::string errMsg2 = "The input " + identifier + " has inf values."; - if (IO::GetParam(paramName).has_nan()) + if (IO::GetParam(identifier).has_nan()) Log::Fatal << errMsg1 << std::endl; - if (IO::GetParam(paramName).has_inf()) + if (IO::GetParam(identifier).has_inf()) Log::Fatal << errMsg2 << std::endl; } From 6ad120aa6e04cad6fc0cbf958042e998dbcb307e Mon Sep 17 00:00:00 2001 From: Nippun Sharma Date: Wed, 13 Jan 2021 17:38:39 +0530 Subject: [PATCH 462/550] added CheckInputMatrix() to reduce code block in CheckInputMatrices() --- src/mlpack/core/util/io.cpp | 17 +++++++++++++++++ src/mlpack/core/util/io.hpp | 16 ++++++++-------- src/mlpack/core/util/io_impl.hpp | 7 +++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 2f1b4792ad..8998f331bb 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -268,6 +268,23 @@ void IO::ClearSettings() GetSingleton().functionMap = persistentFunctions; } +// For handling std::tuple +// seperately. +template<> +void IO::CheckInputMatrix>( + const std::string& identifier) +{ + typedef typename std::tuple TupleType; + + std::string errMsg1 = "The input " + identifier + " has NaN values."; + std::string errMsg2 = "The input " + identifier + " has inf values."; + + if (std::get<1>(IO::GetParam(identifier)).has_nan()) + Log::Fatal << errMsg1 << std::endl; + if (std::get<1>(IO::GetParam(identifier)).has_inf()) + Log::Fatal << errMsg2 << std::endl; +} + void IO::CheckInputMatrices() { typedef typename std::tuple TupleType; diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index 26571659d4..5189695abe 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -219,6 +219,14 @@ class IO template static T& GetRawParam(const std::string& identifier); + /** + * Utility function for CheckInputMatrices(). + * + * @param identifier Name of the parameter in question. + */ + template + static void CheckInputMatrix(const std::string& identifier); + /** * Given two (matrix) parameters, ensure that the first is an in-place copy of * the second. This will generally do nothing (as the bindings already do @@ -285,14 +293,6 @@ class IO */ static void ClearSettings(); - /** - * Utility function for CheckInputMatrices(). - * - * @param identifier Name of the parameter in question. - */ - template - static void CheckInputMatrix(const std::string& identifier); - /** * Checks all input matrices for NaN and inf values, exits if found any. */ diff --git a/src/mlpack/core/util/io_impl.hpp b/src/mlpack/core/util/io_impl.hpp index 59a68418c3..f54aaa4eab 100644 --- a/src/mlpack/core/util/io_impl.hpp +++ b/src/mlpack/core/util/io_impl.hpp @@ -146,15 +146,14 @@ T& IO::GetRawParam(const std::string& identifier) } template -void CheckInputMatrix(const std::string& identifier) +void IO::CheckInputMatrix(const std::string& identifier) { std::string errMsg1 = "The input " + identifier + " has NaN values."; std::string errMsg2 = "The input " + identifier + " has inf values."; - if (IO::GetParam(identifier).has_nan()) + if (GetParam(identifier).has_nan()) Log::Fatal << errMsg1 << std::endl; - - if (IO::GetParam(identifier).has_inf()) + if (GetParam(identifier).has_inf()) Log::Fatal << errMsg2 << std::endl; } From 04dee7ee870c3cae86fe4baa0ac058de736e75b3 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 13 Jan 2021 18:23:07 +0530 Subject: [PATCH 463/550] fix errors --- src/mlpack/core/util/io.cpp | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 8998f331bb..d36b287a4e 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -268,23 +268,6 @@ void IO::ClearSettings() GetSingleton().functionMap = persistentFunctions; } -// For handling std::tuple -// seperately. -template<> -void IO::CheckInputMatrix>( - const std::string& identifier) -{ - typedef typename std::tuple TupleType; - - std::string errMsg1 = "The input " + identifier + " has NaN values."; - std::string errMsg2 = "The input " + identifier + " has inf values."; - - if (std::get<1>(IO::GetParam(identifier)).has_nan()) - Log::Fatal << errMsg1 << std::endl; - if (std::get<1>(IO::GetParam(identifier)).has_inf()) - Log::Fatal << errMsg2 << std::endl; -} - void IO::CheckInputMatrices() { typedef typename std::tuple TupleType; @@ -308,7 +291,15 @@ void IO::CheckInputMatrices() else if (paramType == "arma::Row") IO::CheckInputMatrix>(paramName); else if (paramType == "std::tuple") - IO::CheckInputMatrix(paramName); + { + std::string errMsg1 = "The input " + paramName + " has NaN values."; + std::string errMsg2 = "The input " + paramName + " has inf values."; + + if (std::get<1>(GetParam(paramName)).has_nan()) + Log::Fatal << errMsg1 << std::endl; + if (std::get<1>(GetParam(paramName)).has_inf()) + Log::Fatal << errMsg2 << std::endl; + } } } From 448b1010dae820e1602f0125c5e8cf1ab33bfbea Mon Sep 17 00:00:00 2001 From: Marcus Edel Date: Wed, 13 Jan 2021 21:58:34 +0100 Subject: [PATCH 464/550] Minor style improvement. --- src/mlpack/methods/pca/pca_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/pca/pca_impl.hpp b/src/mlpack/methods/pca/pca_impl.hpp index a122cd7159..f469933c14 100644 --- a/src/mlpack/methods/pca/pca_impl.hpp +++ b/src/mlpack/methods/pca/pca_impl.hpp @@ -78,8 +78,8 @@ void PCA::Apply(const arma::mat& data, /** * Apply Principal Component Analysis to the provided data set. * - * @param data - Data matrix - * @param transformedData - Data with PCA applied + * @param data - Data matrix. + * @param transformedData Data with PCA applied. */ template void PCA::Apply(const arma::mat& data, From c8227266bf5c0fc83e6098bee8e76874d0b282d5 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Thu, 14 Jan 2021 14:24:34 -0500 Subject: [PATCH 465/550] add move assignment operator --- .../methods/adaboost/adaboost_model.cpp | 39 ++++++++++++++----- .../methods/adaboost/adaboost_model.hpp | 3 ++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/mlpack/methods/adaboost/adaboost_model.cpp b/src/mlpack/methods/adaboost/adaboost_model.cpp index a48659b4bd..d71b857d74 100644 --- a/src/mlpack/methods/adaboost/adaboost_model.cpp +++ b/src/mlpack/methods/adaboost/adaboost_model.cpp @@ -72,19 +72,40 @@ AdaBoostModel::AdaBoostModel(AdaBoostModel&& other) : //! Copy assignment operator. AdaBoostModel& AdaBoostModel::operator=(const AdaBoostModel& other) { - mappings = other.mappings; - weakLearnerType = other.weakLearnerType; + if (this != &other) + { + mappings = other.mappings; + weakLearnerType = other.weakLearnerType; - delete dsBoost; - dsBoost = (other.dsBoost == NULL) ? NULL : - new AdaBoost(*other.dsBoost); + delete dsBoost; + dsBoost = (other.dsBoost == NULL) ? NULL : + new AdaBoost(*other.dsBoost); - delete pBoost; - pBoost = (other.pBoost == NULL) ? NULL : - new AdaBoost>(*other.pBoost); + delete pBoost; + pBoost = (other.pBoost == NULL) ? NULL : + new AdaBoost>(*other.pBoost); - dimensionality = other.dimensionality; + dimensionality = other.dimensionality; + } + return *this; +} +//! Move assignment operator. +AdaBoostModel& AdaBoostModel::operator=(AdaBoostModel&& other) +{ + if (this != &other) + { + mappings = std::move(other.mappings); + weakLearnerType = other.weakLearnerType; + + dsBoost = other.dsBoost; + other.dsBoost = nullptr; + + pBoost = other.pBoost; + other.pBoost = nullptr; + + dimensionality = other.dimensionality; + } return *this; } diff --git a/src/mlpack/methods/adaboost/adaboost_model.hpp b/src/mlpack/methods/adaboost/adaboost_model.hpp index e8dcac3a82..36743c4e18 100644 --- a/src/mlpack/methods/adaboost/adaboost_model.hpp +++ b/src/mlpack/methods/adaboost/adaboost_model.hpp @@ -61,6 +61,9 @@ class AdaBoostModel //! Copy assignment operator. AdaBoostModel& operator=(const AdaBoostModel& other); + //! Move assignment operator. + AdaBoostModel& operator=(AdaBoostModel&& other); + //! Clean up memory. ~AdaBoostModel(); From b442b8c33c3794c0840ab9a810ef16d63c1893fb Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 15 Jan 2021 00:17:30 -0500 Subject: [PATCH 466/550] add move assignment for hrectbound --- src/mlpack/core/tree/hrectbound.hpp | 4 +++ src/mlpack/core/tree/hrectbound_impl.hpp | 31 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/mlpack/core/tree/hrectbound.hpp b/src/mlpack/core/tree/hrectbound.hpp index 1d15fe6582..31186f621d 100644 --- a/src/mlpack/core/tree/hrectbound.hpp +++ b/src/mlpack/core/tree/hrectbound.hpp @@ -73,12 +73,16 @@ class HRectBound //! Copy constructor; necessary to prevent memory leaks. HRectBound(const HRectBound& other); + //! Same as copy constructor; necessary to prevent memory leaks. HRectBound& operator=(const HRectBound& other); //! Move constructor: take possession of another bound's information. HRectBound(HRectBound&& other); + //! Move assignment operator + HRectBound& operator=(HRectBound&& other); + //! Destructor: clean up memory. ~HRectBound(); diff --git a/src/mlpack/core/tree/hrectbound_impl.hpp b/src/mlpack/core/tree/hrectbound_impl.hpp index 2b73eb020a..26132e50a5 100644 --- a/src/mlpack/core/tree/hrectbound_impl.hpp +++ b/src/mlpack/core/tree/hrectbound_impl.hpp @@ -103,6 +103,37 @@ inline HRectBound::HRectBound( other.minWidth = 0.0; } +/** + * Move assignment operator + */ +template +inline HRectBound< + MetricType, + ElemType>& HRectBound::operator=(HRectBound&& other) +{ + if (this != &other) + { + if (dim != other.Dim()) + { + // Reallocation is necessary. + if (bounds) + delete[] bounds; + + dim = other.Dim(); + bounds = new math::RangeType[dim]; + } + + // Now move each of the bound values. + // cannot move the bound pointer because there are no accessor method to the bound pointer + for (size_t i = 0; i < dim; ++i) + bounds[i] = std::move(other[i]); + + minWidth = std::move(other.MinWidth()); + } + return *this; +} + /** * Destructor: clean up memory. */ From 8eab8c47df197d9e02c17f60ec4626651c8db72f Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 15 Jan 2021 00:22:27 -0500 Subject: [PATCH 467/550] fix hrectbound move assignment --- src/mlpack/core/tree/hrectbound_impl.hpp | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/mlpack/core/tree/hrectbound_impl.hpp b/src/mlpack/core/tree/hrectbound_impl.hpp index 26132e50a5..45d4b81a76 100644 --- a/src/mlpack/core/tree/hrectbound_impl.hpp +++ b/src/mlpack/core/tree/hrectbound_impl.hpp @@ -114,22 +114,12 @@ inline HRectBound< { if (this != &other) { - if (dim != other.Dim()) - { - // Reallocation is necessary. - if (bounds) - delete[] bounds; - - dim = other.Dim(); - bounds = new math::RangeType[dim]; - } - - // Now move each of the bound values. - // cannot move the bound pointer because there are no accessor method to the bound pointer - for (size_t i = 0; i < dim; ++i) - bounds[i] = std::move(other[i]); - - minWidth = std::move(other.MinWidth()); + bounds = other.bounds; + minWidth = other.minWidth; + dim = other.dim; + other.dim = 0; + other.bounds = nullptr; + other.minWidth = 0.0; } return *this; } From 30e98ec05a814ecc2bc1c7d26759f880b41693d1 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 15 Jan 2021 00:27:02 -0500 Subject: [PATCH 468/550] ball bound move assignment operator --- src/mlpack/core/tree/ballbound.hpp | 3 +++ src/mlpack/core/tree/ballbound_impl.hpp | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/mlpack/core/tree/ballbound.hpp b/src/mlpack/core/tree/ballbound.hpp index 0d6633f7ca..e1a8674f03 100644 --- a/src/mlpack/core/tree/ballbound.hpp +++ b/src/mlpack/core/tree/ballbound.hpp @@ -81,6 +81,9 @@ class BallBound //! Move constructor: take possession of another bound. BallBound(BallBound&& other); + //! Move assignment operator. + BallBound& operator=(BallBound&& other); + //! Destructor to release allocated memory. ~BallBound(); diff --git a/src/mlpack/core/tree/ballbound_impl.hpp b/src/mlpack/core/tree/ballbound_impl.hpp index 59ef8bffc3..d1e5af2c06 100644 --- a/src/mlpack/core/tree/ballbound_impl.hpp +++ b/src/mlpack/core/tree/ballbound_impl.hpp @@ -92,6 +92,22 @@ BallBound::BallBound(BallBound&& other) : other.ownsMetric = false; } +//! Move assignment operator. +template +BallBound& BallBound::operator=( + BallBound&& other) +{ + radius = other.radius, + center = std::move(other.center), + metric = other.metric, + ownsMetric = other.ownsMetric + + other.radius = 0.0; + other.center = VecType(); + other.metric = nullptr; + other.ownsMetric = false; +} + //! Destructor to release allocated memory. template BallBound::~BallBound() From 4abbb39aec00dd178b1119e9cc84c9702f7192bb Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 15 Jan 2021 00:31:14 -0500 Subject: [PATCH 469/550] add move assignment operator and fix static code check --- src/mlpack/core/tree/hollow_ball_bound.hpp | 3 ++ .../core/tree/hollow_ball_bound_impl.hpp | 41 +++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/mlpack/core/tree/hollow_ball_bound.hpp b/src/mlpack/core/tree/hollow_ball_bound.hpp index d8b65dcf87..d699eab693 100644 --- a/src/mlpack/core/tree/hollow_ball_bound.hpp +++ b/src/mlpack/core/tree/hollow_ball_bound.hpp @@ -86,6 +86,9 @@ class HollowBallBound //! Move constructor: take possession of another bound. HollowBallBound(HollowBallBound&& other); + //! Move assignment operator. + HollowBallBound& operator=(HollowBallBound&& other); + //! Destructor to release allocated memory. ~HollowBallBound(); diff --git a/src/mlpack/core/tree/hollow_ball_bound_impl.hpp b/src/mlpack/core/tree/hollow_ball_bound_impl.hpp index b8446ec350..8ccd06225c 100644 --- a/src/mlpack/core/tree/hollow_ball_bound_impl.hpp +++ b/src/mlpack/core/tree/hollow_ball_bound_impl.hpp @@ -80,15 +80,17 @@ template HollowBallBound& HollowBallBound:: operator=(const HollowBallBound& other) { - if (ownsMetric) - delete metric; - - radii = other.radii; - center = other.center; - hollowCenter = other.hollowCenter; - metric = other.metric; - ownsMetric = false; + if (this != &other) + { + if (ownsMetric) + delete metric; + radii = other.radii; + center = other.center; + hollowCenter = other.hollowCenter; + metric = other.metric; + ownsMetric = false; + } return *this; } @@ -111,6 +113,29 @@ HollowBallBound::HollowBallBound( other.ownsMetric = false; } +//! Move assignment operator. +template +HollowBallBound& HollowBallBound:: +operator=(HollowBallBound&& other) +{ + if (this != &other) + { + radii = other.radii; + center = std::move(other.center); + hollowCenter = std::move(other.hollowCenter); + metric = other.metric; + ownsMetric = other.ownsMetric; + + other.radii.Hi() = 0.0; + other.radii.Lo() = 0.0; + other.center = arma::Col(); + other.hollowCenter = arma::Col(); + other.metric = nullptr; + other.ownsMetric = false; + } + return *this; +} + //! Destructor to release allocated memory. template HollowBallBound::~HollowBallBound() From f02eb1464137f02733fc42bdd9d904e933c6d9f5 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 15 Jan 2021 08:58:19 -0500 Subject: [PATCH 470/550] fix error --- src/mlpack/core/tree/ballbound_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/core/tree/ballbound_impl.hpp b/src/mlpack/core/tree/ballbound_impl.hpp index d1e5af2c06..5722fb854a 100644 --- a/src/mlpack/core/tree/ballbound_impl.hpp +++ b/src/mlpack/core/tree/ballbound_impl.hpp @@ -97,10 +97,10 @@ template BallBound& BallBound::operator=( BallBound&& other) { - radius = other.radius, - center = std::move(other.center), - metric = other.metric, - ownsMetric = other.ownsMetric + radius = other.radius; + center = std::move(other.center); + metric = other.metric; + ownsMetric = other.ownsMetric; other.radius = 0.0; other.center = VecType(); From cd42db9f0aea1c2e9c33dbed4bcbc310fe6fdefd Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 15 Jan 2021 21:54:14 -0500 Subject: [PATCH 471/550] continue fixing static code check --- .../rectangle_tree/discrete_hilbert_value.hpp | 8 ++ .../discrete_hilbert_value_impl.hpp | 21 +++++ .../simple_residue_termination.hpp | 10 ++- .../svd_complete_incremental_learning.hpp | 4 +- .../svd_incomplete_incremental_learning.hpp | 2 +- src/mlpack/methods/fastmks/fastmks.hpp | 5 ++ src/mlpack/methods/fastmks/fastmks_impl.hpp | 29 ++++++ src/mlpack/methods/fastmks/fastmks_model.cpp | 90 ++++++++++++------- src/mlpack/methods/fastmks/fastmks_model.hpp | 3 + src/mlpack/methods/hmm/hmm_model.hpp | 14 +++ .../methods/range_search/range_search.hpp | 14 ++- .../range_search/range_search_impl.hpp | 77 ++++++++++++---- 12 files changed, 219 insertions(+), 58 deletions(-) diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp index 405188a4f6..32bb94ece9 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp @@ -182,6 +182,14 @@ class DiscreteHilbertValue */ DiscreteHilbertValue& operator=(const DiscreteHilbertValue& val); + /** + * Move the local Hilbert object. + * + * @param val The DiscreteHilbertValue object from which the dataset + * will be copied. + */ + DiscreteHilbertValue& operator=(DiscreteHilbertValue&& val); + /** * Nullify the localHilbertValues pointer in order to prevent an invalid free. */ diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp index c4baa38a90..48ad8557f7 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp @@ -450,6 +450,27 @@ operator=(const DiscreteHilbertValue& val) return *this; } +template +DiscreteHilbertValue& DiscreteHilbertValue:: +operator=(DiscreteHilbertValue&& other) +{ + if (this != &other) + { + localHilbertValues = other.localHilbertValues; + ownsLocalHilbertValues = other.ownsLocalHilbertValues; + numValues = other.numValues; + valueToInsert = other.valueToInsert; + ownsValueToInsert = other.ownsValueToInsert; + + other.localHilbertValues = nullptr; + other.ownsLocalHilbertValues = false; + other.numValues = 0; + other.valueToInsert = nullptr; + other.ownsValueToInsert = false; + } + return *this; +} + template void DiscreteHilbertValue::NullifyData() { diff --git a/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp b/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp index 970b24289f..81893f4fa3 100644 --- a/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp @@ -41,7 +41,15 @@ class SimpleResidueTermination */ SimpleResidueTermination(const double minResidue = 1e-5, const size_t maxIterations = 10000) - : minResidue(minResidue), maxIterations(maxIterations) { } + : minResidue(minResidue), + maxIterations(maxIterations), + residue(0.0), + iteration(0), + nm(0), + normOld(0) + { + // Nothing to do here. + } /** * Initializes the termination policy before stating the factorization. diff --git a/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp b/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp index 4ab1c0d610..37b7ab8c0a 100644 --- a/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp +++ b/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp @@ -56,7 +56,7 @@ class SVDCompleteIncrementalLearning SVDCompleteIncrementalLearning(double u = 0.0001, double kw = 0, double kh = 0) - : u(u), kw(kw), kh(kh) + : u(u), kw(kw), kh(kh), currentUserIndex(0), currentItemIndex(0) { // Nothing to do. } @@ -172,7 +172,7 @@ class SVDCompleteIncrementalLearning SVDCompleteIncrementalLearning(double u = 0.01, double kw = 0, double kh = 0) - : u(u), kw(kw), kh(kh), it(NULL) + : u(u), kw(kw), kh(kh), it(NULL), m(0), n(0), isStart(false) {} ~SVDCompleteIncrementalLearning() diff --git a/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp b/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp index 0082824129..9880ea2945 100644 --- a/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp +++ b/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp @@ -53,7 +53,7 @@ class SVDIncompleteIncrementalLearning SVDIncompleteIncrementalLearning(double u = 0.001, double kw = 0, double kh = 0) - : u(u), kw(kw), kh(kh) + : u(u), kw(kw), kh(kh), currentUserIndex(0) { // Nothing to do. } diff --git a/src/mlpack/methods/fastmks/fastmks.hpp b/src/mlpack/methods/fastmks/fastmks.hpp index 93d234d541..ea2057b0b9 100644 --- a/src/mlpack/methods/fastmks/fastmks.hpp +++ b/src/mlpack/methods/fastmks/fastmks.hpp @@ -163,6 +163,11 @@ class FastMKS */ FastMKS& operator=(const FastMKS& other); + /** + * Move assignment operator. + */ + FastMKS& operator=(FastMKS&& other); + //! Destructor for the FastMKS object. ~FastMKS(); diff --git a/src/mlpack/methods/fastmks/fastmks_impl.hpp b/src/mlpack/methods/fastmks/fastmks_impl.hpp index 660617fdb0..3b2d12eaae 100644 --- a/src/mlpack/methods/fastmks/fastmks_impl.hpp +++ b/src/mlpack/methods/fastmks/fastmks_impl.hpp @@ -250,6 +250,35 @@ FastMKS::operator=(const FastMKS& other) naive = other.naive; } +template class TreeType> +FastMKS& +FastMKS::operator=(FastMKS&& other) +{ + if (this != &other) + { + referenceSet = other.referenceSet; + referenceTree = other.referenceTree; + treeOwner = other.treeOwner; + setOwner = other.setOwner; + singleMode = other.singleMode; + naive = other.naive; + metric = std::move(other.metric); + + // Clear information from the other. + other.referenceSet = nullptr; + other.referenceTree = nullptr; + other.treeOwner = false; + other.setOwner = false; + other.singleMode = false; + other.naive = false; + } + return *this; +} + template(*other.linear); - if (other.polynomial) - polynomial = new FastMKS(*other.polynomial); - if (other.cosine) - cosine = new FastMKS(*other.cosine); - if (other.gaussian) - gaussian = new FastMKS(*other.gaussian); - if (other.epan) - epan = new FastMKS(*other.epan); - if (other.triangular) - triangular = new FastMKS(*other.triangular); - if (other.hyptan) - hyptan = new FastMKS(*other.hyptan); + kernelType = other.kernelType; + if (other.linear) + linear = new FastMKS(*other.linear); + if (other.polynomial) + polynomial = new FastMKS(*other.polynomial); + if (other.cosine) + cosine = new FastMKS(*other.cosine); + if (other.gaussian) + gaussian = new FastMKS(*other.gaussian); + if (other.epan) + epan = new FastMKS(*other.epan); + if (other.triangular) + triangular = new FastMKS(*other.triangular); + if (other.hyptan) + hyptan = new FastMKS(*other.hyptan); + } + return *this; +} +FastMKSModel& FastMKSModel::operator=(FastMKSModel&& other) +{ + if (this != &other) + { + kernelType = other.kernelType; + linear = other.linear; + polynomial = other.polynomial; + cosine = other.cosine; + gaussian = other.gaussian; + epan = other.epan; + triangular = other.triangular; + hyptan = other.hyptan; + + // Clear other object. + other.kernelType = KernelTypes::LINEAR_KERNEL; + other.linear = nullptr; + other.polynomial = nullptr; + other.cosine = nullptr; + other.gaussian = nullptr; + other.epan = nullptr; + other.triangular = nullptr; + other.hyptan = nullptr; + } return *this; } diff --git a/src/mlpack/methods/fastmks/fastmks_model.hpp b/src/mlpack/methods/fastmks/fastmks_model.hpp index e84eee0c28..0b7568c641 100644 --- a/src/mlpack/methods/fastmks/fastmks_model.hpp +++ b/src/mlpack/methods/fastmks/fastmks_model.hpp @@ -60,6 +60,9 @@ class FastMKSModel //! Copy assignment operator. FastMKSModel& operator=(const FastMKSModel& other); + //! Move assignment operator. + FastMKSModel& operator=(FastMKSModel&& other); + /** * Clean memory. */ diff --git a/src/mlpack/methods/hmm/hmm_model.hpp b/src/mlpack/methods/hmm/hmm_model.hpp index 41a7fd406b..0a2bce384b 100644 --- a/src/mlpack/methods/hmm/hmm_model.hpp +++ b/src/mlpack/methods/hmm/hmm_model.hpp @@ -129,6 +129,20 @@ class HMMModel return *this; } + //! Move assignment operator. + HMMModel& operator=(HMMModel&& other) + { + if (this != &other) + { + type = other.type; + discreteHMM = other.discreteHMM; + gaussianHMM = other.gaussianHMM; + gmmHMM = other.gmmHMM; + diagGMMHMM = other.diagGMMHMM; + } + return *this; + } + //! Clean memory. ~HMMModel() { diff --git a/src/mlpack/methods/range_search/range_search.hpp b/src/mlpack/methods/range_search/range_search.hpp index 06575005ac..98de888a69 100644 --- a/src/mlpack/methods/range_search/range_search.hpp +++ b/src/mlpack/methods/range_search/range_search.hpp @@ -122,12 +122,18 @@ class RangeSearch RangeSearch(RangeSearch&& other); /** - * Copy the given RangeSearch model. - * Use std::move to pass in the model if the old copy is no longer needed. - * + * Deep copy the given RangeSearch model. + * * @param other RangeSearch model to copy. */ - RangeSearch& operator=(RangeSearch other); + RangeSearch& operator=(const RangeSearch& other); + + /** + * Move the given RangeSearch model. + * + * @param other RangeSearch model to move. + */ + RangeSearch& operator=(RangeSearch&& other); /** * Destroy the RangeSearch object. If trees were created, they will be diff --git a/src/mlpack/methods/range_search/range_search_impl.hpp b/src/mlpack/methods/range_search/range_search_impl.hpp index 298aae995e..2652d47c89 100644 --- a/src/mlpack/methods/range_search/range_search_impl.hpp +++ b/src/mlpack/methods/range_search/range_search_impl.hpp @@ -169,25 +169,61 @@ template class TreeType> RangeSearch& -RangeSearch::operator=(RangeSearch other) +RangeSearch::operator=(const RangeSearch& other) { - // Clean memory first. - if (treeOwner) - delete referenceTree; - if (naive) - delete referenceSet; + if (this != &other) + { + oldFromNewReferences = other.oldFromNewReferences; + referenceTree = other.referenceTree ? new Tree(*other.referenceTree) : nullptr; + referenceSet = other.referenceTree ? &referenceTree->Dataset() : + new MatType(*other.referenceSet); + treeOwner = other.referenceTree; + naive = other.naive; + singleMode = other.singleMode; + metric = other.metric; + baseCases = other.baseCases; + scores = other.scores; + } + return *this; +} - // Move the other model. - oldFromNewReferences = std::move(other.oldFromNewReferences); - referenceTree = other.referenceTree; - referenceSet = other.referenceSet; - treeOwner = other.treeOwner; - naive = other.naive; - singleMode = other.singleMode; - metric = std::move(other.metric); - baseCases = other.baseCases; - scores = other.scores; +template class TreeType> +RangeSearch& +RangeSearch::operator=(RangeSearch&& other) +{ + if (this != &other) + { + // Clean memory first. + if (treeOwner) + delete referenceTree; + if (naive) + delete referenceSet; + // Move the other model. + oldFromNewReferences = std::move(other.oldFromNewReferences); + referenceTree = other.referenceTree; + referenceSet = other.referenceSet; + treeOwner = other.treeOwner; + naive = other.naive; + singleMode = other.singleMode; + metric = std::move(other.metric); + baseCases = other.baseCases; + scores = other.scores; + + // Clear other object. + other.referenceTree = nullptr; + other.referenceSet = nullptr; + other.treeOwner = false; + other.naive = false; + other.singleMode = false; + other.baseCases = 0; + other.scores = 0; + + } return *this; } @@ -254,12 +290,15 @@ void RangeSearch::Train( throw std::invalid_argument("cannot train on given reference tree when " "naive search (without trees) is desired"); + // Can only train when passed argument `referenceTree` is not nullptr if (treeOwner && referenceTree) + { delete this->referenceTree; - this->referenceTree = referenceTree; - this->referenceSet = &referenceTree->Dataset(); - treeOwner = false; + this->referenceTree = referenceTree; + this->referenceSet = &referenceTree->Dataset(); + treeOwner = false; + } } template Date: Sun, 17 Jan 2021 00:48:22 -0500 Subject: [PATCH 472/550] fix static code check 17/1 --- .../hoeffding_trees/hoeffding_tree.hpp | 21 ++++ .../hoeffding_trees/hoeffding_tree_impl.hpp | 111 ++++++++++++++++++ .../hoeffding_trees/hoeffding_tree_model.cpp | 78 ++++++------ src/mlpack/methods/kde/kde.hpp | 9 +- src/mlpack/methods/kde/kde_impl.hpp | 104 ++++++++++++---- 5 files changed, 264 insertions(+), 59 deletions(-) diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree.hpp index 488048f4e6..b58d97a423 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree.hpp @@ -155,6 +155,27 @@ class HoeffdingTree */ HoeffdingTree(const HoeffdingTree& other); + /** + * Move another tree. + * + * @param other Tree to move. + */ + HoeffdingTree(HoeffdingTree&& other); + + /** + * Copy assignment operator. + * + * @param other Tree to copy. + */ + HoeffdingTree& operator=(const HoeffdingTree& other); + + /** + * Move assignment operator. + * + * @param other Tree to move. + */ + HoeffdingTree& operator=(HoeffdingTree&& other); + /** * Clean up memory. */ diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp index e6172f8324..f7e8bdd830 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp @@ -224,6 +224,117 @@ HoeffdingTree:: } } +// Move constructor. +template class NumericSplitType, + template class CategoricalSplitType> +HoeffdingTree:: + HoeffdingTree(HoeffdingTree&& other) : + numericSplits(std::move(other.numericSplits)), + categoricalSplits(std::move(other.categoricalSplits)), + dimensionMappings(other.dimensionMappings), + ownsMappings(true), + numSamples(other.numSamples), + numClasses(other.numClasses), + maxSamples(other.maxSamples), + checkInterval(other.checkInterval), + minSamples(other.minSamples), + datasetInfo(other.datasetInfo), + ownsInfo(true), + successProbability(other.successProbability), + splitDimension(other.splitDimension), + majorityClass(other.majorityClass), + majorityProbability(other.majorityProbability), + categoricalSplit(std::move(other.categoricalSplit)), + numericSplit(std::move(other.numericSplit)) +{ + // Remove pointers. + other.dimensionMappings = nullptr; + other.datasetInfo = nullptr; +} + +// Copy assignment operator. +template class NumericSplitType, + template class CategoricalSplitType> +HoeffdingTree& + HoeffdingTree:: + operator=(const HoeffdingTree& other) : +{ + if (this != &other) + { + numericSplits = other.numericSplits; + categoricalSplits = other.categoricalSplits; + dimensionMappings = new std::unordered_map>(*other.dimensionMappings); + ownsMappings = true; + numSamples = other.numSamples; + numClasses = other.numClasses; + maxSamples = other.maxSamples; + checkInterval = other.checkInterval; + minSamples = other.minSamples; + datasetInfo = new data::DatasetInfo(*other.datasetInfo); + ownsInfo = true; + successProbability = other.successProbability; + splitDimension = other.splitDimension; + majorityClass = other.majorityClass; + majorityProbability = other.majorityProbability; + categoricalSplit = other.categoricalSplit; + numericSplit = other.numericSplit; + + // Copy each of the children. + for (size_t i = 0; i < other.children.size(); ++i) + { + children.push_back(new HoeffdingTree(*other.children[i])); + + // Delete copied datasetInfo and dimension mappings. + delete children[i]->datasetInfo; + children[i]->datasetInfo = this->datasetInfo; + children[i]->ownsInfo = false; + + delete children[i]->dimensionMappings; + children[i]->dimensionMappings = this->dimensionMappings; + children[i]->ownsMappings = false; + } + } + return *this; +} + +// Move assignment operator. +template class NumericSplitType, + template class CategoricalSplitType> +HoeffdingTree& + HoeffdingTree:: + operator=(HoeffdingTree&& other) : +{ + if (this != &other) + { + numericSplits = std::move(other.numericSplits); + categoricalSplits = std::move(other.categoricalSplits); + dimensionMappings = other.dimensionMappings; + ownsMappings = true; + numSamples = other.numSamples; + numClasses = other.numClasses; + maxSamples = other.maxSamples; + checkInterval = other.checkInterval; + minSamples = other.minSamples; + datasetInfo = other.datasetInfo; + ownsInfo = true; + successProbability = other.successProbability; + splitDimension = other.splitDimension; + majorityClass = other.majorityClass; + majorityProbability = other.majorityProbability; + categoricalSplit = std::move(other.categoricalSplit); + numericSplit = std::move(other.numericSplit); + // Remove pointers. + other.dimensionMappings = nullptr; + other.datasetInfo = nullptr; + } + return *this; +} + + template class NumericSplitType, template class CategoricalSplitType> diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_model.cpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_model.cpp index d35970dd5b..2dfe857edf 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_model.cpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_model.cpp @@ -62,53 +62,57 @@ HoeffdingTreeModel::HoeffdingTreeModel(HoeffdingTreeModel&& other) : HoeffdingTreeModel& HoeffdingTreeModel::operator=( const HoeffdingTreeModel& other) { - // Clear this model. - delete giniHoeffdingTree; - delete giniBinaryTree; - delete infoHoeffdingTree; - delete infoBinaryTree; + if (this != &other) + { + // Clear this model. + delete giniHoeffdingTree; + delete giniBinaryTree; + delete infoHoeffdingTree; + delete infoBinaryTree; - giniHoeffdingTree = NULL; - giniBinaryTree = NULL; - infoHoeffdingTree = NULL; - infoBinaryTree = NULL; - - // Create the right tree. - type = other.type; - if (other.giniHoeffdingTree && (type == GINI_HOEFFDING)) - giniHoeffdingTree = new GiniHoeffdingTreeType(*other.giniHoeffdingTree); - else if (other.giniBinaryTree && (type == GINI_BINARY)) - giniBinaryTree = new GiniBinaryTreeType(*other.giniBinaryTree); - else if (other.infoHoeffdingTree && (type == INFO_HOEFFDING)) - infoHoeffdingTree = new InfoHoeffdingTreeType(*other.infoHoeffdingTree); - else if (other.infoBinaryTree && (type == INFO_BINARY)) - infoBinaryTree = new InfoBinaryTreeType(*other.infoBinaryTree); + giniHoeffdingTree = NULL; + giniBinaryTree = NULL; + infoHoeffdingTree = NULL; + infoBinaryTree = NULL; + // Create the right tree. + type = other.type; + if (other.giniHoeffdingTree && (type == GINI_HOEFFDING)) + giniHoeffdingTree = new GiniHoeffdingTreeType(*other.giniHoeffdingTree); + else if (other.giniBinaryTree && (type == GINI_BINARY)) + giniBinaryTree = new GiniBinaryTreeType(*other.giniBinaryTree); + else if (other.infoHoeffdingTree && (type == INFO_HOEFFDING)) + infoHoeffdingTree = new InfoHoeffdingTreeType(*other.infoHoeffdingTree); + else if (other.infoBinaryTree && (type == INFO_BINARY)) + infoBinaryTree = new InfoBinaryTreeType(*other.infoBinaryTree); + } return *this; } // Move operator. HoeffdingTreeModel& HoeffdingTreeModel::operator=(HoeffdingTreeModel&& other) { - // Clear this model. - delete giniHoeffdingTree; - delete giniBinaryTree; - delete infoHoeffdingTree; - delete infoBinaryTree; + if (this != &other) + { + // Clear this model. + delete giniHoeffdingTree; + delete giniBinaryTree; + delete infoHoeffdingTree; + delete infoBinaryTree; - type = other.type; - giniHoeffdingTree = other.giniHoeffdingTree; - giniBinaryTree = other.giniBinaryTree; - infoHoeffdingTree = other.infoHoeffdingTree; - infoBinaryTree = other.infoBinaryTree; - - // Clear the other model. - other.type = GINI_HOEFFDING; - other.giniHoeffdingTree = NULL; - other.giniBinaryTree = NULL; - other.infoHoeffdingTree = NULL; - other.infoBinaryTree = NULL; + type = other.type; + giniHoeffdingTree = other.giniHoeffdingTree; + giniBinaryTree = other.giniBinaryTree; + infoHoeffdingTree = other.infoHoeffdingTree; + infoBinaryTree = other.infoBinaryTree; + // Clear the other model. + other.type = GINI_HOEFFDING; + other.giniHoeffdingTree = NULL; + other.giniBinaryTree = NULL; + other.infoHoeffdingTree = NULL; + other.infoBinaryTree = NULL; + } return *this; } diff --git a/src/mlpack/methods/kde/kde.hpp b/src/mlpack/methods/kde/kde.hpp index 448d32dd84..8885c2e894 100644 --- a/src/mlpack/methods/kde/kde.hpp +++ b/src/mlpack/methods/kde/kde.hpp @@ -140,11 +140,16 @@ class KDE /** * Copy a KDE model. * - * Use std::move if the object to copy is no longer needed. + * @param other KDE model to copy. + */ + KDE& operator=(const KDE& other); + + /** + * Move a KDE model. * * @param other KDE model to copy. */ - KDE& operator=(KDE other); + KDE& operator=(KDE&& other); /** * Destroy the KDE object. If this object created any trees, they will be diff --git a/src/mlpack/methods/kde/kde_impl.hpp b/src/mlpack/methods/kde/kde_impl.hpp index b48190e686..054c02119d 100644 --- a/src/mlpack/methods/kde/kde_impl.hpp +++ b/src/mlpack/methods/kde/kde_impl.hpp @@ -190,31 +190,95 @@ KDE:: -operator=(KDE other) +operator=(const KDE& other) { - // Clean memory. - if (ownsReferenceTree) + if (this != &other) { - delete referenceTree; - delete oldFromNewReferences; + // Clean memory. + if (ownsReferenceTree) + { + delete referenceTree; + delete oldFromNewReferences; + } + kernel = KernelType(other.kernel); + metric = MetricType(other.metric); + relError = other.relError; + absError = other.absError; + ownsReferenceTree = other.ownsReferenceTree; + trained = other.trained; + mode = other.mode; + monteCarlo = other.monteCarlo; + mcProb = other.mcProb; + initialSampleSize = other.initialSampleSize; + mcEntryCoef = other.mcEntryCoef; + mcBreakCoef = other.mcBreakCoef; + if (trained) + { + if (ownsReferenceTree) + { + oldFromNewReferences = + new std::vector(*other.oldFromNewReferences); + referenceTree = new Tree(*other.referenceTree); + } + else + { + oldFromNewReferences = other.oldFromNewReferences; + referenceTree = other.referenceTree; + } + } } + return *this; +} - // Move the other object. - this->kernel = std::move(other.kernel); - this->metric = std::move(other.metric); - this->referenceTree = std::move(other.referenceTree); - this->oldFromNewReferences = std::move(other.oldFromNewReferences); - this->relError = other.relError; - this->absError = other.absError; - this->ownsReferenceTree = other.ownsReferenceTree; - this->trained = other.trained; - this->mode = other.mode; - this->monteCarlo = other.monteCarlo; - this->mcProb = other.mcProb; - this->initialSampleSize = other.initialSampleSize; - this->mcEntryCoef = other.mcEntryCoef; - this->mcBreakCoef = other.mcBreakCoef; +template class TreeType, + template class DualTreeTraversalType, + template class SingleTreeTraversalType> +KDE& +KDE:: +operator=(KDE&& other) +{ + if (this != &other) + { + // Clean memory. + if (ownsReferenceTree) + { + delete referenceTree; + delete oldFromNewReferences; + } + // Move the other object. + this->kernel = std::move(other.kernel); + this->metric = std::move(other.metric); + // TODO: This should be: this->referenceTree = other.referenceTree; + this->referenceTree = std::move(other.referenceTree); + // TODO: This should be: this->oldFromNewReferences = other.oldFromNewReferences; + this->oldFromNewReferences = std::move(other.oldFromNewReferences); + this->relError = other.relError; + this->absError = other.absError; + this->ownsReferenceTree = other.ownsReferenceTree; + this->trained = other.trained; + this->mode = other.mode; + this->monteCarlo = other.monteCarlo; + this->mcProb = other.mcProb; + this->initialSampleSize = other.initialSampleSize; + this->mcEntryCoef = other.mcEntryCoef; + this->mcBreakCoef = other.mcBreakCoef; + } return *this; } From 568ce1f15681645600b6e102a033c9d047f3fb4d Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Sun, 17 Jan 2021 14:54:02 -0500 Subject: [PATCH 473/550] finish fixing static code check --- .../complete_incremental_termination.hpp | 3 +- .../incomplete_incremental_termination.hpp | 3 +- .../ann/layer/recurrent_attention_impl.hpp | 3 +- .../ann/layer/reinforce_normal_impl.hpp | 2 +- .../hoeffding_trees/hoeffding_tree_impl.hpp | 4 +-- .../kmeans/dual_tree_kmeans_rules_impl.hpp | 3 +- .../methods/preprocess/scaling_model.hpp | 3 ++ .../methods/preprocess/scaling_model_impl.hpp | 32 ++++++++++++++++++- .../q_networks/categorical_dqn.hpp | 2 +- 9 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp b/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp index e3a030836d..bdd02d7fec 100644 --- a/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp @@ -36,7 +36,8 @@ class CompleteIncrementalTermination */ CompleteIncrementalTermination( TerminationPolicy tPolicy = TerminationPolicy()) : - tPolicy(tPolicy) { } + tPolicy(tPolicy), incrementalIndex(0), iteration(0) + { /** Nothing to do here. */ } /** * Initializes the termination policy before stating the factorization. diff --git a/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp b/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp index 62b112b061..d01fdfd4c5 100644 --- a/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp @@ -35,7 +35,8 @@ class IncompleteIncrementalTermination */ IncompleteIncrementalTermination( TerminationPolicy tPolicy = TerminationPolicy()) : - tPolicy(tPolicy) { } + tPolicy(tPolicy), incrementalIndex(0), iteration(0) + { /** Nothing to do here. */ } /** * Initializes the termination policy before stating the factorization. diff --git a/src/mlpack/methods/ann/layer/recurrent_attention_impl.hpp b/src/mlpack/methods/ann/layer/recurrent_attention_impl.hpp index 4cdb912756..dcc60055d5 100644 --- a/src/mlpack/methods/ann/layer/recurrent_attention_impl.hpp +++ b/src/mlpack/methods/ann/layer/recurrent_attention_impl.hpp @@ -31,7 +31,8 @@ RecurrentAttention::RecurrentAttention() : rho(0), forwardStep(0), backwardStep(0), - deterministic(false) + deterministic(false), + outSize(0) { // Nothing to do. } diff --git a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp index 67eebf107d..b3c2fd700b 100644 --- a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp +++ b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp @@ -21,7 +21,7 @@ namespace ann /** Artificial Neural Network. */ { template ReinforceNormal::ReinforceNormal( - const double stdev) : stdev(stdev) + const double stdev) : stdev(stdev), reward(0.0), deterministic(false) { // Nothing to do here. } diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp index f7e8bdd830..3535f9558b 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp @@ -259,7 +259,7 @@ template class CategoricalSplitType> HoeffdingTree& HoeffdingTree:: - operator=(const HoeffdingTree& other) : + operator=(const HoeffdingTree& other) { if (this != &other) { @@ -306,7 +306,7 @@ template class CategoricalSplitType> HoeffdingTree& HoeffdingTree:: - operator=(HoeffdingTree&& other) : + operator=(HoeffdingTree&& other) { if (this != &other) { diff --git a/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp b/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp index 6f180c2e99..5e08f88a28 100644 --- a/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp +++ b/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp @@ -40,7 +40,8 @@ DualTreeKMeansRules::DualTreeKMeansRules( baseCases(0), scores(0), lastQueryIndex(dataset.n_cols), - lastReferenceIndex(centroids.n_cols) + lastReferenceIndex(centroids.n_cols), + lastBaseCase(0.0) { // We must set the traversal info last query and reference node pointers to // something that is both invalid (i.e. not a tree node) and not NULL. We'll diff --git a/src/mlpack/methods/preprocess/scaling_model.hpp b/src/mlpack/methods/preprocess/scaling_model.hpp index 87693cc796..a5d7082658 100644 --- a/src/mlpack/methods/preprocess/scaling_model.hpp +++ b/src/mlpack/methods/preprocess/scaling_model.hpp @@ -65,6 +65,9 @@ class ScalingModel //! Copy assignment operator. ScalingModel& operator=(const ScalingModel& other); + //! Move assignment operator. + ScalingModel& operator=(ScalingModel&& other); + //! Clean up memory. ~ScalingModel(); diff --git a/src/mlpack/methods/preprocess/scaling_model_impl.hpp b/src/mlpack/methods/preprocess/scaling_model_impl.hpp index dd918de9d9..6da36e6f49 100644 --- a/src/mlpack/methods/preprocess/scaling_model_impl.hpp +++ b/src/mlpack/methods/preprocess/scaling_model_impl.hpp @@ -84,7 +84,7 @@ ScalingModel::ScalingModel(ScalingModel&& other) : } //! Copy assignment operator. -ScalingModel& ScalingModel::operator= (const ScalingModel& other) +ScalingModel& ScalingModel::operator=(const ScalingModel& other) { if (this == &other) { @@ -123,6 +123,36 @@ ScalingModel& ScalingModel::operator= (const ScalingModel& other) return *this; } +//! Move assignment operator. +ScalingModel& ScalingModel::operator=(ScalingModel&& other) +{ + if (this != &other) + { + scalerType = other.scalerType; + minmaxscale = other.minmaxscale; + maxabsscale = other.maxabsscale; + meanscale = other.meanscale; + standardscale = other.standardscale; + pcascale = other.pcascale; + zcascale = other.zcascale; + minValue = other.minValue; + maxValue = other.maxValue; + epsilon = other.epsilon; + + other.scalerType = 0; + other.minmaxscale = nullptr; + other.maxabsscale = nullptr; + other.meanscale = nullptr; + other.standardscale = nullptr; + other.pcascale = nullptr; + other.zcascale = nullptr; + other.minValue = 0; + other.maxValue = 1; + other.epsilon = 0.00005; + } + return *this; +} + ScalingModel::~ScalingModel() { delete minmaxscale; diff --git a/src/mlpack/methods/reinforcement_learning/q_networks/categorical_dqn.hpp b/src/mlpack/methods/reinforcement_learning/q_networks/categorical_dqn.hpp index b52110d744..82ce15e77e 100644 --- a/src/mlpack/methods/reinforcement_learning/q_networks/categorical_dqn.hpp +++ b/src/mlpack/methods/reinforcement_learning/q_networks/categorical_dqn.hpp @@ -53,7 +53,7 @@ class CategoricalDQN /** * Default constructor. */ - CategoricalDQN() : network(), isNoisy(false) + CategoricalDQN() : network(), isNoisy(false), atomSize(0), vMin(0.0), vMax(0.0) { /* Nothing to do here. */ } /** From f7b5537aa790c6ba4ebc540976000032bdefb5fb Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 18 Jan 2021 09:57:30 +0530 Subject: [PATCH 474/550] Added Hinge Loss Skeleton --- .../methods/ann/loss_functions/CMakeLists.txt | 26 ++--- .../methods/ann/loss_functions/hinge_loss.hpp | 102 ++++++++++++++++++ .../ann/loss_functions/hinge_loss_impl.hpp | 65 +++++++++++ 3 files changed, 181 insertions(+), 12 deletions(-) create mode 100644 src/mlpack/methods/ann/loss_functions/hinge_loss.hpp create mode 100644 src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp diff --git a/src/mlpack/methods/ann/loss_functions/CMakeLists.txt b/src/mlpack/methods/ann/loss_functions/CMakeLists.txt index 70b570e0ff..12d9d1718a 100644 --- a/src/mlpack/methods/ann/loss_functions/CMakeLists.txt +++ b/src/mlpack/methods/ann/loss_functions/CMakeLists.txt @@ -9,24 +9,32 @@ set(SOURCES dice_loss_impl.hpp earth_mover_distance.hpp earth_mover_distance_impl.hpp + empty_loss.hpp + empty_loss_impl.hpp huber_loss.hpp huber_loss_impl.hpp + hinge_embedding_loss.hpp + hinge_embedding_loss_impl.hpp + hinge_loss.hpp + hinge_loss_impl.hpp kl_divergence.hpp kl_divergence_impl.hpp - margin_ranking_loss.hpp - margin_ranking_loss_impl.hpp - mean_bias_error.hpp - mean_bias_error_impl.hpp l1_loss.hpp l1_loss_impl.hpp + log_cosh_loss.hpp + log_cosh_loss_impl.hpp + margin_ranking_loss.hpp + margin_ranking_loss_impl.hpp + mean_absolute_percentage_error.hpp + mean_absolute_percentage_error_impl.hpp + mean_bias_error.hpp + mean_bias_error_impl.hpp mean_squared_error.hpp mean_squared_error_impl.hpp mean_squared_logarithmic_error.hpp mean_squared_logarithmic_error_impl.hpp negative_log_likelihood.hpp negative_log_likelihood_impl.hpp - log_cosh_loss.hpp - log_cosh_loss_impl.hpp poisson_nll_loss.hpp poisson_nll_loss_impl.hpp reconstruction_loss.hpp @@ -35,12 +43,6 @@ set(SOURCES sigmoid_cross_entropy_error_impl.hpp soft_margin_loss.hpp soft_margin_loss_impl.hpp - hinge_embedding_loss.hpp - hinge_embedding_loss_impl.hpp - empty_loss.hpp - empty_loss_impl.hpp - mean_absolute_percentage_error.hpp - mean_absolute_percentage_error_impl.hpp triplet_margin_loss.hpp triplet_margin_loss_impl.hpp ) diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp new file mode 100644 index 0000000000..e43ec9d862 --- /dev/null +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp @@ -0,0 +1,102 @@ +/** + * @file methods/ann/loss_functions/hinge_loss.hpp + * @author Anush Kini + * + * Definition of the Hinge Loss Function. + * + * 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_LOSS_FUNCTION_HINGE_LOSS_HPP +#define MLPACK_METHODS_ANN_LOSS_FUNCTION_HINGE_LOSS_HPP + +#include + +namespace mlpack { +namespace ann /** Artificial Neural Network. */ { + +/** + * Computes the hinge loss between y_true and y_pred. Expects y_true to be + * either -1 or 1. If y_true is either 0 or 1, a temporary conversion is made to + * calculate the loss. + * + * @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 HingeLoss +{ + public: + /** + * Create HingeLoss object. + * @param reduction Specifies the reduction to apply to the output. If false, + * 'mean' reduction is used, where sum of the output will be + * divided by the number of elements in the output. If + * true, 'sum' reduction is used and the output will be + * summed. It is set to true by default. + */ + HingeLoss(const bool reduction = true); + + /** + * Computes the Hinge loss function. + * + * @param prediction Prediction used for evaluating the specified loss + * function. + * @param target Target data to compare with. + */ + template + typename PredictionType::elem_type Forward(const PredictionType& prediction, + const TargetType& target); + + /** + * Ordinary feed backward pass of a neural network. + * + * @param prediction Prediction used for evaluating the specified loss + * function. + * @param target The target vector. + * @param loss The calculated error. + */ + template + void Backward(const PredictionType& prediction, + const TargetType& target, + LossType& loss); + + //! Get the output parameter. + OutputDataType& OutputParameter() const { return outputParameter; } + //! Modify the output parameter. + OutputDataType& OutputParameter() { return outputParameter; } + + //! Get the type of reduction used. + bool Reduction() const { return reduction; } + //! Modify the type of reduction used. + bool& Reduction() { return reduction; } + + /** + * Serialize the layer. + */ + template + void serialize(Archive& ar, const uint32_t /* version */); + + private: + //! Locally-stored output parameter object. + OutputDataType outputParameter; + + //! The boolean value that tells if reduction is sum or mean. + bool reduction; +}; // class HingeLoss + +} // namespace ann +} // namespace mlpack + +// include implementation +#include "hinge_loss_impl.hpp" + +#endif diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp new file mode 100644 index 0000000000..8cb74192c7 --- /dev/null +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp @@ -0,0 +1,65 @@ +/** + * @file methods/ann/loss_functions/hinge_loss_impl.hpp + * @author Anush Kini + * + * Implementation of the Hinge loss function. + * + * 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_LOSS_FUNCTION_HINGE_LOSS_IMPL_HPP +#define MLPACK_METHODS_ANN_LOSS_FUNCTION_HINGE_LOSS_IMPL_HPP + +// In case it hasn't yet been included. +#include "hinge_loss.hpp" + +namespace mlpack { +namespace ann /** Artificial Neural Network. */ { + +template +HingeLoss::HingeLoss(const bool reduction): + reduction(reduction) +{ + // Nothing to do here. +} + +template +template +typename PredictionType::elem_type +HingeLoss::Forward( + const PredictionType& prediction, + const TargetType& target) +{ + TargetType temp = target - (target == 0); + TargetType temp_zeros.zeros(target.size()); + + PredictionType loss = arma::mean(arma::max(1 - prediction % temp, temp_zeros), 1); + typename PredictionType::elem_type lossSum = arma::accu(loss); + + if (reduction) + return lossSum; + + return lossSum / loss.n_elem; +} + +template +template +void HingeEmbeddingLoss::Backward( + const PredictionType& prediction, + const TargetType& target, + LossType& loss) +{ + TargetType temp = target - (target == 0); + loss = (prediction < 1 / temp) % -temp; +} + + + + +} // namespace ann +} // namespace mlpack + +#endif From a21a52dec17fdfa516cf4803fcd3a1c1ef8ce60d Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 18 Jan 2021 10:00:32 +0530 Subject: [PATCH 475/550] Style fixes --- src/mlpack/methods/ann/layer/multiply_constant.hpp | 8 ++++---- src/mlpack/methods/ann/layer/multiply_merge.hpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mlpack/methods/ann/layer/multiply_constant.hpp b/src/mlpack/methods/ann/layer/multiply_constant.hpp index a9a32a19ac..32fad5b5b3 100644 --- a/src/mlpack/methods/ann/layer/multiply_constant.hpp +++ b/src/mlpack/methods/ann/layer/multiply_constant.hpp @@ -39,16 +39,16 @@ class MultiplyConstant */ MultiplyConstant(const double scalar = 1.0); - //! Copy Constructor + //! Copy Constructor. MultiplyConstant(const MultiplyConstant& layer); - //! Move Constructor + //! Move Constructor. MultiplyConstant(MultiplyConstant&& layer); - //! Copy assignment operator + //! Copy assignment operator. MultiplyConstant& operator=(const MultiplyConstant& layer); - //! Move assignment operator + //! Move assignment operator. MultiplyConstant& operator=(MultiplyConstant&& layer); /** diff --git a/src/mlpack/methods/ann/layer/multiply_merge.hpp b/src/mlpack/methods/ann/layer/multiply_merge.hpp index 94e4169d52..1ac73a0bbd 100644 --- a/src/mlpack/methods/ann/layer/multiply_merge.hpp +++ b/src/mlpack/methods/ann/layer/multiply_merge.hpp @@ -50,16 +50,16 @@ class MultiplyMerge */ MultiplyMerge(const bool model = false, const bool run = true); - //! Copy Constructor + //! Copy Constructor. MultiplyMerge(const MultiplyMerge& layer); - //! Move Constructor + //! Move Constructor. MultiplyMerge(MultiplyMerge&& layer); - //! Copy assignment operator + //! Copy assignment operator. MultiplyMerge& operator=(const MultiplyMerge& layer); - //! Move assignment operator + //! Move assignment operator. MultiplyMerge& operator=(MultiplyMerge&& layer); //! Destructor to release allocated memory. From e4fb279689f66ffd1ade7ff9d565cee59839ca98 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 18 Jan 2021 19:14:24 +0530 Subject: [PATCH 476/550] Added an implementation of hinge loss --- .../ann/loss_functions/hinge_loss_impl.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp index 8cb74192c7..0d6729b5b5 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp @@ -36,7 +36,8 @@ HingeLoss::Forward( TargetType temp = target - (target == 0); TargetType temp_zeros.zeros(target.size()); - PredictionType loss = arma::mean(arma::max(1 - prediction % temp, temp_zeros), 1); + PredictionType loss = arma::max(1 - prediction % temp, temp_zeros); + typename PredictionType::elem_type lossSum = arma::accu(loss); if (reduction) @@ -53,11 +54,20 @@ void HingeEmbeddingLoss::Backward( LossType& loss) { TargetType temp = target - (target == 0); - loss = (prediction < 1 / temp) % -temp; + loss = (prediction < (1 / temp)) % -temp; + + if (!reduction) + loss /= target.n_elem; } - - +template +template +void HingeEmbeddingLoss::serialize( + Archive& ar, + const uint32_t /* version */) +{ + ar(CEREAL_NVP(reduction)); +} } // namespace ann } // namespace mlpack From 151ca758abed17013287ea5a360acaecf94b66db Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Mon, 18 Jan 2021 16:59:24 -0500 Subject: [PATCH 477/550] fix static error 1/18 --- src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp | 2 +- src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp | 2 +- src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp index b3c2fd700b..2c985dff6d 100644 --- a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp +++ b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp @@ -34,7 +34,7 @@ void ReinforceNormal::Forward( if (!deterministic) { // Multiply by standard deviations and re-center the means to the mean. - output = arma::randn >(input.n_rows, input.n_cols) * + output = arma::randn>(input.n_rows, input.n_cols) * stdev + input; moduleInputParameter.push_back(input); diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp index 3535f9558b..5e31358621 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp @@ -452,7 +452,7 @@ void HoeffdingTree< delete dimensionMappings; const CategoricalSplitType categoricalSplitIn(0, 0); - const NumericSplitType& numericSplitIn(0); + const NumericSplitType numericSplitIn(0); dimensionMappings = new std::unordered_map>(); diff --git a/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp b/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp index 5e08f88a28..2d1a66fe12 100644 --- a/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp +++ b/src/mlpack/methods/kmeans/dual_tree_kmeans_rules_impl.hpp @@ -157,8 +157,7 @@ inline double DualTreeKMeansRules::Score( traversalInfo.LastQueryNode()->MinimumBoundDistance(); const double lastRefDescDist = traversalInfo.LastReferenceNode()->MinimumBoundDistance(); - adjustedScore = lastScore + lastQueryDescDist; - adjustedScore = lastScore + lastRefDescDist; + adjustedScore = lastScore + lastQueryDescDist + lastRefDescDist; } // Assemble an adjusted score. For nearest neighbor search, this adjusted From 0008893ef70f92b4589aa739f7097627f0cf2f89 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Mon, 18 Jan 2021 22:28:24 -0500 Subject: [PATCH 478/550] fix static error --- src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp index 2c985dff6d..be4803b6c6 100644 --- a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp +++ b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp @@ -34,8 +34,12 @@ void ReinforceNormal::Forward( if (!deterministic) { // Multiply by standard deviations and re-center the means to the mean. - output = arma::randn>(input.n_rows, input.n_cols) * - stdev + input; + arma::Mat output(input.n_rows, input.n_cols); + + output = output.randn() * stdev + input; + + // output = arma::randn>(input.n_rows, input.n_cols) * + // stdev + input; moduleInputParameter.push_back(input); } From 2e208af07573ba04ed9215db77704d2d6bab6f25 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 19 Jan 2021 01:41:09 -0500 Subject: [PATCH 479/550] fix static code 1/19 --- src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp index be4803b6c6..74de3d93d4 100644 --- a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp +++ b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp @@ -34,9 +34,7 @@ void ReinforceNormal::Forward( if (!deterministic) { // Multiply by standard deviations and re-center the means to the mean. - arma::Mat output(input.n_rows, input.n_cols); - - output = output.randn() * stdev + input; + output = output.randn(input.n_rows, input.n_cols) * stdev + input; // output = arma::randn>(input.n_rows, input.n_cols) * // stdev + input; From 772b95ffb73e498cfab97c2c78d8ec06ca8c3884 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Tue, 19 Jan 2021 12:40:38 +0530 Subject: [PATCH 480/550] Added hinge loss implementation --- src/mlpack/methods/ann/loss_functions/hinge_loss.hpp | 2 +- src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp index e43ec9d862..a9c2563b9e 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp @@ -64,7 +64,7 @@ class HingeLoss * @param target The target vector. * @param loss The calculated error. */ - template + template void Backward(const PredictionType& prediction, const TargetType& target, LossType& loss); diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp index 0d6729b5b5..85fb07cb88 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp @@ -34,7 +34,7 @@ HingeLoss::Forward( const TargetType& target) { TargetType temp = target - (target == 0); - TargetType temp_zeros.zeros(target.size()); + TargetType temp_zeros(size(target), arma::fill::zeros); PredictionType loss = arma::max(1 - prediction % temp, temp_zeros); @@ -48,7 +48,7 @@ HingeLoss::Forward( template template -void HingeEmbeddingLoss::Backward( +void HingeLoss::Backward( const PredictionType& prediction, const TargetType& target, LossType& loss) @@ -62,7 +62,7 @@ void HingeEmbeddingLoss::Backward( template template -void HingeEmbeddingLoss::serialize( +void HingeLoss::serialize( Archive& ar, const uint32_t /* version */) { From 472e8a4d01186b8733dbf3168cdc2d6d5879e7a7 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Tue, 19 Jan 2021 09:40:42 -0500 Subject: [PATCH 481/550] finishing up --- src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp index 74de3d93d4..c2f92df476 100644 --- a/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp +++ b/src/mlpack/methods/ann/layer/reinforce_normal_impl.hpp @@ -35,9 +35,6 @@ void ReinforceNormal::Forward( { // Multiply by standard deviations and re-center the means to the mean. output = output.randn(input.n_rows, input.n_cols) * stdev + input; - - // output = arma::randn>(input.n_rows, input.n_cols) * - // stdev + input; moduleInputParameter.push_back(input); } From b17bc76a3a47ca920b4a16ccd6c43d9d353b24c8 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Wed, 20 Jan 2021 17:00:40 -0500 Subject: [PATCH 482/550] Update src/mlpack/core/tree/hrectbound_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/core/tree/hrectbound_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/tree/hrectbound_impl.hpp b/src/mlpack/core/tree/hrectbound_impl.hpp index 45d4b81a76..a1259a677c 100644 --- a/src/mlpack/core/tree/hrectbound_impl.hpp +++ b/src/mlpack/core/tree/hrectbound_impl.hpp @@ -104,7 +104,7 @@ inline HRectBound::HRectBound( } /** - * Move assignment operator + * Move assignment operator. */ template inline HRectBound< From 947fc2b83cbdf9b199ed73a70a58cb105e521065 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Wed, 20 Jan 2021 17:00:47 -0500 Subject: [PATCH 483/550] Update src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp Co-authored-by: Marcus Edel --- src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp index 32bb94ece9..c6cc5bb586 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp @@ -182,7 +182,7 @@ class DiscreteHilbertValue */ DiscreteHilbertValue& operator=(const DiscreteHilbertValue& val); - /** + /** * Move the local Hilbert object. * * @param val The DiscreteHilbertValue object from which the dataset From 7bf86ac51bb68f1e0221bed8264f50a219f2ea9b Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Wed, 20 Jan 2021 17:01:15 -0500 Subject: [PATCH 484/550] Update src/mlpack/methods/range_search/range_search_impl.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/range_search/range_search_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/range_search/range_search_impl.hpp b/src/mlpack/methods/range_search/range_search_impl.hpp index 2652d47c89..03f90b3057 100644 --- a/src/mlpack/methods/range_search/range_search_impl.hpp +++ b/src/mlpack/methods/range_search/range_search_impl.hpp @@ -290,7 +290,7 @@ void RangeSearch::Train( throw std::invalid_argument("cannot train on given reference tree when " "naive search (without trees) is desired"); - // Can only train when passed argument `referenceTree` is not nullptr + // Can only train when passed argument `referenceTree` is not nullptr. if (treeOwner && referenceTree) { delete this->referenceTree; From 880471defbf4a9c4df53757ecf47ffb92bb9ad9f Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Wed, 20 Jan 2021 19:19:03 -0500 Subject: [PATCH 485/550] change val to other --- .../core/tree/rectangle_tree/discrete_hilbert_value.hpp | 8 ++++---- .../tree/rectangle_tree/discrete_hilbert_value_impl.hpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp index c6cc5bb586..a21dd1af3d 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp @@ -177,18 +177,18 @@ class DiscreteHilbertValue /** * Copy the local Hilbert value's pointer. * - * @param val The DiscreteHilbertValue object from which the dataset + * @param other The DiscreteHilbertValue object from which the dataset * will be copied. */ - DiscreteHilbertValue& operator=(const DiscreteHilbertValue& val); + DiscreteHilbertValue& operator=(const DiscreteHilbertValue& other); /** * Move the local Hilbert object. * - * @param val The DiscreteHilbertValue object from which the dataset + * @param other The DiscreteHilbertValue object from which the dataset * will be copied. */ - DiscreteHilbertValue& operator=(DiscreteHilbertValue&& val); + DiscreteHilbertValue& operator=(DiscreteHilbertValue&& other); /** * Nullify the localHilbertValues pointer in order to prevent an invalid free. diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp index 48ad8557f7..bd3c9cb87e 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp @@ -434,18 +434,18 @@ RemoveNode(TreeType* node, const size_t nodeIndex) template DiscreteHilbertValue& DiscreteHilbertValue:: -operator=(const DiscreteHilbertValue& val) +operator=(const DiscreteHilbertValue& other) { - if (this == &val) + if (this == &other) return *this; if (ownsLocalHilbertValues) delete localHilbertValues; localHilbertValues = const_cast* > - (val.LocalHilbertValues()); + (other.LocalHilbertValues()); ownsLocalHilbertValues = false; - numValues = val.NumValues(); + numValues = other.NumValues(); return *this; } From 2fbb7cdcb1087b4e9363a8e526c0209c92d2e935 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Thu, 21 Jan 2021 11:24:12 +0530 Subject: [PATCH 486/550] Added Test for Hinge Loss Function --- src/mlpack/tests/loss_functions_test.cpp | 73 ++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 5a208984dd..b5ab0c155a 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -955,3 +956,75 @@ TEST_CASE("TripletMarginLossTest") REQUIRE(arma::accu(output) == -12); REQUIRE(output.n_elem == 1); } + +/** + * Simple test for the Hinge loss function. + */ +TEST_CASE("HingeLossTest", "[LossFunctionsTest]") +{ + arma::mat input, target, target_b, output; + double loss, loss_b; + HingeLoss<> module1; + HingeLoss<> module2(false); + + // Test the Forward function. Loss should be 0 if input = target. + input = arma::ones(10, 1); + target = arma::ones(10, 1); + loss = module1.Forward(input, target); + REQUIRE(loss == 0); + + // Test the Backward function for input = target. + module1.Backward(input, target, output); + for (double el : output) + { + // For input = target we should get 0.0 everywhere. + REQUIRE(el == Approx(0.0).epsilon(1e-5)); + } + + REQUIRE(output.n_rows == input.n_rows); + REQUIRE(output.n_cols == input.n_cols); + + input = {{0.90599973, -0.33040298, 0.07123354}, + {0.71988434, 0.49657596, 0.39873373}, + {-0.57646927, 0.3951491 , -0.1003365}, + {0.12528634, 0.68122971, 0.85448826}}; + + target = {{-1, -1, 1}, + {-1, 1, 1}, + {1, -1, -1}, + {1, -1, -1}}; + + // Binary labels for target + target_b = {{0, 0, 1}, + {0, 1, 1}, + {1, 0, 0}, + {1, 0, 0}}; + + // Test for binary labels as target. + loss = module1.Forward(input, target); + loss_b = module1.Forward(input, target_b); + + // Loss should be same due to internal conversion of binary labels. + REQUIRE(loss == loss_b); + + // Test for sum reduction. + // Test the Forward function. + loss = module1.Forward(input, target); + REQUIRE(loss == Approx(14.61065).epsilon(1e-3)); + + // Test the Backward function + module1.Backward(input, target, output); + REQUIRE(arma::accu(output) == Approx(-5).epsilon(1e-3)); + REQUIRE(output.n_rows == input.n_rows); + REQUIRE(output.n_cols == input.n_cols); + + // Test for mean reduction. + loss = module2.Forward(input, target); + REQUIRE(loss == Approx(1.21755).epsilon(1e-3)); + + // Test the Backward function. + module2.Backward(input, target, output); + REQUIRE(arma::accu(output) == Approx(-0.41667).epsilon(1e-3)); + REQUIRE(output.n_rows == input.n_rows); + REQUIRE(output.n_cols == input.n_cols); +} From 67ee79d51a3a7fa79c3b20b9b32919630c8d6830 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Thu, 21 Jan 2021 18:53:09 +0530 Subject: [PATCH 487/550] Minor comment addition --- src/mlpack/tests/loss_functions_test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index b5ab0c155a..82e7c76db8 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -994,7 +994,7 @@ TEST_CASE("HingeLossTest", "[LossFunctionsTest]") {1, -1, -1}, {1, -1, -1}}; - // Binary labels for target + // Binary labels for target. target_b = {{0, 0, 1}, {0, 1, 1}, {1, 0, 0}, @@ -1019,6 +1019,7 @@ TEST_CASE("HingeLossTest", "[LossFunctionsTest]") REQUIRE(output.n_cols == input.n_cols); // Test for mean reduction. + // Test for the Forward function. loss = module2.Forward(input, target); REQUIRE(loss == Approx(1.21755).epsilon(1e-3)); From d81f60ca931a4652fcba9c395eb0bd5e5ad2d859 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 09:48:15 -0500 Subject: [PATCH 488/550] Add k-means++ initialization. --- src/mlpack/methods/kmeans/CMakeLists.txt | 1 + src/mlpack/methods/kmeans/kmeans_main.cpp | 31 ++++-- .../kmeans_plus_plus_initialization.hpp | 102 ++++++++++++++++++ src/mlpack/tests/kmeans_test.cpp | 66 ++++++++++++ src/mlpack/tests/main.cpp | 4 +- 5 files changed, 194 insertions(+), 10 deletions(-) create mode 100644 src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp diff --git a/src/mlpack/methods/kmeans/CMakeLists.txt b/src/mlpack/methods/kmeans/CMakeLists.txt index 1dbbbba626..6782ed2f66 100644 --- a/src/mlpack/methods/kmeans/CMakeLists.txt +++ b/src/mlpack/methods/kmeans/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES kill_empty_clusters.hpp kmeans.hpp kmeans_impl.hpp + kmeans_plus_plus_initialization.hpp max_variance_new_cluster.hpp max_variance_new_cluster_impl.hpp naive_kmeans.hpp diff --git a/src/mlpack/methods/kmeans/kmeans_main.cpp b/src/mlpack/methods/kmeans/kmeans_main.cpp index 4c7a689aec..1f0833e9da 100644 --- a/src/mlpack/methods/kmeans/kmeans_main.cpp +++ b/src/mlpack/methods/kmeans/kmeans_main.cpp @@ -17,6 +17,7 @@ #include "allow_empty_clusters.hpp" #include "kill_empty_clusters.hpp" #include "refined_start.hpp" +#include "kmeans_plus_plus_initialization.hpp" #include "elkan_kmeans.hpp" #include "hamerly_kmeans.hpp" #include "pelleg_moore_kmeans.hpp" @@ -44,14 +45,17 @@ BINDING_LONG_DESC( " the point furthest from the centroid of the cluster with maximum variance" " is taken to fill that cluster." "\n\n" - "Optionally, the Bradley and Fayyad approach (\"Refining initial points for" - " k-means clustering\", 1998) can be used to select initial points by " - "specifying the " + PRINT_PARAM_STRING("refined_start") + " parameter. " - "This approach works by taking random samplings of the dataset; to specify " - "the number of samplings, the " + PRINT_PARAM_STRING("samplings") + - " parameter is used, and to specify the percentage of the dataset to be " - "used in each sample, the " + PRINT_PARAM_STRING("percentage") + - " parameter is used (it should be a value between 0.0 and 1.0)." + "Optionally, the strategy to choose initial centroids can be specified. " + "The k-means++ algorithm can be used to choose initial centroids with " + "the " + PRINT_PARAM_STRING("kmeans_plus_plus") + " parameter. The " + "Bradley and Fayyad approach (\"Refining initial points for k-means " + "clustering\", 1998) can be used to select initial points by specifying " + "the " + PRINT_PARAM_STRING("refined_start") + " parameter. This approach " + "works by taking random samplings of the dataset; to specify the number of " + "samplings, the " + PRINT_PARAM_STRING("samplings") + " parameter is used, " + "and to specify the percentage of the dataset to be used in each sample, " + "the " + PRINT_PARAM_STRING("percentage") + " parameter is used (it should " + "be a value between 0.0 and 1.0)." "\n\n" "There are several options available for the algorithm used for each Lloyd " "iteration, specified with the " + PRINT_PARAM_STRING("algorithm") + " " @@ -102,6 +106,7 @@ BINDING_EXAMPLE( // See also... BINDING_SEE_ALSO("K-Means tutorial", "@doxygen/kmtutorial.html"); BINDING_SEE_ALSO("@dbscan", "#dbscan"); +BINDING_SEE_ALSO("k-means++", "https://en.wikipedia.org/wiki/K-means%2B%2B"); BINDING_SEE_ALSO("Using the triangle inequality to accelerate k-means (pdf)", "http://www.aaai.org/Papers/ICML/2003/ICML03-022.pdf"); BINDING_SEE_ALSO("Making k-means even faster (pdf)", @@ -147,6 +152,8 @@ PARAM_INT_IN("samplings", "Number of samplings to perform for refined start " "(use when --refined_start is specified).", "S", 100); PARAM_DOUBLE_IN("percentage", "Percentage of dataset to use for each refined " "start sampling (use when --refined_start is specified).", "p", 0.02); +PARAM_FLAG("kmeans_plus_plus", "Use the k-means++ initialization strategy to " + "choose initial points.", "K"); PARAM_STRING_IN("algorithm", "Algorithm to use for the Lloyd iteration " "('naive', 'pelleg-moore', 'elkan', 'hamerly', 'dualtree', or " @@ -176,6 +183,9 @@ static void mlpackMain() else math::RandomSeed((size_t) std::time(NULL)); + util::RequireOnlyOnePassed({ "refined_start", "kmeans_plus_plus" }, true, + "Only one initialization strategy can be specified!"); + // Now, start building the KMeans type that we'll be using. Start with the // initial partition policy. The call to FindEmptyClusterPolicy<> results in // a call to RunKMeans<> and the algorithm is completed. @@ -191,6 +201,11 @@ static void mlpackMain() FindEmptyClusterPolicy(RefinedStart(samplings, percentage)); } + else if (IO::HasParam("kmeans_plus_plus")) + { + FindEmptyClusterPolicy( + KMeansPlusPlusInitialization()); + } else { FindEmptyClusterPolicy(SampleInitialization()); diff --git a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp new file mode 100644 index 0000000000..23164ec231 --- /dev/null +++ b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp @@ -0,0 +1,102 @@ +/** + * @file kmeans_plus_plus_initialization.hpp + * @author Ryan Curtin + * + * This file implements the k-means++ initialization strategy. + */ +#ifndef KMEANS_PLUS_PLUS_INITIALIZATION_HPP +#define KMEANS_PLUS_PLUS_INITIALIZATION_HPP + +#include + +/** + * This class implements the k-means++ initialization, as described in the + * following paper: + * + * @code + * @inproceedings{arthur2007k, + * title={k-means++: The advantages of careful seeding}, + * author={Arthur, David and Vassilvitskii, Sergei}, + * booktitle={Proceedings of the Eighteenth Annual ACM-SIAM Symposium on + * Discrete Algorithms (SODA '07)}, + * pages={1027--1035}, + * year={2007}, + * organization={Society for Industrial and Applied Mathematics} + * } + * @endcode + * + * In accordance with mlpack's InitialPartitionPolicy template type, we only + * need to implement a constructor and a method to compute the initial + * centroids. + */ +class KMeansPlusPlusInitialization +{ + public: + //! Empty constructor, required by the InitialPartitionPolicy type definition. + KMeansPlusPlusInitialization() { } + + /** + * Initialize the centroids matrix by randomly sampling points from the data + * matrix. + * + * @param data Dataset. + * @param clusters Number of clusters. + * @param centroids Matrix to put initial centroids into. + */ + template + inline static void Cluster(const MatType& data, + const size_t clusters, + arma::mat& centroids) + { + centroids.set_size(data.n_rows, clusters); + + // We'll sample our first point fully randomly. + size_t firstPoint = mlpack::math::RandInt(0, data.n_cols); + centroids.col(0) = data.col(firstPoint); + + // Utility variable. + arma::vec distribution(data.n_cols); + + // Now, sample other points... + for (size_t i = 1; i < clusters; ++i) + { + // We must compute the CDF for sampling... this depends on the computation + // of the minimum distance between each point and its closest + // already-chosen centroid. + // + // This computation is ripe for speedup with trees! I am not sure exactly + // how much we would need to approximate, but I think it could be done + // without breaking the O(log k)-competitive guarantee (I think). + for (size_t p = 0; p < data.n_cols; ++p) + { + double minDistance = std::numeric_limits::max(); + for (size_t j = 0; j < i; ++j) + { + const double distance = + mlpack::metric::SquaredEuclideanDistance::Evaluate(data.col(p), + centroids.col(j)); + minDistance = std::min(distance, minDistance); + } + + distribution[p] = minDistance; + } + + // Next normalize the distribution (actually technically we could avoid + // this.) + distribution /= arma::accu(distribution); + + // Turn it into a CDF for convenience... + for (size_t j = 1; j < distribution.n_elem; ++j) + distribution[j] += distribution[j - 1]; + + // Sample a point... + const double sampleValue = mlpack::math::Random(); + double* elem = std::lower_bound(distribution.begin(), distribution.end(), + sampleValue); + size_t position = (size_t) (elem - distribution.begin()) / sizeof(double); + centroids.col(i) = data.col(position); + } + } +}; + +#endif diff --git a/src/mlpack/tests/kmeans_test.cpp b/src/mlpack/tests/kmeans_test.cpp index 5d4bae2abf..ef14467b74 100644 --- a/src/mlpack/tests/kmeans_test.cpp +++ b/src/mlpack/tests/kmeans_test.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -486,6 +487,71 @@ TEST_CASE("RefinedStartTest", "[KMeansTest]") REQUIRE(distortion < 14000.0); } +/** + * Test that the k-means++ initialization strategy returns decent initial + * cluster estimates. + */ +TEST_CASE("KMeansPlusPlusTest", "[KMeansTest]") +{ + // Our dataset will be five Gaussians of largely varying numbers of points and + // we expect that the refined starting policy should return good guesses at + // what these Gaussians are. + arma::mat data(3, 3000); + data.randn(); + + // First Gaussian: 10000 points, centered at (0, 0, 0). + // Second Gaussian: 2000 points, centered at (5, 0, -2). + // Third Gaussian: 5000 points, centered at (-2, -2, -2). + // Fourth Gaussian: 1000 points, centered at (-6, 8, 8). + // Fifth Gaussian: 12000 points, centered at (1, 6, 1). + arma::mat centroids(" 0 5 -2 -6 1;" + " 0 0 -2 8 6;" + " 0 -2 -2 8 1"); + + for (size_t i = 1000; i < 1200; ++i) + data.col(i) += centroids.col(1); + for (size_t i = 1200; i < 1700; ++i) + data.col(i) += centroids.col(2); + for (size_t i = 1700; i < 1800; ++i) + data.col(i) += centroids.col(3); + for (size_t i = 1800; i < 3000; ++i) + data.col(i) += centroids.col(4); + + KMeansPlusPlusInitialization k; + arma::mat resultingCentroids; + k.Cluster(data, 5, resultingCentroids); + + // Calculate resulting assignments. + arma::Row assignments(data.n_cols); + for (size_t i = 0; i < data.n_cols; ++i) + { + double bestDist = DBL_MAX; + for (size_t j = 0; j < 5; ++j) + { + const double dist = metric::EuclideanDistance::Evaluate(data.col(i), + resultingCentroids.col(j)); + if (dist < bestDist) + { + bestDist = dist; + assignments[i] = j; + } + } + } + + // Calculate sum of distances from centroid means. + double distortion = 0; + for (size_t i = 0; i < 3000; ++i) + distortion += metric::EuclideanDistance::Evaluate(data.col(i), + resultingCentroids.col(assignments[i])); + + // Using k-means++, the distance for this dataset is usually around + // 10000. Regular k-means is between 10000 and 30000 (I think the 10000 + // figure is a corner case which actually does not give good clusters), and + // random initial starts give distortion around 22000. So we'll require that + // our distortion is less than 12000. + REQUIRE(distortion < 12000.0); +} + #ifdef ARMA_HAS_SPMAT /** * Make sure sparse k-means works okay. diff --git a/src/mlpack/tests/main.cpp b/src/mlpack/tests/main.cpp index 3267ae850d..44ae40d641 100644 --- a/src/mlpack/tests/main.cpp +++ b/src/mlpack/tests/main.cpp @@ -22,8 +22,8 @@ int main(int argc, char** argv) * each run. This is good for ensuring that a test's tolerance is sufficient * across many different runs. */ - // size_t seed = std::time(NULL); - // mlpack::math::RandomSeed(seed); + size_t seed = std::time(NULL); + mlpack::math::RandomSeed(seed); #ifndef TEST_VERBOSE #ifdef DEBUG mlpack::Log::Debug.ignoreInput = true; From 295d24b42e1ea5b3544c321c858040b48c95ce65 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 09:50:32 -0500 Subject: [PATCH 489/550] Update HISTORY. --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 7529a3ee86..c5b118476e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,8 @@ * Add finalizers to Julia binding model types to fix memory handling (#2756). + * Add k-means++ initialization strategy (#2813). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. From 2ea6d50b6da6b222f9e5190a4d8f4b2af4d7d0e5 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 18:36:56 -0500 Subject: [PATCH 490/550] Apply suggestions from code review Co-authored-by: Marcus Edel --- src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp index 23164ec231..c4e074e4f7 100644 --- a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp +++ b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp @@ -1,5 +1,5 @@ /** - * @file kmeans_plus_plus_initialization.hpp + * @file methods/kmeans/kmeans_plus_plus_initialization.hpp * @author Ryan Curtin * * This file implements the k-means++ initialization strategy. @@ -82,7 +82,7 @@ class KMeansPlusPlusInitialization } // Next normalize the distribution (actually technically we could avoid - // this.) + // this). distribution /= arma::accu(distribution); // Turn it into a CDF for convenience... From 1d90bf817d757406a3141deb4da9abae104abc0e Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 18:38:02 -0500 Subject: [PATCH 491/550] Update header guard macro name. --- src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp index c4e074e4f7..ae63ee80c5 100644 --- a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp +++ b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp @@ -4,8 +4,8 @@ * * This file implements the k-means++ initialization strategy. */ -#ifndef KMEANS_PLUS_PLUS_INITIALIZATION_HPP -#define KMEANS_PLUS_PLUS_INITIALIZATION_HPP +#ifndef MLPACK_METHODS_KMEANS_KMEANS_PLUS_PLUS_INITIALIZATION_HPP +#define MLPACK_METHODS_KMEANS_KMEANS_PLUS_PLUS_INITIALIZATION_HPP #include From 79d2621a838256dafd77ab05645df6a178363d7c Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 18:39:20 -0500 Subject: [PATCH 492/550] Add const. --- .../methods/kmeans/kmeans_plus_plus_initialization.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp index ae63ee80c5..e43c59fe1a 100644 --- a/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp +++ b/src/mlpack/methods/kmeans/kmeans_plus_plus_initialization.hpp @@ -91,9 +91,10 @@ class KMeansPlusPlusInitialization // Sample a point... const double sampleValue = mlpack::math::Random(); - double* elem = std::lower_bound(distribution.begin(), distribution.end(), - sampleValue); - size_t position = (size_t) (elem - distribution.begin()) / sizeof(double); + const double* elem = std::lower_bound(distribution.begin(), + distribution.end(), sampleValue); + const size_t position = (size_t) + (elem - distribution.begin()) / sizeof(double); centroids.col(i) = data.col(position); } } From 4e39217837bd05934c2dc4a8cacacb0adc538bcd Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 18:53:01 -0500 Subject: [PATCH 493/550] Modify RequireOnlyOnePassed() to allow none to be passed. --- src/mlpack/core/util/param_checks.hpp | 5 ++++- src/mlpack/core/util/param_checks_impl.hpp | 5 +++-- src/mlpack/methods/kmeans/kmeans_main.cpp | 6 +++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/mlpack/core/util/param_checks.hpp b/src/mlpack/core/util/param_checks.hpp index a9180a4816..c1ac39aeea 100644 --- a/src/mlpack/core/util/param_checks.hpp +++ b/src/mlpack/core/util/param_checks.hpp @@ -43,11 +43,14 @@ namespace util { * @param fatal If true, output goes to Log::Fatal instead of Log::Warn and an * exception is thrown. * @param customErrorMessage Error message to append. + * @param allowNone If true, then no error message will be thrown if none of the + * parameters in the constraints were passed. */ void RequireOnlyOnePassed( const std::vector& constraints, const bool fatal = true, - const std::string& customErrorMessage = ""); + const std::string& customErrorMessage = "", + const bool allowNone = false); /** * Require that at least one of the given parameters in the constraints set was diff --git a/src/mlpack/core/util/param_checks_impl.hpp b/src/mlpack/core/util/param_checks_impl.hpp index be88c8a3e9..8562e1341f 100644 --- a/src/mlpack/core/util/param_checks_impl.hpp +++ b/src/mlpack/core/util/param_checks_impl.hpp @@ -21,7 +21,8 @@ namespace util { inline void RequireOnlyOnePassed( const std::vector& constraints, const bool fatal, - const std::string& errorMessage) + const std::string& errorMessage, + const bool allowNone) { if (BINDING_IGNORE_CHECK(constraints)) return; @@ -57,7 +58,7 @@ inline void RequireOnlyOnePassed( stream << "; " << errorMessage; stream << "!" << std::endl; } - else if (set == 0) + else if (set == 0 && !allowNone) { stream << (fatal ? "Must " : "Should "); diff --git a/src/mlpack/methods/kmeans/kmeans_main.cpp b/src/mlpack/methods/kmeans/kmeans_main.cpp index 1f0833e9da..4707c05b7e 100644 --- a/src/mlpack/methods/kmeans/kmeans_main.cpp +++ b/src/mlpack/methods/kmeans/kmeans_main.cpp @@ -183,8 +183,8 @@ static void mlpackMain() else math::RandomSeed((size_t) std::time(NULL)); - util::RequireOnlyOnePassed({ "refined_start", "kmeans_plus_plus" }, true, - "Only one initialization strategy can be specified!"); + RequireOnlyOnePassed({ "refined_start", "kmeans_plus_plus" }, true, + "Only one initialization strategy can be specified!", true); // Now, start building the KMeans type that we'll be using. Start with the // initial partition policy. The call to FindEmptyClusterPolicy<> results in @@ -286,7 +286,7 @@ void RunKMeans(const InitialPartitionPolicy& ipp) const int maxIterations = IO::GetParam("max_iterations"); // Make sure we have an output file if we're not doing the work in-place. - RequireAtLeastOnePassed({ "in_place", "output", "centroid" }, false, + RequireOnlyOnePassed({ "in_place", "output", "centroid" }, false, "no results will be saved"); arma::mat dataset = IO::GetParam("input"); // Load our dataset. From 5ffb8b4ea41424fcdaf0063f917befd81b681c5d Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 18:53:50 -0500 Subject: [PATCH 494/550] Update src/mlpack/tests/main.cpp Co-authored-by: Marcus Edel --- src/mlpack/tests/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/main.cpp b/src/mlpack/tests/main.cpp index 44ae40d641..3267ae850d 100644 --- a/src/mlpack/tests/main.cpp +++ b/src/mlpack/tests/main.cpp @@ -22,8 +22,8 @@ int main(int argc, char** argv) * each run. This is good for ensuring that a test's tolerance is sufficient * across many different runs. */ - size_t seed = std::time(NULL); - mlpack::math::RandomSeed(seed); + // size_t seed = std::time(NULL); + // mlpack::math::RandomSeed(seed); #ifndef TEST_VERBOSE #ifdef DEBUG mlpack::Log::Debug.ignoreInput = true; From 2f504f5669c570401b8e4efc260813ab7a1bead3 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 21 Jan 2021 18:55:46 -0500 Subject: [PATCH 495/550] Fix style. --- src/mlpack/methods/cf/cf_main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/cf/cf_main.cpp b/src/mlpack/methods/cf/cf_main.cpp index ce083c8c4a..0c8cd49539 100644 --- a/src/mlpack/methods/cf/cf_main.cpp +++ b/src/mlpack/methods/cf/cf_main.cpp @@ -371,10 +371,15 @@ static void mlpackMain() arma::Mat users = std::move(IO::GetParam>("query")); if (users.n_rows > 1) + { users = users.t(); + } + if (users.n_rows > 1) + { Log::Fatal << "List of query users must be one-dimensional!" - << std::endl; + << std::endl; + } Log::Info << "Generating recommendations for " << users.n_elem << " users." << endl; From 0c77578f47cac2d14a67e70af56bb9260f511036 Mon Sep 17 00:00:00 2001 From: jeffin143 Date: Fri, 22 Jan 2021 21:18:33 +0530 Subject: [PATCH 496/550] Add cereal library to history --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index c8a3c94497..b7b0ad75ee 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -16,6 +16,8 @@ * HMM: add functions to calculate likelihood for data stream with/without pre-calculated emission probability (#2142). + * Replace boost Boost serialization library by Cereal (#2458). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. From 22e3fb4bff0512e98716ea3b3c6922b22de56a4c Mon Sep 17 00:00:00 2001 From: jeffin sam Date: Sat, 23 Jan 2021 01:40:33 +0530 Subject: [PATCH 497/550] Update HISTORY.md Co-authored-by: Marcus Edel --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b7b0ad75ee..001e6e2762 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -16,7 +16,7 @@ * HMM: add functions to calculate likelihood for data stream with/without pre-calculated emission probability (#2142). - * Replace boost Boost serialization library by Cereal (#2458). + * Replace Boost serialization library by Cereal (#2458). ### mlpack 3.4.2 ###### 2020-10-26 From eba621e9cbc965f4ea209d2d2f500d05c9168842 Mon Sep 17 00:00:00 2001 From: Omar Shrit Date: Fri, 22 Jan 2021 22:48:37 +0100 Subject: [PATCH 498/550] Remove libarmadillo-dev from the path, keep the manually installed one Signed-off-by: Omar Shrit --- .ci/linux-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/linux-steps.yaml b/.ci/linux-steps.yaml index 21baace148..eba826ac92 100644 --- a/.ci/linux-steps.yaml +++ b/.ci/linux-steps.yaml @@ -21,7 +21,7 @@ steps: unset BOOST_ROOT echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT - sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost1.70-dev libarmadillo-dev xz-utils + sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost1.70-dev xz-utils if [ "$(binding)" == "python" ]; then export PYBIN=$(which python) From 0e8e6f1ba14755e072f68f952625f7dca0a32c15 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 23 Jan 2021 19:53:47 +0530 Subject: [PATCH 499/550] simplification --- src/mlpack/core/util/io.cpp | 29 ++++++++++++++--------------- src/mlpack/core/util/io.hpp | 3 ++- src/mlpack/core/util/io_impl.hpp | 6 +++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index d36b287a4e..8687a6df12 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -279,27 +279,26 @@ void IO::CheckInputMatrices() std::string paramType = itr->second.cppType; if (paramType == "arma::mat") - IO::CheckInputMatrix>(paramName); + IO::CheckInputMatrix>( + IO::GetParam>(paramName), paramName); else if (paramType == "arma::Mat") - IO::CheckInputMatrix>(paramName); + IO::CheckInputMatrix>( + IO::GetParam>(paramName), paramName); else if (paramType == "arma::colvec") - IO::CheckInputMatrix>(paramName); + IO::CheckInputMatrix>( + IO::GetParam>(paramName), paramName); else if (paramType == "arma::Col") - IO::CheckInputMatrix>(paramName); + IO::CheckInputMatrix>( + IO::GetParam>(paramName), paramName); else if (paramType == "arma::rowvec") - IO::CheckInputMatrix>(paramName); + IO::CheckInputMatrix>( + IO::GetParam>(paramName), paramName); else if (paramType == "arma::Row") - IO::CheckInputMatrix>(paramName); + IO::CheckInputMatrix>( + IO::GetParam>(paramName), paramName); else if (paramType == "std::tuple") - { - std::string errMsg1 = "The input " + paramName + " has NaN values."; - std::string errMsg2 = "The input " + paramName + " has inf values."; - - if (std::get<1>(GetParam(paramName)).has_nan()) - Log::Fatal << errMsg1 << std::endl; - if (std::get<1>(GetParam(paramName)).has_inf()) - Log::Fatal << errMsg2 << std::endl; - } + IO::CheckInputMatrix>( + std::get<1>(IO::GetParam(paramName)), paramName); } } diff --git a/src/mlpack/core/util/io.hpp b/src/mlpack/core/util/io.hpp index 5189695abe..aa9d71c16f 100644 --- a/src/mlpack/core/util/io.hpp +++ b/src/mlpack/core/util/io.hpp @@ -222,10 +222,11 @@ class IO /** * Utility function for CheckInputMatrices(). * + * @param matrix Matrix to check. * @param identifier Name of the parameter in question. */ template - static void CheckInputMatrix(const std::string& identifier); + static void CheckInputMatrix(const T& matrix, const std::string& identifier); /** * Given two (matrix) parameters, ensure that the first is an in-place copy of diff --git a/src/mlpack/core/util/io_impl.hpp b/src/mlpack/core/util/io_impl.hpp index f54aaa4eab..e7407efd7f 100644 --- a/src/mlpack/core/util/io_impl.hpp +++ b/src/mlpack/core/util/io_impl.hpp @@ -146,14 +146,14 @@ T& IO::GetRawParam(const std::string& identifier) } template -void IO::CheckInputMatrix(const std::string& identifier) +void IO::CheckInputMatrix(const T& matrix, const std::string& identifier) { std::string errMsg1 = "The input " + identifier + " has NaN values."; std::string errMsg2 = "The input " + identifier + " has inf values."; - if (GetParam(identifier).has_nan()) + if (matrix.has_nan()) Log::Fatal << errMsg1 << std::endl; - if (GetParam(identifier).has_inf()) + if (matrix.has_inf()) Log::Fatal << errMsg2 << std::endl; } From 654e6503d892e9f4934266a5f977297c56a44b10 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sat, 23 Jan 2021 19:57:18 +0530 Subject: [PATCH 500/550] updated HISTORY.md --- HISTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 001e6e2762..0c81a8265a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,8 @@ ### mlpack ?.?.? ###### ????-??-?? + * Add "check_input_matrices" option to python bindings that checks + for NaN and inf values in all the input matrices (#2787). + * Add Adjusted R squared functionality to R2Score::Evaluate (#2624). * Disabled all the bindings by default in CMake (#2782). From 33af71dbce383b4809509429d40603aa4e69a1ab Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Sun, 24 Jan 2021 00:35:21 +0530 Subject: [PATCH 501/550] Update src/mlpack/core/util/io.cpp Co-authored-by: Ryan Curtin --- src/mlpack/core/util/io.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 8687a6df12..dba1bbecd8 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -279,26 +279,36 @@ void IO::CheckInputMatrices() std::string paramType = itr->second.cppType; if (paramType == "arma::mat") - IO::CheckInputMatrix>( - IO::GetParam>(paramName), paramName); + { + IO::CheckInputMatrix(IO::GetParam(paramName), paramName); + } else if (paramType == "arma::Mat") - IO::CheckInputMatrix>( + { + IO::CheckInputMatrix( IO::GetParam>(paramName), paramName); + } else if (paramType == "arma::colvec") - IO::CheckInputMatrix>( - IO::GetParam>(paramName), paramName); + { + IO::CheckInputMatrix(IO::GetParam(paramName), paramName); + } else if (paramType == "arma::Col") - IO::CheckInputMatrix>( + { + IO::CheckInputMatrix( IO::GetParam>(paramName), paramName); + } else if (paramType == "arma::rowvec") - IO::CheckInputMatrix>( - IO::GetParam>(paramName), paramName); + { + IO::CheckInputMatrix(IO::GetParam(paramName), paramName); + } else if (paramType == "arma::Row") - IO::CheckInputMatrix>( + { + IO::CheckInputMatrix( IO::GetParam>(paramName), paramName); + } else if (paramType == "std::tuple") - IO::CheckInputMatrix>( + { + IO::CheckInputMatrix( std::get<1>(IO::GetParam(paramName)), paramName); + } } } - From 723ecf82ebf0a6e47d3ab50e9804bc1a2f8f32f9 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 24 Jan 2021 00:36:50 +0530 Subject: [PATCH 502/550] added more tests --- .../python/tests/test_python_binding.py | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/src/mlpack/bindings/python/tests/test_python_binding.py b/src/mlpack/bindings/python/tests/test_python_binding.py index f6beffa483..207e8711d3 100644 --- a/src/mlpack/bindings/python/tests/test_python_binding.py +++ b/src/mlpack/bindings/python/tests/test_python_binding.py @@ -1354,6 +1354,60 @@ class TestPythonBinding(unittest.TestCase): matrix_in=x, check_input_matrices=True)) + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + umatrix_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + row_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + urow_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + col_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + ucol_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + matrix_and_info_in=x, + check_input_matrices=True)) + def testCheckInputMatricesInf(self): """ Checks that an exception is thrown if the input matrix contains @@ -1372,5 +1426,59 @@ class TestPythonBinding(unittest.TestCase): matrix_in=x, check_input_matrices=True)) + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + umatrix_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + row_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + urow_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + col_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + ucol_in=x, + check_input_matrices=True)) + + self.assertRaises(RuntimeError, + lambda : test_python_binding(string_in="hello", + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + matrix_and_info_in=x, + check_input_matrices=True)) + if __name__ == '__main__': unittest.main() From 8cc834fe4357a0a5289f739c9fcc8c8ee277c02d Mon Sep 17 00:00:00 2001 From: Omar Shrit Date: Sat, 23 Jan 2021 20:20:03 +0100 Subject: [PATCH 503/550] Remove lapack, it is not need, openblas should be enough Signed-off-by: Omar Shrit --- .ci/linux-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/linux-steps.yaml b/.ci/linux-steps.yaml index eba826ac92..f695c14fe1 100644 --- a/.ci/linux-steps.yaml +++ b/.ci/linux-steps.yaml @@ -21,7 +21,7 @@ steps: unset BOOST_ROOT echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT - sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost1.70-dev xz-utils + sudo apt-get install -y --allow-unauthenticated libopenblas-dev g++ libboost1.70-dev xz-utils if [ "$(binding)" == "python" ]; then export PYBIN=$(which python) From 141b92d07cef34ace3b3e2714125195755cb9183 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 24 Jan 2021 00:57:00 +0530 Subject: [PATCH 504/550] fixes --- .../python/tests/test_python_binding.py | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/mlpack/bindings/python/tests/test_python_binding.py b/src/mlpack/bindings/python/tests/test_python_binding.py index 207e8711d3..0fcdb70353 100644 --- a/src/mlpack/bindings/python/tests/test_python_binding.py +++ b/src/mlpack/bindings/python/tests/test_python_binding.py @@ -1363,13 +1363,16 @@ class TestPythonBinding(unittest.TestCase): umatrix_in=x, check_input_matrices=True)) + x_row = np.random.rand(1, 100) + a = np.random.randint(low=0, high=100) + x_row[0][a] = np.nan self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - row_in=x, + row_in=x_row, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1378,16 +1381,19 @@ class TestPythonBinding(unittest.TestCase): double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - urow_in=x, + urow_in=x_row, check_input_matrices=True)) + x_col = np.random.rand(100, 1) + a = np.random.randint(low=0, high=100) + x_col[a][0] = np.nan self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - col_in=x, + col_in=x_col, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1396,7 +1402,7 @@ class TestPythonBinding(unittest.TestCase): double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - ucol_in=x, + ucol_in=x_col, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1435,13 +1441,16 @@ class TestPythonBinding(unittest.TestCase): umatrix_in=x, check_input_matrices=True)) + x_row = np.random.rand(1, 100) + a = np.random.randint(low=0, high=100) + x_row[0][a] = np.inf self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - row_in=x, + row_in=x_row, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1450,16 +1459,19 @@ class TestPythonBinding(unittest.TestCase): double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - urow_in=x, + urow_in=x_row, check_input_matrices=True)) + x_col = np.random.rand(100, 1) + a = np.random.randint(low=0, high=100) + x_col[a][0] = np.inf self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - col_in=x, + col_in=x_col, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1468,7 +1480,7 @@ class TestPythonBinding(unittest.TestCase): double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - ucol_in=x, + ucol_in=x_col, check_input_matrices=True)) self.assertRaises(RuntimeError, From 0d31176db8dfe643578d66645d759e29abcd2876 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Sun, 24 Jan 2021 21:14:41 +0530 Subject: [PATCH 505/550] added check for unsigned matrix --- src/mlpack/core/util/io.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index dba1bbecd8..8c36aa442a 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -287,6 +287,11 @@ void IO::CheckInputMatrices() IO::CheckInputMatrix( IO::GetParam>(paramName), paramName); } + else if (paramType == "arma::Mat") + { + IO::CheckInputMatrix( + IO::GetParam>(paramName), paramName); + } else if (paramType == "arma::colvec") { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); From 954f3c490e8d0617f09a74dba55233bd0804d289 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Mon, 25 Jan 2021 00:51:57 +0530 Subject: [PATCH 506/550] fixing parameter types while checking --- .../python/tests/test_python_binding.py | 48 +++++++++---------- src/mlpack/core/util/io.cpp | 10 +--- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/mlpack/bindings/python/tests/test_python_binding.py b/src/mlpack/bindings/python/tests/test_python_binding.py index 0fcdb70353..c4af5fa18b 100644 --- a/src/mlpack/bindings/python/tests/test_python_binding.py +++ b/src/mlpack/bindings/python/tests/test_python_binding.py @@ -1341,7 +1341,7 @@ class TestPythonBinding(unittest.TestCase): Checks that an exception is thrown if the input matrix contains NaN values. """ - x = np.random.rand(100, 5) + x = np.random.randint(low=0, high=500, size=[100, 5]).astype(float) a = np.random.randint(low=0, high=100) b = np.random.randint(low=0, high=5) x[a][b] = np.nan @@ -1356,16 +1356,16 @@ class TestPythonBinding(unittest.TestCase): self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - umatrix_in=x, - check_input_matrices=True)) + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + umatrix_in=x, + check_input_matrices=True)) - x_row = np.random.rand(1, 100) + x_row = np.random.randint(0, high=500, size=100).astype(float) a = np.random.randint(low=0, high=100) - x_row[0][a] = np.nan + x_row[a] = np.nan self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, @@ -1384,9 +1384,9 @@ class TestPythonBinding(unittest.TestCase): urow_in=x_row, check_input_matrices=True)) - x_col = np.random.rand(100, 1) + x_col = np.random.randint(0, high=500, size=100).astype(float) a = np.random.randint(low=0, high=100) - x_col[a][0] = np.nan + x_col[a] = np.nan self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, @@ -1395,7 +1395,7 @@ class TestPythonBinding(unittest.TestCase): col_req_in=[1.0], col_in=x_col, check_input_matrices=True)) - + self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, @@ -1419,7 +1419,7 @@ class TestPythonBinding(unittest.TestCase): Checks that an exception is thrown if the input matrix contains inf values. """ - x = np.random.rand(100, 5) + x = np.random.randint(low=0, high=500, size=[100, 5]).astype(float) a = np.random.randint(low=0, high=100) b = np.random.randint(low=0, high=5) x[a][b] = np.inf @@ -1434,16 +1434,16 @@ class TestPythonBinding(unittest.TestCase): self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - umatrix_in=x, - check_input_matrices=True)) + int_in=12, + double_in=4.0, + mat_req_in=[[1.0]], + col_req_in=[1.0], + umatrix_in=x, + check_input_matrices=True)) - x_row = np.random.rand(1, 100) + x_row = np.random.randint(0, high=500, size=100).astype(float) a = np.random.randint(low=0, high=100) - x_row[0][a] = np.inf + x_row[a] = np.inf self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, @@ -1462,9 +1462,9 @@ class TestPythonBinding(unittest.TestCase): urow_in=x_row, check_input_matrices=True)) - x_col = np.random.rand(100, 1) + x_col = np.random.randint(0, high=500, size=100).astype(float) a = np.random.randint(low=0, high=100) - x_col[a][0] = np.inf + x_col[a] = np.inf self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, @@ -1473,7 +1473,7 @@ class TestPythonBinding(unittest.TestCase): col_req_in=[1.0], col_in=x_col, check_input_matrices=True)) - + self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 8c36aa442a..e13903d6cf 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -277,7 +277,6 @@ void IO::CheckInputMatrices() { std::string paramName = itr->first; std::string paramType = itr->second.cppType; - if (paramType == "arma::mat") { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); @@ -287,14 +286,9 @@ void IO::CheckInputMatrices() IO::CheckInputMatrix( IO::GetParam>(paramName), paramName); } - else if (paramType == "arma::Mat") + else if (paramType == "arma::vec") { - IO::CheckInputMatrix( - IO::GetParam>(paramName), paramName); - } - else if (paramType == "arma::colvec") - { - IO::CheckInputMatrix(IO::GetParam(paramName), paramName); + IO::CheckInputMatrix(IO::GetParam(paramName), paramName); } else if (paramType == "arma::Col") { From 3890be60f15be006771a8192d1151ec4642adf11 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Sun, 24 Jan 2021 17:21:07 -0500 Subject: [PATCH 507/550] Update tolerance. --- src/mlpack/tests/kmeans_test.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mlpack/tests/kmeans_test.cpp b/src/mlpack/tests/kmeans_test.cpp index ef14467b74..c20014c046 100644 --- a/src/mlpack/tests/kmeans_test.cpp +++ b/src/mlpack/tests/kmeans_test.cpp @@ -548,8 +548,9 @@ TEST_CASE("KMeansPlusPlusTest", "[KMeansTest]") // 10000. Regular k-means is between 10000 and 30000 (I think the 10000 // figure is a corner case which actually does not give good clusters), and // random initial starts give distortion around 22000. So we'll require that - // our distortion is less than 12000. - REQUIRE(distortion < 12000.0); + // our distortion is less than 14500. (It seems like there is a lot of noise + // in the result.) + REQUIRE(distortion < 14500.0); } #ifdef ARMA_HAS_SPMAT From f5b32bc890c38f38f1e763907c3c9401f5b18fec Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Mon, 25 Jan 2021 19:59:51 +0530 Subject: [PATCH 508/550] removing size_t tests --- .../python/tests/test_python_binding.py | 80 +++---------------- src/mlpack/core/util/io.cpp | 2 +- 2 files changed, 11 insertions(+), 71 deletions(-) diff --git a/src/mlpack/bindings/python/tests/test_python_binding.py b/src/mlpack/bindings/python/tests/test_python_binding.py index c4af5fa18b..dd67aed974 100644 --- a/src/mlpack/bindings/python/tests/test_python_binding.py +++ b/src/mlpack/bindings/python/tests/test_python_binding.py @@ -1341,7 +1341,7 @@ class TestPythonBinding(unittest.TestCase): Checks that an exception is thrown if the input matrix contains NaN values. """ - x = np.random.randint(low=0, high=500, size=[100, 5]).astype(float) + x = np.random.rand(100, 5) a = np.random.randint(low=0, high=100) b = np.random.randint(low=0, high=5) x[a][b] = np.nan @@ -1354,25 +1354,16 @@ class TestPythonBinding(unittest.TestCase): matrix_in=x, check_input_matrices=True)) - self.assertRaises(RuntimeError, - lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - umatrix_in=x, - check_input_matrices=True)) - - x_row = np.random.randint(0, high=500, size=100).astype(float) + x_vec = np.random.rand(100) a = np.random.randint(low=0, high=100) - x_row[a] = np.nan + x_vec[a] = np.nan self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - row_in=x_row, + row_in=x_vec, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1381,28 +1372,7 @@ class TestPythonBinding(unittest.TestCase): double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - urow_in=x_row, - check_input_matrices=True)) - - x_col = np.random.randint(0, high=500, size=100).astype(float) - a = np.random.randint(low=0, high=100) - x_col[a] = np.nan - self.assertRaises(RuntimeError, - lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - col_in=x_col, - check_input_matrices=True)) - - self.assertRaises(RuntimeError, - lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - ucol_in=x_col, + col_in=x_vec, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1419,7 +1389,7 @@ class TestPythonBinding(unittest.TestCase): Checks that an exception is thrown if the input matrix contains inf values. """ - x = np.random.randint(low=0, high=500, size=[100, 5]).astype(float) + x = np.random.rand(100, 5) a = np.random.randint(low=0, high=100) b = np.random.randint(low=0, high=5) x[a][b] = np.inf @@ -1432,25 +1402,16 @@ class TestPythonBinding(unittest.TestCase): matrix_in=x, check_input_matrices=True)) - self.assertRaises(RuntimeError, - lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - umatrix_in=x, - check_input_matrices=True)) - - x_row = np.random.randint(0, high=500, size=100).astype(float) + x_vec = np.random.rand(100) a = np.random.randint(low=0, high=100) - x_row[a] = np.inf + x_vec[a] = np.inf self.assertRaises(RuntimeError, lambda : test_python_binding(string_in="hello", int_in=12, double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - row_in=x_row, + row_in=x_vec, check_input_matrices=True)) self.assertRaises(RuntimeError, @@ -1459,28 +1420,7 @@ class TestPythonBinding(unittest.TestCase): double_in=4.0, mat_req_in=[[1.0]], col_req_in=[1.0], - urow_in=x_row, - check_input_matrices=True)) - - x_col = np.random.randint(0, high=500, size=100).astype(float) - a = np.random.randint(low=0, high=100) - x_col[a] = np.inf - self.assertRaises(RuntimeError, - lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - col_in=x_col, - check_input_matrices=True)) - - self.assertRaises(RuntimeError, - lambda : test_python_binding(string_in="hello", - int_in=12, - double_in=4.0, - mat_req_in=[[1.0]], - col_req_in=[1.0], - ucol_in=x_col, + col_in=x_vec, check_input_matrices=True)) self.assertRaises(RuntimeError, diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index e13903d6cf..c3c3182ac3 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -304,7 +304,7 @@ void IO::CheckInputMatrices() IO::CheckInputMatrix( IO::GetParam>(paramName), paramName); } - else if (paramType == "std::tuple") + else if (paramType == "TUPLE_TYPE") { IO::CheckInputMatrix( std::get<1>(IO::GetParam(paramName)), paramName); From 7ec4058f35e6af50db55123a0c16899763b574f4 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 26 Jan 2021 19:08:07 +0530 Subject: [PATCH 509/550] removed size_t conditions from CheckInputMatrices() --- src/mlpack/core/util/io.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index c3c3182ac3..2c9efefb3a 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -281,29 +281,14 @@ void IO::CheckInputMatrices() { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); } - else if (paramType == "arma::Mat") - { - IO::CheckInputMatrix( - IO::GetParam>(paramName), paramName); - } else if (paramType == "arma::vec") { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); } - else if (paramType == "arma::Col") - { - IO::CheckInputMatrix( - IO::GetParam>(paramName), paramName); - } else if (paramType == "arma::rowvec") { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); } - else if (paramType == "arma::Row") - { - IO::CheckInputMatrix( - IO::GetParam>(paramName), paramName); - } else if (paramType == "TUPLE_TYPE") { IO::CheckInputMatrix( From 16ff91b60b201bde0c18aff0a4aa35e839eba613 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Tue, 26 Jan 2021 21:58:03 +0530 Subject: [PATCH 510/550] made definition of TUPLE_TYPE inline --- src/mlpack/core/util/param.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index 208ca64b2f..c820df4b65 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -1013,9 +1013,9 @@ using DatasetInfo = DatasetMapper; * collisions are still possible, and they produce bizarre error messages. See * https://github.com/mlpack/mlpack/issues/100 for more information. */ -#define TUPLE_TYPE std::tuple #define PARAM_MATRIX_AND_INFO_IN(ID, DESC, ALIAS) \ - PARAM_IN(TUPLE_TYPE, ID, DESC, ALIAS, TUPLE_TYPE(), false) + PARAM_IN(std::tuple, ID, DESC, \ + ALIAS, std::tuple(), false) /** * Define an input model. From the command line, the user can specify the file From 458b302c39ffbf11e293ea115f8eeca8eec9bdc5 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 27 Jan 2021 00:31:58 +0530 Subject: [PATCH 511/550] removed TUPLE_TYPE --- src/mlpack/core/util/io.cpp | 2 +- src/mlpack/core/util/param.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 2c9efefb3a..9dd571e369 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -289,7 +289,7 @@ void IO::CheckInputMatrices() { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); } - else if (paramType == "TUPLE_TYPE") + else if (paramType == "std::tuple") { IO::CheckInputMatrix( std::get<1>(IO::GetParam(paramName)), paramName); diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index c820df4b65..73f462e464 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -1014,8 +1014,8 @@ using DatasetInfo = DatasetMapper; * https://github.com/mlpack/mlpack/issues/100 for more information. */ #define PARAM_MATRIX_AND_INFO_IN(ID, DESC, ALIAS) \ - PARAM_IN(std::tuple, ID, DESC, \ - ALIAS, std::tuple(), false) + PARAM_IN(std::tuple, ID, DESC, ALIAS, \ + std::tuple(), false) /** * Define an input model. From the command line, the user can specify the file From ab3110e08965b437e62d44fcb8162074907a3dea Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 27 Jan 2021 00:33:23 +0530 Subject: [PATCH 512/550] minor change --- src/mlpack/core/util/io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index 9dd571e369..b7ca51987e 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -289,7 +289,7 @@ void IO::CheckInputMatrices() { IO::CheckInputMatrix(IO::GetParam(paramName), paramName); } - else if (paramType == "std::tuple") + else if (paramType == "std::tuple") { IO::CheckInputMatrix( std::get<1>(IO::GetParam(paramName)), paramName); From 28f369cb14c0b81d64f78d0f382df1034356926a Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:32:29 -0500 Subject: [PATCH 513/550] Update src/mlpack/core/tree/hrectbound.hpp Co-authored-by: Marcus Edel --- src/mlpack/core/tree/hrectbound.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/tree/hrectbound.hpp b/src/mlpack/core/tree/hrectbound.hpp index 31186f621d..6b8ef6c69a 100644 --- a/src/mlpack/core/tree/hrectbound.hpp +++ b/src/mlpack/core/tree/hrectbound.hpp @@ -80,7 +80,7 @@ class HRectBound //! Move constructor: take possession of another bound's information. HRectBound(HRectBound&& other); - //! Move assignment operator + //! Move assignment operator. HRectBound& operator=(HRectBound&& other); //! Destructor: clean up memory. From e2adf5ec7c08a7495de2d855736db49164801c37 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:32:37 -0500 Subject: [PATCH 514/550] Update src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp Co-authored-by: Marcus Edel --- .../termination_policies/incomplete_incremental_termination.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp b/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp index d01fdfd4c5..5646b0d205 100644 --- a/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/incomplete_incremental_termination.hpp @@ -36,7 +36,7 @@ class IncompleteIncrementalTermination IncompleteIncrementalTermination( TerminationPolicy tPolicy = TerminationPolicy()) : tPolicy(tPolicy), incrementalIndex(0), iteration(0) - { /** Nothing to do here. */ } + { /* Nothing to do here. */ } /** * Initializes the termination policy before stating the factorization. From dd8f73d246ea4e4745fef1f2510ec436cc8bbb94 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Tue, 26 Jan 2021 23:32:46 -0500 Subject: [PATCH 515/550] Update src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp Co-authored-by: Marcus Edel --- .../termination_policies/complete_incremental_termination.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp b/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp index bdd02d7fec..78eb24108e 100644 --- a/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/complete_incremental_termination.hpp @@ -37,7 +37,7 @@ class CompleteIncrementalTermination CompleteIncrementalTermination( TerminationPolicy tPolicy = TerminationPolicy()) : tPolicy(tPolicy), incrementalIndex(0), iteration(0) - { /** Nothing to do here. */ } + { /* Nothing to do here. */ } /** * Initializes the termination policy before stating the factorization. @@ -120,4 +120,3 @@ class CompleteIncrementalTermination } // namespace mlpack #endif // MLPACK_METHODS_AMF_COMPLETE_INCREMENTAL_TERMINATION_HPP - From 0914fe94394eaefba557a304b37c8a25283ee66f Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Wed, 27 Jan 2021 16:01:41 +0530 Subject: [PATCH 516/550] added PARAM_IN_WITH_NAME --- src/mlpack/core/util/param.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index 73f462e464..e2b58d1dcd 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -1013,9 +1013,11 @@ using DatasetInfo = DatasetMapper; * collisions are still possible, and they produce bizarre error messages. See * https://github.com/mlpack/mlpack/issues/100 for more information. */ +#define TUPLE_TYPE std::tuple #define PARAM_MATRIX_AND_INFO_IN(ID, DESC, ALIAS) \ - PARAM_IN(std::tuple, ID, DESC, ALIAS, \ - std::tuple(), false) + PARAM_IN_WITH_NAME(TUPLE_TYPE, ID, DESC, ALIAS, \ + "std::tuple", TUPLE_TYPE(), \ + false) /** * Define an input model. From the command line, the user can specify the file @@ -1228,6 +1230,11 @@ using DatasetInfo = DatasetMapper; JOIN(io_option_dummy_object_in_, __COUNTER__) \ (DEF, ID, DESC, ALIAS, #T, REQ, true, false, testName); + #define PARAM_IN_WITH_NAME(T, ID, DESC, ALIAS, NAME, DEF, REQ) \ + static mlpack::util::Option \ + JOIN(io_option_dummy_object_in_, __COUNTER__) \ + (DEF, ID, DESC, ALIAS, NAME, REQ, true, false, testName); + #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ static mlpack::util::Option \ JOIN(io_option_dummy_object_out_, __COUNTER__) \ @@ -1285,6 +1292,11 @@ using DatasetInfo = DatasetMapper; JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \ (DEF, ID, DESC, ALIAS, #T, REQ, true, false, testName); + #define PARAM_IN_WITH_NAME(T, ID, DESC, ALIAS, NAME, DEF, REQ) \ + static mlpack::util::Option \ + JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \ + (DEF, ID, DESC, ALIAS, NAME, REQ, true, false, testName); + #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ static mlpack::util::Option \ JOIN(JOIN(io_option_dummy_object_out_, __LINE__), opt) \ From 46281ee3ef45a6bd25b6cf170a0a3becba256ef1 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Wed, 27 Jan 2021 19:20:44 -0500 Subject: [PATCH 517/550] Update HISTORY and ANN tutorial. --- HISTORY.md | 5 ++++- doc/tutorials/ann/ann.txt | 13 +++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ffc90ca02a..6d1cd06bc4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -12,7 +12,7 @@ * Add Triplet Margin Loss function (#2762). * Add finalizers to Julia binding model types to fix memory handling (#2756). - + * HMM: add functions to calculate likelihood for data stream with/without pre-calculated emission probability (#2142). @@ -23,6 +23,9 @@ * Add k-means++ initialization strategy (#2813). + * `NegativeLogLikelihood<>` now expects classes in the range `0` to + `numClasses - 1` (#2534). + ### mlpack 3.4.2 ###### 2020-10-26 * Added Mean Absolute Percentage Error. diff --git a/doc/tutorials/ann/ann.txt b/doc/tutorials/ann/ann.txt index 7cdb9d1f57..43678fb84e 100644 --- a/doc/tutorials/ann/ann.txt +++ b/doc/tutorials/ann/ann.txt @@ -210,8 +210,9 @@ int main() data::Load("thyroid_test.csv", testData, true); // Split the labels from the training set and testing set respectively. - arma::mat trainLabels = trainData.row(trainData.n_rows - 1); - arma::mat testLabels = testData.row(testData.n_rows - 1); + // Decrement the labels by 1, so they are in the range 0 to (numClasses - 1). + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; + arma::mat testLabels = testData.row(testData.n_rows - 1) - 1; trainData.shed_row(trainData.n_rows - 1); testData.shed_row(testData.n_rows - 1); @@ -246,9 +247,8 @@ int main() // Find index of max prediction for each data point and store in "prediction" for (size_t i = 0; i < predictionTemp.n_cols; ++i) { - // we add 1 to the max index, so that it matches the actual test labels. prediction(i) = arma::as_scalar(arma::find( - arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)) + 1; + arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)); } /* @@ -311,7 +311,7 @@ void RNNModel() for (size_t i = 0; i < labelsTemp.n_cols; ++i) { const int value = arma::as_scalar(arma::find( - arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1; + arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)); labels.col(i).fill(value); } @@ -589,8 +589,9 @@ arma::mat trainData = dataset.submat(0, 0, dataset.n_rows - 4, dataset.n_cols - 1); // Split the data from the training set. +// Subtract 1 so the labels are the range from 0 to (numClasses - 1). arma::mat trainLabels = dataset.submat(dataset.n_rows - 3, 0, - dataset.n_rows - 1, dataset.n_cols - 1); + dataset.n_rows - 1, dataset.n_cols - 1) - 1; // Initialize the network. FFN<> model; From 5b76b2f5e752bb3f298de89568eaa9d20a0e56de Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 28 Jan 2021 13:02:19 +0530 Subject: [PATCH 518/550] changed PARAM_IN_WITH_NAME to PARAM_COMPLETE and editted other macros --- src/mlpack/core/util/param.hpp | 136 +++++++++------------------------ 1 file changed, 37 insertions(+), 99 deletions(-) diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index e2b58d1dcd..8652db4fbe 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -1015,9 +1015,9 @@ using DatasetInfo = DatasetMapper; */ #define TUPLE_TYPE std::tuple #define PARAM_MATRIX_AND_INFO_IN(ID, DESC, ALIAS) \ - PARAM_IN_WITH_NAME(TUPLE_TYPE, ID, DESC, ALIAS, \ - "std::tuple", TUPLE_TYPE(), \ - false) + PARAM_COMPLETE(TUPLE_TYPE, ID, DESC, ALIAS, \ + "std::tuple", false, true, true, \ + TUPLE_TYPE()) /** * Define an input model. From the command line, the user can specify the file @@ -1208,6 +1208,36 @@ using DatasetInfo = DatasetMapper; #define PARAM_VECTOR_IN_REQ(T, ID, DESC, ALIAS) \ PARAM_IN(std::vector, ID, DESC, ALIAS, std::vector(), true); +#define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ + PARAM_COMPLETE(T, ID, DESC, ALIAS, #T, REQ, true, false, DEF); + +#define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ + PARAM_COMPLETE(T, ID, DESC, ALIAS, #T, REQ, false, false, DEF); + +#define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ + PARAM_COMPLETE(arma::mat, ID, DESC, ALIAS, "arma::mat", REQ, IN, \ + TRANS, arma::mat()); + +#define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ + PARAM_COMPLETE(arma::Mat, ID, DESC, ALIAS, "arma::Mat", \ + REQ, IN, TRANS, arma::Mat()); + +#define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \ + PARAM_COMPLETE(arma::vec, ID, DESC, ALIAS, "arma::vec", REQ, IN, TRANS, \ + arma::vec()); + +#define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \ + PARAM_COMPLETE(arma::Col, ID, DESC, ALIAS, "arma::Col", \ + REQ, IN, TRANS, arma::Col()); + +#define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ + PARAM_COMPLETE(arma::rowvec, ID, DESC, ALIAS, "arma::rowvec", REQ, IN, \ + TRANS, arma::rowvec()); + +#define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ + PARAM_COMPLETE(arma::Row, ID, DESC, ALIAS, "arma::Row", \ + REQ, IN, TRANS, arma::Row()); + /** * Define an input parameter. Don't use this function; use the other ones above * that call it. Note that we are using the __LINE__ macro for naming these @@ -1225,56 +1255,10 @@ using DatasetInfo = DatasetMapper; * @param REQ Whether or not parameter is required (boolean value). */ #ifdef __COUNTER__ - #define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ + #define PARAM_COMPLETE(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \ static mlpack::util::Option \ JOIN(io_option_dummy_object_in_, __COUNTER__) \ - (DEF, ID, DESC, ALIAS, #T, REQ, true, false, testName); - - #define PARAM_IN_WITH_NAME(T, ID, DESC, ALIAS, NAME, DEF, REQ) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_object_in_, __COUNTER__) \ - (DEF, ID, DESC, ALIAS, NAME, REQ, true, false, testName); - - #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_object_out_, __COUNTER__) \ - (DEF, ID, DESC, ALIAS, #T, REQ, false, false, testName); - - #define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_matrix_, __COUNTER__) \ - (arma::mat(), ID, DESC, ALIAS, "arma::mat", \ - REQ, IN, !TRANS, testName); - - #define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option> \ - JOIN(io_option_dummy_umatrix_, __COUNTER__) \ - (arma::Mat(), ID, DESC, ALIAS, "arma::Mat", \ - REQ, IN, !TRANS, testName); - - #define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_col_, __COUNTER__) \ - (arma::vec(), ID, DESC, ALIAS, "arma::vec", \ - REQ, IN, !TRANS, testName); - - #define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option> \ - JOIN(io_option_dummy_ucol_, __COUNTER__) \ - (arma::Col(), ID, DESC, ALIAS, "arma::Col", \ - REQ, IN, !TRANS, testName); - - #define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_row_, __COUNTER__) \ - (arma::rowvec(), ID, DESC, ALIAS, "arma::rowvec", \ - REQ, IN, !TRANS, testName); - - #define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option> \ - JOIN(io_option_dummy_urow_, __COUNTER__) \ - (arma::Row(), ID, DESC, ALIAS, "arma::Row", \ - REQ, IN, !TRANS, testName); + (DEF, ID, DESC, ALIAS, NAME, REQ, IN, !TRANS, testName); // There are no uses of required models, so that is not an option to this // macro (it would be easy to add). @@ -1287,56 +1271,10 @@ using DatasetInfo = DatasetMapper; // don't think we can absolutely guarantee success, but it should be "good // enough". We use the __LINE__ macro and the type of the parameter to try // and get a good guess at something unique. - #define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ + #define PARAM_COMPLETE(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \ static mlpack::util::Option \ JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \ - (DEF, ID, DESC, ALIAS, #T, REQ, true, false, testName); - - #define PARAM_IN_WITH_NAME(T, ID, DESC, ALIAS, NAME, DEF, REQ) \ - static mlpack::util::Option \ - JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \ - (DEF, ID, DESC, ALIAS, NAME, REQ, true, false, testName); - - #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ - static mlpack::util::Option \ - JOIN(JOIN(io_option_dummy_object_out_, __LINE__), opt) \ - (DEF, ID, DESC, ALIAS, #T, REQ, false, false, testName); - - #define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option \ - JOIN(JOIN(io_option_dummy_object_matrix_, __LINE__), opt) \ - (arma::mat(), ID, DESC, ALIAS, "arma::mat", REQ, IN, !TRANS, \ - testName); - - #define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option> \ - JOIN(JOIN(io_option_dummy_object_umatrix_, __LINE__), opt) \ - (arma::Mat(), ID, DESC, ALIAS, "arma::Mat", REQ, IN, \ - !TRANS, testName); - - #define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_object_col_, __LINE__) \ - (arma::vec(), ID, DESC, ALIAS, "arma::vec", REQ, IN, !TRANS, \ - testName); - - #define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option> \ - JOIN(io_option_dummy_object_ucol_, __LINE__) \ - (arma::Col(), ID, DESC, ALIAS, "arma::Col", REQ, IN, \ - !TRANS, testName); - - #define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option \ - JOIN(io_option_dummy_object_row_, __LINE__) \ - (arma::rowvec(), ID, DESC, ALIAS, "arma::rowvec", REQ, IN, !TRANS, \ - testName); - - #define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ - static mlpack::util::Option> \ - JOIN(io_option_dummy_object_urow_, __LINE__) \ - (arma::Row(), ID, DESC, ALIAS, "arma::Row", REQ, IN, \ - !TRANS, testName); + (DEF, ID, DESC, ALIAS, NAME, REQ, IN, !TRANS, testName); #define PARAM_MODEL(TYPE, ID, DESC, ALIAS, REQ, IN) \ static mlpack::util::Option \ From 3664422c3996b59a140854e1a1d4bc02497f7ce6 Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Thu, 28 Jan 2021 13:23:23 +0530 Subject: [PATCH 519/550] added comments --- src/mlpack/core/util/param.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index 8652db4fbe..9499e1a870 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -1208,6 +1208,9 @@ using DatasetInfo = DatasetMapper; #define PARAM_VECTOR_IN_REQ(T, ID, DESC, ALIAS) \ PARAM_IN(std::vector, ID, DESC, ALIAS, std::vector(), true); +/** + * Defining useful macros using PARAM_COMPLETE() macro defined later. + */ #define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ PARAM_COMPLETE(T, ID, DESC, ALIAS, #T, REQ, true, false, DEF); @@ -1239,11 +1242,11 @@ using DatasetInfo = DatasetMapper; REQ, IN, TRANS, arma::Row()); /** - * Define an input parameter. Don't use this function; use the other ones above - * that call it. Note that we are using the __LINE__ macro for naming these - * actual parameters when __COUNTER__ does not exist, which is a bit of an ugly - * hack... but this is the preprocessor, after all. We don't have much choice - * other than ugliness. + * Define the PARAM_COMPLETE(), PARAM_MODEL() macro. Don't use this function; + * use the other ones above that call it. Note that we are using the __LINE__ + * macro for naming these actual parameters when __COUNTER__ does not exist, + * which is a bit of an ugly hack... but this is the preprocessor, after all. + * We don't have much choice other than ugliness. * * @param T Type of the parameter. * @param ID Name of the parameter. From b48ba3e77d9aea9ef0ede600f058355d448d0aa8 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 28 Jan 2021 14:03:33 -0500 Subject: [PATCH 520/550] Normalize labels of thyroid data. --- src/mlpack/tests/feedforward_network_test.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index f12573e4ee..552145704e 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -109,7 +109,8 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]") arma::mat trainData; data::Load("thyroid_train.csv", trainData, true); - arma::mat trainLabels = trainData.row(trainData.n_rows - 1); + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; trainData.shed_row(trainData.n_rows - 1); /* @@ -162,7 +163,8 @@ TEST_CASE("CheckCopyMovingReparametrizationNetworkTest", "[FeedForwardNetworkTes arma::mat trainData; data::Load("thyroid_train.csv", trainData, true); - arma::mat trainLabels = trainData.row(trainData.n_rows - 1); + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; trainData.shed_row(trainData.n_rows - 1); /* @@ -196,7 +198,8 @@ TEST_CASE("CheckCopyMovingLinear3DNetworkTest", "[FeedForwardNetworkTest]") arma::mat trainData; data::Load("thyroid_train.csv", trainData, true); - arma::mat trainLabels = trainData.row(trainData.n_rows - 1); + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; trainData.shed_row(trainData.n_rows - 1); /* @@ -334,7 +337,8 @@ TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]") arma::mat trainData; data::Load("thyroid_train.csv", trainData, true); - arma::mat trainLabels = trainData.row(trainData.n_rows - 1); + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; trainData.shed_row(trainData.n_rows - 1); /* @@ -962,13 +966,14 @@ TEST_CASE("FFNCheckInputShapeTest", "[FeedForwardNetworkTest]") arma::mat trainData; data::Load("thyroid_train.csv", trainData, true); - arma::mat trainLabels = trainData.row(trainData.n_rows - 1); + // Normalize labels to [0, 2]. + arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1; trainData.shed_row(trainData.n_rows - 1); arma::mat testData; data::Load("thyroid_test.csv", testData, true); - arma::mat testLabels = testData.row(testData.n_rows - 1); + arma::mat testLabels = testData.row(testData.n_rows - 1) - 1; testData.shed_row(testData.n_rows - 1); FFN, RandomInitialization, CustomLayer<> > model; From 5dd135b551e799612744668d36ae2071fe6b5893 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Thu, 28 Jan 2021 20:22:59 -0500 Subject: [PATCH 521/550] Fix (hopefully) last test. --- src/mlpack/tests/feedforward_network_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mlpack/tests/feedforward_network_test.cpp b/src/mlpack/tests/feedforward_network_test.cpp index 552145704e..d4789aac1c 100644 --- a/src/mlpack/tests/feedforward_network_test.cpp +++ b/src/mlpack/tests/feedforward_network_test.cpp @@ -248,10 +248,10 @@ TEST_CASE("CheckCopyMovingLinear3DNetworkTest", "[FeedForwardNetworkTest]") */ TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]") { - // Create training input by 5x5 matrix. - arma::mat input = arma::randu(10,1); - // Create training output by 1 matrix. - arma::mat output = arma::mat("1"); + // Create training input by 10x1 matrix (only 1 point). + arma::mat input = arma::randu(10, 1); + // Create training output by 1-point matrix. + arma::mat output = arma::mat("0"); // Check copying constructor. FFN> *model1 = new FFN>(); From d7bc9e364890ab53b442c7143ac950b7edbf2e53 Mon Sep 17 00:00:00 2001 From: Alex Nguyen <60036798+rxng8@users.noreply.github.com> Date: Fri, 29 Jan 2021 00:04:59 -0500 Subject: [PATCH 522/550] Update src/mlpack/core/tree/hrectbound_impl.hpp Co-authored-by: Ryan Curtin --- src/mlpack/core/tree/hrectbound_impl.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mlpack/core/tree/hrectbound_impl.hpp b/src/mlpack/core/tree/hrectbound_impl.hpp index a1259a677c..491e25fed6 100644 --- a/src/mlpack/core/tree/hrectbound_impl.hpp +++ b/src/mlpack/core/tree/hrectbound_impl.hpp @@ -107,10 +107,9 @@ inline HRectBound::HRectBound( * Move assignment operator. */ template -inline HRectBound< - MetricType, - ElemType>& HRectBound::operator=(HRectBound&& other) +inline HRectBound& +HRectBound::operator=( + HRectBound&& other) { if (this != &other) { From 53571929d57ef8a1a4bf4b3f52cc034465661419 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 29 Jan 2021 01:05:49 -0500 Subject: [PATCH 523/550] next static code fix --- src/mlpack/core/tree/ballbound_impl.hpp | 32 ++++++++++++------- .../simple_residue_termination.hpp | 14 ++++---- src/mlpack/methods/hmm/hmm_model.hpp | 6 ++++ 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/mlpack/core/tree/ballbound_impl.hpp b/src/mlpack/core/tree/ballbound_impl.hpp index 5722fb854a..59cc86a5ea 100644 --- a/src/mlpack/core/tree/ballbound_impl.hpp +++ b/src/mlpack/core/tree/ballbound_impl.hpp @@ -71,10 +71,14 @@ template BallBound& BallBound::operator=( const BallBound& other) { - radius = other.radius; - center = other.center; - metric = other.metric; - ownsMetric = false; + if (this != &other) + { + radius = other.radius; + center = other.center; + metric = other.metric; + ownsMetric = false; + } + return *this; } //! Move constructor. @@ -97,15 +101,19 @@ template BallBound& BallBound::operator=( BallBound&& other) { - radius = other.radius; - center = std::move(other.center); - metric = other.metric; - ownsMetric = other.ownsMetric; + if (this != &other) + { + radius = other.radius; + center = std::move(other.center); + metric = other.metric; + ownsMetric = other.ownsMetric; - other.radius = 0.0; - other.center = VecType(); - other.metric = nullptr; - other.ownsMetric = false; + other.radius = 0.0; + other.center = VecType(); + other.metric = nullptr; + other.ownsMetric = false; + } + return *this; } //! Destructor to release allocated memory. diff --git a/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp b/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp index 81893f4fa3..86631e32ce 100644 --- a/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp @@ -40,13 +40,13 @@ class SimpleResidueTermination * @param maxIterations Maximum number of iterations. */ SimpleResidueTermination(const double minResidue = 1e-5, - const size_t maxIterations = 10000) - : minResidue(minResidue), - maxIterations(maxIterations), - residue(0.0), - iteration(0), - nm(0), - normOld(0) + const size_t maxIterations = 10000) : + minResidue(minResidue), + maxIterations(maxIterations), + residue(0.0), + iteration(0), + nm(0), + normOld(0) { // Nothing to do here. } diff --git a/src/mlpack/methods/hmm/hmm_model.hpp b/src/mlpack/methods/hmm/hmm_model.hpp index 0a2bce384b..7665397bdc 100644 --- a/src/mlpack/methods/hmm/hmm_model.hpp +++ b/src/mlpack/methods/hmm/hmm_model.hpp @@ -139,6 +139,12 @@ class HMMModel gaussianHMM = other.gaussianHMM; gmmHMM = other.gmmHMM; diagGMMHMM = other.diagGMMHMM; + + other.type = HMMType::DiscreteHMM; + other.discreteHMM = new HMM(); + other.gaussianHMM = nullptr; + other.gmmHMM = nullptr; + other.diagGMMHMM = nullptr; } return *this; } From 8b6d068913b2be86589bc8d0625accd6287d1483 Mon Sep 17 00:00:00 2001 From: Alex Nguyen Date: Fri, 29 Jan 2021 01:59:45 -0500 Subject: [PATCH 524/550] next static code fix --- .../hoeffding_trees/hoeffding_tree_impl.hpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp index 5e31358621..f79b0eb027 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_tree_impl.hpp @@ -251,6 +251,16 @@ HoeffdingTree:: // Remove pointers. other.dimensionMappings = nullptr; other.datasetInfo = nullptr; + + // Reset primary type variables. + other.numSamples = 0; + other.numClasses = 0; + other.checkInterval = 0; + other.minSamples = 0; + other.successProbability = 0.0; + other.splitDimension = 0; + other.majorityClass = 0; + other.majorityProbability = 0.0; } // Copy assignment operator. @@ -327,9 +337,20 @@ HoeffdingTree& majorityProbability = other.majorityProbability; categoricalSplit = std::move(other.categoricalSplit); numericSplit = std::move(other.numericSplit); + // Remove pointers. other.dimensionMappings = nullptr; other.datasetInfo = nullptr; + + // Reset primary type variables. + other.numSamples = 0; + other.numClasses = 0; + other.checkInterval = 0; + other.minSamples = 0; + other.successProbability = 0.0; + other.splitDimension = 0; + other.majorityClass = 0; + other.majorityProbability = 0.0; } return *this; } From 23c39033dee1f3b543d5b982f6708554fa6fd1df Mon Sep 17 00:00:00 2001 From: Nippun Sharma <53967069+NippunSharma@users.noreply.github.com> Date: Fri, 29 Jan 2021 18:04:40 +0530 Subject: [PATCH 525/550] Update src/mlpack/core/util/io.cpp Co-authored-by: Ryan Curtin --- src/mlpack/core/util/io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mlpack/core/util/io.cpp b/src/mlpack/core/util/io.cpp index b7ca51987e..904a155cc0 100644 --- a/src/mlpack/core/util/io.cpp +++ b/src/mlpack/core/util/io.cpp @@ -292,7 +292,7 @@ void IO::CheckInputMatrices() else if (paramType == "std::tuple") { IO::CheckInputMatrix( - std::get<1>(IO::GetParam(paramName)), paramName); + std::get<1>(IO::GetParam(paramName)), paramName); } } } From 9a3815fc1475f4bebf2d31416d800b5b13ab84dc Mon Sep 17 00:00:00 2001 From: NippunSharma Date: Fri, 29 Jan 2021 18:08:37 +0530 Subject: [PATCH 526/550] changed name to PARAM --- src/mlpack/core/util/param.hpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mlpack/core/util/param.hpp b/src/mlpack/core/util/param.hpp index 9499e1a870..fc809c5b6e 100644 --- a/src/mlpack/core/util/param.hpp +++ b/src/mlpack/core/util/param.hpp @@ -1015,7 +1015,7 @@ using DatasetInfo = DatasetMapper; */ #define TUPLE_TYPE std::tuple #define PARAM_MATRIX_AND_INFO_IN(ID, DESC, ALIAS) \ - PARAM_COMPLETE(TUPLE_TYPE, ID, DESC, ALIAS, \ + PARAM(TUPLE_TYPE, ID, DESC, ALIAS, \ "std::tuple", false, true, true, \ TUPLE_TYPE()) @@ -1209,40 +1209,40 @@ using DatasetInfo = DatasetMapper; PARAM_IN(std::vector, ID, DESC, ALIAS, std::vector(), true); /** - * Defining useful macros using PARAM_COMPLETE() macro defined later. + * Defining useful macros using PARAM macro defined later. */ #define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \ - PARAM_COMPLETE(T, ID, DESC, ALIAS, #T, REQ, true, false, DEF); + PARAM(T, ID, DESC, ALIAS, #T, REQ, true, false, DEF); #define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \ - PARAM_COMPLETE(T, ID, DESC, ALIAS, #T, REQ, false, false, DEF); + PARAM(T, ID, DESC, ALIAS, #T, REQ, false, false, DEF); #define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ - PARAM_COMPLETE(arma::mat, ID, DESC, ALIAS, "arma::mat", REQ, IN, \ + PARAM(arma::mat, ID, DESC, ALIAS, "arma::mat", REQ, IN, \ TRANS, arma::mat()); #define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \ - PARAM_COMPLETE(arma::Mat, ID, DESC, ALIAS, "arma::Mat", \ + PARAM(arma::Mat, ID, DESC, ALIAS, "arma::Mat", \ REQ, IN, TRANS, arma::Mat()); #define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \ - PARAM_COMPLETE(arma::vec, ID, DESC, ALIAS, "arma::vec", REQ, IN, TRANS, \ + PARAM(arma::vec, ID, DESC, ALIAS, "arma::vec", REQ, IN, TRANS, \ arma::vec()); #define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \ - PARAM_COMPLETE(arma::Col, ID, DESC, ALIAS, "arma::Col", \ + PARAM(arma::Col, ID, DESC, ALIAS, "arma::Col", \ REQ, IN, TRANS, arma::Col()); #define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ - PARAM_COMPLETE(arma::rowvec, ID, DESC, ALIAS, "arma::rowvec", REQ, IN, \ + PARAM(arma::rowvec, ID, DESC, ALIAS, "arma::rowvec", REQ, IN, \ TRANS, arma::rowvec()); #define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \ - PARAM_COMPLETE(arma::Row, ID, DESC, ALIAS, "arma::Row", \ + PARAM(arma::Row, ID, DESC, ALIAS, "arma::Row", \ REQ, IN, TRANS, arma::Row()); /** - * Define the PARAM_COMPLETE(), PARAM_MODEL() macro. Don't use this function; + * Define the PARAM(), PARAM_MODEL() macro. Don't use this function; * use the other ones above that call it. Note that we are using the __LINE__ * macro for naming these actual parameters when __COUNTER__ does not exist, * which is a bit of an ugly hack... but this is the preprocessor, after all. @@ -1258,7 +1258,7 @@ using DatasetInfo = DatasetMapper; * @param REQ Whether or not parameter is required (boolean value). */ #ifdef __COUNTER__ - #define PARAM_COMPLETE(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \ + #define PARAM(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \ static mlpack::util::Option \ JOIN(io_option_dummy_object_in_, __COUNTER__) \ (DEF, ID, DESC, ALIAS, NAME, REQ, IN, !TRANS, testName); @@ -1274,7 +1274,7 @@ using DatasetInfo = DatasetMapper; // don't think we can absolutely guarantee success, but it should be "good // enough". We use the __LINE__ macro and the type of the parameter to try // and get a good guess at something unique. - #define PARAM_COMPLETE(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \ + #define PARAM(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \ static mlpack::util::Option \ JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \ (DEF, ID, DESC, ALIAS, NAME, REQ, IN, !TRANS, testName); From e339c551e0baf1d3f65fa538572d84e6f7b939a9 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Tue, 2 Feb 2021 19:40:34 +0530 Subject: [PATCH 527/550] Review Cfixes --- .../methods/ann/loss_functions/hinge_loss.hpp | 5 +++- .../ann/loss_functions/hinge_loss_impl.hpp | 2 +- src/mlpack/tests/loss_functions_test.cpp | 30 +++++++++++-------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp index a9c2563b9e..37e6ed20f4 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp @@ -22,6 +22,8 @@ namespace ann /** Artificial Neural Network. */ { * Computes the hinge loss between y_true and y_pred. Expects y_true to be * either -1 or 1. If y_true is either 0 or 1, a temporary conversion is made to * calculate the loss. + * The hinge loss \f$l(y_true, y_pred)\f$ is defined as + * \f$l(y_true, y_pred) = max(0, 1 - y_true*y_pred)\f$. * * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, * arma::sp_mat or arma::cube). @@ -37,6 +39,7 @@ class HingeLoss public: /** * Create HingeLoss object. + * * @param reduction Specifies the reduction to apply to the output. If false, * 'mean' reduction is used, where sum of the output will be * divided by the number of elements in the output. If @@ -54,7 +57,7 @@ class HingeLoss */ template typename PredictionType::elem_type Forward(const PredictionType& prediction, - const TargetType& target); + const TargetType& target); /** * Ordinary feed backward pass of a neural network. diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp index 85fb07cb88..6de5a553fa 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss_impl.hpp @@ -36,7 +36,7 @@ HingeLoss::Forward( TargetType temp = target - (target == 0); TargetType temp_zeros(size(target), arma::fill::zeros); - PredictionType loss = arma::max(1 - prediction % temp, temp_zeros); + PredictionType loss = arma::max(temp_zeros, 1 - prediction % temp); typename PredictionType::elem_type lossSum = arma::accu(loss); diff --git a/src/mlpack/tests/loss_functions_test.cpp b/src/mlpack/tests/loss_functions_test.cpp index 82e7c76db8..1fa4283c1a 100644 --- a/src/mlpack/tests/loss_functions_test.cpp +++ b/src/mlpack/tests/loss_functions_test.cpp @@ -984,21 +984,23 @@ TEST_CASE("HingeLossTest", "[LossFunctionsTest]") REQUIRE(output.n_rows == input.n_rows); REQUIRE(output.n_cols == input.n_cols); - input = {{0.90599973, -0.33040298, 0.07123354}, - {0.71988434, 0.49657596, 0.39873373}, - {-0.57646927, 0.3951491 , -0.1003365}, - {0.12528634, 0.68122971, 0.85448826}}; + // Randomly generated input. + input = { { 0.90599973, -0.33040298, 0.07123354}, + { 0.71988434, 0.49657596, 0.39873373}, + { -0.57646927, 0.3951491 , -0.1003365}, + { 0.12528634, 0.68122971, 0.85448826} }; - target = {{-1, -1, 1}, - {-1, 1, 1}, - {1, -1, -1}, - {1, -1, -1}}; + // Randomly generated target. + target = { { -1, -1, 1}, + { -1, 1, 1}, + { 1, -1, -1}, + { 1, -1, -1} }; - // Binary labels for target. - target_b = {{0, 0, 1}, - {0, 1, 1}, - {1, 0, 0}, - {1, 0, 0}}; + // Binary target can be obtained by replacing -1 with 0 in target. + target_b = { { 0, 0, 1}, + { 0, 1, 1}, + { 1, 0, 0}, + { 1, 0, 0} }; // Test for binary labels as target. loss = module1.Forward(input, target); @@ -1009,6 +1011,7 @@ TEST_CASE("HingeLossTest", "[LossFunctionsTest]") // Test for sum reduction. // Test the Forward function. + // Loss calculated by referring to implementation of tf.keras.losses.hinge. loss = module1.Forward(input, target); REQUIRE(loss == Approx(14.61065).epsilon(1e-3)); @@ -1020,6 +1023,7 @@ TEST_CASE("HingeLossTest", "[LossFunctionsTest]") // Test for mean reduction. // Test for the Forward function. + // Loss calculated by referring to implementation of tf.keras.losses.hinge. loss = module2.Forward(input, target); REQUIRE(loss == Approx(1.21755).epsilon(1e-3)); From 422ce97209bb6939716de8266aa8fbc9fc21c4dd Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Tue, 2 Feb 2021 19:48:38 +0530 Subject: [PATCH 528/550] Adding Doxygen to y_true and y_pred --- src/mlpack/methods/ann/loss_functions/hinge_loss.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp index 37e6ed20f4..60a2002782 100644 --- a/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp +++ b/src/mlpack/methods/ann/loss_functions/hinge_loss.hpp @@ -19,9 +19,9 @@ namespace mlpack { namespace ann /** Artificial Neural Network. */ { /** - * Computes the hinge loss between y_true and y_pred. Expects y_true to be - * either -1 or 1. If y_true is either 0 or 1, a temporary conversion is made to - * calculate the loss. + * Computes the hinge loss between \f$y_true\f$ and \f$y_pred\f$. Expects + * \f$y_true\f$ to be either -1 or 1. If \f$y_true\f$ is either 0 or 1, a + * temporary conversion is made to calculate the loss. * The hinge loss \f$l(y_true, y_pred)\f$ is defined as * \f$l(y_true, y_pred) = max(0, 1 - y_true*y_pred)\f$. * From 2d98d2ac9a1d95c89f76bd601c77c99135c2c46c Mon Sep 17 00:00:00 2001 From: Marcus Edel Date: Wed, 3 Feb 2021 01:03:11 +0100 Subject: [PATCH 529/550] Test file is no no longer used. --- src/mlpack/tests/function_test.cpp | 681 ----------------------------- 1 file changed, 681 deletions(-) delete mode 100644 src/mlpack/tests/function_test.cpp diff --git a/src/mlpack/tests/function_test.cpp b/src/mlpack/tests/function_test.cpp deleted file mode 100644 index 5486ac1e87..0000000000 --- a/src/mlpack/tests/function_test.cpp +++ /dev/null @@ -1,681 +0,0 @@ -/** - * @file tests/function_test.cpp - * @author Ryan Curtin - * @author Shikhar Bhardwaj - * - * Test the Function<> class to see that it properly adds functionality. - * - * 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. - */ -#include -#include -#include -#include -#include -#include - -#include -#include "test_tools.hpp" - -using namespace mlpack; -using namespace mlpack::optimization; -using namespace ens::traits; // For some SFINAE checks. -using namespace mlpack::regression; - -/** - * Utility class with no functions. - */ -class EmptyTestFunction { }; - -/** - * Utility class with Evaluate() but no Evaluate(). - */ -class EvaluateTestFunction -{ - public: - double Evaluate(const arma::mat& coordinates) - { - return arma::accu(coordinates); - } - - double Evaluate(const arma::mat& coordinates, - const size_t begin, - const size_t batchSize) - { - return arma::accu(coordinates) + begin + batchSize; - } -}; - -/** - * Utility class with Gradient() but no Evaluate(). - */ -class GradientTestFunction -{ - public: - void Gradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } - - void Gradient(const arma::mat& coordinates, - const size_t /* begin */, - arma::mat& gradient, - const size_t /* batchSize */) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } -}; - -/** - * Utility class with Gradient() and Evaluate(). - */ -class EvaluateGradientTestFunction -{ - public: - double Evaluate(const arma::mat& coordinates) - { - return arma::accu(coordinates); - } - - double Evaluate(const arma::mat& coordinates, - const size_t /* begin */, - const size_t /* batchSize */) - { - return arma::accu(coordinates); - } - - void Gradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } - - void Gradient(const arma::mat& coordinates, - const size_t /* begin */, - arma::mat& gradient, - const size_t /* batchSize */) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } -}; - -/** - * Utility class with EvaluateWithGradient(). - */ -class EvaluateWithGradientTestFunction -{ - public: - double EvaluateWithGradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - return arma::accu(coordinates); - } - - double EvaluateWithGradient(const arma::mat& coordinates, - const size_t /* begin */, - arma::mat& gradient, - const size_t /* batchSize */) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - return arma::accu(coordinates); - } -}; - -/** - * Utility class with all three functions. - */ -class EvaluateAndWithGradientTestFunction -{ - public: - double Evaluate(const arma::mat& coordinates) - { - return arma::accu(coordinates); - } - - double Evaluate(const arma::mat& coordinates, - const size_t begin, - const size_t batchSize) - { - return arma::accu(coordinates) + batchSize + begin; - } - - void Gradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } - - void Gradient(const arma::mat& coordinates, - const size_t /* begin */, - arma::mat& gradient, - const size_t /* batchSize */) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } - - double EvaluateWithGradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - return arma::accu(coordinates); - } - - double EvaluateWithGradient(const arma::mat& coordinates, - const size_t /* begin */, - arma::mat& gradient, - const size_t /* batchSize */) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - return arma::accu(coordinates); - } -}; - -/** - * Utility class with const Evaluate() and non-const Gradient(). - */ -class EvaluateAndNonConstGradientTestFunction -{ - public: - double Evaluate(const arma::mat& coordinates) const - { - return arma::accu(coordinates); - } - - void Gradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } -}; - -/** - * Utility class with const Evaluate() and non-const Gradient(). - */ -class EvaluateAndStaticGradientTestFunction -{ - public: - double Evaluate(const arma::mat& coordinates) const - { - return arma::accu(coordinates); - } - - static void Gradient(const arma::mat& coordinates, arma::mat& gradient) - { - gradient.ones(coordinates.n_rows, coordinates.n_cols); - } -}; - -BOOST_AUTO_TEST_SUITE(FunctionTest); - -/** - * Make sure that an empty class doesn't have any methods added to it. - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientEmptyTest) -{ - const bool hasEvaluate = HasEvaluate, - EvaluateForm>::value; - const bool hasGradient = HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, false); - BOOST_REQUIRE_EQUAL(hasGradient, false); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, false); -} - -/** - * Make sure we don't add any functions if we only have Evaluate(). - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientEvaluateOnlyTest) -{ - const bool hasEvaluate = HasEvaluate, - EvaluateForm>::value; - const bool hasGradient = HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, false); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, false); -} - -/** - * Make sure we don't add any functions if we only have Gradient(). - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientGradientOnlyTest) -{ - const bool hasEvaluate = HasEvaluate, - EvaluateForm>::value; - const bool hasGradient = HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, false); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, false); -} - -/** - * Make sure we add EvaluateWithGradient() when we have both Evaluate() and - * Gradient(). - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientBothTest) -{ - const bool hasEvaluate = - HasEvaluate, - EvaluateForm>::value; - const bool hasGradient = - HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure we add Evaluate() and Gradient() when we have only - * EvaluateWithGradient(). - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientEvaluateWithGradientTest) -{ - const bool hasEvaluate = - HasEvaluate, - EvaluateForm>::value; - const bool hasGradient = - HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure we add no methods when we already have all three. - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientAllThreeTest) -{ - const bool hasEvaluate = - HasEvaluate, - EvaluateForm>::value; - const bool hasGradient = - HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -BOOST_AUTO_TEST_CASE(LogisticRegressionEvaluateWithGradientTest) -{ - const bool hasEvaluate = - HasEvaluate>, - EvaluateConstForm>::value; - const bool hasGradient = - HasGradient>, - GradientConstForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient>, - EvaluateWithGradientConstForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -BOOST_AUTO_TEST_CASE(SDPTest) -{ - typedef AugLagrangianFunction>> FunctionType; - - const bool hasEvaluate = - HasEvaluate, EvaluateConstForm>::value; - const bool hasGradient = - HasGradient, GradientConstForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientConstForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure that an empty class doesn't have any methods added to it. - */ -BOOST_AUTO_TEST_CASE(AddDecomposableEvaluateWithGradientEmptyTest) -{ - const bool hasEvaluate = HasEvaluate, - DecomposableEvaluateForm>::value; - const bool hasGradient = HasGradient, - DecomposableGradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - DecomposableEvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, false); - BOOST_REQUIRE_EQUAL(hasGradient, false); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, false); -} - -/** - * Make sure we don't add any functions if we only have Evaluate(). - */ -BOOST_AUTO_TEST_CASE(AddDecomposableEvaluateWithGradientEvaluateOnlyTest) -{ - const bool hasEvaluate = HasEvaluate, - DecomposableEvaluateForm>::value; - const bool hasGradient = HasGradient, - DecomposableGradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - DecomposableEvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, false); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, false); -} - -/** - * Make sure we don't add any functions if we only have Gradient(). - */ -BOOST_AUTO_TEST_CASE(AddDecomposableEvaluateWithGradientGradientOnlyTest) -{ - const bool hasEvaluate = HasEvaluate, - DecomposableEvaluateForm>::value; - const bool hasGradient = HasGradient, - DecomposableGradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - DecomposableEvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, false); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, false); -} - -/** - * Make sure we add EvaluateWithGradient() when we have both Evaluate() and - * Gradient(). - */ -BOOST_AUTO_TEST_CASE(AddDecomposableEvaluateWithGradientBothTest) -{ - const bool hasEvaluate = - HasEvaluate, - DecomposableEvaluateForm>::value; - const bool hasGradient = - HasGradient, - DecomposableGradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - DecomposableEvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure we add Evaluate() and Gradient() when we have only - * EvaluateWithGradient(). - */ -BOOST_AUTO_TEST_CASE(AddDecomposableEvaluateWGradientEvaluateWithGradientTest) -{ - const bool hasEvaluate = - HasEvaluate, - DecomposableEvaluateForm>::value; - const bool hasGradient = - HasGradient, - DecomposableGradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - DecomposableEvaluateWithGradientForm>::value; - - Function f; - arma::mat coordinates(10, 10, arma::fill::ones); - arma::mat gradient; - f.Gradient(coordinates, 0, gradient, 5); - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure we add no methods when we already have all three. - */ -BOOST_AUTO_TEST_CASE(AddDecomposableEvaluateWithGradientAllThreeTest) -{ - const bool hasEvaluate = - HasEvaluate, - DecomposableEvaluateForm>::value; - const bool hasGradient = - HasGradient, - DecomposableGradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - DecomposableEvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure we can properly create EvaluateWithGradient() even when one of the - * functions is non-const. - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientMixedTypesTest) -{ - const bool hasEvaluate = - HasEvaluate, - EvaluateConstForm>::value; - const bool hasGradient = - HasGradient, - GradientForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -/** - * Make sure we can properly create EvaluateWithGradient() even when one of the - * functions is static. - */ -BOOST_AUTO_TEST_CASE(AddEvaluateWithGradientMixedTypesStaticTest) -{ - const bool hasEvaluate = - HasEvaluate, - EvaluateConstForm>::value; - const bool hasGradient = - HasGradient, - GradientStaticForm>::value; - const bool hasEvaluateWithGradient = - HasEvaluateWithGradient, - EvaluateWithGradientConstForm>::value; - - BOOST_REQUIRE_EQUAL(hasEvaluate, true); - BOOST_REQUIRE_EQUAL(hasGradient, true); - BOOST_REQUIRE_EQUAL(hasEvaluateWithGradient, true); -} - -class A -{ - public: - size_t NumFunctions() const; - size_t NumFeatures() const; - double Evaluate(const arma::mat&, const size_t, const size_t) const; - void Gradient(const arma::mat&, const size_t, arma::mat&, const size_t) const; - void Gradient(const arma::mat&, const size_t, arma::sp_mat&, const size_t) - const; - void PartialGradient(const arma::mat&, const size_t, arma::sp_mat&) const; -}; - -class B -{ - public: - size_t NumFunctions(); - size_t NumFeatures(); - double Evaluate(const arma::mat&, const size_t, const size_t); - void Gradient(const arma::mat&, const size_t, arma::mat&, const size_t); - void Gradient(const arma::mat&, const size_t, arma::sp_mat&, const size_t); - void PartialGradient(const arma::mat&, const size_t, arma::sp_mat&); -}; - -class C -{ - public: - size_t NumConstraints() const; - double Evaluate(const arma::mat&) const; - void Gradient(const arma::mat&, arma::mat&) const; - double EvaluateConstraint(const size_t, const arma::mat&) const; - void GradientConstraint(const size_t, const arma::mat&, arma::mat&) const; -}; - -class D -{ - public: - size_t NumConstraints(); - double Evaluate(const arma::mat&); - void Gradient(const arma::mat&, arma::mat&); - double EvaluateConstraint(const size_t, const arma::mat&); - void GradientConstraint(const size_t, const arma::mat&, arma::mat&); -}; - - -/** - * Test the correctness of the static check for DecomposableFunctionType API. - */ -BOOST_AUTO_TEST_CASE(DecomposableFunctionTypeCheckTest) -{ - static_assert(CheckNumFunctions::value, - "CheckNumFunctions static check failed."); - static_assert(CheckNumFunctions::value, - "CheckNumFunctions static check failed."); - static_assert(!CheckNumFunctions::value, - "CheckNumFunctions static check failed."); - static_assert(!CheckNumFunctions::value, - "CheckNumFunctions static check failed."); - - static_assert(CheckDecomposableEvaluate::value, - "CheckDecomposableEvaluate static check failed."); - static_assert(CheckDecomposableEvaluate::value, - "CheckDecomposableEvaluate static check failed."); - static_assert(!CheckDecomposableEvaluate::value, - "CheckDecomposableEvaluate static check failed."); - static_assert(!CheckDecomposableEvaluate::value, - "CheckDecomposableEvaluate static check failed."); - - static_assert(CheckDecomposableGradient::value, - "CheckDecomposableGradient static check failed."); - static_assert(CheckDecomposableGradient::value, - "CheckDecomposableGradient static check failed."); - static_assert(!CheckDecomposableGradient::value, - "CheckDecomposableGradient static check failed."); - static_assert(!CheckDecomposableGradient::value, - "CheckDecomposableGradient static check failed."); -} - -/** - * Test the correctness of the static check for LagrangianFunctionType API. - */ -BOOST_AUTO_TEST_CASE(LagrangianFunctionTypeCheckTest) -{ - static_assert(!CheckEvaluate::value, "CheckEvaluate static check failed."); - static_assert(!CheckEvaluate::value, "CheckEvaluate static check failed."); - static_assert(CheckEvaluate::value, "CheckEvaluate static check failed."); - static_assert(CheckEvaluate::value, "CheckEvaluate static check failed."); - - static_assert(!CheckGradient::value, "CheckGradient static check failed."); - static_assert(!CheckGradient::value, "CheckGradient static check failed."); - static_assert(CheckGradient::value, "CheckGradient static check failed."); - static_assert(CheckGradient::value, "CheckGradient static check failed."); - - static_assert(!CheckNumConstraints::value, - "CheckNumConstraints static check failed."); - static_assert(!CheckNumConstraints::value, - "CheckNumConstraints static check failed."); - static_assert(CheckNumConstraints::value, - "CheckNumConstraints static check failed."); - static_assert(CheckNumConstraints::value, - "CheckNumConstraints static check failed."); - - static_assert(!CheckEvaluateConstraint::value, - "CheckEvaluateConstraint static check failed."); - static_assert(!CheckEvaluateConstraint::value, - "CheckEvaluateConstraint static check failed."); - static_assert(CheckEvaluateConstraint::value, - "CheckEvaluateConstraint static check failed."); - static_assert(CheckEvaluateConstraint::value, - "CheckEvaluateConstraint static check failed."); - - static_assert(!CheckGradientConstraint::value, - "CheckGradientConstraint static check failed."); - static_assert(!CheckGradientConstraint::value, - "CheckGradientConstraint static check failed."); - static_assert(CheckGradientConstraint::value, - "CheckGradientConstraint static check failed."); - static_assert(CheckGradientConstraint::value, - "CheckGradientConstraint static check failed."); -} - -/** - * Test the correctness of the static check for SparseFunctionType API. - */ -BOOST_AUTO_TEST_CASE(SparseFunctionTypeCheckTest) -{ - static_assert(CheckSparseGradient::value, - "CheckSparseGradient static check failed."); - static_assert(CheckSparseGradient::value, - "CheckSparseGradient static check failed."); - static_assert(!CheckSparseGradient::value, - "CheckSparseGradient static check failed."); - static_assert(!CheckSparseGradient::value, - "CheckSparseGradient static check failed."); -} - -/** - * Test the correctness of the static check for SparseFunctionType API. - */ -BOOST_AUTO_TEST_CASE(ResolvableFunctionTypeCheckTest) -{ - static_assert(CheckNumFeatures::value, - "CheckNumFeatures static check failed."); - static_assert(CheckNumFeatures::value, - "CheckNumFeatures static check failed."); - static_assert(!CheckNumFeatures::value, - "CheckNumFeatures static check failed."); - static_assert(!CheckNumFeatures::value, - "CheckNumFeatures static check failed."); - - static_assert(CheckPartialGradient::value, - "CheckPartialGradient static check failed."); - static_assert(CheckPartialGradient::value, - "CheckPartialGradient static check failed."); - static_assert(!CheckPartialGradient::value, - "CheckPartialGradient static check failed."); - static_assert(!CheckPartialGradient::value, - "CheckPartialGradient static check failed."); -} - -BOOST_AUTO_TEST_SUITE_END(); From b2366ab1088cf08e6698309cb1ae3c7caae162d1 Mon Sep 17 00:00:00 2001 From: Marcus Edel Date: Wed, 3 Feb 2021 01:21:35 +0100 Subject: [PATCH 530/550] brew cask instal is no longer supported, use brew install --cask instead. --- .ci/macos-steps.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index c437344050..85e92fe3b3 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -22,7 +22,7 @@ steps: fi if [ "a$(julia.version)" != "a" ]; then - brew cask install julia + brew install --cask julia fi git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf From 0ed4da96cdb8e6ebdecf2c6f09b85f4b49c9a51f Mon Sep 17 00:00:00 2001 From: Abhinav Anand Date: Sat, 6 Feb 2021 01:32:55 +0530 Subject: [PATCH 531/550] 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 532/550] 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 533/550] 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 534/550] 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 535/550] 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 536/550] 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 537/550] 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 538/550] 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 539/550] 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 540/550] 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 541/550] 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 542/550] 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); From 1160f1f5f2b45440324e1c2e0cc2da153d1340bf Mon Sep 17 00:00:00 2001 From: Ale Presacco Date: Wed, 10 Feb 2021 17:56:26 -0600 Subject: [PATCH 543/550] Update convolution.hpp Adding a description about how the input matrix of the CNN layer should be organized --- src/mlpack/methods/ann/layer/convolution.hpp | 22 ++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index 1571c3e414..2ab22ddbfd 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -29,8 +29,26 @@ namespace ann /** Artificial Neural Network. */ { /** * Implementation of the Convolution class. The Convolution class represents a * single layer of a neural network. - * - * @tparam ForwardConvolutionRule Convolution to perform forward process. + *Example about how to organize the input matrix of the CNN. Say that I pass a matrix M(2744x100) to model.Add>, which I have obtained from "flattening" + *100 images (or Mel cepstral coefficients, if we talk about speech, or whatever you like) of dimension 196x14. In other words, the first 196 columns of each row of M + *will be made of the 196 columns of the first row of each of the 100 images (or Mel cepstral coefficients). Then the next 295 columns of M (196 - 393) will be made + *of the 196 columns of the second row of the 100 images (or Mel cepstral coefficients), etc. I want my input to be 196x14 for, so my add will be something like this: + + *model.Add> + *(1, // Number of input activation maps. + *14, // Number of output activation maps. + *3, // Filter width. + *3, // Filter height. + *1, // Stride along width. + *1, // Stride along height. + *0, // Padding width. + *0, // Padding height. + *196, // Input width. + *14 // Input height. + *); + *By doing so, will recreate the original 196x14 matrix for each image (or Mel cepstral coefficients) that will be used as input for the 14 filters of this example. + +* @tparam ForwardConvolutionRule Convolution to perform forward process. * @tparam BackwardConvolutionRule Convolution to perform backward process. * @tparam GradientConvolutionRule Convolution to calculate gradient. * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, From a2da41c0a0aaf38429b7cd06a7cb042a68aae003 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Fri, 12 Feb 2021 12:55:15 -0500 Subject: [PATCH 544/550] Update src/mlpack/methods/ann/layer/convolution.hpp --- src/mlpack/methods/ann/layer/convolution.hpp | 50 ++++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index 2ab22ddbfd..5459f34733 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -29,26 +29,36 @@ namespace ann /** Artificial Neural Network. */ { /** * Implementation of the Convolution class. The Convolution class represents a * single layer of a neural network. - *Example about how to organize the input matrix of the CNN. Say that I pass a matrix M(2744x100) to model.Add>, which I have obtained from "flattening" - *100 images (or Mel cepstral coefficients, if we talk about speech, or whatever you like) of dimension 196x14. In other words, the first 196 columns of each row of M - *will be made of the 196 columns of the first row of each of the 100 images (or Mel cepstral coefficients). Then the next 295 columns of M (196 - 393) will be made - *of the 196 columns of the second row of the 100 images (or Mel cepstral coefficients), etc. I want my input to be 196x14 for, so my add will be something like this: - - *model.Add> - *(1, // Number of input activation maps. - *14, // Number of output activation maps. - *3, // Filter width. - *3, // Filter height. - *1, // Stride along width. - *1, // Stride along height. - *0, // Padding width. - *0, // Padding height. - *196, // Input width. - *14 // Input height. - *); - *By doing so, will recreate the original 196x14 matrix for each image (or Mel cepstral coefficients) that will be used as input for the 14 filters of this example. - -* @tparam ForwardConvolutionRule Convolution to perform forward process. + * Example usage: + * + * Suppose we want to pass a matrix M (2744x100) to a `Convolution` layer; + * in this example, `M` was obtained from "flattening" 100 images (or Mel + * cepstral coefficients, if we talk about speech, or whatever you like) of + * dimension 196x14. In other words, the first 196 columns of each row of M + * will be made of the 196 columns of the first row of each of the 100 images + * (or Mel cepstral coefficients). Then the next 295 columns of M (196 - 393) + * will be made of the 196 columns of the second row of the 100 images (or Mel + * cepstral coefficients), etc. Given that the size of our 2-D input images is + * 196x14, the parameters for our `Convolution` layer will be something like + * this: + * + * ``` + * Convolution<> c(1, // Number of input activation maps. + * 14, // Number of output activation maps. + * 3, // Filter width. + * 3, // Filter height. + * 1, // Stride along width. + * 1, // Stride along height. + * 0, // Padding width. + * 0, // Padding height. + * 196, // Input width. + * 14); // Input height. + * ``` + * + * This `Convolution<>` layer will treat each column of the input matrix `M` as * a 2-D image (or object) of the original 196x14 size, using this as the input + * for the 14 filters of this example. + * + * @tparam ForwardConvolutionRule Convolution to perform forward process. * @tparam BackwardConvolutionRule Convolution to perform backward process. * @tparam GradientConvolutionRule Convolution to calculate gradient. * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, From 517a3a5e8d1ccfa75fa90e6e4e2239fa0494585b Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Sun, 14 Feb 2021 12:54:35 +0530 Subject: [PATCH 545/550] Added Hard Swish Function Implementation and Test Skeleton --- .../ann/activation_functions/CMakeLists.txt | 1 + .../hard_swish_function.hpp | 116 ++++++++++++++++++ .../tests/activation_functions_test.cpp | 20 +++ 3 files changed, 137 insertions(+) create mode 100644 src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp diff --git a/src/mlpack/methods/ann/activation_functions/CMakeLists.txt b/src/mlpack/methods/ann/activation_functions/CMakeLists.txt index fd4e765006..d5c0868c1c 100644 --- a/src/mlpack/methods/ann/activation_functions/CMakeLists.txt +++ b/src/mlpack/methods/ann/activation_functions/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES multi_quadratic_function.hpp poisson1_function.hpp gaussian_function.hpp + hard_swish_function.hpp ) # Add directory name to sources. diff --git a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp new file mode 100644 index 0000000000..d3526da428 --- /dev/null +++ b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp @@ -0,0 +1,116 @@ +/** + * @file methods/ann/activation_functions/hard_swish_function.hpp + * @author Anush Kini + * + * Definition and implementation of the Hard Swish function as described by + * Howard A, Sandler M, Chu G, Chen LC, Chen B, Tan M, Wang W, Zhu Y, Pang R, + * Vasudevan V and Le QV. + * For more information, see the following paper. + * + * @code + * @misc{ + * author = {Howard A, Sandler M, Chu G, Chen LC, Chen B, Tan M, Wang W, + * Zhu Y, Pang R, Vasudevan V and Le QV}, + * title = {Searching for MobileNetV3}, + * year = {2019} + * } + * @endcode + * + * 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_ACTIVATION_FUNCTIONS_HARD_SWISH_FUNCTION_HPP +#define MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_HARD_SWISH_FUNCTION_HPP + +#include + +namespace mlpack { +namespace ann /** Artificial Neural Network. */ { +/** + * The Hard Swish function, defined by + * + * @f{eqnarray*}{ + * f(x) &=& \begin{cases} + * 0 & x \leq -3\\ + * x & x \geq +3\\ + * \frac{x * (x + 3)}{6} & otherwise\\ + * \end{cases} \\ + * f'(x) &=& \begin{cases} + * 0 & x \leq -3\\ + * 1 & x \geq +3\\ + * \frac{2x + 3}{6} & otherwise\\ + * \end{cases} + * @f} + */ +class HardSwishFunction +{ + public: + /** + * Computes the Hard Swish function. + * + * @param x Input data. + * @return f(x). + */ + static double Fn(const double x) + { + double x2 = x + 3.0; + x2 = x2 > 0.0 ? x2 : 0.0; + x2 = x2 < 6.0 ? x2 : 6.0; + x2 = x * x2 / 6.0; + + return x2; + } + + /** + * Computes the Hard Swish function. + * + * @param x Input data. + * @param y The resulting output activation. + */ + template + static void Fn(const InputVecType &x, OutputVecType &y) + { + y.set_size(size(x)); + + for (size_t i = 0; i < x.n_elem; i++) + y(i) = Fn(x(i)); + } + + /** + * Computes the first derivative of the Hard Swish function. + * + * @param y Input data. + * @return f'(x). + */ + static double Deriv(const double y) + { + if (y <= -3) + return 0; + else if (y >= 3) + return 1; + + return (2*y + 3.0)/6.0; + } + + /** + * Computes the first derivatives of the Hard Swish function. + * + * @param y Input activations. + * @param x The resulting derivatives. + */ + template + static void Deriv(const InputVecType &y, OutputVecType &x) + { + x.set_size(size(y)); + + for (size_t i = 0; i < y.n_elem; i++) + x(i) = Deriv(y(i)); + } +}; // class HardSwishFunction + +} // namespace ann +} // namespace mlpack + +#endif diff --git a/src/mlpack/tests/activation_functions_test.cpp b/src/mlpack/tests/activation_functions_test.cpp index d88c0a5109..f99f9781e8 100644 --- a/src/mlpack/tests/activation_functions_test.cpp +++ b/src/mlpack/tests/activation_functions_test.cpp @@ -1134,3 +1134,23 @@ TEST_CASE("SoftminFunctionTest", "[ActivationFunctionsTest]") CheckSoftminDerivativeCorrect(activationData, desiredDerivatives); } + +/** + * Basic test of the Hard Swish function. + */ +TEST_CASE("HardSwishFunctionTest", "[ActivationFunctionsTest]") +{ + // Randomly generated data. + const arma::colvec activationData("3.6544 -1.9714 -5.2277 1.5448 2.1164"); + + // Calculated from torch.nn.Hardswish. + const arma::colvec desiredActivations("3.6544 -0.3380 0 1.1701 1.8047"); + + // Hand Calculated Values. + const arma::colvec desiredDerivatives("1 "); + + CheckSoftminActivationCorrect(activationData, + desiredActivations); + CheckSoftminDerivativeCorrect(activationData, + desiredDerivatives); +} From 990803af2b4904279c49cd2374e13f2918be21f9 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Sun, 14 Feb 2021 19:31:57 +0530 Subject: [PATCH 546/550] Fixes for failing test --- src/mlpack/methods/ann/layer/base_layer.hpp | 13 +++++++++++++ src/mlpack/tests/activation_functions_test.cpp | 16 +++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/mlpack/methods/ann/layer/base_layer.hpp b/src/mlpack/methods/ann/layer/base_layer.hpp index 8429c818a7..ae49f30fe6 100644 --- a/src/mlpack/methods/ann/layer/base_layer.hpp +++ b/src/mlpack/methods/ann/layer/base_layer.hpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace mlpack { namespace ann /** Artificial Neural Network. */ { @@ -50,6 +51,7 @@ namespace ann /** Artificial Neural Network. */ { * - ELiSHLayer * - ElliotLayer * - GaussianLayer + * - HardSwishLayer * * @tparam ActivationFunction Activation function used for the embedding layer. * @tparam InputDataType Type of the input data (arma::colvec, arma::mat, @@ -277,6 +279,17 @@ template < using GaussianFunctionLayer = BaseLayer< ActivationFunction, InputDataType, OutputDataType>; +/** + * Standard HardSwish-Layer using the HardSwish activation function. + */ +template < + class ActivationFunction = HardSwishFunction, + typename InputDataType = arma::mat, + typename OutputDataType = arma::mat +> +using HardSwishFunctionLayer = BaseLayer< + ActivationFunction, InputDataType, OutputDataType>; + } // namespace ann } // namespace mlpack diff --git a/src/mlpack/tests/activation_functions_test.cpp b/src/mlpack/tests/activation_functions_test.cpp index f99f9781e8..56682880da 100644 --- a/src/mlpack/tests/activation_functions_test.cpp +++ b/src/mlpack/tests/activation_functions_test.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "catch.hpp" @@ -1143,14 +1144,15 @@ TEST_CASE("HardSwishFunctionTest", "[ActivationFunctionsTest]") // Randomly generated data. const arma::colvec activationData("3.6544 -1.9714 -5.2277 1.5448 2.1164"); - // Calculated from torch.nn.Hardswish. - const arma::colvec desiredActivations("3.6544 -0.3380 0 1.1701 1.8047"); + // Hand Calculated Values. from torch.nn.Hardswish. + const arma::colvec desiredActivations("3.6544 -0.3379636 0.0 \ + 1.1701345 1.8047248"); // Hand Calculated Values. - const arma::colvec desiredDerivatives("1 "); + const arma::colvec desiredDerivatives("1.0 0.38734546 0.5 \ + 0.89004483 1.1015749"); - CheckSoftminActivationCorrect(activationData, - desiredActivations); - CheckSoftminDerivativeCorrect(activationData, - desiredDerivatives); + CheckActivationCorrect(activationData, desiredActivations); + CheckDerivativeCorrect + (desiredActivations, desiredDerivatives); } From 665c750e1f56a12cf014eac180b1862a9b9efaa1 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Sun, 14 Feb 2021 22:48:25 +0530 Subject: [PATCH 547/550] Some more comment fixes --- .../methods/ann/activation_functions/hard_swish_function.hpp | 2 +- src/mlpack/tests/activation_functions_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp index d3526da428..f2780aac6e 100644 --- a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp +++ b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp @@ -97,7 +97,7 @@ class HardSwishFunction /** * Computes the first derivatives of the Hard Swish function. * - * @param y Input activations. + * @param y Input data. * @param x The resulting derivatives. */ template diff --git a/src/mlpack/tests/activation_functions_test.cpp b/src/mlpack/tests/activation_functions_test.cpp index 56682880da..20631566e9 100644 --- a/src/mlpack/tests/activation_functions_test.cpp +++ b/src/mlpack/tests/activation_functions_test.cpp @@ -1144,7 +1144,7 @@ TEST_CASE("HardSwishFunctionTest", "[ActivationFunctionsTest]") // Randomly generated data. const arma::colvec activationData("3.6544 -1.9714 -5.2277 1.5448 2.1164"); - // Hand Calculated Values. from torch.nn.Hardswish. + // Hand Calculated Values. const arma::colvec desiredActivations("3.6544 -0.3379636 0.0 \ 1.1701345 1.8047248"); From 3856cdd00ca20995a06d0f16a20935fde538b60e Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Mon, 15 Feb 2021 10:03:06 +0530 Subject: [PATCH 548/550] Review fixes --- .../methods/ann/activation_functions/hard_swish_function.hpp | 2 +- src/mlpack/tests/activation_functions_test.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp index f2780aac6e..d308358f31 100644 --- a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp +++ b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp @@ -91,7 +91,7 @@ class HardSwishFunction else if (y >= 3) return 1; - return (2*y + 3.0)/6.0; + return (2 * y + 3.0) / 6.0; } /** diff --git a/src/mlpack/tests/activation_functions_test.cpp b/src/mlpack/tests/activation_functions_test.cpp index 20631566e9..5e4c5aa217 100644 --- a/src/mlpack/tests/activation_functions_test.cpp +++ b/src/mlpack/tests/activation_functions_test.cpp @@ -1144,11 +1144,11 @@ TEST_CASE("HardSwishFunctionTest", "[ActivationFunctionsTest]") // Randomly generated data. const arma::colvec activationData("3.6544 -1.9714 -5.2277 1.5448 2.1164"); - // Hand Calculated Values. + // Hand-calculated values. const arma::colvec desiredActivations("3.6544 -0.3379636 0.0 \ 1.1701345 1.8047248"); - // Hand Calculated Values. + // Hand-calculated values. const arma::colvec desiredDerivatives("1.0 0.38734546 0.5 \ 0.89004483 1.1015749"); From e29da13c01d03986dff8f9ef3d502ba48e294362 Mon Sep 17 00:00:00 2001 From: Ryan Curtin Date: Mon, 15 Feb 2021 16:33:30 -0500 Subject: [PATCH 549/550] Update src/mlpack/methods/ann/layer/convolution.hpp Co-authored-by: Marcus Edel --- src/mlpack/methods/ann/layer/convolution.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/ann/layer/convolution.hpp b/src/mlpack/methods/ann/layer/convolution.hpp index 5459f34733..5ea92f37ea 100644 --- a/src/mlpack/methods/ann/layer/convolution.hpp +++ b/src/mlpack/methods/ann/layer/convolution.hpp @@ -55,7 +55,8 @@ namespace ann /** Artificial Neural Network. */ { * 14); // Input height. * ``` * - * This `Convolution<>` layer will treat each column of the input matrix `M` as * a 2-D image (or object) of the original 196x14 size, using this as the input + * This `Convolution<>` layer will treat each column of the input matrix `M` as + * a 2-D image (or object) of the original 196x14 size, using this as the input * for the 14 filters of this example. * * @tparam ForwardConvolutionRule Convolution to perform forward process. From 1994c4fc419e0623938039389fba90e571e56940 Mon Sep 17 00:00:00 2001 From: Anush V Kini Date: Thu, 18 Feb 2021 11:15:15 +0530 Subject: [PATCH 550/550] Fn implementation changed to if else statements --- .../ann/activation_functions/hard_swish_function.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp index d308358f31..d387e86474 100644 --- a/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp +++ b/src/mlpack/methods/ann/activation_functions/hard_swish_function.hpp @@ -55,12 +55,12 @@ class HardSwishFunction */ static double Fn(const double x) { - double x2 = x + 3.0; - x2 = x2 > 0.0 ? x2 : 0.0; - x2 = x2 < 6.0 ? x2 : 6.0; - x2 = x * x2 / 6.0; + if (x <= -3) + return 0; + else if (x >= 3) + return x; - return x2; + return x * (x + 3) / 6; } /**