Merge branch 'master' of https://github.com/KARTHEEKCIC/mlpack into KARTHEEKCIC-master

This commit is contained in:
Ryan Curtin
2018-02-15 09:15:09 -05:00
7 changed files with 870 additions and 0 deletions
+1
View File
@@ -90,6 +90,7 @@ Copyright:
Copyright 2018, Projyal Dev <projyal@gmail.com>
Copyright 2018, Nikhil Goel <nikhilgoel199797@gmail.com>
Copyright 2018, Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
Copyright 2018, B Kartheek Reddy <bkartheekreddy@gmail.com>
License: BSD-3-clause
All rights reserved.
+1
View File
@@ -233,6 +233,7 @@
* - Projyal Dev <projyal@gmail.com>
* - Nikhil Goel <nikhilgoel199797@gmail.com>
* - Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
* - B Kartheek Reddy <bkartheekreddy@gmail.com>
*/
// First, include all of the prerequisites.
@@ -161,6 +161,14 @@ static void mlpackMain()
ReportIgnoredParam({{ "test", false }}, "output");
ReportIgnoredParam({{ "test", false }}, "output_probabilities");
// Max Iterations needs to be positive.
RequireParamValue<int>("max_iterations", [](int x) { return x >= 0; },
true, "max_iterations must be positive or zero");
// Batch Size needs to be greater than zero.
RequireParamValue<int>("batch_size", [](int x) { return x > 0; },
true, "batch_size must be greater than zero");
// Tolerance needs to be positive.
RequireParamValue<double>("tolerance", [](double x) { return x >= 0.0; },
true, "tolerance must be positive or zero");
@@ -230,6 +238,13 @@ static void mlpackMain()
}
else if (CLI::HasParam("training"))
{
// Checking the size of training data if no labels are passed.
if (regressors.n_rows < 2)
{
Log::Fatal << "Can't get responses from training data "
"since it has less than 2 rows." << endl;
}
// The initial predictors for y, Nx1.
responses = arma::conv_to<arma::Row<size_t>>::from(
regressors.row(regressors.n_rows - 1));
@@ -274,6 +289,14 @@ static void mlpackMain()
{
testSet = std::move(CLI::GetParam<arma::mat>("test"));
// Checking the dimensionality of the test data.
if (testSet.n_rows != model->Parameters().n_cols - 1)
{
Log::Fatal << "Test data dimensionality (" << testSet.n_rows << ") must "
<< "be the same as the dimensionality of the Training Data ("
<< model->Parameters().n_cols-1 << ")!" << endl;
}
// We must perform predictions on the test set. Training (and the
// optimizer) are irrelevant here; we'll pass in the model we have.
if (CLI::HasParam("output"))
@@ -177,9 +177,23 @@ static void mlpackMain()
if (CLI::HasParam("labels"))
{
labelsIn = std::move(CLI::GetParam<Row<size_t>>("labels"));
// Checking the size of the responses and training data.
if (labelsIn.n_cols != trainingData.n_cols)
{
Log::Fatal << "The responses must have the same number of columns "
"as the training set." << endl;
}
}
else
{
// Checking the size of training data if no labels are passed.
if (trainingData.n_rows < 2)
{
Log::Fatal << "Can't get responses from training data "
"since it has less than 2 rows." << endl;
}
// Use the last row of the training data as the labels.
Log::Info << "Using the last dimension of training set as labels."
<< endl;
+1
View File
@@ -133,6 +133,7 @@ add_executable(mlpack_test
main_tests/decision_tree_test.cpp
main_tests/decision_stump_test.cpp
main_tests/linear_regression_test.cpp
main_tests/logistic_regression_test.cpp
main_tests/nbc_test.cpp
main_tests/pca_test.cpp
main_tests/perceptron_test.cpp
@@ -0,0 +1,650 @@
/**
* @file logistic_regression_test.cpp
* @author B Kartheek Reddy
*
* Test mlpackMain() of logistic_regression_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
static const std::string testName = "LogisticRegression";
#include <mlpack/core.hpp>
#include <mlpack/methods/logistic_regression/logistic_regression_main.cpp>
#include <mlpack/core/util/mlpack_main.hpp>
#include "test_helper.hpp"
#include <boost/test/unit_test.hpp>
using namespace mlpack;
struct LogisticRegressionTestFixture
{
public:
LogisticRegressionTestFixture()
{
// Cache in the options for this program.
CLI::RestoreSettings(testName);
}
~LogisticRegressionTestFixture()
{
// Clear the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
}
};
BOOST_FIXTURE_TEST_SUITE(LogisticRegressionMainTest,
LogisticRegressionTestFixture);
/**
* Ensuring that absence of training data is checked.
**/
BOOST_AUTO_TEST_CASE(LRNoTrainingData)
{
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr;
SetInputParam("labels", std::move(trainY));
// Training data is not provided. Should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that absence of responses is checked.
*/
BOOST_AUTO_TEST_CASE(LRNoResponses)
{
constexpr int N = 10;
constexpr int D = 1;
arma::mat trainX = arma::randu<arma::mat>(D, N);
SetInputParam("training", std::move(trainX));
// Labels to the training data is not provided. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Checking that that size and dimensionality of prediction is correct.
*/
BOOST_AUTO_TEST_CASE(LRPridictionSizeCheck)
{
constexpr int N = 10;
constexpr int D = 3;
constexpr int M = 15;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr;
arma::mat testX = arma::randu<arma::mat>(D, M);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("test", std::move(testX));
// Training the model.
mlpackMain();
// Get the output predictions of the test data.
const arma::Row<size_t> &testY = CLI::GetParam<arma::Row<size_t>>("output");
// Output predictions size must match the test data set size.
BOOST_REQUIRE_EQUAL(testY.n_rows, 1);
BOOST_REQUIRE_EQUAL(testY.n_cols, M);
}
/**
* Ensuring that the response size is checked.
**/
BOOST_AUTO_TEST_CASE(LRWrongResponseSizeTest)
{
constexpr int D = 3;
constexpr int N = 10;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY; // Response vector with wrong size.
// 8 responses - incorrect size.
trainY << 0 << 0 << 1 << 0 << 1 << 1 << 1 << 0 << arma::endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
// Labels with incorrect size. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Checking two options of specifying responses (extra row in train matrix and
* extra parameter) and ensuring that predictions are the same.
*/
BOOST_AUTO_TEST_CASE(LRResponsesRepresentationTest)
{
arma::mat trainX1({{1.0, 2.0, 3.0}, {1.0, 4.0, 9.0}, {0, 1, 1}});
arma::mat testX({{4.0, 5.0}, {1.0, 6.0}});
SetInputParam("training", std::move(trainX1));
SetInputParam("test", testX);
// The first solution.
mlpackMain();
// Get the output.
const arma::Row<size_t> testY1 =
std::move(CLI::GetParam<arma::Row<size_t>>("output"));
// Reset the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
CLI::RestoreSettings(testName);
// Now train by providing labels as extra parameter.
arma::mat trainX2({{1.0, 2.0, 3.0}, {1.0, 4.0, 9.0}});
arma::Row<size_t> trainY2({0, 1, 1});
SetInputParam("training", std::move(trainX2));
SetInputParam("labels", std::move(trainY2));
SetInputParam("test", std::move(testX));
// The second solution.
mlpackMain();
// get the output
const arma::Row<size_t> &testY2 =
CLI::GetParam<arma::Row<size_t>>("output");
// Both solutions should be equal.
BOOST_REQUIRE_EQUAL_COLLECTIONS(testY1.begin(), testY1.end(),
testY2.begin(), testY2.end());
}
/**
* Check that model can saved / loaded and used. Ensuring that results are the
* same.
*/
BOOST_AUTO_TEST_CASE(LRModelReload)
{
constexpr int N = 10;
constexpr int D = 3;
constexpr int M = 15;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr;
arma::mat testX = arma::randu<arma::mat>(D, M);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("test", testX);
// First solution
mlpackMain();
// Get the output model obtained from training.
LogisticRegression<>* model =
CLI::GetParam<LogisticRegression<>*>("output_model");
// Get the output.
const arma::Row<size_t> testY1 =
std::move(CLI::GetParam<arma::Row<size_t>>("output"));
// Reset the data passed.
CLI::GetSingleton().Parameters()["training"].wasPassed = false;
CLI::GetSingleton().Parameters()["labels"].wasPassed = false;
CLI::GetSingleton().Parameters()["test"].wasPassed = false;
SetInputParam("input_model", model);
SetInputParam("test", std::move(testX));
// Second solution.
mlpackMain();
// Get the output.
const arma::Row<size_t> &testY2 =
CLI::GetParam<arma::Row<size_t>>("output");
// Both solutions must be equal.
BOOST_REQUIRE_EQUAL_COLLECTIONS(testY1.begin(), testY1.end(),
testY2.begin(), testY2.end());
}
/**
* Checking for dimensionality of the test data set.
**/
BOOST_AUTO_TEST_CASE(LRWrongDimOfTestData)
{
constexpr int N = 10;
constexpr int D = 4;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr;
// Test data with wrong dimensionality.
arma::mat testX = arma::randu<arma::mat>(D-1, N);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("test", std::move(testX));
// Dimensionality of test data is wrong. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that test data dimensionality is checked when model is loaded.
*/
BOOST_AUTO_TEST_CASE(LRWrongDimOfTestData2)
{
constexpr int N = 10;
constexpr int D = 3;
constexpr int M = 15;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
// Training the model.
mlpackMain();
// Get the output model obtained from training.
LogisticRegression<>* model =
CLI::GetParam<LogisticRegression<>*>("output_model");
// Reset the data passed.
CLI::GetSingleton().Parameters()["training"].wasPassed = false;
CLI::GetSingleton().Parameters()["labels"].wasPassed = false;
// Test data with Wrong dimensionality.
arma::mat testX = arma::randu<arma::mat>(D - 1, M);
SetInputParam("input_model", model);
SetInputParam("test", std::move(testX));
// Test data dimensionality is wrong. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that training responses contain only two classes (0 or 1).
**/
BOOST_AUTO_TEST_CASE(LRTrainWithMoreThanTwoClasses)
{
constexpr int N = 8;
constexpr int D = 2;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 8 responses containing more than two classes.
trainY << 0 << 1 << 0 << 1 << 2 << 1 << 3 << 1 << arma::endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
// Training data contains more than two classes. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that max iteration for optimizers is non negative.
**/
BOOST_AUTO_TEST_CASE(LRNonNegativeMaxIterationTest)
{
constexpr int N = 10;
constexpr int D = 3;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << arma::endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("max_iterations", int(-1));
// Maximum iterations is negative. It should a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that step size for optimizer is non negative.
**/
BOOST_AUTO_TEST_CASE(LRNonNegativeStepSizeTest)
{
constexpr int N = 10;
constexpr int D = 2;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("optimizer", std::string("sgd"));
SetInputParam("step_size", double(-0.01));
// Step size for optimizer is negative. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that tolerance is non negative.
**/
BOOST_AUTO_TEST_CASE(LRNonNegativeToleranceTest)
{
constexpr int N = 10;
constexpr int D = 3;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 1 << 1 << 0 << 1 << 0 << 0 << 0 << 1 << 0 << 1 << arma::endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("tolerance", double(-0.01));
// Tolerance is negative. It should throw a runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring changing Maximum number of iterations changes the output model.
**/
BOOST_AUTO_TEST_CASE(LRMaxIterationsChangeTest)
{
constexpr int N = 10;
constexpr int D = 3;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr;
SetInputParam("training", trainX);
SetInputParam("labels", trainY);
SetInputParam("max_iterations", int(1));
// First solution.
mlpackMain();
// Get the parameters of the output model obtained after first training.
const arma::rowvec parameters1 =
std::move(CLI::GetParam<LogisticRegression<>*>("output_model")
->Parameters());
// Reset the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
CLI::RestoreSettings(testName);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("max_iterations", int(100));
// Second solution.
mlpackMain();
// Get the parameters of the output model obtained after second training.
const arma::rowvec &parameters2 =
CLI::GetParam<LogisticRegression<>*>("output_model")->Parameters();
// Check that the parameters (parameters1 and parameters2) are not equal
// which ensures Max Iteration changes the output model.
// arma::all function checks that each element of the vector is equal to zero.
BOOST_REQUIRE_MESSAGE(!arma::all((parameters1-parameters2) == 0),
"Parameter(Max Iteration) has no effect on the output");
}
/**
* Ensuring that lambda has some effects on the output.
**/
BOOST_AUTO_TEST_CASE(LRLambdaChangeTest)
{
constexpr int N = 10;
constexpr int D = 4;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr;
SetInputParam("training", trainX);
SetInputParam("labels", trainY);
SetInputParam("lambda", double(0));
// First solution.
mlpackMain();
// Get the parameters of the output model obtained after first training.
const arma::rowvec parameters1 =
std::move(CLI::GetParam<LogisticRegression<>*>("output_model")
->Parameters());
// Reset the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
CLI::RestoreSettings(testName);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("lambda", double(1000));
// Second solution.
mlpackMain();
// Get the parameters of the output model obtained after second training.
const arma::rowvec &parameters2 =
CLI::GetParam<LogisticRegression<>*>("output_model")->Parameters();
// Check that the parameters (parameters1 and parameters2) are not equal
// which ensures lambda changes the output model.
// arma::all function checks that each element of the vector is equal to zero.
BOOST_REQUIRE_MESSAGE(!arma::all((parameters1-parameters2) == 0),
"Parameter(lambda) has no effect on the output");
}
/**
* Ensuring that Step size has some effects on the output.
**/
BOOST_AUTO_TEST_CASE(LRStepSizeChangeTest)
{
constexpr int N = 10;
constexpr int D = 3;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr;
SetInputParam("training", trainX);
SetInputParam("labels", trainY);
SetInputParam("optimizer", std::string("sgd"));
SetInputParam("step_size", double(0.02));
// First solution.
mlpackMain();
// Get the parameters of the output model obtained after first training.
const arma::rowvec parameters1 =
std::move(CLI::GetParam<LogisticRegression<>*>("output_model")
->Parameters());
// Reset the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
CLI::RestoreSettings(testName);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("optimizer", std::string("sgd"));
SetInputParam("step_size", double(1.02));
// Second solution.
mlpackMain();
// Get the parameters of the output model obtained after second training.
const arma::rowvec &parameters2 =
CLI::GetParam<LogisticRegression<>*>("output_model")->Parameters();
// Check that the parameters (parameters1 and parameters2) are not equal
// which ensures Step Size changes the output model.
// arma::all function checks that each element of the vector is equal to zero.
BOOST_REQUIRE_MESSAGE(!arma::all((parameters1-parameters2) == 0),
"Parameter(Step Size) has no effect on the output");
}
/**
* Ensuring that lbfgs optimizer converges to a different result than sgd.
**/
BOOST_AUTO_TEST_CASE(LROptimizerChangeTest)
{
constexpr int N = 10;
constexpr int D = 3;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr;
SetInputParam("training", trainX);
SetInputParam("labels", trainY);
SetInputParam("optimizer", std::string("lbfgs"));
SetInputParam("max_iterations", int(1000));
// First solution.
mlpackMain();
// Get the parameters of the output model obtained after first training.
const arma::rowvec parameters1 =
std::move(CLI::GetParam<LogisticRegression<>*>("output_model")
->Parameters());
// Reset the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
CLI::RestoreSettings(testName);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("optimizer", std::string("sgd"));
SetInputParam("max_iterations", int(1000));
// Second solution.
mlpackMain();
// Get the parameters of the output model obtained after second training.
const arma::rowvec &parameters2 =
CLI::GetParam<LogisticRegression<>*>("output_model")->Parameters();
// Check that the parameters (parameters1 and parameters2) are not equal which
// ensures that different optimizer converge to different results.
// arma::all function checks that each element of the vector is equal to zero.
BOOST_REQUIRE_MESSAGE(!arma::all((parameters1-parameters2) == 0),
"Parameter(Step Size) has no effect on the output");
}
/**
* Ensuring decision_boundary parameter does something.
**/
BOOST_AUTO_TEST_CASE(LRDecisionBoundaryTest)
{
constexpr int N = 10;
constexpr int D = 3;
constexpr int M = 15;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 1 << 0 << 0 << 1 << 0 << 1 << 0 << 1 << 0 << 1 << arma::endr;
arma::mat testX = arma::randu<arma::mat>(D, M);
SetInputParam("training", trainX);
SetInputParam("labels", trainY);
SetInputParam("decision_boundary", double(1));
SetInputParam("test", testX);
// First solution.
mlpackMain();
// Get the output after first training.
const arma::Row<size_t> &output1 = CLI::GetParam<arma::Row<size_t>>("output");
// Check that the parameters (parameters1 and parameters2) are not equal which
// ensures that decision boundary has some effect on the output.
// arma::all function checks that each element of the vector is equal to zero.
BOOST_REQUIRE_MESSAGE(arma::all(output1 == 0),
"Parameter(Decision Boudary) has"
"no effect on the output");
// Reset the settings.
bindings::tests::CleanMemory();
CLI::ClearSettings();
CLI::RestoreSettings(testName);
SetInputParam("training", trainX);
SetInputParam("labels", trainY);
SetInputParam("decision_boundary", double(0));
SetInputParam("test", testX);
// Second solution.
mlpackMain();
// Get the output after second training.
const arma::Row<size_t> &output2 = CLI::GetParam<arma::Row<size_t>>("output");
// Check that the parameters (parameters1 and parameters2) are not equal which
// ensures that decision boundary has som effect on the output.
// arma::all function checks that each element of the vector is equal to one.
BOOST_REQUIRE_MESSAGE(arma::all(output2 == 1),
"Parameter(Decision Boudary) has"
"no effect on the output");
}
BOOST_AUTO_TEST_SUITE_END();
@@ -232,4 +232,184 @@ BOOST_AUTO_TEST_CASE(PerceptronMaxItrTest)
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that re-training of an existing model
* with different of classes is checked.
**/
BOOST_AUTO_TEST_CASE(PerceptronReTrainWithWrongClasses)
{
arma::mat trainX1;
arma::Row<size_t> labelsX1;
// Loading a train data set with 3 classes.
if (!data::Load("vc2.csv", trainX1))
{
BOOST_FAIL("Could not load the train data (vc2.csv)");
}
// Loading the corresponding labels to the dataset.
if (!data::Load("vc2_labels.txt", labelsX1))
{
BOOST_FAIL("Could not load the train data (vc2_labels.csv)");
}
SetInputParam("training", std::move(trainX1)); // Training data.
// Labels for the training data.
SetInputParam("labels", std::move(labelsX1));
// Training model using first training dataset.
mlpackMain();
// Get the output model obtained after training.
PerceptronModel* model =
CLI::GetParam<PerceptronModel*>("output_model");
// Reset the data passed.
CLI::GetSingleton().Parameters()["training"].wasPassed = false;
CLI::GetSingleton().Parameters()["labels"].wasPassed = false;
// Creating training data with five classes.
constexpr int D = 3;
constexpr int N = 10;
arma::mat trainX2 = arma::randu<arma::mat>(D, N);
arma::Row<size_t> labelsX2;
// 10 responses.
labelsX2 << 0 << 1 << 4 << 1 << 2 << 1 << 0 << 3 << 3 << 0 << endr;
// Last column of trainX2 contains the class labels.
SetInputParam("training", std::move(trainX2));
SetInputParam("input_model", model);
// Re-training an existing model of 3 classes
// with training data of 5 classes. It should give runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Checking for dimensionality of the test data set.
**/
BOOST_AUTO_TEST_CASE(PerceptronWrongDimOfTestData)
{
constexpr int N = 10;
constexpr int D = 4;
constexpr int M = 20;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << endr;
// Test data with wrong dimensionality.
arma::mat testX = arma::randu<arma::mat>(D-3, M);
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
SetInputParam("test", std::move(testX));
// Test data set with wrong dimensionality. It should give runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that the response size is checked.
**/
BOOST_AUTO_TEST_CASE(PerceptronWrongResponseSizeTest)
{
constexpr int D = 2;
constexpr int N = 10;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY; // Response vector with wrong size.
// 8 responses.
trainY << 0 << 0 << 1 << 0 << 1 << 1 << 1 << 0 << endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
// Labels for training data have wrong size. It should give runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that absence of responses is checked.
*/
BOOST_AUTO_TEST_CASE(PerceptronNoResponsesTest)
{
constexpr int N = 10;
constexpr int D = 1;
arma::mat trainX = arma::randu<arma::mat>(D, N);
SetInputParam("training", std::move(trainX));
// No labels for training data. It should give runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that absence of training data is checked.
*/
BOOST_AUTO_TEST_CASE(PerceptronNoTrainingDataTest)
{
arma::Row<size_t> trainY;
trainY << 1 << 1 << 0 << 1 << 0 << 0 <<endr;
SetInputParam("labels", std::move(trainY));
// No training data. It should give runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
/**
* Ensuring that test data dimensionality is checked when model is loaded.
*/
BOOST_AUTO_TEST_CASE(PerceptronWrongDimOfTestData2)
{
constexpr int N = 10;
constexpr int D = 3;
constexpr int M = 15;
arma::mat trainX = arma::randu<arma::mat>(D, N);
arma::Row<size_t> trainY;
// 10 responses.
trainY << 0 << 1 << 0 << 1 << 1 << 1 << 0 << 1 << 0 << 0 << endr;
SetInputParam("training", std::move(trainX));
SetInputParam("labels", std::move(trainY));
// Training the model.
mlpackMain();
// Get the output model obtained after the training.
PerceptronModel* model =
CLI::GetParam<PerceptronModel*>("output_model");
// Reset the data passed.
CLI::GetSingleton().Parameters()["training"].wasPassed = false;
CLI::GetSingleton().Parameters()["labels"].wasPassed = false;
// Test data with Wrong dimensionality.
arma::mat testX = arma::randu<arma::mat>(D - 1, M);
SetInputParam("input_model", model);
SetInputParam("test", std::move(testX));
// Wrong dimensionality of test data. It should give runtime error.
Log::Fatal.ignoreInput = true;
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
Log::Fatal.ignoreInput = false;
}
BOOST_AUTO_TEST_SUITE_END();