Merge branch 'master' into cereal
Signed-off-by: Omar Shrit <omar@shrit.me>
This commit is contained in:
@@ -8,13 +8,31 @@ on:
|
||||
- master
|
||||
release:
|
||||
types: [published, created, edited]
|
||||
name: R CMD check mlpack
|
||||
|
||||
jobs:
|
||||
cancel:
|
||||
name: 'Cancel Previous Builds'
|
||||
if: ${{ github.event_name == 'pull_request' && github.repository == 'mlpack/mlpack' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 3
|
||||
steps:
|
||||
- name: Get all workflow ids and set to env variable
|
||||
run: echo ::set-env name=WORKFLOW_IDS_TO_CANCEL::$(curl https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/workflows -s | jq -r '.workflows | map(.id|tostring) | join(",")')
|
||||
|
||||
- uses: styfle/cancel-workflow-action@0.5.0
|
||||
with:
|
||||
workflow_id: ${{ env.WORKFLOW_IDS_TO_CANCEL }}
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobR:
|
||||
name: mlpack-R
|
||||
name: Build mlpack_r_tarball
|
||||
if: ${{ github.repository == 'mlpack/mlpack' }}
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
outputs:
|
||||
r_bindings: ${{ steps.mlpack_version.outputs.mlpack_r_package }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -27,6 +45,23 @@ jobs:
|
||||
MLPACK_VERSION_VALUE=${MLPACK_VERSION_MAJOR}.${MLPACK_VERSION_MINOR}.${MLPACK_VERSION_PATCH}
|
||||
echo ::set-output name=mlpack_r_package::$(echo mlpack_"$MLPACK_VERSION_VALUE".tar.gz)
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
with:
|
||||
r-version: release
|
||||
|
||||
- name: Query dependencies
|
||||
run: |
|
||||
cp src/mlpack/bindings/R/mlpack/DESCRIPTION.in DESCRIPTION
|
||||
Rscript -e "install.packages('remotes')" -e "saveRDS(remotes::dev_package_deps(dependencies = TRUE), 'depends.Rds')"
|
||||
|
||||
- name: Cache R packages
|
||||
if: runner.os != 'Windows'
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-release-${{ hashFiles('depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-r-release-
|
||||
|
||||
- name: Install Build Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
@@ -38,6 +73,12 @@ jobs:
|
||||
sudo apt-get install -y r-base-core
|
||||
sudo Rscript -e "install.packages(c('Rcpp', 'RcppArmadillo', 'RcppEnsmallen', 'BH', 'roxygen2', 'testthat', 'Rcereal'))"
|
||||
|
||||
- name: Install R-bindings dependencies
|
||||
run: |
|
||||
remotes::install_deps(dependencies = TRUE)
|
||||
remotes::install_cran("roxygen2")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
mkdir build
|
||||
@@ -58,6 +99,7 @@ jobs:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
||||
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
|
||||
if: ${{ github.repository == 'mlpack/mlpack' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -74,6 +116,8 @@ jobs:
|
||||
R_CHECK_ARGS: "--no-build-vignettes"
|
||||
_R_CHECK_FORCE_SUGGESTS: 0
|
||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||
RSPM: ${{ matrix.config.rspm }}
|
||||
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
@@ -86,10 +130,24 @@ jobs:
|
||||
|
||||
- uses: r-lib/actions/setup-pandoc@master
|
||||
|
||||
- name: Query dependencies
|
||||
run: Rscript -e "install.packages('remotes')" -e "saveRDS(remotes::dev_package_deps('${{ needs.jobR.outputs.r_bindings }}', dependencies = TRUE), 'depends.Rds')"
|
||||
|
||||
- name: Cache R packages
|
||||
if: runner.os != 'Windows'
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-${{ matrix.config.r }}-${{ hashFiles('depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
Rscript -e "install.packages('remotes')" -e "remotes::install_cran('rcmdcheck')"
|
||||
Rscript -e "install.packages(c('Rcpp', 'RcppArmadillo', 'RcppEnsmallen', 'BH', 'roxygen2', 'testthat', 'Rcereal'))"
|
||||
remotes::install_deps('${{ needs.jobR.outputs.r_bindings }}', dependencies = TRUE)
|
||||
remotes::install_cran("rcmdcheck")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Check
|
||||
run: Rscript -e "rcmdcheck::rcmdcheck('${{ needs.jobR.outputs.r_bindings }}', args = c('--no-manual','--as-cran'), error_on = 'warning', check_dir = 'check')"
|
||||
|
||||
+3
-1
@@ -132,7 +132,9 @@ Copyright:
|
||||
Copyright 2020, Lakshya Ojha <ojhalakshya@gmail.com>
|
||||
Copyright 2020, Bisakh Mondal <bisakhmondal00@gmail.com>
|
||||
Copyright 2020, Benson Muite <benson_muite@emailplus.org>
|
||||
Copyright 2020, Sarthak Bhardwaj <7sarthakbhardwaj@gmail.com>
|
||||
Copyright 2020, Sarthak Bhardwaj <7sarthakbhardwaj@gmail.com>
|
||||
Copyright 2020, Aakash Kaushik <kaushikaakash7539@gmail.com>
|
||||
Copyright 2020, Anush Kini <anushkini@gmail.com>
|
||||
|
||||
License: BSD-3-clause
|
||||
All rights reserved.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
###### ????-??-??
|
||||
* Added Mean Absolute Percentage Error.
|
||||
|
||||
* Added Softmin activation function as layer in ann/layer.
|
||||
|
||||
### mlpack 3.4.1
|
||||
###### 2020-09-07
|
||||
* Fix incorrect parsing of required matrix/model parameters for command-line
|
||||
|
||||
@@ -116,6 +116,8 @@ set(SOURCES
|
||||
celu_impl.hpp
|
||||
softshrink.hpp
|
||||
softshrink_impl.hpp
|
||||
softmin.hpp
|
||||
softmin_impl.hpp
|
||||
)
|
||||
|
||||
# Add directory name to sources.
|
||||
|
||||
@@ -100,6 +100,9 @@ class Add
|
||||
//! Get the output size.
|
||||
size_t OutputSize() const { return outSize; }
|
||||
|
||||
//! Get the size of weights.
|
||||
size_t WeightSize() const { return outSize; }
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
*/
|
||||
|
||||
@@ -257,6 +257,12 @@ class AtrousConvolution
|
||||
//! Modify the internal Padding layer.
|
||||
ann::Padding<>& Padding() { return padding; }
|
||||
|
||||
//! Get size of the weight matrix.
|
||||
size_t WeightSize() const
|
||||
{
|
||||
return (outSize * inSize * kernelWidth * kernelHeight) + outSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "sequential.hpp"
|
||||
#include "softshrink.hpp"
|
||||
#include "softmax.hpp"
|
||||
#include "softmin.hpp"
|
||||
#include "spatial_dropout.hpp"
|
||||
#include "subview.hpp"
|
||||
#include "transposed_convolution.hpp"
|
||||
|
||||
@@ -146,6 +146,12 @@ class Linear
|
||||
//! Modify the bias weights of the layer.
|
||||
OutputDataType& Bias() { return bias; }
|
||||
|
||||
//! Get the size of the weights.
|
||||
size_t WeightSize() const
|
||||
{
|
||||
return (inSize * outSize) + outSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file methods/ann/layer/softmin.hpp
|
||||
* @author Aakash Kaushik
|
||||
*
|
||||
* Definition of the Softmin 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_SOFTMIN_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_SOFTMIN_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
/**
|
||||
* Implementation of the Softmin layer. The Softmin function takes as a input
|
||||
* a vector of K real numbers, rescaling them so that the elements of the
|
||||
* K-dimensional output vector lie in the range [0, 1] and sum to 1.
|
||||
*
|
||||
* @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 Softmin
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create the Softmin object.
|
||||
*/
|
||||
Softmin();
|
||||
|
||||
/**
|
||||
* 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<typename InputType, typename OutputType>
|
||||
void Forward(const InputType& input, OutputType& output);
|
||||
|
||||
/**
|
||||
* Ordinary feed backward pass of a neural network, 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<typename eT>
|
||||
void Backward(const arma::Mat<eT>& input,
|
||||
const arma::Mat<eT>& gy,
|
||||
arma::Mat<eT>& g);
|
||||
|
||||
//! Get the output parameter.
|
||||
OutputDataType& OutputParameter() const { return outputParameter; }
|
||||
//! Modify the output parameter.
|
||||
OutputDataType& OutputParameter() { return outputParameter; }
|
||||
|
||||
//! Get the delta.
|
||||
InputDataType& Delta() const { return delta; }
|
||||
//! Modify the delta.
|
||||
InputDataType& Delta() { return delta; }
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& /* ar */, const unsigned int /* version */);
|
||||
|
||||
private:
|
||||
//! Locally-stored delta object.
|
||||
OutputDataType delta;
|
||||
|
||||
//! Locally stored output parameter object.
|
||||
OutputDataType outputParameter;
|
||||
}; // class Softmin
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "softmin_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @file methods/ann/layer/softmin_impl.hpp
|
||||
* @author Aakash Kaushik
|
||||
*
|
||||
* Implementation of the Softmin 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_SOFTMIN_IMPL_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_SOFTMIN_IMPL_HPP
|
||||
|
||||
// In case it hasn't yet been included.
|
||||
#include "softmin.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Softmin<InputDataType, OutputDataType>::Softmin()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename OutputType>
|
||||
void Softmin<InputDataType, OutputDataType>::Forward(
|
||||
const InputType& input,
|
||||
OutputType& output)
|
||||
{
|
||||
InputType inputMin = arma::repmat(arma::min(input,0), input.n_rows, 1);
|
||||
output = arma::repmat(arma::log(arma::sum(
|
||||
arma::exp(-(input - inputMin)),0)), input.n_rows, 1);
|
||||
output = arma::exp(-(input - inputMin) - output);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename eT>
|
||||
void Softmin<InputDataType, OutputDataType>::Backward(
|
||||
const arma::Mat<eT>& input,
|
||||
const arma::Mat<eT>& gy,
|
||||
arma::Mat<eT>& g)
|
||||
{
|
||||
g = input % (gy - arma::repmat(arma::sum(gy % input), input.n_rows, 1));
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename Archive>
|
||||
void Softmin<InputDataType, OutputDataType>::serialize(
|
||||
Archive& /* ar */,
|
||||
const unsigned int /* version */)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,5 @@
|
||||
# mlpack test executable.
|
||||
add_executable(mlpack_test
|
||||
arma_extend_test.cpp
|
||||
async_learning_test.cpp
|
||||
augmented_rnns_tasks_test.cpp
|
||||
callback_test.cpp
|
||||
@@ -8,7 +7,6 @@ add_executable(mlpack_test
|
||||
cli_binding_test.cpp
|
||||
io_test.cpp
|
||||
cosine_tree_test.cpp
|
||||
dbscan_test.cpp
|
||||
dcgan_test.cpp
|
||||
det_test.cpp
|
||||
distribution_test.cpp
|
||||
@@ -34,12 +32,10 @@ add_executable(mlpack_test
|
||||
local_coordinate_coding_test.cpp
|
||||
log_test.cpp
|
||||
logistic_regression_test.cpp
|
||||
loss_functions_test.cpp
|
||||
lsh_test.cpp
|
||||
math_test.cpp
|
||||
matrix_completion_test.cpp
|
||||
maximal_inputs_test.cpp
|
||||
mean_shift_test.cpp
|
||||
metric_test.cpp
|
||||
mlpack_test.cpp
|
||||
mock_categorical_data.hpp
|
||||
@@ -47,14 +43,12 @@ add_executable(mlpack_test
|
||||
nmf_test.cpp
|
||||
nystroem_method_test.cpp
|
||||
octree_test.cpp
|
||||
pca_test.cpp
|
||||
perceptron_test.cpp
|
||||
prefixedoutstream_test.cpp
|
||||
python_binding_test.cpp
|
||||
q_learning_test.cpp
|
||||
qdafn_test.cpp
|
||||
radical_test.cpp
|
||||
random_forest_test.cpp
|
||||
random_test.cpp
|
||||
range_search_test.cpp
|
||||
rectangle_tree_test.cpp
|
||||
@@ -80,7 +74,6 @@ add_executable(mlpack_test
|
||||
wgan_mnist_test.cpp
|
||||
wgan_gp_mnist_test.cpp
|
||||
main_tests/cf_test.cpp
|
||||
main_tests/dbscan_test.cpp
|
||||
main_tests/det_test.cpp
|
||||
main_tests/emst_test.cpp
|
||||
main_tests/fastmks_test.cpp
|
||||
@@ -100,13 +93,10 @@ add_executable(mlpack_test
|
||||
main_tests/local_coordinate_coding_test.cpp
|
||||
main_tests/logistic_regression_test.cpp
|
||||
main_tests/lsh_test.cpp
|
||||
main_tests/mean_shift_test.cpp
|
||||
main_tests/nbc_test.cpp
|
||||
main_tests/nmf_test.cpp
|
||||
main_tests/pca_test.cpp
|
||||
main_tests/perceptron_test.cpp
|
||||
main_tests/radical_test.cpp
|
||||
main_tests/random_forest_test.cpp
|
||||
main_tests/range_search_test.cpp
|
||||
main_tests/test_helper.hpp
|
||||
)
|
||||
@@ -122,6 +112,7 @@ add_executable(mlpack_catch_test
|
||||
ann_test_tools.hpp
|
||||
ann_visitor_test.cpp
|
||||
armadillo_svd_test.cpp
|
||||
arma_extend_test.cpp
|
||||
bayesian_linear_regression_test.cpp
|
||||
bias_svd_test.cpp
|
||||
binarize_test.cpp
|
||||
@@ -129,6 +120,7 @@ add_executable(mlpack_catch_test
|
||||
convolutional_network_test.cpp
|
||||
convolution_test.cpp
|
||||
cv_test.cpp
|
||||
dbscan_test.cpp
|
||||
decision_stump_test.cpp
|
||||
decision_tree_test.cpp
|
||||
feedforward_network_test.cpp
|
||||
@@ -143,10 +135,14 @@ add_executable(mlpack_catch_test
|
||||
knn_test.cpp
|
||||
linear_regression_test.cpp
|
||||
load_save_test.cpp
|
||||
loss_functions_test.cpp
|
||||
main.cpp
|
||||
mean_shift_test.cpp
|
||||
nca_test.cpp
|
||||
one_hot_encoding_test.cpp
|
||||
pca_test.cpp
|
||||
quic_svd_test.cpp
|
||||
random_forest_test.cpp
|
||||
randomized_svd_test.cpp
|
||||
rbm_network_test.cpp
|
||||
recurrent_network_test.cpp
|
||||
@@ -166,6 +162,7 @@ add_executable(mlpack_catch_test
|
||||
main_tests/adaboost_test.cpp
|
||||
main_tests/approx_kfn_test.cpp
|
||||
main_tests/bayesian_linear_regression_test.cpp
|
||||
main_tests/dbscan_test.cpp
|
||||
main_tests/decision_stump_test.cpp
|
||||
main_tests/decision_tree_test.cpp
|
||||
main_tests/image_converter_test.cpp
|
||||
@@ -174,12 +171,15 @@ add_executable(mlpack_catch_test
|
||||
main_tests/kmeans_test.cpp
|
||||
main_tests/knn_test.cpp
|
||||
main_tests/linear_regression_test.cpp
|
||||
main_tests/mean_shift_test.cpp
|
||||
main_tests/nca_test.cpp
|
||||
main_tests/pca_test.cpp
|
||||
main_tests/preprocess_binarize_test.cpp
|
||||
main_tests/preprocess_imputer_test.cpp
|
||||
main_tests/preprocess_one_hot_encode_test.cpp
|
||||
main_tests/preprocess_scale_test.cpp
|
||||
main_tests/preprocess_split_test.cpp
|
||||
main_tests/random_forest_test.cpp
|
||||
main_tests/softmax_regression_test.cpp
|
||||
main_tests/sparse_coding_test.cpp
|
||||
main_tests/test_helper.hpp
|
||||
@@ -276,4 +276,3 @@ add_test(NAME "catch_test" COMMAND mlpack_catch_test WORKING_DIRECTORY ${CMAKE_B
|
||||
|
||||
# Use RUN_SERIAL for long running parallel tests
|
||||
set_tests_properties(${parallel_tests} PROPERTIES RUN_SERIAL TRUE)
|
||||
|
||||
|
||||
@@ -558,6 +558,58 @@ void CheckCELUDerivativeCorrect(const arma::colvec input,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the Softmin activation function test. The function is
|
||||
* implemented as Softmin layer in the file softmin.hpp.
|
||||
*
|
||||
* @param input Input data used for evaluating the Softmin activation function.
|
||||
* @param target Target data used to evaluate the Softmin activation.
|
||||
*/
|
||||
void CheckSoftminActivationCorrect(const arma::colvec input,
|
||||
const arma::colvec target)
|
||||
{
|
||||
// Initialize Softmin object.
|
||||
Softmin<> softmin;
|
||||
|
||||
// Test the activation function using the entire vector as input.
|
||||
arma::colvec activations;
|
||||
softmin.Forward(input,activations);
|
||||
for (size_t i = 0; i < activations.n_elem; ++i)
|
||||
{
|
||||
REQUIRE(activations.at(i) == Approx(target.at(i)).epsilon(1e-5));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the Softmin activation function derivative test.
|
||||
* The function is implemented as Softmin layer in the file softmin.hpp.
|
||||
*
|
||||
* @param input Input data used for evaluating the Softmin activation function.
|
||||
* @param target Target data used to evaluate the Softmin activation.
|
||||
*/
|
||||
void CheckSoftminDerivativeCorrect(const arma::colvec input,
|
||||
const arma::colvec target)
|
||||
{
|
||||
// Initialize Softmin object.
|
||||
Softmin<> softmin;
|
||||
|
||||
// Test the calculation of the derivatives using the entire vector as input.
|
||||
arma::colvec derivatives, activations;
|
||||
|
||||
// This error vector will be set to [[1.0],[0.0],[1.0],[0.0]]
|
||||
// to get the derivatives.
|
||||
arma::colvec error = arma::ones<arma::colvec>(input.n_elem);
|
||||
error(1) = 0.0;
|
||||
error(3) = 0.0;
|
||||
softmin.Forward(input, activations);
|
||||
softmin.Backward(activations, error, derivatives);
|
||||
for (size_t i = 0; i < derivatives.n_elem; ++i)
|
||||
{
|
||||
REQUIRE(derivatives.at(i) == Approx(target.at(i)).epsilon(1e-5));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test of the tanh function.
|
||||
*/
|
||||
@@ -1063,3 +1115,23 @@ TEST_CASE("GaussianFunctionTest", "[ActivationFunctionsTest]")
|
||||
CheckDerivativeCorrect<GaussianFunction>(desiredActivations,
|
||||
desiredDerivatives);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test of the Softmin function.
|
||||
*/
|
||||
TEST_CASE("SoftminFunctionTest", "[ActivationFunctionsTest]")
|
||||
{
|
||||
const arma::colvec activationData("4.2 2.4 7.0 6.4");
|
||||
|
||||
// Hand-calculated Values.
|
||||
const arma::colvec desiredActivations("0.1384799751 0.8377550303 \
|
||||
0.008420976 0.0153440186");
|
||||
|
||||
const arma::colvec desiredDerivatives("0.1181371351 -0.12306701070 \
|
||||
0.0071839266 -0.0022540509");
|
||||
|
||||
CheckSoftminActivationCorrect(activationData,
|
||||
desiredActivations);
|
||||
CheckSoftminDerivativeCorrect(activationData,
|
||||
desiredDerivatives);
|
||||
}
|
||||
|
||||
@@ -52,3 +52,37 @@ TEST_CASE("BiasSetVisitorTest", "[ANNVisitorTest]")
|
||||
|
||||
boost::apply_visitor(DeleteVisitor(), linear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that WeightSetVisitor works properly.
|
||||
*/
|
||||
TEST_CASE("WeightSetVisitorTest", "[ANNVisitorTest]")
|
||||
{
|
||||
size_t randomSize = arma::randi(arma::distr_param(1, 100));
|
||||
|
||||
LayerTypes<> linear = new Linear<>(randomSize, randomSize);
|
||||
|
||||
arma::mat layerWeights(randomSize * randomSize + randomSize, 1);
|
||||
layerWeights.zeros();
|
||||
|
||||
size_t setWeights = boost::apply_visitor(WeightSetVisitor(layerWeights, 0),
|
||||
linear);
|
||||
|
||||
REQUIRE(setWeights == randomSize * randomSize + randomSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that WeightSizeVisitor works properly.
|
||||
*/
|
||||
TEST_CASE("WeightSizeVisitorTest", "[ANNVisitorTest]")
|
||||
{
|
||||
size_t randomSize = arma::randi(arma::distr_param(1, 100));
|
||||
|
||||
LayerTypes<> linear = new Linear<>(randomSize, randomSize);
|
||||
|
||||
size_t weightSize = boost::apply_visitor(WeightSizeVisitor(),
|
||||
linear);
|
||||
|
||||
REQUIRE(weightSize == randomSize * randomSize + randomSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,18 +11,17 @@
|
||||
*/
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "test_catch_tools.hpp"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace arma;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ArmaExtendTest);
|
||||
|
||||
/**
|
||||
* Test const_row_col_iterator for basic functionality.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ConstRowColIteratorTest)
|
||||
TEST_CASE("ConstRowColIteratorTest", "[ArmaExtendTest]")
|
||||
{
|
||||
mat X;
|
||||
X.zeros(5, 5);
|
||||
@@ -39,15 +38,15 @@ BOOST_AUTO_TEST_CASE(ConstRowColIteratorTest)
|
||||
for (it = X.begin_row_col(); it != X.end_row_col(); ++it)
|
||||
{
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
|
||||
++count;
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(count, 25);
|
||||
REQUIRE(count == 25);
|
||||
it = X.end_row_col();
|
||||
do
|
||||
{
|
||||
@@ -55,20 +54,20 @@ BOOST_AUTO_TEST_CASE(ConstRowColIteratorTest)
|
||||
--count;
|
||||
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
} while (it != X.begin_row_col());
|
||||
|
||||
BOOST_REQUIRE_EQUAL(count, 0);
|
||||
REQUIRE(count == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test row_col_iterator for basic functionality.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RowColIteratorTest)
|
||||
TEST_CASE("RowColIteratorTest", "[ArmaExtendTest]")
|
||||
{
|
||||
mat X;
|
||||
X.zeros(5, 5);
|
||||
@@ -85,15 +84,15 @@ BOOST_AUTO_TEST_CASE(RowColIteratorTest)
|
||||
for (it = X.begin_row_col(); it != X.end_row_col(); ++it)
|
||||
{
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
|
||||
++count;
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(count, 25);
|
||||
REQUIRE(count == 25);
|
||||
it = X.end_row_col();
|
||||
do
|
||||
{
|
||||
@@ -101,20 +100,20 @@ BOOST_AUTO_TEST_CASE(RowColIteratorTest)
|
||||
--count;
|
||||
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
} while (it != X.begin_row_col());
|
||||
|
||||
BOOST_REQUIRE_EQUAL(count, 0);
|
||||
REQUIRE(count == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator-- test for mat::row_col_iterator and mat::const_row_col_iterator
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MatRowColIteratorDecrementOperatorTest)
|
||||
TEST_CASE("MatRowColIteratorDecrementOperatorTest", "[ArmaExtendTest]")
|
||||
{
|
||||
mat test = ones<mat>(5, 5);
|
||||
|
||||
@@ -124,14 +123,14 @@ BOOST_AUTO_TEST_CASE(MatRowColIteratorDecrementOperatorTest)
|
||||
// Check that postfix-- does not decrement the position when position is
|
||||
// pointing to the beginning.
|
||||
auto junk = it2--; (void)(junk);
|
||||
BOOST_REQUIRE_EQUAL(it1.row(), it2.row());
|
||||
BOOST_REQUIRE_EQUAL(it1.col(), it2.col());
|
||||
REQUIRE(it1.row() == it2.row());
|
||||
REQUIRE(it1.col() == it2.col());
|
||||
|
||||
// Check that prefix-- does not decrement the position when position is
|
||||
// pointing to the beginning.
|
||||
--it2;
|
||||
BOOST_REQUIRE_EQUAL(it1.row(), it2.row());
|
||||
BOOST_REQUIRE_EQUAL(it1.col(), it2.col());
|
||||
REQUIRE(it1.row() == it2.row());
|
||||
REQUIRE(it1.col() == it2.col());
|
||||
}
|
||||
|
||||
// These tests don't work when the sparse iterators hold references and not
|
||||
@@ -140,7 +139,7 @@ BOOST_AUTO_TEST_CASE(MatRowColIteratorDecrementOperatorTest)
|
||||
/**
|
||||
* Test sparse const_row_col_iterator for basic functionality.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ConstSpRowColIteratorTest)
|
||||
TEST_CASE("ConstSpRowColIteratorTest", "[ArmaExtendTest]")
|
||||
{
|
||||
sp_mat X(5, 5);
|
||||
for (size_t i = 0; i < 5; ++i)
|
||||
@@ -156,15 +155,15 @@ BOOST_AUTO_TEST_CASE(ConstSpRowColIteratorTest)
|
||||
for (it = X.begin_row_col(); it != X.end_row_col(); ++it)
|
||||
{
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == (count % 5) * 3 + (count / 5));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
|
||||
++count;
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(count, 25);
|
||||
REQUIRE(count == 25);
|
||||
it = X.end_row_col();
|
||||
do
|
||||
{
|
||||
@@ -172,20 +171,20 @@ BOOST_AUTO_TEST_CASE(ConstSpRowColIteratorTest)
|
||||
--count;
|
||||
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
} while (it != X.begin_row_col());
|
||||
|
||||
BOOST_REQUIRE_EQUAL(count, 1);
|
||||
REQUIRE(count == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sparse row_col_iterator for basic functionality.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SpRowColIteratorTest)
|
||||
TEST_CASE("SpRowColIteratorTest", "[ArmaExtendTest]")
|
||||
{
|
||||
sp_mat X(5, 5);
|
||||
for (size_t i = 0; i < 5; ++i)
|
||||
@@ -201,15 +200,15 @@ BOOST_AUTO_TEST_CASE(SpRowColIteratorTest)
|
||||
for (it = X.begin_row_col(); it != X.end_row_col(); ++it)
|
||||
{
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
|
||||
++count;
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(count, 25);
|
||||
REQUIRE(count == 25);
|
||||
it = X.end_row_col();
|
||||
do
|
||||
{
|
||||
@@ -217,14 +216,12 @@ BOOST_AUTO_TEST_CASE(SpRowColIteratorTest)
|
||||
--count;
|
||||
|
||||
// Check iterator value.
|
||||
BOOST_REQUIRE_EQUAL(*it, (count % 5) * 3 + (count / 5));
|
||||
REQUIRE(*it == ((count % 5) * 3 + (count / 5)));
|
||||
|
||||
// Check iterator position.
|
||||
BOOST_REQUIRE_EQUAL(it.row(), count % 5);
|
||||
BOOST_REQUIRE_EQUAL(it.col(), count / 5);
|
||||
REQUIRE(it.row() == count % 5);
|
||||
REQUIRE(it.col() == count / 5);
|
||||
} while (it != X.begin_row_col());
|
||||
|
||||
BOOST_REQUIRE_EQUAL(count, 1);
|
||||
REQUIRE(count == 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -13,17 +13,15 @@
|
||||
#include <mlpack/methods/dbscan/dbscan.hpp>
|
||||
#include <mlpack/methods/dbscan/random_point_selection.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "test_catch_tools.hpp"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::range;
|
||||
using namespace mlpack::dbscan;
|
||||
using namespace mlpack::distribution;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(DBSCANTest);
|
||||
|
||||
BOOST_AUTO_TEST_CASE(OneClusterTest)
|
||||
TEST_CASE("OneClusterTest", "[DBSCANTest]")
|
||||
{
|
||||
// Make sure that if we have points in the unit box, and if we set epsilon
|
||||
// large enough, all points end up as in one cluster.
|
||||
@@ -34,16 +32,16 @@ BOOST_AUTO_TEST_CASE(OneClusterTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(clusters, 1);
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
REQUIRE(clusters == 1);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
for (size_t i = 0; i < assignments.n_elem; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments[i], 0);
|
||||
REQUIRE(assignments[i] == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* When epsilon is small enough, every point returned should be noise.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(TinyEpsilonTest)
|
||||
TEST_CASE("TinyEpsilonTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(10, 200, arma::fill::randu);
|
||||
|
||||
@@ -52,16 +50,16 @@ BOOST_AUTO_TEST_CASE(TinyEpsilonTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(clusters, 0);
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
REQUIRE(clusters == 0);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
for (size_t i = 0; i < assignments.n_elem; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments[i], SIZE_MAX);
|
||||
REQUIRE(assignments[i] == SIZE_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that outliers are properly labeled as noise.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(OutlierTest)
|
||||
TEST_CASE("OutlierTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(2, 200, arma::fill::randu);
|
||||
|
||||
@@ -75,17 +73,17 @@ BOOST_AUTO_TEST_CASE(OutlierTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_GT(clusters, 0);
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(assignments[15], SIZE_MAX);
|
||||
BOOST_REQUIRE_EQUAL(assignments[45], SIZE_MAX);
|
||||
BOOST_REQUIRE_EQUAL(assignments[101], SIZE_MAX);
|
||||
REQUIRE(clusters > 0);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
REQUIRE(assignments[15] == SIZE_MAX);
|
||||
REQUIRE(assignments[45] == SIZE_MAX);
|
||||
REQUIRE(assignments[101] == SIZE_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the Gaussian clusters are correctly found.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(GaussiansTest)
|
||||
TEST_CASE("GaussiansTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(3, 300);
|
||||
|
||||
@@ -105,7 +103,7 @@ BOOST_AUTO_TEST_CASE(GaussiansTest)
|
||||
arma::Row<size_t> assignments;
|
||||
arma::mat centroids;
|
||||
const size_t clusters = d.Cluster(points, assignments, centroids);
|
||||
BOOST_REQUIRE_EQUAL(clusters, 3);
|
||||
REQUIRE(clusters == 3);
|
||||
|
||||
// Our centroids should be close to one of our Gaussians.
|
||||
arma::Row<size_t> matches(3);
|
||||
@@ -120,35 +118,35 @@ BOOST_AUTO_TEST_CASE(GaussiansTest)
|
||||
matches(2) = j;
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_NE(matches(0), matches(1));
|
||||
BOOST_REQUIRE_NE(matches(1), matches(2));
|
||||
BOOST_REQUIRE_NE(matches(2), matches(0));
|
||||
REQUIRE(matches(0) != matches(1));
|
||||
REQUIRE(matches(1) != matches(2));
|
||||
REQUIRE(matches(2) != matches(0));
|
||||
|
||||
BOOST_REQUIRE_NE(matches(0), 3);
|
||||
BOOST_REQUIRE_NE(matches(1), 3);
|
||||
BOOST_REQUIRE_NE(matches(2), 3);
|
||||
REQUIRE(matches(0) != 3);
|
||||
REQUIRE(matches(1) != 3);
|
||||
REQUIRE(matches(2) != 3);
|
||||
|
||||
for (size_t i = 0; i < 100; ++i)
|
||||
{
|
||||
// Each point should either be noise or in cluster matches(0).
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(1));
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(2));
|
||||
REQUIRE(assignments(i) != matches(1));
|
||||
REQUIRE(assignments(i) != matches(2));
|
||||
}
|
||||
|
||||
for (size_t i = 100; i < 200; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(0));
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(2));
|
||||
REQUIRE(assignments(i) != matches(0));
|
||||
REQUIRE(assignments(i) != matches(2));
|
||||
}
|
||||
|
||||
for (size_t i = 200; i < 300; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(0));
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(1));
|
||||
REQUIRE(assignments(i) != matches(0));
|
||||
REQUIRE(assignments(i) != matches(1));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(OneClusterSingleModeTest)
|
||||
TEST_CASE("OneClusterSingleModeTest", "[DBSCANTest]")
|
||||
{
|
||||
// Make sure that if we have points in the unit box, and if we set epsilon
|
||||
// large enough, all points end up as in one cluster.
|
||||
@@ -159,16 +157,16 @@ BOOST_AUTO_TEST_CASE(OneClusterSingleModeTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(clusters, 1);
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
REQUIRE(clusters == 1);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
for (size_t i = 0; i < assignments.n_elem; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments[i], 0);
|
||||
REQUIRE(assignments[i] == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* When epsilon is small enough, every point returned should be noise.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(TinyEpsilonSingleModeTest)
|
||||
TEST_CASE("TinyEpsilonSingleModeTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(10, 200, arma::fill::randu);
|
||||
|
||||
@@ -177,16 +175,16 @@ BOOST_AUTO_TEST_CASE(TinyEpsilonSingleModeTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(clusters, 0);
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
REQUIRE(clusters == 0);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
for (size_t i = 0; i < assignments.n_elem; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments[i], SIZE_MAX);
|
||||
REQUIRE(assignments[i] == SIZE_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that outliers are properly labeled as noise.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(OutlierSingleModeTest)
|
||||
TEST_CASE("OutlierSingleModeTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(2, 200, arma::fill::randu);
|
||||
|
||||
@@ -200,17 +198,17 @@ BOOST_AUTO_TEST_CASE(OutlierSingleModeTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_GT(clusters, 0);
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(assignments[15], SIZE_MAX);
|
||||
BOOST_REQUIRE_EQUAL(assignments[45], SIZE_MAX);
|
||||
BOOST_REQUIRE_EQUAL(assignments[101], SIZE_MAX);
|
||||
REQUIRE(clusters > 0);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
REQUIRE(assignments[15] == SIZE_MAX);
|
||||
REQUIRE(assignments[45] == SIZE_MAX);
|
||||
REQUIRE(assignments[101] == SIZE_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the Gaussian clusters are correctly found.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(GaussiansSingleModeTest)
|
||||
TEST_CASE("GaussiansSingleModeTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(3, 300);
|
||||
|
||||
@@ -230,7 +228,7 @@ BOOST_AUTO_TEST_CASE(GaussiansSingleModeTest)
|
||||
arma::Row<size_t> assignments;
|
||||
arma::mat centroids;
|
||||
const size_t clusters = d.Cluster(points, assignments, centroids);
|
||||
BOOST_REQUIRE_EQUAL(clusters, 3);
|
||||
REQUIRE(clusters == 3);
|
||||
|
||||
// Our centroids should be close to one of our Gaussians.
|
||||
arma::Row<size_t> matches(3);
|
||||
@@ -245,38 +243,38 @@ BOOST_AUTO_TEST_CASE(GaussiansSingleModeTest)
|
||||
matches(2) = j;
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_NE(matches(0), matches(1));
|
||||
BOOST_REQUIRE_NE(matches(1), matches(2));
|
||||
BOOST_REQUIRE_NE(matches(2), matches(0));
|
||||
REQUIRE(matches(0) != matches(1));
|
||||
REQUIRE(matches(1) != matches(2));
|
||||
REQUIRE(matches(2) != matches(0));
|
||||
|
||||
BOOST_REQUIRE_NE(matches(0), 3);
|
||||
BOOST_REQUIRE_NE(matches(1), 3);
|
||||
BOOST_REQUIRE_NE(matches(2), 3);
|
||||
REQUIRE(matches(0) != 3);
|
||||
REQUIRE(matches(1) != 3);
|
||||
REQUIRE(matches(2) != 3);
|
||||
|
||||
for (size_t i = 0; i < 100; ++i)
|
||||
{
|
||||
// Each point should either be noise or in cluster matches(0).
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(1));
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(2));
|
||||
REQUIRE(assignments(i) != matches(1));
|
||||
REQUIRE(assignments(i) != matches(2));
|
||||
}
|
||||
|
||||
for (size_t i = 100; i < 200; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(0));
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(2));
|
||||
REQUIRE(assignments(i) != matches(0));
|
||||
REQUIRE(assignments(i) != matches(2));
|
||||
}
|
||||
|
||||
for (size_t i = 200; i < 300; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(0));
|
||||
BOOST_REQUIRE_NE(assignments(i), matches(1));
|
||||
REQUIRE(assignments(i) != matches(0));
|
||||
REQUIRE(assignments(i) != matches(1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that OrderedPointSelection works correctly.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(OrderedPointSelectionTest)
|
||||
TEST_CASE("OrderedPointSelectionTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(10, 200, arma::fill::randu);
|
||||
|
||||
@@ -285,16 +283,16 @@ BOOST_AUTO_TEST_CASE(OrderedPointSelectionTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(clusters, 1);
|
||||
REQUIRE(clusters == 1);
|
||||
|
||||
// The number of assignments returned should be the same as points.
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that RandomPointSelection works correctly.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomPointSelectionTest)
|
||||
TEST_CASE("RandomPointSelectionTest", "[DBSCANTest]")
|
||||
{
|
||||
arma::mat points(10, 200, arma::fill::randu);
|
||||
|
||||
@@ -303,10 +301,8 @@ BOOST_AUTO_TEST_CASE(RandomPointSelectionTest)
|
||||
arma::Row<size_t> assignments;
|
||||
const size_t clusters = d.Cluster(points, assignments);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(clusters, 1);
|
||||
REQUIRE(clusters == 1);
|
||||
|
||||
// The number of assignments returned should be the same as points.
|
||||
BOOST_REQUIRE_EQUAL(assignments.n_elem, points.n_cols);
|
||||
REQUIRE(assignments.n_elem == points.n_cols);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -36,19 +36,17 @@
|
||||
#include <mlpack/methods/ann/init_rules/nguyen_widrow_init.hpp>
|
||||
#include <mlpack/methods/ann/ffn.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "catch.hpp"
|
||||
#include "test_catch_tools.hpp"
|
||||
#include "ann_test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LossFunctionsTest);
|
||||
|
||||
/**
|
||||
* Simple Huber Loss test.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(HuberLossTest)
|
||||
TEST_CASE("HuberLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output;
|
||||
HuberLoss<> module;
|
||||
@@ -57,7 +55,7 @@ BOOST_AUTO_TEST_CASE(HuberLossTest)
|
||||
input = arma::mat("17.45 12.91 13.63 29.01 7.12 15.47 31.52 31.97");
|
||||
target = arma::mat("16.52 13.11 13.67 29.51 24.31 15.03 30.72 34.07");
|
||||
double loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss, 2.410631, 0.00001);
|
||||
REQUIRE(loss == Approx(2.410631).epsilon(1e-5));
|
||||
|
||||
// Test the backward function.
|
||||
module.Backward(input, target, output);
|
||||
@@ -66,16 +64,16 @@ BOOST_AUTO_TEST_CASE(HuberLossTest)
|
||||
// [0.1162 -0.0250 -0.0050 -0.0625 -0.1250 0.0550 0.1000 -0.1250]
|
||||
// Sum of Expected Output = -0.07125.
|
||||
double expectedOutputSum = arma::accu(output);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(expectedOutputSum, -0.07125, 0.00001);
|
||||
REQUIRE(expectedOutputSum == Approx(-0.07125).epsilon(1e-5));
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Poisson Negative Log Likelihood Loss function test.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(PoissonNLLLossTest)
|
||||
TEST_CASE("PoissonNLLLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, input4, target4;
|
||||
arma::mat output1, output2, output3, output4;
|
||||
@@ -98,10 +96,10 @@ BOOST_AUTO_TEST_CASE(PoissonNLLLossTest)
|
||||
double loss2 = module2.Forward(input, target);
|
||||
double loss3 = module3.Forward(input, target);
|
||||
double loss4 = module4.Forward(input4, target4);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss1, 4.8986, 0.0001);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss2, 45.4139, 0.0001);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss3, 5.6767, 0.0001);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss4, 3.742157, 0.0001);
|
||||
REQUIRE(loss1 == Approx(4.8986).epsilon(1e-4));
|
||||
REQUIRE(loss2 == Approx(45.4139).epsilon(1e-4));
|
||||
REQUIRE(loss3 == Approx(5.6767).epsilon(1e-4));
|
||||
REQUIRE(loss4 == Approx(3.742157).epsilon(1e-4));
|
||||
|
||||
// Test the Backward function.
|
||||
module1.Backward(input, target, output1);
|
||||
@@ -118,31 +116,31 @@ BOOST_AUTO_TEST_CASE(PoissonNLLLossTest)
|
||||
expOutput4 = arma::mat("-0.064825 -0.716511 -0.062224 -0.680027 \
|
||||
-0.087030 -9.386517 -0.329736 -0.202650");
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output1.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output1.n_cols, input.n_cols);
|
||||
REQUIRE(output1.n_rows == input.n_rows);
|
||||
REQUIRE(output1.n_cols == input.n_cols);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output2.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output2.n_cols, input.n_cols);
|
||||
REQUIRE(output2.n_rows == input.n_rows);
|
||||
REQUIRE(output2.n_cols == input.n_cols);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output3.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output3.n_cols, input.n_cols);
|
||||
REQUIRE(output3.n_rows == input.n_rows);
|
||||
REQUIRE(output3.n_cols == input.n_cols);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output4.n_rows, input4.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output4.n_cols, input4.n_cols);
|
||||
REQUIRE(output4.n_rows == input4.n_rows);
|
||||
REQUIRE(output4.n_cols == input4.n_cols);
|
||||
|
||||
for (size_t i = 0; i < expOutput1.n_elem; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(output1[i], expOutput1[i], 0.0001);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(output2[i], expOutput2[i], 0.0001);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(output3[i], expOutput3[i], 0.0001);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(output4[i], expOutput4[i], 0.0001);
|
||||
REQUIRE(output1[i] == Approx(expOutput1[i]).epsilon(1e-4));
|
||||
REQUIRE(output2[i] == Approx(expOutput2[i]).epsilon(1e-4));
|
||||
REQUIRE(output3[i] == Approx(expOutput3[i]).epsilon(1e-4));
|
||||
REQUIRE(output4[i] == Approx(expOutput4[i]).epsilon(1e-4));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple KL Divergence test. The loss should be zero if input = target.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleKLDivergenceTest)
|
||||
TEST_CASE("SimpleKLDivergenceTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output;
|
||||
double loss;
|
||||
@@ -152,13 +150,13 @@ BOOST_AUTO_TEST_CASE(SimpleKLDivergenceTest)
|
||||
input = arma::ones(10, 1);
|
||||
target = arma::ones(10, 1);
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_SMALL(loss, 0.00001);
|
||||
REQUIRE(loss == Approx(0.0).margin(1e-5));
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the mean squared logarithmic error function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleMeanSquaredLogarithmicErrorTest)
|
||||
TEST_CASE("SimpleMeanSquaredLogarithmicErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, output, target;
|
||||
MeanSquaredLogarithmicError<> module;
|
||||
@@ -168,31 +166,31 @@ BOOST_AUTO_TEST_CASE(SimpleMeanSquaredLogarithmicErrorTest)
|
||||
input = arma::zeros(1, 8);
|
||||
target = arma::zeros(1, 8);
|
||||
double error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_SMALL(error, 0.00001);
|
||||
REQUIRE(error == Approx(0.0).margin(1e-5));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
// The output should be equal to 0.
|
||||
CheckMatrices(input, output);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
|
||||
// Test the error function on a single input.
|
||||
input = arma::mat("2");
|
||||
target = arma::mat("3");
|
||||
error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(error, 0.082760974810151655, 0.001);
|
||||
REQUIRE(error == Approx(0.082760974810151655).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function on a single input.
|
||||
module.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), -0.1917880483011872, 0.001);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 1);
|
||||
REQUIRE(arma::accu(output) == Approx(-0.1917880483011872).epsilon(1e-3));
|
||||
REQUIRE(output.n_elem == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to check KL Divergence loss function when we take mean.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(KLDivergenceMeanTest)
|
||||
TEST_CASE("KLDivergenceMeanTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output;
|
||||
double loss;
|
||||
@@ -203,17 +201,17 @@ BOOST_AUTO_TEST_CASE(KLDivergenceMeanTest)
|
||||
target = arma::exp(arma::mat("2 1 1 1 1 1 1 1 1 1"));
|
||||
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss, -1.1 , 0.00001);
|
||||
REQUIRE(loss == Approx(-1.1 ).epsilon(1e-5));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(arma::as_scalar(output), -0.1, 0.00001);
|
||||
REQUIRE(arma::as_scalar(output) == Approx(-0.1).epsilon(1e-5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to check KL Divergence loss function when we do not take mean.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(KLDivergenceNoMeanTest)
|
||||
TEST_CASE("KLDivergenceNoMeanTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output;
|
||||
double loss;
|
||||
@@ -224,17 +222,17 @@ BOOST_AUTO_TEST_CASE(KLDivergenceNoMeanTest)
|
||||
target = arma::exp(arma::mat("2 1 1 1 1 1 1 1 1 1"));
|
||||
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(loss, -11, 0.00001);
|
||||
REQUIRE(loss == Approx(-11).epsilon(1e-5));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE_FRACTION(arma::as_scalar(output), -1, 0.00001);
|
||||
REQUIRE(arma::as_scalar(output) == Approx(-1).epsilon(1e-5));
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the mean squared error performance function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleMeanSquaredErrorTest)
|
||||
TEST_CASE("SimpleMeanSquaredErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, output, target;
|
||||
MeanSquaredError<> module;
|
||||
@@ -244,7 +242,7 @@ BOOST_AUTO_TEST_CASE(SimpleMeanSquaredErrorTest)
|
||||
input = arma::mat("1.0 0.0 1.0 0.0 -1.0 0.0 -1.0 0.0");
|
||||
target = arma::zeros(1, 8);
|
||||
double error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_EQUAL(error, 0.5);
|
||||
REQUIRE(error == 0.5);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
@@ -252,26 +250,26 @@ BOOST_AUTO_TEST_CASE(SimpleMeanSquaredErrorTest)
|
||||
// output = 2 * (input - target) / target.n_cols,
|
||||
// output * nofColumns / 2 should be equal to input.
|
||||
CheckMatrices(input, output * output.n_cols / 2);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
|
||||
// Test the error function on a single input.
|
||||
input = arma::mat("2");
|
||||
target = arma::mat("3");
|
||||
error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_EQUAL(error, 1.0);
|
||||
REQUIRE(error == 1.0);
|
||||
|
||||
// Test the Backward function on a single input.
|
||||
module.Backward(input, target, output);
|
||||
// Test whether the output is negative.
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), -2);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 1);
|
||||
REQUIRE(arma::accu(output) == -2);
|
||||
REQUIRE(output.n_elem == 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the cross-entropy error performance function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleCrossEntropyErrorTest)
|
||||
TEST_CASE("SimpleCrossEntropyErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input1, input2, output, target1, target2;
|
||||
CrossEntropyError<> module(1e-6);
|
||||
@@ -281,40 +279,40 @@ BOOST_AUTO_TEST_CASE(SimpleCrossEntropyErrorTest)
|
||||
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);
|
||||
BOOST_REQUIRE_SMALL(error1 - 8 * std::log(2), 2e-5);
|
||||
REQUIRE(error1 - 8 * 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);
|
||||
BOOST_REQUIRE_SMALL(error2, 1e-5);
|
||||
REQUIRE(error2 == Approx(0.0).margin(1e-5));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, target1, output);
|
||||
for (double el : output)
|
||||
{
|
||||
// For the 0.5 constant vector we should get 1 / (1 - 0.5) = 2 everywhere.
|
||||
BOOST_REQUIRE_SMALL(el - 2, 5e-6);
|
||||
REQUIRE(el - 2 == Approx(0.0).margin(5e-6));
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input1.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input1.n_cols);
|
||||
REQUIRE(output.n_rows == input1.n_rows);
|
||||
REQUIRE(output.n_cols == input1.n_cols);
|
||||
|
||||
module.Backward(input2, target2, output);
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
double el = output.at(0, i);
|
||||
if (input2.at(i) == 0)
|
||||
BOOST_REQUIRE_SMALL(el - 1, 2e-6);
|
||||
REQUIRE(el - 1 == Approx(0.0).margin(2e-6));
|
||||
else
|
||||
BOOST_REQUIRE_SMALL(el + 1, 2e-6);
|
||||
REQUIRE(el + 1 == Approx(0.0).margin(2e-6));
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input2.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input2.n_cols);
|
||||
REQUIRE(output.n_rows == input2.n_rows);
|
||||
REQUIRE(output.n_cols == input2.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the Sigmoid Cross Entropy performance function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleSigmoidCrossEntropyErrorTest)
|
||||
TEST_CASE("SimpleSigmoidCrossEntropyErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input1, input2, input3, output, target1,
|
||||
target2, target3, expectedOutput;
|
||||
@@ -327,35 +325,35 @@ BOOST_AUTO_TEST_CASE(SimpleSigmoidCrossEntropyErrorTest)
|
||||
double error1 = module.Forward(input1, target1);
|
||||
double expected = 0.97407699;
|
||||
// Value computed using tensorflow.
|
||||
BOOST_REQUIRE_SMALL(error1 / input1.n_elem - expected, 1e-7);
|
||||
REQUIRE(error1 / input1.n_elem - expected == Approx(0.0).margin(1e-7));
|
||||
|
||||
input2 = arma::mat("1 2 3 4 5");
|
||||
target2 = arma::mat("0 0 1 0 1");
|
||||
double error2 = module.Forward(input2, target2);
|
||||
expected = 1.5027283;
|
||||
BOOST_REQUIRE_SMALL(error2 / input2.n_elem - expected, 1e-6);
|
||||
REQUIRE(error2 / input2.n_elem - expected == Approx(0.0).margin(1e-6));
|
||||
|
||||
input3 = arma::mat("0 -1 -1 0 -1 0 0 -1");
|
||||
target3 = arma::mat("0 -1 -1 0 -1 0 0 -1");
|
||||
double error3 = module.Forward(input3, target3);
|
||||
expected = 0.00320443;
|
||||
BOOST_REQUIRE_SMALL(error3 / input3.n_elem - expected, 1e-6);
|
||||
REQUIRE(error3 / input3.n_elem - expected == Approx(0.0).margin(1e-6));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, target1, output);
|
||||
expected = 0.62245929;
|
||||
for (size_t i = 0; i < output.n_elem; ++i)
|
||||
BOOST_REQUIRE_SMALL(output(i) - expected, 1e-5);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input1.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input1.n_cols);
|
||||
REQUIRE(output(i) - expected == Approx(0.0).margin(1e-5));
|
||||
REQUIRE(output.n_rows == input1.n_rows);
|
||||
REQUIRE(output.n_cols == input1.n_cols);
|
||||
|
||||
expectedOutput = arma::mat(
|
||||
"0.7310586 0.88079709 -0.04742587 0.98201376 -0.00669285");
|
||||
module.Backward(input2, target2, output);
|
||||
for (size_t i = 0; i < output.n_elem; ++i)
|
||||
BOOST_REQUIRE_SMALL(output(i) - expectedOutput(i), 1e-5);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input2.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input2.n_cols);
|
||||
REQUIRE(output(i) - expectedOutput(i) == Approx(0.0).margin(1e-5));
|
||||
REQUIRE(output.n_rows == input2.n_rows);
|
||||
REQUIRE(output.n_cols == input2.n_cols);
|
||||
|
||||
module.Backward(input3, target3, output);
|
||||
expectedOutput = arma::mat("0.5 1.2689414");
|
||||
@@ -363,18 +361,18 @@ BOOST_AUTO_TEST_CASE(SimpleSigmoidCrossEntropyErrorTest)
|
||||
{
|
||||
double el = output.at(0, i);
|
||||
if (std::abs(input3.at(i) - 0.0) < 1e-5)
|
||||
BOOST_REQUIRE_SMALL(el - expectedOutput[0], 2e-6);
|
||||
REQUIRE(el - expectedOutput[0] == Approx(0.0).margin(2e-6));
|
||||
else
|
||||
BOOST_REQUIRE_SMALL(el - expectedOutput[1], 2e-6);
|
||||
REQUIRE(el - expectedOutput[1] == Approx(0.0).margin(2e-6));
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input3.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input3.n_cols);
|
||||
REQUIRE(output.n_rows == input3.n_rows);
|
||||
REQUIRE(output.n_cols == input3.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the Earth Mover Distance Layer.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleEarthMoverDistanceLayerTest)
|
||||
TEST_CASE("SimpleEarthMoverDistanceLayerTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input1, input2, output, target1, target2, expectedOutput;
|
||||
EarthMoverDistance<> module;
|
||||
@@ -385,34 +383,34 @@ BOOST_AUTO_TEST_CASE(SimpleEarthMoverDistanceLayerTest)
|
||||
target1 = arma::zeros(1, 8);
|
||||
double error1 = module.Forward(input1, target1);
|
||||
double expected = 0.0;
|
||||
BOOST_REQUIRE_SMALL(error1 / input1.n_elem - expected, 1e-7);
|
||||
REQUIRE(error1 / input1.n_elem - expected == Approx(0.0).margin(1e-7));
|
||||
|
||||
input2 = arma::mat("1 2 3 4 5");
|
||||
target2 = arma::mat("1 0 1 0 1");
|
||||
double error2 = module.Forward(input2, target2);
|
||||
expected = -1.8;
|
||||
BOOST_REQUIRE_SMALL(error2 / input2.n_elem - expected, 1e-6);
|
||||
REQUIRE(error2 / input2.n_elem - expected == Approx(0.0).margin(1e-6));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, target1, output);
|
||||
expected = 0.0;
|
||||
for (size_t i = 0; i < output.n_elem; ++i)
|
||||
BOOST_REQUIRE_SMALL(output(i) - expected, 1e-5);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input1.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input1.n_cols);
|
||||
REQUIRE(output(i) - expected == Approx(0.0).margin(1e-5));
|
||||
REQUIRE(output.n_rows == input1.n_rows);
|
||||
REQUIRE(output.n_cols == input1.n_cols);
|
||||
|
||||
expectedOutput = arma::mat("-1 0 -1 0 -1");
|
||||
module.Backward(input2, target2, output);
|
||||
for (size_t i = 0; i < output.n_elem; ++i)
|
||||
BOOST_REQUIRE_SMALL(output(i) - expectedOutput(i), 1e-5);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input2.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input2.n_cols);
|
||||
REQUIRE(output(i) - expectedOutput(i) == Approx(0.0).margin(1e-5));
|
||||
REQUIRE(output.n_rows == input2.n_rows);
|
||||
REQUIRE(output.n_cols == input2.n_cols);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mean Squared Error numerical gradient test.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(GradientMeanSquaredErrorTest)
|
||||
TEST_CASE("GradientMeanSquaredErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
// Linear function gradient instantiation.
|
||||
struct GradientFunction
|
||||
@@ -449,13 +447,13 @@ BOOST_AUTO_TEST_CASE(GradientMeanSquaredErrorTest)
|
||||
arma::mat input, target;
|
||||
} function;
|
||||
|
||||
BOOST_REQUIRE_LE(CheckGradient(function), 1e-4);
|
||||
REQUIRE(CheckGradient(function) <= 1e-4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reconstruction Loss numerical gradient test.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(GradientReconstructionLossTest)
|
||||
TEST_CASE("GradientReconstructionLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
// Linear function gradient instantiation.
|
||||
struct GradientFunction
|
||||
@@ -492,13 +490,13 @@ BOOST_AUTO_TEST_CASE(GradientReconstructionLossTest)
|
||||
arma::mat input, target;
|
||||
} function;
|
||||
|
||||
BOOST_REQUIRE_LE(CheckGradient(function), 1e-4);
|
||||
REQUIRE(CheckGradient(function) <= 1e-4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the dice loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DiceLossTest)
|
||||
TEST_CASE("DiceLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input1, input2, target, output;
|
||||
double loss;
|
||||
@@ -508,38 +506,38 @@ BOOST_AUTO_TEST_CASE(DiceLossTest)
|
||||
input1 = arma::ones(10, 1);
|
||||
target = arma::ones(10, 1);
|
||||
loss = module.Forward(input1, target);
|
||||
BOOST_REQUIRE_SMALL(loss, 0.00001);
|
||||
REQUIRE(loss == Approx(0.0).margin(1e-5));
|
||||
|
||||
// Test the Forward function. Loss should be 0.185185185.
|
||||
input2 = arma::ones(10, 1) * 0.5;
|
||||
loss = module.Forward(input2, target);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.185185185, 0.00001);
|
||||
REQUIRE(loss == Approx(0.185185185).epsilon(1e-5));
|
||||
|
||||
// Test the Backward function for input = target.
|
||||
module.Backward(input1, target, output);
|
||||
for (double el : output)
|
||||
{
|
||||
// For input = target we should get 0.0 everywhere.
|
||||
BOOST_REQUIRE_CLOSE(el, 0.0, 0.00001);
|
||||
REQUIRE(el == Approx(0.0).epsilon(1e-5));
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input1.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input1.n_cols);
|
||||
REQUIRE(output.n_rows == input1.n_rows);
|
||||
REQUIRE(output.n_cols == input1.n_cols);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input2, target, output);
|
||||
for (double el : output)
|
||||
{
|
||||
// For the 0.5 constant vector we should get -0.0877914951989026 everywhere.
|
||||
BOOST_REQUIRE_CLOSE(el, -0.0877914951989026, 0.00001);
|
||||
REQUIRE(el == Approx(-0.0877914951989026).epsilon(1e-5));
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input2.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input2.n_cols);
|
||||
REQUIRE(output.n_rows == input2.n_rows);
|
||||
REQUIRE(output.n_cols == input2.n_cols);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the mean bias error performance function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleMeanBiasErrorTest)
|
||||
TEST_CASE("SimpleMeanBiasErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, output, target;
|
||||
MeanBiasError<> module;
|
||||
@@ -549,35 +547,35 @@ BOOST_AUTO_TEST_CASE(SimpleMeanBiasErrorTest)
|
||||
input = arma::mat("1.0 0.0 1.0 -1.0 -1.0 0.0 -1.0 0.0");
|
||||
target = arma::zeros(1, 8);
|
||||
double error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_EQUAL(error, 0.125);
|
||||
REQUIRE(error == 0.125);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
// We should get a vector with -1 everywhere.
|
||||
for (double el : output)
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(el, -1);
|
||||
REQUIRE(el == -1);
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
|
||||
// Test the error function on a single input.
|
||||
input = arma::mat("2");
|
||||
target = arma::mat("3");
|
||||
error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_EQUAL(error, 1.0);
|
||||
REQUIRE(error == 1.0);
|
||||
|
||||
// Test the Backward function on a single input.
|
||||
module.Backward(input, target, output);
|
||||
// Test whether the output is negative.
|
||||
BOOST_REQUIRE_EQUAL(arma::accu(output), -1);
|
||||
BOOST_REQUIRE_EQUAL(output.n_elem, 1);
|
||||
REQUIRE(arma::accu(output) == -1);
|
||||
REQUIRE(output.n_elem == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the Log-Hyperbolic-Cosine loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(LogCoshLossTest)
|
||||
TEST_CASE("LogCoshLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output;
|
||||
double loss;
|
||||
@@ -587,36 +585,36 @@ BOOST_AUTO_TEST_CASE(LogCoshLossTest)
|
||||
input = arma::ones(10, 1);
|
||||
target = arma::ones(10, 1);
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_EQUAL(loss, 0);
|
||||
REQUIRE(loss == 0);
|
||||
|
||||
// Test the Backward function for input = target.
|
||||
module.Backward(input, target, output);
|
||||
for (double el : output)
|
||||
{
|
||||
// For input = target we should get 0.0 everywhere.
|
||||
BOOST_REQUIRE_CLOSE(el, 0.0, 1e-5);
|
||||
REQUIRE(el == Approx(0.0).epsilon(1e-5));
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
|
||||
// Test the Forward function. Loss should be 0.546621.
|
||||
input = arma::mat("1 2 3 4 5");
|
||||
target = arma::mat("1 2.4 3.4 4.2 5.5");
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.546621, 1e-3);
|
||||
REQUIRE(loss == Approx(0.546621).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), 2.46962, 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(arma::accu(output) == Approx(2.46962).epsilon(1e-3));
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the Hinge Embedding loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(HingeEmbeddingLossTest)
|
||||
TEST_CASE("HingeEmbeddingLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output;
|
||||
double loss;
|
||||
@@ -626,36 +624,36 @@ BOOST_AUTO_TEST_CASE(HingeEmbeddingLossTest)
|
||||
input = arma::ones(10, 1);
|
||||
target = arma::ones(10, 1);
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_EQUAL(loss, 0);
|
||||
REQUIRE(loss == 0);
|
||||
|
||||
// Test the Backward function for input = target.
|
||||
module.Backward(input, target, output);
|
||||
for (double el : output)
|
||||
{
|
||||
// For input = target we should get 0.0 everywhere.
|
||||
BOOST_REQUIRE_CLOSE(el, 0.0, 1e-5);
|
||||
REQUIRE(el == Approx(0.0).epsilon(1e-5));
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
|
||||
// Test the Forward function. Loss should be 0.84.
|
||||
input = arma::mat("0.1 0.8 0.6 0.0 0.5");
|
||||
target = arma::mat("0 1.0 1.0 0 0");
|
||||
loss = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.84, 1e-3);
|
||||
REQUIRE(loss == Approx(0.84).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), -2, 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(arma::accu(output) == Approx(-2).epsilon(1e-3));
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the l1 loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SimpleL1LossTest)
|
||||
TEST_CASE("SimpleL1LossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input1, input2, output, target1, target2;
|
||||
L1Loss<> module(false);
|
||||
@@ -665,33 +663,33 @@ BOOST_AUTO_TEST_CASE(SimpleL1LossTest)
|
||||
input1 = arma::mat("0.5 0.5 0.5 0.5 0.5 0.5 0.5");
|
||||
target1 = arma::zeros(1, 7);
|
||||
double error1 = module.Forward(input1, target1);
|
||||
BOOST_REQUIRE_EQUAL(error1, 3.5);
|
||||
REQUIRE(error1 == 3.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);
|
||||
BOOST_REQUIRE_CLOSE(error2, 0.0, 0.00001);
|
||||
REQUIRE(error2 == Approx(0.0).epsilon(1e-5));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, target1, output);
|
||||
for (double el : output)
|
||||
BOOST_REQUIRE_EQUAL(el , 1);
|
||||
REQUIRE(el == 1);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input1.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input1.n_cols);
|
||||
REQUIRE(output.n_rows == input1.n_rows);
|
||||
REQUIRE(output.n_cols == input1.n_cols);
|
||||
|
||||
module.Backward(input2, target2, output);
|
||||
for (double el : output)
|
||||
BOOST_REQUIRE_EQUAL(el, 0);
|
||||
REQUIRE(el == 0);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input2.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input2.n_cols);
|
||||
REQUIRE(output.n_rows == input2.n_rows);
|
||||
REQUIRE(output.n_cols == input2.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the Cosine Embedding loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(CosineEmbeddingLossTest)
|
||||
TEST_CASE("CosineEmbeddingLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input1, input2, y, output;
|
||||
double loss;
|
||||
@@ -705,20 +703,20 @@ BOOST_AUTO_TEST_CASE(CosineEmbeddingLossTest)
|
||||
y = arma::mat(1, 1);
|
||||
y.ones();
|
||||
loss = module.Forward(input1, input1);
|
||||
BOOST_REQUIRE_SMALL(loss, 1e-6);
|
||||
REQUIRE(loss == Approx(0.0).margin(1e-6));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, input1, output);
|
||||
BOOST_REQUIRE_SMALL(arma::accu(output), 1e-6);
|
||||
REQUIRE(arma::accu(output) == Approx(0.0).margin(1e-6));
|
||||
|
||||
// Check for dissimilarity.
|
||||
module.Similarity() = false;
|
||||
loss = module.Forward(input1, input1);
|
||||
BOOST_REQUIRE_CLOSE(loss, 1.0, 1e-4);
|
||||
REQUIRE(loss == Approx(1.0).epsilon(1e-4));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, input1, output);
|
||||
BOOST_REQUIRE_SMALL(arma::accu(output), 1e-6);
|
||||
REQUIRE(arma::accu(output) == Approx(0.0).margin(1e-6));
|
||||
|
||||
input1 = arma::mat(3, 2);
|
||||
input2 = arma::mat(3, 2);
|
||||
@@ -730,11 +728,11 @@ BOOST_AUTO_TEST_CASE(CosineEmbeddingLossTest)
|
||||
input2(2) = 2;
|
||||
loss = module.Forward(input1, input2);
|
||||
// Calculated using torch.nn.CosineEmbeddingLoss().
|
||||
BOOST_REQUIRE_CLOSE(loss, 2.897367, 1e-3);
|
||||
REQUIRE(loss == Approx(2.897367).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, input2, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), 0.06324556, 1e-3);
|
||||
REQUIRE(arma::accu(output) == Approx(0.06324556).epsilon(1e-3));
|
||||
|
||||
// Check for correctness for cube.
|
||||
CosineEmbeddingLoss<> module2(0.5, true);
|
||||
@@ -754,31 +752,31 @@ BOOST_AUTO_TEST_CASE(CosineEmbeddingLossTest)
|
||||
input4(11) = 2;
|
||||
loss = module2.Forward(input3, input4);
|
||||
// Calculated using torch.nn.CosineEmbeddingLoss().
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.55395, 1e-3);
|
||||
REQUIRE(loss == Approx(0.55395).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module2.Backward(input3, input4, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), -0.36649111, 1e-3);
|
||||
REQUIRE(arma::accu(output) == Approx(-0.36649111).epsilon(1e-3));
|
||||
|
||||
// Check Output for mean type of reduction.
|
||||
CosineEmbeddingLoss<> module3(0.0, true, true);
|
||||
loss = module3.Forward(input3, input4);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.092325, 1e-3);
|
||||
REQUIRE(loss == Approx(0.092325).epsilon(1e-3));
|
||||
|
||||
// Check correctness for cube.
|
||||
module3.Similarity() = false;
|
||||
loss = module3.Forward(input3, input4);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.90767498236, 1e-3);
|
||||
REQUIRE(loss == Approx(0.90767498236).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module3.Backward(input3, input4, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), 0.36649111, 1e-4);
|
||||
REQUIRE(arma::accu(output) == Approx(0.36649111).epsilon(1e-4));
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the Margin Ranking Loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MarginRankingLossTest)
|
||||
TEST_CASE("MarginRankingLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, input1, input2, target, output;
|
||||
MarginRankingLoss<> module;
|
||||
@@ -791,15 +789,15 @@ BOOST_AUTO_TEST_CASE(MarginRankingLossTest)
|
||||
target = arma::mat("1 -1 -1 1 -1 1");
|
||||
double error = module.Forward(input, target);
|
||||
// Computed using torch.nn.functional.margin_ranking_loss()
|
||||
BOOST_REQUIRE_CLOSE(error, 2.66667, 1e-3);
|
||||
REQUIRE(error == Approx(2.66667).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
|
||||
CheckMatrices(output, arma::mat("-0.000000 0.166667 -1.500000 0.666667 "
|
||||
"0.000000 -0.000000"), 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, target.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, target.n_cols);
|
||||
REQUIRE(output.n_rows == target.n_rows);
|
||||
REQUIRE(output.n_cols == target.n_cols);
|
||||
|
||||
// Test the error function on another input.
|
||||
input1 = arma::mat("0.4287 -1.6208 -1.5006 -0.4473 1.5208 -4.5184 9.3574 "
|
||||
@@ -809,7 +807,7 @@ BOOST_AUTO_TEST_CASE(MarginRankingLossTest)
|
||||
input = arma::join_cols(input1, input2);
|
||||
target = arma::mat("1 1 -1 1 -1 1 1 1 -1 1");
|
||||
error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(error, 3.03530, 1e-3);
|
||||
REQUIRE(error == Approx(3.03530).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function on the second input.
|
||||
module.Backward(input, target, output);
|
||||
@@ -821,7 +819,7 @@ BOOST_AUTO_TEST_CASE(MarginRankingLossTest)
|
||||
/**
|
||||
* Simple test for the Softmargin Loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SoftMarginLossTest)
|
||||
TEST_CASE("SoftMarginLossTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output, expectedOutput;
|
||||
double loss;
|
||||
@@ -844,13 +842,13 @@ BOOST_AUTO_TEST_CASE(SoftMarginLossTest)
|
||||
// Test the Forward function. Loss should be 6.41456.
|
||||
// Value calculated using torch.nn.SoftMarginLoss(reduction='sum').
|
||||
loss = module1.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(loss, 6.41456, 1e-3);
|
||||
REQUIRE(loss == Approx(6.41456).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module1.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::as_scalar(arma::accu(output)), -1.48227, 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(arma::as_scalar(arma::accu(output)) == Approx(-1.48227).epsilon(1e-3));
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
CheckMatrices(output, expectedOutput, 0.1);
|
||||
|
||||
// Test for mean reduction.
|
||||
@@ -863,19 +861,19 @@ BOOST_AUTO_TEST_CASE(SoftMarginLossTest)
|
||||
// Test the Forward function. Loss should be 0.712729.
|
||||
// Value calculated using torch.nn.SoftMarginLoss(reduction='mean').
|
||||
loss = module2.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.712729, 1e-3);
|
||||
REQUIRE(loss == Approx(0.712729).epsilon(1e-3));
|
||||
|
||||
// Test the Backward function.
|
||||
module2.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::as_scalar(arma::accu(output)), -0.164697, 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(arma::as_scalar(arma::accu(output)) == Approx(-0.164697).epsilon(1e-3));
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
CheckMatrices(output, expectedOutput, 0.1);
|
||||
}
|
||||
/**
|
||||
* Simple test for the Mean Absolute Percentage Error function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanAbsolutePercentageErrorTest)
|
||||
TEST_CASE("MeanAbsolutePercentageErrorTest", "[LossFunctionsTest]")
|
||||
{
|
||||
arma::mat input, target, output, expectedOutput;
|
||||
MeanAbsolutePercentageError<> module;
|
||||
@@ -887,14 +885,12 @@ BOOST_AUTO_TEST_CASE(MeanAbsolutePercentageErrorTest)
|
||||
// Test the Forward function. Loss should be 95.625.
|
||||
// Loss value calculated manually.
|
||||
double loss = module.Forward(input,target);
|
||||
BOOST_REQUIRE_CLOSE(loss, 95.625, 1e-1);
|
||||
REQUIRE(loss == Approx(95.625).epsilon(1e-1));
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::as_scalar(arma::accu(output)), -105.625, 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
REQUIRE(arma::as_scalar(arma::accu(output)) == Approx(-105.625).epsilon(1e-3));
|
||||
REQUIRE(output.n_rows == input.n_rows);
|
||||
REQUIRE(output.n_cols == input.n_cols);
|
||||
CheckMatrices(output, expectedOutput, 0.1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -19,8 +19,8 @@ static const std::string testName = "DBSCAN";
|
||||
#include "test_helper.hpp"
|
||||
#include <mlpack/methods/dbscan/dbscan_main.cpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "../test_tools.hpp"
|
||||
#include "../catch.hpp"
|
||||
#include "../test_catch_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -41,17 +41,16 @@ struct DBSCANTestFixture
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(DBSCANMainTest, DBSCANTestFixture);
|
||||
|
||||
/**
|
||||
* Check that number of output labels and number of input
|
||||
* points are equal.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANOutputDimensionTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANOutputDimensionTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
size_t inputSize = inputData.n_cols;
|
||||
|
||||
@@ -60,45 +59,45 @@ BOOST_AUTO_TEST_CASE(DBSCANOutputDimensionTest)
|
||||
mlpackMain();
|
||||
|
||||
// Check that number of predicted labels is equal to the input test points.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::Row<size_t>>("assignments").n_cols,
|
||||
inputSize);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::Row<size_t>>("assignments").n_rows,
|
||||
1);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("centroids").n_rows, 4);
|
||||
BOOST_REQUIRE_GE(IO::GetParam<arma::mat>("centroids").n_cols, 1);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("assignments").n_cols == inputSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("assignments").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("centroids").n_rows == 4);
|
||||
REQUIRE(IO::GetParam<arma::mat>("centroids").n_cols >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that radius of search(epsilon) is always non-negative.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANEpsilonTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANEpsilonTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
SetInputParam("epsilon", (double) -0.5);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that minimum size of cluster is always non-negative.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANMinSizeTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANMinSizeTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
SetInputParam("min_size", (int) -1);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
@@ -106,11 +105,12 @@ BOOST_AUTO_TEST_CASE(DBSCANMinSizeTest)
|
||||
* Check that no point is labelled as noise point
|
||||
* when min_size is equal to 1.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANClusterNumberTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANClusterNumberTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
SetInputParam("min_size", (int) 1);
|
||||
@@ -122,18 +122,19 @@ BOOST_AUTO_TEST_CASE(DBSCANClusterNumberTest)
|
||||
output = std::move(IO::GetParam<arma::Row<size_t>>("assignments"));
|
||||
|
||||
for (size_t i = 0; i < output.n_elem; ++i)
|
||||
BOOST_REQUIRE_LT(output[i], inputData.n_cols);
|
||||
REQUIRE(output[i] < inputData.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the cluster assignment is different for different
|
||||
* values of epsilon.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANDiffEpsilonTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANDiffEpsilonTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
SetInputParam("epsilon", (double) 1.0);
|
||||
@@ -156,18 +157,19 @@ BOOST_AUTO_TEST_CASE(DBSCANDiffEpsilonTest)
|
||||
arma::Row<size_t> output2;
|
||||
output2 = std::move(IO::GetParam<arma::Row<size_t>>("assignments"));
|
||||
|
||||
BOOST_REQUIRE_GT(arma::accu(output1 != output2), 1);
|
||||
REQUIRE(arma::accu(output1 != output2) > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the cluster assignment is different for different
|
||||
* values of Min Size.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANDiffMinSizeTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANDiffMinSizeTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
SetInputParam("epsilon", (double) 0.4);
|
||||
@@ -193,7 +195,7 @@ BOOST_AUTO_TEST_CASE(DBSCANDiffMinSizeTest)
|
||||
arma::Row<size_t> output2;
|
||||
output2 = std::move(IO::GetParam<arma::Row<size_t>>("assignments"));
|
||||
|
||||
BOOST_REQUIRE_GT(arma::accu(output1 != output2), 1);
|
||||
REQUIRE(arma::accu(output1 != output2) > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,17 +203,18 @@ BOOST_AUTO_TEST_CASE(DBSCANDiffMinSizeTest)
|
||||
* tree types. ’kd’, ’r’, ’r-star’, ’x’, ’hilbert-r’, ’r-plus’,
|
||||
* ’r-plus-plus’, ’cover’, ’ball’.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANTreeTypeTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANTreeTypeTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", std::move(inputData));
|
||||
SetInputParam("tree_type", std::string("binary"));
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
@@ -219,11 +222,12 @@ BOOST_AUTO_TEST_CASE(DBSCANTreeTypeTest)
|
||||
* Check that the assignment of cluster is same if
|
||||
* different tree type is used for search.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANDiffTreeTypeTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANDiffTreeTypeTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
// Tree type = kd tree.
|
||||
|
||||
@@ -369,11 +373,12 @@ BOOST_AUTO_TEST_CASE(DBSCANDiffTreeTypeTest)
|
||||
* Check that the assignment of cluster is same if
|
||||
* single tree is used for search.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANSingleTreeTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANSingleTreeTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
|
||||
@@ -401,11 +406,12 @@ BOOST_AUTO_TEST_CASE(DBSCANSingleTreeTest)
|
||||
* Check that the assignment of cluster is same if
|
||||
* single tree is used for search.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANNaiveSearchTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANNaiveSearchTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
|
||||
@@ -433,11 +439,12 @@ BOOST_AUTO_TEST_CASE(DBSCANNaiveSearchTest)
|
||||
* Check that the assignment of cluster is different if
|
||||
* point selection policies are different.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DBSCANRandomSelectionFlagTest)
|
||||
TEST_CASE_METHOD(DBSCANTestFixture, "DBSCANRandomSelectionFlagTest",
|
||||
"[DBSCANMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("iris.csv", inputData))
|
||||
BOOST_FAIL("Unable to load dataset iris.csv!");
|
||||
FAIL("Unable to load dataset iris.csv!");
|
||||
|
||||
SetInputParam("input", inputData);
|
||||
SetInputParam("epsilon", (double) 0.358);
|
||||
@@ -466,7 +473,5 @@ BOOST_AUTO_TEST_CASE(DBSCANRandomSelectionFlagTest)
|
||||
arma::Row<size_t> randomOutput;
|
||||
randomOutput = std::move(IO::GetParam<arma::Row<size_t>>("assignments"));
|
||||
|
||||
BOOST_REQUIRE_GT(arma::accu(orderedOutput != randomOutput), 0);
|
||||
REQUIRE(arma::accu(orderedOutput != randomOutput) > 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
#include <string>
|
||||
|
||||
#define BINDING_TYPE BINDING_TYPE_TEST
|
||||
static const std::string testName = "MeanShift";
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
static const std::string testName = "MeanShift";
|
||||
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/methods/mean_shift/mean_shift_main.cpp>
|
||||
#include "test_helper.hpp"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "../test_tools.hpp"
|
||||
#include "test_helper.hpp"
|
||||
#include "../test_catch_tools.hpp"
|
||||
#include "../catch.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -48,13 +49,13 @@ static void ResetSettings()
|
||||
IO::RestoreSettings(testName);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(MeanShiftMainTest, MeanShiftTestFixture);
|
||||
|
||||
/**
|
||||
* Ensure that the output has 1 extra row for the labels and
|
||||
* check the number of points for output remain the same.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftOutputDimensionTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftOutputDimensionTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
x.randu(3, 100); // 100 points in 3 dimension
|
||||
@@ -65,16 +66,18 @@ BOOST_AUTO_TEST_CASE(MeanShiftOutputDimensionTest)
|
||||
mlpackMain();
|
||||
|
||||
// Now check that the output has 1 extra row for labels.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_rows, 3 + 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_rows == 3 + 1);
|
||||
// Check number of output points are the same.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_cols, 100);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_cols == 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that if we ask for labels_only, output has 1 row and
|
||||
* same number of columns for each point's label.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftLabelOnlyOutputDimensionTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftLabelOnlyOutputDimensionTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
x.randu(3, 100); // 100 points in 3 dimension
|
||||
@@ -86,9 +89,9 @@ BOOST_AUTO_TEST_CASE(MeanShiftLabelOnlyOutputDimensionTest)
|
||||
mlpackMain();
|
||||
|
||||
// Check that there is only 1 row containing all the labels.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_rows, 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_rows == 1);
|
||||
// Check number of output points are the same.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_cols, 100);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_cols == 100);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,11 +99,13 @@ BOOST_AUTO_TEST_CASE(MeanShiftLabelOnlyOutputDimensionTest)
|
||||
* and check the number of points remain the same if the --in_place
|
||||
* flag is set.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftInPlaceTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftInPlaceTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
if (!data::Load("iris_test.csv", x))
|
||||
BOOST_FAIL("Cannot load test dataset iris_test.csv!");
|
||||
FAIL("Cannot load test dataset iris_test.csv!");
|
||||
|
||||
// Get initial number of rows and columns in file.
|
||||
int numRows = x.n_rows;
|
||||
@@ -113,20 +118,22 @@ BOOST_AUTO_TEST_CASE(MeanShiftInPlaceTest)
|
||||
mlpackMain();
|
||||
|
||||
// Now check that the output has 1 extra row for labels.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_rows, numRows + 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_rows == numRows + 1);
|
||||
// Check number of output points are the same.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_cols, numCols);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_cols == numCols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that force_convergence is used by testing that the
|
||||
* force_convergence flag makes a difference in the program.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftForceConvergenceTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftForceConvergenceTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
if (!data::Load("iris_test.csv", x))
|
||||
BOOST_FAIL("Cannot load test dataset iris_test.csv!");
|
||||
FAIL("Cannot load test dataset iris_test.csv!");
|
||||
|
||||
// Input random data points.
|
||||
SetInputParam("input", x);
|
||||
@@ -150,18 +157,20 @@ BOOST_AUTO_TEST_CASE(MeanShiftForceConvergenceTest)
|
||||
|
||||
const int numCentroids2 = IO::GetParam<arma::mat>("centroid").n_cols;
|
||||
// Resulting number of centroids should be different.
|
||||
BOOST_REQUIRE_NE(numCentroids1, numCentroids2);
|
||||
REQUIRE(numCentroids1 != numCentroids2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that radius is used by testing that the radius
|
||||
* makes a difference in the program.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftRadiusTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftRadiusTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
if (!data::Load("iris_test.csv", x))
|
||||
BOOST_FAIL("Cannot load test dataset iris_test.csv!");
|
||||
FAIL("Cannot load test dataset iris_test.csv!");
|
||||
|
||||
// Input random data points.
|
||||
SetInputParam("input", x);
|
||||
@@ -183,18 +192,20 @@ BOOST_AUTO_TEST_CASE(MeanShiftRadiusTest)
|
||||
|
||||
const int numCentroids2 = IO::GetParam<arma::mat>("centroid").n_cols;
|
||||
// Resulting number of centroids should be different.
|
||||
BOOST_REQUIRE_NE(numCentroids1, numCentroids2);
|
||||
REQUIRE(numCentroids1 != numCentroids2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that max_iterations is used by testing that the
|
||||
* max_iteration makes a difference in the program.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftMaxIterationsTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftMaxIterationsTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
if (!data::Load("iris_test.csv", x))
|
||||
BOOST_FAIL("Cannot load test dataset iris_test.csv!");
|
||||
FAIL("Cannot load test dataset iris_test.csv!");
|
||||
|
||||
// Input random data points.
|
||||
SetInputParam("input", x);
|
||||
@@ -216,13 +227,15 @@ BOOST_AUTO_TEST_CASE(MeanShiftMaxIterationsTest)
|
||||
|
||||
const int numCentroids2 = IO::GetParam<arma::mat>("centroid").n_cols;
|
||||
// Resulting number of centroids should be different.
|
||||
BOOST_REQUIRE_NE(numCentroids1, numCentroids2);
|
||||
REQUIRE(numCentroids1 != numCentroids2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that we can't specify an invalid max number of iterations.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftInvalidMaxIterationsTest)
|
||||
TEST_CASE_METHOD(
|
||||
MeanShiftTestFixture, "MeanShiftInvalidMaxIterationsTest",
|
||||
"[MeanShiftMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x;
|
||||
x.randu(3, 100); // 100 points in 3 dimension
|
||||
@@ -233,8 +246,6 @@ BOOST_AUTO_TEST_CASE(MeanShiftInvalidMaxIterationsTest)
|
||||
SetInputParam("max_iterations", (int) -1);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -19,8 +19,7 @@ static const std::string testName = "PrincipalComponentAnalysis";
|
||||
#include "test_helper.hpp"
|
||||
#include <mlpack/methods/pca/pca_main.cpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "../test_tools.hpp"
|
||||
#include "../catch.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -41,12 +40,11 @@ struct PCATestFixture
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(PCAMainTest, PCATestFixture);
|
||||
|
||||
/**
|
||||
* Make sure that if we ask for a dataset in 3 dimensions back, we get it.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(PCADimensionTest)
|
||||
TEST_CASE_METHOD(PCATestFixture, "PCADimensionTest",
|
||||
"[PCAMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x = arma::randu<arma::mat>(5, 5);
|
||||
|
||||
@@ -57,15 +55,16 @@ BOOST_AUTO_TEST_CASE(PCADimensionTest)
|
||||
mlpackMain();
|
||||
|
||||
// Now check that the output has 3 dimensions.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_rows, 3);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_cols, 5);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_rows == 3);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_cols == 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that if we retain all variance, we get back a matrix with the same
|
||||
* dimensionality.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(PCAVarRetainTest)
|
||||
TEST_CASE_METHOD(PCATestFixture, "PCAVarRetainTest",
|
||||
"[PCAMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x = arma::randu<arma::mat>(4, 5);
|
||||
|
||||
@@ -77,14 +76,15 @@ BOOST_AUTO_TEST_CASE(PCAVarRetainTest)
|
||||
mlpackMain();
|
||||
|
||||
// Check that the output has 5 dimensions.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_rows, 4);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_cols, 5);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_rows == 4);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_cols == 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that if we retain no variance, we get back no dimensions.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(PCANoVarRetainTest)
|
||||
TEST_CASE_METHOD(PCATestFixture, "PCANoVarRetainTest",
|
||||
"[PCAMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x = arma::randu<arma::mat>(5, 5);
|
||||
|
||||
@@ -96,14 +96,15 @@ BOOST_AUTO_TEST_CASE(PCANoVarRetainTest)
|
||||
mlpackMain();
|
||||
|
||||
// Check that the output has 1 dimensions.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("output").n_cols, 5);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("output").n_cols == 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that we can't specify an invalid new dimensionality.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(PCATooHighNewDimensionalityTest)
|
||||
TEST_CASE_METHOD(PCATestFixture, "PCATooHighNewDimensionalityTest",
|
||||
"[PCAMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat x = arma::randu<arma::mat>(5, 5);
|
||||
|
||||
@@ -111,8 +112,6 @@ BOOST_AUTO_TEST_CASE(PCATooHighNewDimensionalityTest)
|
||||
SetInputParam("new_dimensionality", (int) 7); // Invalid.
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -18,8 +18,8 @@ static const std::string testName = "RandomForest";
|
||||
#include <mlpack/methods/random_forest/random_forest_main.cpp>
|
||||
#include "test_helper.hpp"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "../test_tools.hpp"
|
||||
#include "../catch.hpp"
|
||||
#include "../test_catch_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -40,25 +40,24 @@ struct RandomForestTestFixture
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(RandomForestMainTest, RandomForestTestFixture);
|
||||
|
||||
/**
|
||||
* Check that number of output points and number of input
|
||||
* points are equal and have appropriate number of classes.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestOutputDimensionTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestOutputDimensionTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
arma::mat testData;
|
||||
if (!data::Load("vc2_test.csv", testData))
|
||||
BOOST_FAIL("Cannot load test dataset vc2.csv!");
|
||||
FAIL("Cannot load test dataset vc2.csv!");
|
||||
|
||||
size_t testSize = testData.n_cols;
|
||||
|
||||
@@ -72,34 +71,32 @@ BOOST_AUTO_TEST_CASE(RandomForestOutputDimensionTest)
|
||||
mlpackMain();
|
||||
|
||||
// Check that number of output points are equal to number of input points.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::Row<size_t>>("predictions").n_cols,
|
||||
testSize);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_cols,
|
||||
testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals number of classes in case of
|
||||
// probabilities and 1 for predictions.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::Row<size_t>>("predictions").n_rows,
|
||||
1);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_rows, 3);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_rows == 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that saved model can be used again.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestModelReuseTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestModelReuseTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
arma::mat testData;
|
||||
if (!data::Load("vc2_test.csv", testData))
|
||||
BOOST_FAIL("Cannot load test dataset vc2.csv!");
|
||||
FAIL("Cannot load test dataset vc2.csv!");
|
||||
|
||||
size_t testSize = testData.n_cols;
|
||||
|
||||
@@ -130,16 +127,13 @@ BOOST_AUTO_TEST_CASE(RandomForestModelReuseTest)
|
||||
mlpackMain();
|
||||
|
||||
// Check that number of output points are equal to number of input points.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::Row<size_t>>("predictions").n_cols,
|
||||
testSize);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_cols,
|
||||
testSize);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_cols == testSize);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_cols == testSize);
|
||||
|
||||
// Check number of output rows equals number of classes in case of
|
||||
// probabilities and 1 for predicitions.
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::Row<size_t>>("predictions").n_rows,
|
||||
1);
|
||||
BOOST_REQUIRE_EQUAL(IO::GetParam<arma::mat>("probabilities").n_rows, 3);
|
||||
REQUIRE(IO::GetParam<arma::Row<size_t>>("predictions").n_rows == 1);
|
||||
REQUIRE(IO::GetParam<arma::mat>("probabilities").n_rows == 3);
|
||||
|
||||
// Check that initial predictions and predictions using saved model are same.
|
||||
CheckMatrices(predictions, IO::GetParam<arma::Row<size_t>>("predictions"));
|
||||
@@ -149,75 +143,79 @@ BOOST_AUTO_TEST_CASE(RandomForestModelReuseTest)
|
||||
/**
|
||||
* Make sure number of trees specified is always a positive number.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestNumOfTreesTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestNumOfTreesTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
SetInputParam("num_trees", (int) 0); // Invalid.
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure minimum leaf size specified is always a positive number.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestMinimumLeafSizeTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestMinimumLeafSizeTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
SetInputParam("minimum_leaf_size", (int) 0); // Invalid.
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure maximum depth specified is always a positive number.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestMaximumDepthTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestMaximumDepthTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
SetInputParam("maximum_depth", (int) -1); // Invalid.
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(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(RandomForestTrainingVerTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestTrainingVerTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
// Input training data.
|
||||
SetInputParam("training", std::move(inputData));
|
||||
@@ -230,7 +228,7 @@ BOOST_AUTO_TEST_CASE(RandomForestTrainingVerTest)
|
||||
IO::GetParam<RandomForestModel*>("output_model"));
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
@@ -254,16 +252,17 @@ inline bool CheckDifferentTrees(const TreeType& nodeA, const TreeType& nodeB)
|
||||
* Ensure that the trees have different structure as the minimum leaf size is
|
||||
* changed.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestDiffMinLeafSizeTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestDiffMinLeafSizeTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
// Train for minimum leaf size 20.
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
// Input training data.
|
||||
SetInputParam("training", inputData);
|
||||
@@ -310,8 +309,8 @@ BOOST_AUTO_TEST_CASE(RandomForestDiffMinLeafSizeTest)
|
||||
// Check that each tree is different.
|
||||
for (size_t i = 0; i < rf1->rf.NumTrees(); ++i)
|
||||
{
|
||||
BOOST_REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf2->rf.Tree(i)));
|
||||
BOOST_REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf3->rf.Tree(i)));
|
||||
REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf2->rf.Tree(i)));
|
||||
REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf3->rf.Tree(i)));
|
||||
}
|
||||
|
||||
delete rf1;
|
||||
@@ -323,24 +322,25 @@ BOOST_AUTO_TEST_CASE(RandomForestDiffMinLeafSizeTest)
|
||||
* Ensure that the number of trees are different when num_trees is specified
|
||||
* differently.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestDiffNumTreeTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestDiffNumTreeTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
// Train for num_trees 1.
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
arma::mat testData;
|
||||
if (!data::Load("vc2_test.csv", testData))
|
||||
BOOST_FAIL("Cannot load test dataset vc2_test.csv!");
|
||||
FAIL("Cannot load test dataset vc2_test.csv!");
|
||||
|
||||
arma::Row<size_t> testLabels;
|
||||
if (!data::Load("vc2_test_labels.txt", testLabels))
|
||||
BOOST_FAIL("Cannot load labels for vc2__test_labels.txt");
|
||||
FAIL("Cannot load labels for vc2__test_labels.txt");
|
||||
|
||||
// Input training data.
|
||||
SetInputParam("training", inputData);
|
||||
@@ -383,23 +383,24 @@ BOOST_AUTO_TEST_CASE(RandomForestDiffNumTreeTest)
|
||||
const size_t numTrees3 =
|
||||
IO::GetParam<RandomForestModel*>("output_model")->rf.NumTrees();
|
||||
|
||||
BOOST_REQUIRE_NE(numTrees1, numTrees2);
|
||||
BOOST_REQUIRE_NE(numTrees2, numTrees3);
|
||||
REQUIRE(numTrees1 != numTrees2);
|
||||
REQUIRE(numTrees2 != numTrees3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the maximum_depth parameter makes a difference.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestDiffMaxDepthTest)
|
||||
TEST_CASE_METHOD(RandomForestTestFixture, "RandomForestDiffMaxDepthTest",
|
||||
"[RandomForestMainTest][BindingTests]")
|
||||
{
|
||||
// Train for minimum leaf size 20.
|
||||
arma::mat inputData;
|
||||
if (!data::Load("vc2.csv", inputData))
|
||||
BOOST_FAIL("Cannot load train dataset vc2.csv!");
|
||||
FAIL("Cannot load train dataset vc2.csv!");
|
||||
|
||||
arma::Row<size_t> labels;
|
||||
if (!data::Load("vc2_labels.txt", labels))
|
||||
BOOST_FAIL("Cannot load labels for vc2_labels.txt");
|
||||
FAIL("Cannot load labels for vc2_labels.txt");
|
||||
|
||||
// Input training data.
|
||||
SetInputParam("training", inputData);
|
||||
@@ -444,13 +445,11 @@ BOOST_AUTO_TEST_CASE(RandomForestDiffMaxDepthTest)
|
||||
// Check that each tree is different.
|
||||
for (size_t i = 0; i < rf1->rf.NumTrees(); ++i)
|
||||
{
|
||||
BOOST_REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf2->rf.Tree(i)));
|
||||
BOOST_REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf3->rf.Tree(i)));
|
||||
REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf2->rf.Tree(i)));
|
||||
REQUIRE(CheckDifferentTrees(rf1->rf.Tree(i), rf3->rf.Tree(i)));
|
||||
}
|
||||
|
||||
delete rf1;
|
||||
delete rf2;
|
||||
delete rf3;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -12,15 +12,13 @@
|
||||
|
||||
#include <mlpack/methods/mean_shift/mean_shift.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "test_catch_tools.hpp"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::meanshift;
|
||||
using namespace mlpack::distribution;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(MeanShiftTest);
|
||||
|
||||
// Generate dataset; written transposed because it's easier to read.
|
||||
arma::mat meanShiftData(" 0.0 0.0;" // Class 1.
|
||||
" 0.3 0.4;"
|
||||
@@ -57,7 +55,7 @@ arma::mat meanShiftData(" 0.0 0.0;" // Class 1.
|
||||
/**
|
||||
* 30-point 3-class test case for Mean Shift.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MeanShiftSimpleTest)
|
||||
TEST_CASE("MeanShiftSimpleTest", "[MeanShiftTest]")
|
||||
{
|
||||
MeanShift<> meanShift;
|
||||
|
||||
@@ -70,29 +68,29 @@ BOOST_AUTO_TEST_CASE(MeanShiftSimpleTest)
|
||||
size_t firstClass = assignments(0);
|
||||
|
||||
for (size_t i = 1; i < 13; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments(i), firstClass);
|
||||
REQUIRE(assignments(i) == firstClass);
|
||||
|
||||
size_t secondClass = assignments(13);
|
||||
|
||||
// To ensure that class 1 != class 2.
|
||||
BOOST_REQUIRE_NE(firstClass, secondClass);
|
||||
REQUIRE(firstClass != secondClass);
|
||||
|
||||
for (size_t i = 13; i < 20; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments(i), secondClass);
|
||||
REQUIRE(assignments(i) == secondClass);
|
||||
|
||||
size_t thirdClass = assignments(20);
|
||||
|
||||
// To ensure that this is the third class which we haven't seen yet.
|
||||
BOOST_REQUIRE_NE(firstClass, thirdClass);
|
||||
BOOST_REQUIRE_NE(secondClass, thirdClass);
|
||||
REQUIRE(firstClass != thirdClass);
|
||||
REQUIRE(secondClass != thirdClass);
|
||||
|
||||
for (size_t i = 20; i < 30; ++i)
|
||||
BOOST_REQUIRE_EQUAL(assignments(i), thirdClass);
|
||||
REQUIRE(assignments(i) == thirdClass);
|
||||
}
|
||||
|
||||
// Generate samples from four Gaussians, and make sure mean shift nearly
|
||||
// recovers those four centers.
|
||||
BOOST_AUTO_TEST_CASE(GaussianClustering)
|
||||
TEST_CASE("GaussianClustering", "[MeanShiftTest]")
|
||||
{
|
||||
GaussianDistribution g1("0.0 0.0 0.0", arma::eye<arma::mat>(3, 3));
|
||||
GaussianDistribution g2("5.0 5.0 5.0", 2 * arma::eye<arma::mat>(3, 3));
|
||||
@@ -162,7 +160,5 @@ BOOST_AUTO_TEST_CASE(GaussianClustering)
|
||||
break;
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_EQUAL(success, true);
|
||||
REQUIRE(success == true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
#include <mlpack/methods/pca/decomposition_policies/randomized_svd_method.hpp>
|
||||
#include <mlpack/methods/pca/decomposition_policies/randomized_block_krylov_method.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(PCATest);
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace arma;
|
||||
using namespace mlpack;
|
||||
@@ -50,9 +47,9 @@ void ArmaComparisonPCA(
|
||||
for (size_t i = 0; i < eigVal.n_elem; ++i)
|
||||
{
|
||||
if (eigVal[i] == 0.0)
|
||||
BOOST_REQUIRE_SMALL(eigVal1[i], 1e-15);
|
||||
REQUIRE(eigVal1[i] == Approx(0.0).margin(1e-15));
|
||||
else
|
||||
BOOST_REQUIRE_CLOSE(eigVal[i], eigVal1[i], 0.0001);
|
||||
REQUIRE(eigVal[i] == Approx(eigVal1[i]).epsilon(1e-6));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,14 +85,14 @@ void PCADimensionalityReduction(
|
||||
++trial;
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_EQUAL(success, true);
|
||||
REQUIRE(success == true);
|
||||
|
||||
// Compare with correct results.
|
||||
mat correct("-1.53781086 -3.51358020 -0.16139887 -1.87706634 7.08985628;"
|
||||
" 1.29937798 3.45762685 -2.69910005 -3.15620704 1.09830225");
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, correct.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, correct.n_cols);
|
||||
REQUIRE(data.n_rows == correct.n_rows);
|
||||
REQUIRE(data.n_cols == correct.n_cols);
|
||||
|
||||
// If the eigenvectors are pointed opposite directions, they will cancel
|
||||
// each other out in this summation.
|
||||
@@ -110,10 +107,10 @@ void PCADimensionalityReduction(
|
||||
|
||||
for (size_t row = 0; row < 2; row++)
|
||||
for (size_t col = 0; col < 5; col++)
|
||||
BOOST_REQUIRE_CLOSE(data(row, col), correct(row, col), 1e-3);
|
||||
REQUIRE(data(row, col) == Approx(correct(row, col)).epsilon(1e-5));
|
||||
|
||||
// Check that the amount of variance retained is right.
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 0.904876047045906, 1e-5);
|
||||
REQUIRE(varRetained == Approx(0.904876047045906).epsilon(1e-7));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,50 +138,50 @@ void PCAVarianceRetained()
|
||||
arma::mat origData = data;
|
||||
double varRetained = p.Apply(data, 0.1);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, 5);
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 0.616237391936100, 1e-5);
|
||||
REQUIRE(data.n_rows == 1);
|
||||
REQUIRE(data.n_cols == 5);
|
||||
REQUIRE(varRetained == Approx(0.616237391936100).epsilon(1e-7));
|
||||
|
||||
data = origData;
|
||||
varRetained = p.Apply(data, 0.5);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, 5);
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 0.616237391936100, 1e-5);
|
||||
REQUIRE(data.n_rows == 1);
|
||||
REQUIRE(data.n_cols == 5);
|
||||
REQUIRE(varRetained == Approx(0.616237391936100).epsilon(1e-7));
|
||||
|
||||
data = origData;
|
||||
varRetained = p.Apply(data, 0.7);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, 2);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, 5);
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 0.904876047045906, 1e-5);
|
||||
REQUIRE(data.n_rows == 2);
|
||||
REQUIRE(data.n_cols == 5);
|
||||
REQUIRE(varRetained == Approx(0.904876047045906).epsilon(1e-7));
|
||||
|
||||
data = origData;
|
||||
varRetained = p.Apply(data, 0.904);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, 2);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, 5);
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 0.904876047045906, 1e-5);
|
||||
REQUIRE(data.n_rows == 2);
|
||||
REQUIRE(data.n_cols == 5);
|
||||
REQUIRE(varRetained == Approx(0.904876047045906).epsilon(1e-7));
|
||||
|
||||
data = origData;
|
||||
varRetained = p.Apply(data, 0.905);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, 3);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, 5);
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 1.0, 1e-5);
|
||||
REQUIRE(data.n_rows == 3);
|
||||
REQUIRE(data.n_cols == 5);
|
||||
REQUIRE(varRetained == Approx(1.0).epsilon(1e-7));
|
||||
|
||||
data = origData;
|
||||
varRetained = p.Apply(data, 1.0);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, 3);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, 5);
|
||||
BOOST_REQUIRE_CLOSE(varRetained, 1.0, 1e-5);
|
||||
REQUIRE(data.n_rows == 3);
|
||||
REQUIRE(data.n_cols == 5);
|
||||
REQUIRE(varRetained == Approx(1.0).epsilon(1e-7));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the output of our exact PCA implementation with Armadillo's.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ArmaComparisonExactPCATest)
|
||||
TEST_CASE("ArmaComparisonExactPCATest", "[PCATest]")
|
||||
{
|
||||
ArmaComparisonPCA<ExactSVDPolicy>();
|
||||
}
|
||||
@@ -193,7 +190,7 @@ BOOST_AUTO_TEST_CASE(ArmaComparisonExactPCATest)
|
||||
* Compare the output of our randomized block krylov PCA implementation with
|
||||
* Armadillo's.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ArmaComparisonRandomizedBlockKrylovPCATest)
|
||||
TEST_CASE("ArmaComparisonRandomizedBlockKrylovPCATest", "[PCATest]")
|
||||
{
|
||||
RandomizedBlockKrylovSVDPolicy decomposition(5);
|
||||
ArmaComparisonPCA<RandomizedBlockKrylovSVDPolicy>(false, decomposition);
|
||||
@@ -202,7 +199,7 @@ BOOST_AUTO_TEST_CASE(ArmaComparisonRandomizedBlockKrylovPCATest)
|
||||
/**
|
||||
* Compare the output of our randomized-SVD PCA implementation with Armadillo's.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ArmaComparisonRandomizedPCATest)
|
||||
TEST_CASE("ArmaComparisonRandomizedPCATest", "[PCATest]")
|
||||
{
|
||||
ArmaComparisonPCA<RandomizedSVDPolicy>();
|
||||
}
|
||||
@@ -211,7 +208,7 @@ BOOST_AUTO_TEST_CASE(ArmaComparisonRandomizedPCATest)
|
||||
* Test that dimensionality reduction with exact-svd PCA works the same way
|
||||
* MATLAB does (which should be correct!).
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ExactPCADimensionalityReductionTest)
|
||||
TEST_CASE("ExactPCADimensionalityReductionTest", "[PCATest]")
|
||||
{
|
||||
PCADimensionalityReduction<ExactSVDPolicy>();
|
||||
}
|
||||
@@ -220,7 +217,7 @@ BOOST_AUTO_TEST_CASE(ExactPCADimensionalityReductionTest)
|
||||
* Test that dimensionality reduction with randomized block krylov PCA works the
|
||||
* same way MATLAB does (which should be correct!).
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomizedBlockKrylovPCADimensionalityReductionTest)
|
||||
TEST_CASE("RandomizedBlockKrylovPCADimensionalityReductionTest", "[PCATest]")
|
||||
{
|
||||
RandomizedBlockKrylovSVDPolicy decomposition(5);
|
||||
PCADimensionalityReduction<RandomizedBlockKrylovSVDPolicy>(false,
|
||||
@@ -231,7 +228,7 @@ BOOST_AUTO_TEST_CASE(RandomizedBlockKrylovPCADimensionalityReductionTest)
|
||||
* Test that dimensionality reduction with randomized-svd PCA works the same way
|
||||
* MATLAB does (which should be correct!).
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomizedPCADimensionalityReductionTest)
|
||||
TEST_CASE("RandomizedPCADimensionalityReductionTest", "[PCATest]")
|
||||
{
|
||||
PCADimensionalityReduction<RandomizedSVDPolicy>();
|
||||
}
|
||||
@@ -240,7 +237,7 @@ BOOST_AUTO_TEST_CASE(RandomizedPCADimensionalityReductionTest)
|
||||
* Test that dimensionality reduction with QUIC-SVD PCA works the same way
|
||||
* as the Exact-SVD PCA method.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(QUICPCADimensionalityReductionTest)
|
||||
TEST_CASE("QUICPCADimensionalityReductionTest", "[PCATest]")
|
||||
{
|
||||
arma::mat data, data1;
|
||||
data::Load("test_data_3_1000.csv", data);
|
||||
@@ -275,16 +272,16 @@ BOOST_AUTO_TEST_CASE(QUICPCADimensionalityReductionTest)
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_GE(successes, 1);
|
||||
BOOST_REQUIRE_EQUAL(data.n_rows, data1.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(data.n_cols, data1.n_cols);
|
||||
REQUIRE(successes >= 1);
|
||||
REQUIRE(data.n_rows == data1.n_rows);
|
||||
REQUIRE(data.n_cols == data1.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that setting the variance retained parameter to perform dimensionality
|
||||
* reduction works using the exact svd PCA method.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ExactPCAVarianceRetainedTest)
|
||||
TEST_CASE("ExactPCAVarianceRetainedTest", "[PCATest]")
|
||||
{
|
||||
PCAVarianceRetained<ExactSVDPolicy>();
|
||||
}
|
||||
@@ -292,7 +289,7 @@ BOOST_AUTO_TEST_CASE(ExactPCAVarianceRetainedTest)
|
||||
/**
|
||||
* Test that scaling PCA works.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(PCAScalingTest)
|
||||
TEST_CASE("PCAScalingTest", "[PCATest]")
|
||||
{
|
||||
// Generate an artificial dataset in 3 dimensions.
|
||||
arma::mat data(3, 5000);
|
||||
@@ -317,25 +314,22 @@ BOOST_AUTO_TEST_CASE(PCAScalingTest)
|
||||
// The first two components of the eigenvector with largest eigenvalue should
|
||||
// be somewhere near sqrt(2) / 2. The third component should be close to
|
||||
// zero. There is noise, of course...
|
||||
BOOST_REQUIRE_CLOSE(std::abs(eigvec(0, 0)), sqrt(2) / 2, 0.35);
|
||||
BOOST_REQUIRE_CLOSE(std::abs(eigvec(1, 0)), sqrt(2) / 2, 0.35);
|
||||
BOOST_REQUIRE_SMALL(eigvec(2, 0), 0.1); // Large tolerance for noise.
|
||||
REQUIRE(std::abs(eigvec(0, 0)) == Approx(sqrt(2) / 2).epsilon(0.0035));
|
||||
REQUIRE(std::abs(eigvec(1, 0)) == Approx(sqrt(2) / 2).epsilon(0.0035));
|
||||
REQUIRE(eigvec(2, 0) == Approx(0.0).margin(0.1)); // Large tolerance for noise.
|
||||
|
||||
// The second component should be focused almost entirely in the third
|
||||
// dimension.
|
||||
BOOST_REQUIRE_SMALL(eigvec(0, 1), 0.1);
|
||||
BOOST_REQUIRE_SMALL(eigvec(1, 1), 0.1);
|
||||
BOOST_REQUIRE_CLOSE(std::abs(eigvec(2, 1)), 1.0, 0.35);
|
||||
REQUIRE(eigvec(0, 1) == Approx(0.0).margin(0.1));
|
||||
REQUIRE(eigvec(1, 1) == Approx(0.0).margin(0.1));
|
||||
REQUIRE(std::abs(eigvec(2, 1)) == Approx(1.0).epsilon(0.0035));
|
||||
|
||||
// The third component should have the same absolute value characteristics as
|
||||
// the first (plus 20% tolerance).
|
||||
BOOST_REQUIRE_CLOSE(std::abs(eigvec(0, 0)), sqrt(2) / 2, 0.35);
|
||||
BOOST_REQUIRE_CLOSE(std::abs(eigvec(1, 0)), sqrt(2) / 2, 0.35);
|
||||
BOOST_REQUIRE_SMALL(eigvec(2, 0), 0.1); // Large tolerance for noise.
|
||||
// the first (plus tolerance).
|
||||
REQUIRE(std::abs(eigvec(0, 0)) == Approx(sqrt(2) / 2).epsilon(0.0035));
|
||||
REQUIRE(std::abs(eigvec(1, 0)) == Approx(sqrt(2) / 2).epsilon(0.0035));
|
||||
REQUIRE(eigvec(2, 0) == Approx(0.0).margin(0.1)); // Large tolerance for noise.
|
||||
|
||||
// The eigenvalues should sum to three.
|
||||
BOOST_REQUIRE_CLOSE(accu(eigval), 3.0, 0.1); // 10% tolerance.
|
||||
REQUIRE(accu(eigval) == Approx(3.0).epsilon(0.001));
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -13,20 +13,18 @@
|
||||
#include <mlpack/methods/random_forest/random_forest.hpp>
|
||||
#include <mlpack/methods/decision_tree/random_dimension_select.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
#include "serialization_catch.hpp"
|
||||
#include "test_catch_tools.hpp"
|
||||
#include "catch.hpp"
|
||||
#include "mock_categorical_data.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::tree;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(RandomForestTest);
|
||||
|
||||
/**
|
||||
* Make sure bootstrap sampling produces numbers in the dataset.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(BootstrapNoWeightsTest)
|
||||
TEST_CASE("BootstrapNoWeightsTest", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat dataset(1, 1000);
|
||||
dataset.row(0) = arma::linspace<arma::rowvec>(1000, 1999, 1000);
|
||||
@@ -44,16 +42,16 @@ BOOST_AUTO_TEST_CASE(BootstrapNoWeightsTest)
|
||||
Bootstrap<false>(dataset, labels, weights, bootstrapDataset,
|
||||
bootstrapLabels, bootstrapWeights);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(bootstrapDataset.n_cols, 1000);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapDataset.n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapLabels.n_elem, 1000);
|
||||
REQUIRE(bootstrapDataset.n_cols == 1000);
|
||||
REQUIRE(bootstrapDataset.n_rows == 1);
|
||||
REQUIRE(bootstrapLabels.n_elem == 1000);
|
||||
|
||||
// Check each dataset element.
|
||||
for (size_t i = 0; i < dataset.n_cols; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_GE(bootstrapDataset(0, i), 1000);
|
||||
BOOST_REQUIRE_LE(bootstrapDataset(0, i), 1999);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapLabels[i], 1);
|
||||
REQUIRE(bootstrapDataset(0, i) >= 1000);
|
||||
REQUIRE(bootstrapDataset(0, i) <= 1999);
|
||||
REQUIRE(bootstrapLabels[i] == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +59,7 @@ BOOST_AUTO_TEST_CASE(BootstrapNoWeightsTest)
|
||||
/**
|
||||
* Make sure bootstrap sampling produces numbers in the dataset.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(BootstrapWeightsTest)
|
||||
TEST_CASE("BootstrapWeightsTest", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat dataset(1, 1000);
|
||||
dataset.row(0) = arma::linspace<arma::rowvec>(1000, 1999, 1000);
|
||||
@@ -79,19 +77,19 @@ BOOST_AUTO_TEST_CASE(BootstrapWeightsTest)
|
||||
Bootstrap<true>(dataset, labels, weights, bootstrapDataset,
|
||||
bootstrapLabels, bootstrapWeights);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(bootstrapDataset.n_cols, 1000);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapDataset.n_rows, 1);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapLabels.n_elem, 1000);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapWeights.n_elem, 1000);
|
||||
REQUIRE(bootstrapDataset.n_cols == 1000);
|
||||
REQUIRE(bootstrapDataset.n_rows == 1);
|
||||
REQUIRE(bootstrapLabels.n_elem == 1000);
|
||||
REQUIRE(bootstrapWeights.n_elem == 1000);
|
||||
|
||||
// Check each dataset element.
|
||||
for (size_t i = 0; i < dataset.n_cols; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_GE(bootstrapDataset(0, i), 1000);
|
||||
BOOST_REQUIRE_LE(bootstrapDataset(0, i), 1999);
|
||||
BOOST_REQUIRE_EQUAL(bootstrapLabels[i], 1);
|
||||
BOOST_REQUIRE_GE(bootstrapWeights[i], 0.0);
|
||||
BOOST_REQUIRE_LE(bootstrapWeights[i], 1.0);
|
||||
REQUIRE(bootstrapDataset(0, i) >= 1000);
|
||||
REQUIRE(bootstrapDataset(0, i) <= 1999);
|
||||
REQUIRE(bootstrapLabels[i] == 1);
|
||||
REQUIRE(bootstrapWeights[i] >= 0.0);
|
||||
REQUIRE(bootstrapWeights[i] <= 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,7 +97,7 @@ BOOST_AUTO_TEST_CASE(BootstrapWeightsTest)
|
||||
/**
|
||||
* Make sure an empty forest cannot predict.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(EmptyClassifyTest)
|
||||
TEST_CASE("EmptyClassifyTest", "[RandomForestTest]")
|
||||
{
|
||||
RandomForest<> rf; // No training.
|
||||
|
||||
@@ -108,11 +106,11 @@ BOOST_AUTO_TEST_CASE(EmptyClassifyTest)
|
||||
arma::mat probabilities;
|
||||
size_t prediction;
|
||||
arma::vec pointProbabilities;
|
||||
BOOST_REQUIRE_THROW(rf.Classify(points, predictions), std::invalid_argument);
|
||||
BOOST_REQUIRE_THROW(rf.Classify(points.col(0)), std::invalid_argument);
|
||||
BOOST_REQUIRE_THROW(rf.Classify(points, predictions, probabilities),
|
||||
REQUIRE_THROWS_AS(rf.Classify(points, predictions), std::invalid_argument);
|
||||
REQUIRE_THROWS_AS(rf.Classify(points.col(0)), std::invalid_argument);
|
||||
REQUIRE_THROWS_AS(rf.Classify(points, predictions, probabilities),
|
||||
std::invalid_argument);
|
||||
BOOST_REQUIRE_THROW(rf.Classify(points.col(0), prediction,
|
||||
REQUIRE_THROWS_AS(rf.Classify(points.col(0), prediction,
|
||||
pointProbabilities), std::invalid_argument);
|
||||
}
|
||||
|
||||
@@ -120,7 +118,7 @@ BOOST_AUTO_TEST_CASE(EmptyClassifyTest)
|
||||
* Test unweighted numeric learning, making sure that we get better performance
|
||||
* than a single decision tree.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(UnweightedNumericLearningTest)
|
||||
TEST_CASE("UnweightedNumericLearningTest", "[RandomForestTest]")
|
||||
{
|
||||
// Load the vc2 dataset.
|
||||
arma::mat dataset;
|
||||
@@ -148,15 +146,15 @@ BOOST_AUTO_TEST_CASE(UnweightedNumericLearningTest)
|
||||
size_t rfCorrect = arma::accu(rfPredictions == testLabels);
|
||||
size_t dtCorrect = arma::accu(dtPredictions == testLabels);
|
||||
|
||||
BOOST_REQUIRE_GE(rfCorrect, dtCorrect * 0.9);
|
||||
BOOST_REQUIRE_GE(rfCorrect, size_t(0.7 * testDataset.n_cols));
|
||||
REQUIRE(rfCorrect >= dtCorrect * 0.9);
|
||||
REQUIRE(rfCorrect >= size_t(0.7 * testDataset.n_cols));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test weighted numeric learning, making sure that we get better performance
|
||||
* than a single decision tree.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(WeightedNumericLearningTest)
|
||||
TEST_CASE("WeightedNumericLearningTest", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat dataset;
|
||||
arma::Row<size_t> labels;
|
||||
@@ -200,15 +198,15 @@ BOOST_AUTO_TEST_CASE(WeightedNumericLearningTest)
|
||||
size_t rfCorrect = arma::accu(rfPredictions == testLabels);
|
||||
size_t dtCorrect = arma::accu(dtPredictions == testLabels);
|
||||
|
||||
BOOST_REQUIRE_GE(rfCorrect, dtCorrect * 0.9);
|
||||
BOOST_REQUIRE_GE(rfCorrect, size_t(0.7 * testDataset.n_cols));
|
||||
REQUIRE(rfCorrect >= dtCorrect * 0.9);
|
||||
REQUIRE(rfCorrect >= size_t(0.7 * testDataset.n_cols));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test unweighted categorical learning. Ensure that we get better performance
|
||||
* with a random forest.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(UnweightedCategoricalLearningTest)
|
||||
TEST_CASE("UnweightedCategoricalLearningTest", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat d;
|
||||
arma::Row<size_t> l;
|
||||
@@ -237,14 +235,14 @@ BOOST_AUTO_TEST_CASE(UnweightedCategoricalLearningTest)
|
||||
size_t rfCorrect = arma::accu(rfPredictions == testLabels);
|
||||
size_t dtCorrect = arma::accu(dtPredictions == testLabels);
|
||||
|
||||
BOOST_REQUIRE_GE(rfCorrect, dtCorrect - 25);
|
||||
BOOST_REQUIRE_GE(rfCorrect, size_t(0.7 * testData.n_cols));
|
||||
REQUIRE(rfCorrect >= dtCorrect - 25);
|
||||
REQUIRE(rfCorrect >= size_t(0.7 * testData.n_cols));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test weighted categorical learning.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(WeightedCategoricalLearningTest)
|
||||
TEST_CASE("WeightedCategoricalLearningTest", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat d;
|
||||
arma::Row<size_t> l;
|
||||
@@ -295,14 +293,14 @@ BOOST_AUTO_TEST_CASE(WeightedCategoricalLearningTest)
|
||||
size_t rfCorrect = arma::accu(rfPredictions == testLabels);
|
||||
size_t dtCorrect = arma::accu(dtPredictions == testLabels);
|
||||
|
||||
BOOST_REQUIRE_GE(rfCorrect, dtCorrect - 25);
|
||||
BOOST_REQUIRE_GE(rfCorrect, size_t(0.7 * testData.n_cols));
|
||||
REQUIRE(rfCorrect >= dtCorrect - 25);
|
||||
REQUIRE(rfCorrect >= size_t(0.7 * testData.n_cols));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a leaf size equal to the dataset size learns nothing.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(LeafSizeDatasetTest)
|
||||
TEST_CASE("LeafSizeDatasetTest", "[RandomForestTest]")
|
||||
{
|
||||
// Load the vc2 dataset.
|
||||
arma::mat dataset;
|
||||
@@ -324,19 +322,19 @@ BOOST_AUTO_TEST_CASE(LeafSizeDatasetTest)
|
||||
size_t majorityClass = predictions[0];
|
||||
arma::vec majorityProbs = probabilities.col(0);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(probabilities.n_rows, 3);
|
||||
BOOST_REQUIRE_EQUAL(probabilities.n_cols, dataset.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(predictions.n_elem, dataset.n_cols);
|
||||
REQUIRE(probabilities.n_rows == 3);
|
||||
REQUIRE(probabilities.n_cols == dataset.n_cols);
|
||||
REQUIRE(predictions.n_elem == dataset.n_cols);
|
||||
for (size_t i = 1; i < predictions.n_cols; ++i)
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(predictions[i], majorityClass);
|
||||
REQUIRE(predictions[i] == majorityClass);
|
||||
for (size_t j = 0; j < probabilities.n_rows; ++j)
|
||||
BOOST_REQUIRE_CLOSE(probabilities(j, i), majorityProbs[j], 1e-5);
|
||||
REQUIRE(probabilities(j, i) == Approx(majorityProbs[j]).epsilon(1e-7));
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we can serialize a random forest.
|
||||
BOOST_AUTO_TEST_CASE(SerializationTest)
|
||||
TEST_CASE("RandomForestSerializationTest", "[RandomForestTest]")
|
||||
{
|
||||
// Load the vc2 dataset.
|
||||
arma::mat dataset;
|
||||
@@ -372,7 +370,7 @@ BOOST_AUTO_TEST_CASE(SerializationTest)
|
||||
* Test that RandomForest::Train() returns finite average entropy on numeric
|
||||
* dataset.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestNumericTrainReturnEntropy)
|
||||
TEST_CASE("RandomForestNumericTrainReturnEntropy", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat dataset;
|
||||
arma::Row<size_t> labels;
|
||||
@@ -400,20 +398,20 @@ BOOST_AUTO_TEST_CASE(RandomForestNumericTrainReturnEntropy)
|
||||
RandomForest<GiniGain, RandomDimensionSelect> rf;
|
||||
double entropy = rf.Train(dataset, labels, 3, 10, 1);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(std::isfinite(entropy), true);
|
||||
REQUIRE(std::isfinite(entropy) == true);
|
||||
|
||||
// Test random forest on weighted numeric dataset.
|
||||
RandomForest<GiniGain, RandomDimensionSelect> wrf;
|
||||
entropy = wrf.Train(dataset, labels, 3, weights, 10, 1);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(std::isfinite(entropy), true);
|
||||
REQUIRE(std::isfinite(entropy) == true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that RandomForest::Train() returns finite average entropy on categorical
|
||||
* dataset.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RandomForestCategoricalTrainReturnEntropy)
|
||||
TEST_CASE("RandomForestCategoricalTrainReturnEntropy", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat d;
|
||||
arma::Row<size_t> l;
|
||||
@@ -447,20 +445,20 @@ BOOST_AUTO_TEST_CASE(RandomForestCategoricalTrainReturnEntropy)
|
||||
double entropy = rf.Train(fullData, di, fullLabels, 5, 15 /* 15 trees */, 1,
|
||||
1e-7, 0, MultipleRandomDimensionSelect(3));
|
||||
|
||||
BOOST_REQUIRE_EQUAL(std::isfinite(entropy), true);
|
||||
REQUIRE(std::isfinite(entropy) == true);
|
||||
|
||||
// Test random forest on weighted categorical dataset.
|
||||
RandomForest<> wrf;
|
||||
entropy = wrf.Train(fullData, di, fullLabels, 5, weights, 15 /* 15 trees */,
|
||||
1, 1e-7, 0, MultipleRandomDimensionSelect(3));
|
||||
|
||||
BOOST_REQUIRE_EQUAL(std::isfinite(entropy), true);
|
||||
REQUIRE(std::isfinite(entropy) == true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that different trees get generated.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DifferentTreesTest)
|
||||
TEST_CASE("DifferentTreesTest", "[RandomForestTest]")
|
||||
{
|
||||
arma::mat d(10, 100, arma::fill::randu);
|
||||
arma::Row<size_t> l(100);
|
||||
@@ -484,7 +482,5 @@ BOOST_AUTO_TEST_CASE(DifferentTreesTest)
|
||||
++trial;
|
||||
}
|
||||
|
||||
BOOST_REQUIRE_EQUAL(success, true);
|
||||
REQUIRE(success == true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
Reference in New Issue
Block a user